Chromium Code Reviews| OLD | NEW |
|---|---|
| (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__)) | |
|
nodir
2015/09/29 16:46:05
You can check that $GOROOT equals this and suggest
Vadim Sh.
2015/09/29 19:49:34
GOROOT points to goland SDK. GOPATH have multiple
| |
| 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 get_deps(pkg_glob): | |
|
tandrii(chromium)
2015/09/29 10:17:27
Add caching of the result, and it'll be so much fa
Vadim Sh.
2015/09/29 19:49:34
Added cache, it doesn't make much difference.
| |
| 36 """Returns a set of imported dependencies.""" | |
| 37 cmd = ['go', 'list', '-f', '{{ join .Deps "\\n" }}', pkg_glob] | |
|
nodir
2015/09/29 16:46:05
this must be ran with GO_DIR as current dir, becau
Vadim Sh.
2015/09/29 19:49:34
relpath(...) below builds correct path regardless
nodir
2015/09/29 20:39:13
I just ran go/clean_goop.py from root and it error
| |
| 38 print 'Running ', cmd | |
| 39 deps = subprocess.check_output(cmd).strip() | |
| 40 return sorted(set(deps.splitlines())) | |
| 41 | |
| 42 | |
| 43 def get_all_goop(): | |
|
tandrii(chromium)
2015/09/29 10:17:27
and maybe cache this too?
Vadim Sh.
2015/09/29 19:49:33
Done.
| |
| 44 """Returns a list of packages specified in Goopfile.lock.""" | |
| 45 with open(os.path.join(GO_DIR, 'Goopfile.lock'), 'rt') as f: | |
|
nodir
2015/09/29 16:46:05
't' mode is unnecessary to specify since it is def
Vadim Sh.
2015/09/29 19:49:34
r is too for that matter
| |
| 46 goop = f.read() | |
|
tandrii(chromium)
2015/09/29 10:17:27
nit: return [l.split()[0] for l in f]
Vadim Sh.
2015/09/29 19:49:34
Done.
| |
| 47 return [line.split()[0] for line in goop.splitlines()] | |
| 48 | |
| 49 | |
| 50 def get_used_goop(deps): | |
| 51 """Returns set of packages in Goopfile.lock that cover a dependency list.""" | |
| 52 used = set() | |
| 53 for pkg in get_all_goop(): | |
| 54 for dep in deps: | |
| 55 # If goop pkg covers at least one dependency, it is used. | |
| 56 if dep.startswith(pkg): | |
|
nodir
2015/09/29 16:46:05
if dep == pkg or dep.startswith(pkg+'/'):
Vadim Sh.
2015/09/29 19:49:34
Done.
| |
| 57 used.add(pkg) | |
| 58 break | |
| 59 return used | |
| 60 | |
| 61 | |
| 62 def main(): | |
| 63 all_deps = set(EXCEPTIONS) | |
| 64 | |
| 65 # We want to enumerate packages in infra/go/src/... and only them (not all | |
| 66 # packages in GOPAHT, since we don't want to enumerate vendored packages). | |
|
nodir
2015/09/29 16:46:05
GOPATH
| |
| 67 # A package glob needs to start with '.' or '..' to be interpreted as file | |
| 68 # system path. See 'go help packages'. | |
| 69 go_dir_rel = os.path.relpath(os.path.join(GO_DIR)) | |
|
nodir
2015/09/29 16:46:05
os.path.join(GO_DIR) == GO_DIR ? Am I missing some
Vadim Sh.
2015/09/29 19:49:34
There used to be something else there.
| |
| 70 assert go_dir_rel.startswith('.') | |
| 71 all_deps.update(get_deps(os.path.join(go_dir_rel, 'src', '...'))) | |
| 72 | |
| 73 # Tools build by bootstrap script may not be directly referenced by src/ code. | |
| 74 for tool in bootstrap.VENDORED_TOOLS: | |
| 75 all_deps.add(tool) | |
| 76 all_deps.update(get_deps(tool)) | |
| 77 | |
| 78 # all_deps is all direct dependencies of infra/go/src code. Find what part of | |
| 79 # Goopfile.lock covers them. Then recurse into them. Note that Goopfile | |
| 80 # may specify a parent package of a package used in actual code. So recursing | |
| 81 # into deps of that parent package may reveal more dependencies. | |
| 82 goop_deps = set() | |
| 83 while True: | |
| 84 for pkg in goop_deps: | |
|
nodir
2015/09/29 16:46:05
goop_deps is set() in the first iteration. Then it
Vadim Sh.
2015/09/29 19:49:33
Done.
| |
| 85 all_deps.update(get_deps(pkg + '/...')) | |
| 86 new_goop_deps = get_used_goop(all_deps) | |
| 87 if new_goop_deps == goop_deps: | |
| 88 break | |
| 89 goop_deps = new_goop_deps | |
| 90 | |
| 91 # Find what is not used. | |
| 92 unused = [p for p in get_all_goop() if p not in goop_deps] | |
| 93 if unused: | |
| 94 print '-' * 80 | |
| 95 print 'Consider removing from Goopfile following packages:' | |
|
tandrii(chromium)
2015/09/29 10:17:27
nit: s/following/the following
Vadim Sh.
2015/09/29 19:49:34
Done.
| |
| 96 print '\n'.join(unused) | |
| 97 else: | |
| 98 print 'Hooray! All Goopfile packages seems to be in use.' | |
|
tandrii(chromium)
2015/09/29 10:17:28
s/seems/seem
Vadim Sh.
2015/09/29 19:49:34
Done.
| |
| 99 | |
| 100 return 0 | |
| 101 | |
| 102 | |
| 103 if __name__ == '__main__': | |
| 104 sys.exit(main()) | |
| OLD | NEW |