diff options
author | Adam Spiers <git@adamspiers.org> | 2016-05-26 00:28:25 +0100 |
---|---|---|
committer | Adam Spiers <git@adamspiers.org> | 2017-01-02 13:06:39 +0000 |
commit | d601e35f6ea42eb6110e3d1449d03f16a1da3f10 (patch) | |
tree | 8f2a9a399435b4c0ed9cc8aabe5d5a850779f39b | |
parent | e4fb3d9eb288b3f0ed8cce1e8e58bd805ef3eed0 (diff) | |
download | git-deps-d601e35f6ea42eb6110e3d1449d03f16a1da3f10.tar.gz |
allow passing a revision range to CLI or web UI
Now revision ranges like A..B or A...B are also accepted, and then git
deps will analyse the dependencies for all revisions in that range.
In the CLI invocation, if a dependency is encountered more than once
from separate commits, it will only be output once.
-rwxr-xr-x | git-deps.py | 82 | ||||
-rw-r--r-- | html/git-deps.html | 2 | ||||
-rw-r--r-- | html/js/git-deps-data.coffee | 2 | ||||
-rw-r--r-- | html/js/git-deps-graph.coffee | 13 |
4 files changed, 71 insertions, 28 deletions
diff --git a/git-deps.py b/git-deps.py index 568abfa..8c3572e 100755 --- a/git-deps.py +++ b/git-deps.py @@ -107,6 +107,19 @@ class CLIDependencyListener(DependencyListener): too long for useful output if recursion is enabled. """ + def __init__(self, options): + super(CLIDependencyListener, self).__init__(options) + + # Count each mention of each revision, so we can avoid duplicating + # commits in the output. + self._revs = {} + + def new_commit(self, commit): + rev = commit.hex + if rev not in self._revs: + self._revs[rev] = 0 + self._revs[rev] += 1 + def new_dependency(self, dependent, dependency, path, line_num): dependent_sha1 = dependent.hex dependency_sha1 = dependency.hex @@ -117,10 +130,10 @@ class CLIDependencyListener(DependencyListener): else: print("%s %s" % (dependent_sha1, dependency_sha1)) else: - if not self.options.log: + if not self.options.log and self._revs[dependency_sha1] <= 1: print(dependency_sha1) - if self.options.log: + if self.options.log and self._revs[dependency_sha1] <= 1: cmd = [ 'git', '--no-pager', @@ -281,6 +294,12 @@ class GitUtils(object): return matching + @classmethod + def rev_list(cls, rev_range): + cmd = ['git', 'rev-list', rev_range] + return subprocess.check_output(cmd).strip().split('\n') + + class InvalidCommitish(StandardError): def __init__(self, commitish): self.commitish = commitish @@ -367,6 +386,9 @@ class DependencyDetector(object): logger.addHandler(handler) return logger + def seen_commit(self, rev): + return rev in self.commits + def get_commit(self, rev): if rev in self.commits: return self.commits[rev] @@ -670,11 +692,12 @@ def cli(options, args): detector.add_listener(listener) - for dependent_rev in args: - try: - detector.find_dependencies(dependent_rev) - except KeyboardInterrupt: - pass + for revspec in args: + for rev in GitUtils.rev_list(revspec): + try: + detector.find_dependencies(rev) + except KeyboardInterrupt: + pass if options.json: print(json.dumps(listener.json(), sort_keys=True, indent=4)) @@ -743,26 +766,43 @@ def serve(options): client_options['repo_path'] = os.getcwd() return jsonify(client_options) - @webserver.route('/deps.json/<commitish>') - def deps(commitish): + @webserver.route('/deps.json/<revspec>') + def deps(revspec): detector = DependencyDetector(options) listener = JSONDependencyListener(options) detector.add_listener(listener) - try: - root_commit = detector.get_commit(commitish) - except InvalidCommitish as e: - return json_error( - 422, 'Invalid commitish', - "Could not resolve commitish '%s'" % commitish, - commitish=commitish) + if '..' in revspec: + try: + revisions = GitUtils.rev_list(revspec) + except subprocess.CalledProcessError as e: + return json_err( + 422, 'Invalid revision range', + "Could not resolve revision range '%s'" % revspec, + revspec=revspec) + else: + revisions = [revspec] + + for rev in revisions: + try: + commit = detector.get_commit(rev) + except InvalidCommitish as e: + return json_error( + 422, 'Invalid revision', + "Could not resolve revision '%s'" % rev, + rev=rev) + + detector.find_dependencies(rev) + + tip_commit = detector.get_commit(revisions[0]) + tip_sha1 = tip_commit.hex - detector.find_dependencies(commitish) json = listener.json() - json['root'] = { - 'commitish': commitish, - 'sha1': root_commit.hex, - 'abbrev': GitUtils.abbreviate_sha1(root_commit.hex), + json['query'] = { + 'revspec': revspec, + 'revisions': revisions, + 'tip_sha1': tip_sha1, + 'tip_abbrev': GitUtils.abbreviate_sha1(tip_sha1), } return jsonify(json) diff --git a/html/git-deps.html b/html/git-deps.html index 2957e74..848ccad 100644 --- a/html/git-deps.html +++ b/html/git-deps.html @@ -26,7 +26,7 @@ </p> <form class="commitish" action="#"> - Detect dependencies for commit: + Detect dependencies for: <input type="text" name="commitish" size="20" value="master" autofocus /> <button>Submit</button> diff --git a/html/js/git-deps-data.coffee b/html/js/git-deps-data.coffee index 9034b18..34715a3 100644 --- a/html/js/git-deps-data.coffee +++ b/html/js/git-deps-data.coffee @@ -82,7 +82,7 @@ add_data = (data) -> return [ new_nodes new_deps - data.root + data.query ] return false diff --git a/html/js/git-deps-graph.coffee b/html/js/git-deps-graph.coffee index b2d36fa..299ed0b 100644 --- a/html/js/git-deps-graph.coffee +++ b/html/js/git-deps-graph.coffee @@ -356,13 +356,16 @@ launch_viewer = (d) -> new_data_notification = (new_data) -> new_nodes = new_data[0] new_deps = new_data[1] - root = new_data[2] + query = new_data[2] notification = - if root.commitish == root.sha1 - "Analysed dependencies of #{root.abbrev}" + if query.revspec == query.tip_sha1 + "Analysed dependencies of #{query.revspec}" + else if query.revisions.length == 1 + "<span class=\"commit-ref\">#{query.revspec}</span> + resolved as #{query.tip_abbrev}" else - "<span class=\"commit-ref\">#{root.commitish}</span> - resolved as #{root.sha1}" + "<span class=\"commit-ref\">#{query.revspec}</span> + expanded; tip is #{query.tip_abbrev}" notification += "<p>#{new_nodes} new commit" notification += "s" unless new_nodes == 1 notification += "; #{new_deps} new " + |