Last active
July 27, 2020 16:15
-
-
Save gooooloo/6d959f6a2ed48357523d8441ce0006ed to your computer and use it in GitHub Desktop.
In some of visual studio solution I met, there are very much more projects inside. This is a simple script to extract and simplify the dependencies and generate VBA of Visio to draw the diagram better visualization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import os | |
import sys | |
def vba_vso_name(text): | |
ans = text.replace(' ', '_').replace('.', '_') | |
assert re.compile(r'^\w*$').match(ans) | |
return ans | |
def generate_VBA(d_dir_dep): | |
VBA = r''' | |
Sub aaa() | |
Dim vsoPages As Visio.Pages | |
Dim vsoPage As Visio.Page | |
Dim vsoDocument As Visio.Document | |
Dim Textline As String | |
Dim vsoShape As Visio.Shape | |
''' | |
for i,x in enumerate(list(d_dir_dep.keys())): | |
vsoname = vba_vso_name(x) | |
VBA += rf''' | |
Set {vsoname} = ActivePage.DrawRectangle({2*0}, {11.3-0.3*i}, {2*0} + 4, {11.0 - 0.3*i}) | |
{vsoname}.Text = "{x}" | |
{vsoname}.CellsSRC(visSectionCharacter, 0, visCharacterSize).FormulaU = "MIN(1,Height/TEXTHEIGHT(TheText,Width))*13&""pt""" | |
''' | |
for x in d_dir_dep: | |
for y in d_dir_dep[x]: | |
xname = vba_vso_name(x) | |
yname = vba_vso_name(y) | |
VBA += rf''' | |
Set conn = ActivePage.Drop(Visio.Application.ConnectorToolDataObject, 1, 4) | |
conn.Cells("BeginX").GlueTo {xname}.Cells("PinX") | |
conn.Cells("EndX").GlueTo {yname}.Cells("PinX") | |
''' | |
VBA += r''' | |
End Sub | |
''' | |
return VBA | |
def main(): | |
sln_path = sys.argv[1] if len(sys.argv) > 1 else None | |
if not sln_path: | |
print(f'usage: main.py /path/to/*.sln') | |
exit(1) | |
with open(sln_path, 'rt') as f: | |
all_projectes = f.readlines() | |
all_projectes = [re.compile(fr'^Project.* = (.*csproj.*)$').match(x) for x in all_projectes] | |
all_projectes = [x.group(1) for x in all_projectes if x] | |
all_projectes = [x for x in all_projectes if x] | |
all_projectes = [x.split(',') for x in all_projectes] | |
all_projectes = [[y.split('"')[1] for y in x] for x in all_projectes] | |
all_projectes = [(x, os.path.join(os.path.dirname(sln_path), proj_path)) for x,proj_path,_ in all_projectes] | |
all_projectes = [(x, os.path.abspath(proj_path)) for x,proj_path in all_projectes] | |
d_path_projname = {proj_path: proj_name for proj_name,proj_path in all_projectes} | |
d_direct_dep = {} | |
for proj_name,proj_path in all_projectes: | |
d_direct_dep[proj_name] = set() | |
with open(proj_path, 'rt') as pf: | |
deps = pf.readlines() | |
deps = [line for line in deps if '<ProjectReference Include=' in line] | |
deps = [line.split('ProjectReference Include="')[1].split('"')[0] for line in deps] | |
deps = [os.path.join(os.path.dirname(proj_path), line) for line in deps] | |
deps = [os.path.abspath(line) for line in deps] | |
d_direct_dep[proj_name] = set(d_path_projname[y] for y in deps if y in d_path_projname) | |
d_all_dep = {} | |
for x in d_direct_dep: | |
d_all_dep[x] = set() | |
queue = list(d_direct_dep[x]) | |
while queue: | |
head,queue = queue[0],queue[1:] | |
d_all_dep[x].add(head) | |
for nn in d_direct_dep[head]: | |
if nn not in d_all_dep[x]: | |
queue.append(nn) | |
for x in d_direct_dep: | |
for y in list(d_direct_dep[x]): | |
if any(y in d_all_dep[z] for z in d_direct_dep[x]): | |
d_direct_dep[x].remove(y) | |
d_direct_dep = {x:d_direct_dep[x] for x in d_direct_dep if 'test' not in x.lower()} | |
d_direct_dep = {x:[y for y in d_direct_dep[x] if y in d_direct_dep.keys()] for x in d_direct_dep} | |
for x in sorted(d_direct_dep.keys()): | |
print(x, '-->', d_direct_dep[x]) | |
print(generate_VBA(d_direct_dep)) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment