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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « go/README.md ('k') | go/roll_goop.py » ('j') | go/roll_goop.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: go/clean_goop.py
diff --git a/go/clean_goop.py b/go/clean_goop.py
new file mode 100755
index 0000000000000000000000000000000000000000..36ae6e81c419bf01a5ae55fac205153a97e7f924
--- /dev/null
+++ b/go/clean_goop.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Suggests what Goop file entries can be removed.
+
+Horribly slow, but simple. Evaluates recursive dependencies of all packages
+in infra/go/... (including github ones) and compares them against Goopfile.lock
+entries.
+
+Supposed to be called under activated go environment.
+"""
+
+import os
+import subprocess
+import sys
+
+# For VENDORED_TOOLS.
+import bootstrap
+
+
+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
+
+
+# List of Goopfile.lock entries we want to keep because they are imported only
+# when building on Windows (and thus detected as unused when script is used
+# on Linux).
+EXCEPTIONS = [
+ 'github.com/mattn/go-isatty',
+ 'github.com/olekukonko/ts',
+]
+
+
+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.
+ """Returns a set of imported dependencies."""
+ 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
+ print 'Running ', cmd
+ deps = subprocess.check_output(cmd).strip()
+ return sorted(set(deps.splitlines()))
+
+
+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.
+ """Returns a list of packages specified in Goopfile.lock."""
+ 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
+ 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.
+ return [line.split()[0] for line in goop.splitlines()]
+
+
+def get_used_goop(deps):
+ """Returns set of packages in Goopfile.lock that cover a dependency list."""
+ used = set()
+ for pkg in get_all_goop():
+ for dep in deps:
+ # If goop pkg covers at least one dependency, it is used.
+ 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.
+ used.add(pkg)
+ break
+ return used
+
+
+def main():
+ all_deps = set(EXCEPTIONS)
+
+ # We want to enumerate packages in infra/go/src/... and only them (not all
+ # packages in GOPAHT, since we don't want to enumerate vendored packages).
nodir 2015/09/29 16:46:05 GOPATH
+ # A package glob needs to start with '.' or '..' to be interpreted as file
+ # system path. See 'go help packages'.
+ 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.
+ assert go_dir_rel.startswith('.')
+ all_deps.update(get_deps(os.path.join(go_dir_rel, 'src', '...')))
+
+ # Tools build by bootstrap script may not be directly referenced by src/ code.
+ for tool in bootstrap.VENDORED_TOOLS:
+ all_deps.add(tool)
+ all_deps.update(get_deps(tool))
+
+ # all_deps is all direct dependencies of infra/go/src code. Find what part of
+ # Goopfile.lock covers them. Then recurse into them. Note that Goopfile
+ # may specify a parent package of a package used in actual code. So recursing
+ # into deps of that parent package may reveal more dependencies.
+ goop_deps = set()
+ while True:
+ 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.
+ all_deps.update(get_deps(pkg + '/...'))
+ new_goop_deps = get_used_goop(all_deps)
+ if new_goop_deps == goop_deps:
+ break
+ goop_deps = new_goop_deps
+
+ # Find what is not used.
+ unused = [p for p in get_all_goop() if p not in goop_deps]
+ if unused:
+ print '-' * 80
+ 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.
+ print '\n'.join(unused)
+ else:
+ 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.
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
« no previous file with comments | « go/README.md ('k') | go/roll_goop.py » ('j') | go/roll_goop.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698