Changeset - c76638100ca0
[Not reviewed]
default
0 1 0
Mads Kiilerich (mads) - 5 years ago 2020-12-29 22:30:48
mads@kiilerich.com
deps: also report unseen known violations
1 file changed with 4 insertions and 2 deletions:
0 comments (0 inline, 0 general)
scripts/deps.py
Show inline comments
 
@@ -132,62 +132,62 @@ conftest
 
normal_modules = set('''
 
kallithea
 
kallithea.controllers.base
 
kallithea.lib
 
kallithea.lib.auth
 
kallithea.lib.auth_modules
 
kallithea.lib.celerylib
 
kallithea.lib.db_manage
 
kallithea.lib.helpers
 
kallithea.lib.hooks
 
kallithea.lib.indexers
 
kallithea.lib.utils
 
kallithea.lib.utils2
 
kallithea.lib.vcs
 
kallithea.lib.webutils
 
kallithea.model
 
kallithea.model.async_tasks
 
kallithea.model.scm
 
kallithea.templates.py
 
'''.split())
 

	
 
shown_modules = normal_modules | top_modules
 

	
 
# break the chains somehow - this is a cleanup TODO list
 
known_violations = [
 
known_violations = set([
 
('kallithea.lib.auth_modules', 'kallithea.lib.auth'),  # needs base&facade
 
('kallithea.lib.utils', 'kallithea.model'),  # clean up utils
 
('kallithea.lib.utils', 'kallithea.model.db'),
 
('kallithea.lib.utils', 'kallithea.model.scm'),
 
('kallithea.model.async_tasks', 'kallithea.lib.hooks'),
 
('kallithea.model.async_tasks', 'kallithea.lib.indexers'),
 
('kallithea.model.async_tasks', 'kallithea.model'),
 
('kallithea.model', 'kallithea.lib.auth'),  # auth.HasXXX
 
('kallithea.model', 'kallithea.lib.auth_modules'),  # validators
 
('kallithea.model', 'kallithea.lib.hooks'),  # clean up hooks
 
('kallithea.model', 'kallithea.model.scm'),
 
('kallithea.model.scm', 'kallithea.lib.hooks'),
 
]
 
])
 

	
 
extra_edges = [
 
('kallithea.config', 'kallithea.controllers'),  # through TG
 
('kallithea.lib.auth', 'kallithea.lib.auth_modules'),  # custom loader
 
]
 

	
 

	
 
def normalize(s):
 
    """Given a string with dot path, return the string it should be shown as."""
 
    parts = s.replace('.__init__', '').split('.')
 
    short_2 = '.'.join(parts[:2])
 
    short_3 = '.'.join(parts[:3])
 
    short_4 = '.'.join(parts[:4])
 
    if parts[0] in ['scripts', 'contributor_data', 'i18n_utils']:
 
        return 'scripts'
 
    if short_3 == 'kallithea.model.meta':
 
        return 'kallithea.model.db'
 
    if parts[:4] == ['kallithea', 'lib', 'vcs', 'ssh']:
 
        return 'kallithea.lib.vcs.ssh'
 
    if short_4 in shown_modules:
 
        return short_4
 
    if short_3 in shown_modules:
 
        return short_3
 
    if short_2 in shown_modules:
 
@@ -250,44 +250,46 @@ Usage:
 

	
 
    normalized_dep_edges = set()
 
    for dot_name, full_imp in import_deps:
 
        a = normalize(dot_name)
 
        b = normalize(full_imp)
 
        if a is None or b is None or a == b:
 
            continue
 
        normalized_dep_edges.add((a, b))
 
        #print((dot_name, full_imp, a, b))
 
    normalized_dep_edges.update(extra_edges)
 

	
 
    unseen_shown_modules = shown_modules.difference(a for a, b in normalized_dep_edges).difference(b for a, b in normalized_dep_edges)
 
    assert not unseen_shown_modules, unseen_shown_modules
 

	
 
    with open('deps.dot', 'w') as f:
 
        f.write('digraph {\n')
 
        f.write('subgraph { rank = same; %s}\n' % ''.join('"%s"; ' % s for s in sorted(top_modules)))
 
        f.write('subgraph { rank = same; %s}\n' % ''.join('"%s"; ' % s for s in sorted(only_imported)))
 
        for a, b in sorted(normalized_dep_edges):
 
            f.write('  "%s" -> "%s"%s\n' % (a, b, ' [color=red]' if (a, b) in known_violations else ' [color=green]' if (a, b) in extra_edges else ''))
 
        f.write('}\n')
 

	
 
    # verify dependencies by untangling dependency chain bottom-up:
 
    todo = set(normalized_dep_edges)
 
    unseen_violations = known_violations.difference(todo)
 
    assert not unseen_violations, unseen_violations
 
    for x in known_violations:
 
        todo.remove(x)
 

	
 
    while todo:
 
        depending = set(a for a, b in todo)
 
        depended = set(b for a, b in todo)
 
        drop = depended - depending
 
        if not drop:
 
            print('ERROR: cycles:', len(todo))
 
            for x in sorted(todo):
 
                print('%s,' % (x,))
 
            raise SystemExit(1)
 
        #for do_b in sorted(drop):
 
        #    print('Picking', do_b, '- unblocks:', ' '.join(a for a, b in sorted((todo)) if b == do_b))
 
        todo = set((a, b) for a, b in todo if b in depending)
 
        #print()
 

	
 

	
 
if __name__ == '__main__':
 
    main(sys.argv[1:])
0 comments (0 inline, 0 general)