Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: go/clean_goop.py

Issue 1375553003: go: Roll Goopfile, remove two no longer used packages. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « go/README.md ('k') | go/roll_goop.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Suggests what Goop file entries can be removed.
7
8 Horribly slow, but simple. Evaluates recursive dependencies of all packages
9 in infra/go/... (including github ones) and compares them against Goopfile.lock
10 entries.
11
12 Supposed to be called under activated go environment.
13 """
14
15 import os
16 import subprocess
17 import sys
18
19 # For VENDORED_TOOLS.
20 import bootstrap
21
22
23 GO_DIR = os.path.dirname(os.path.abspath(__file__))
24
25
26 # List of Goopfile.lock entries we want to keep because they are imported only
27 # when building on Windows (and thus detected as unused when script is used
28 # on Linux).
29 EXCEPTIONS = [
30 'github.com/mattn/go-isatty',
31 'github.com/olekukonko/ts',
32 ]
33
34
35 def dumbcache(f):
36 """Simple cache decorator for functions with hashable args."""
37 cache = {}
38 def wrapper(*args):
39 if args not in cache:
40 cache[args] = f(*args)
41 return cache[args]
42 return wrapper
43
44
45 @dumbcache
46 def get_deps(pkg_glob):
47 """Returns a set of imported dependencies."""
48 cmd = ['go', 'list', '-f', '{{ join .Deps "\\n" }}', pkg_glob]
49 print 'Running ', cmd
50 deps = subprocess.check_output(cmd).strip()
51 return sorted(set(deps.splitlines()))
52
53
54 @dumbcache
55 def get_all_goop():
56 """Returns a list of packages specified in Goopfile.lock."""
57 with open(os.path.join(GO_DIR, 'Goopfile.lock')) as f:
58 return [l.split()[0] for l in f]
59
60
61 def get_used_goop(deps):
62 """Returns set of packages in Goopfile.lock that cover a dependency list."""
63 used = set()
64 for pkg in get_all_goop():
65 for dep in deps:
66 # If goop pkg covers at least one dependency, it is used.
67 if dep == pkg or dep.startswith(pkg + '/'):
68 used.add(pkg)
69 break
70 return used
71
72
73 def main():
74 all_deps = set(EXCEPTIONS)
75
76 # We want to enumerate packages in infra/go/src/... and only them (not all
77 # packages in GOPATH, since we don't want to enumerate vendored packages).
78 # A package glob needs to start with '.' or '..' to be interpreted as file
79 # system path. See 'go help packages'.
80 go_dir_rel = os.path.relpath(GO_DIR)
81 assert go_dir_rel.startswith('.')
82 all_deps.update(get_deps(os.path.join(go_dir_rel, 'src', '...')))
83
84 # Tools build by bootstrap script may not be directly referenced by src/ code.
85 for tool in bootstrap.VENDORED_TOOLS:
86 all_deps.add(tool)
87 all_deps.update(get_deps(tool))
88
89 # all_deps is all direct dependencies of infra/go/src code. Find what part of
90 # Goopfile.lock covers them. Then recurse into them. Note that Goopfile
91 # may specify a parent package of a package used in actual code. So recursing
92 # into deps of that parent package may reveal more dependencies.
93 goop_deps = set()
94 while True:
95 new_goop_deps = get_used_goop(all_deps)
96 if new_goop_deps == goop_deps:
97 break
98 goop_deps = new_goop_deps
99 for pkg in goop_deps:
100 all_deps.update(get_deps(pkg + '/...'))
101
102 # Find what is not used.
103 unused = [p for p in get_all_goop() if p not in goop_deps]
104 if unused:
105 print '-' * 80
106 print 'Consider removing from Goopfile the following packages:'
107 print '\n'.join(unused)
108 else:
109 print 'Hooray! All Goopfile packages seem to be in use.'
110
111 return 0
112
113
114 if __name__ == '__main__':
115 sys.exit(main())
OLDNEW
« no previous file with comments | « go/README.md ('k') | go/roll_goop.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698