capillary 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capillary (0.2.3)
4
+ capillary (0.3.0)
5
5
  json (~> 1.5.1)
6
6
 
7
7
  GEM
data/README CHANGED
@@ -18,7 +18,13 @@ Capillary.rb emits a JSON array consisting of JSON objects in the
18
18
  following form (starting with seqId=0):
19
19
 
20
20
  [[{
21
- "refNames": ["HEAD", "origin/production", "production"],
21
+ "refs": {
22
+ "remotes": {
23
+ "origin": { "production" }
24
+ },
25
+ "heads": ["production", "master"],
26
+ "tags": ["v2.0.0"]
27
+ },
22
28
  "seqId": 0,
23
29
  "committedAt": "Fri Jul 15 07:23:44 +0200 2011",
24
30
  "parentIds": ["8f38426b1641a20511f6eeb6878f2e1e00712df2", "ce7de03fc2cb6114d2f859fefc996e7fffa2d7f6"],
@@ -26,7 +32,7 @@ following form (starting with seqId=0):
26
32
  "committerEmail": "christian@gitorious.org",
27
33
  "message": "Merge branch 'master' into production"
28
34
  }, {
29
- "refNames": [],
35
+ "refs": { "heads": [], "tags": [], "remotes": {} },
30
36
  "seqId": 1,
31
37
  "committedAt": "Thu Jun 16 10:20:03 +0200 2011",
32
38
  "parentIds": ["0443fcdf66df410993441b617d14dab121245ff7"],
@@ -43,8 +49,8 @@ following form (starting with seqId=0):
43
49
  * id: The commit sha
44
50
  * parentIds: The commit sha of all parent commits of this commit
45
51
  * message: The commit message
46
- * Ref names: Relevant names of branches that concern the commit
47
- in question
52
+ * refs: Relevant names of heads, tags, remotes and others that concern the
53
+ commit in question
48
54
 
49
55
  Note that the JSON emitted is a nested array - an array of "paths", where each
50
56
  path is an array of commits.
@@ -138,14 +144,19 @@ Capillary parses output from Git log, in the format as specified in
138
144
  test/fixtures/single_commit.txt. This output was generated from Git using the
139
145
  following command:
140
146
 
141
- git log --pretty=format:"%H§%P§%ad§%ae§%d§%s§"
147
+ git log --pretty=format:"%H§%P§%ad§%ae§%d§%s§" --decorate=full
142
148
 
143
- You may also use the following command, which orders commits slightly
144
- differently, and is perhaps more suitable for graph generation. Note that this
145
- command outputs an extra line per commit, which may be an issue if I/O is a
146
- concern:
149
+ This will produce a graph where commits are strictly ordered by date. To get a
150
+ graph similar to that produced by `git log --graph`, you add - surprise - the
151
+ `--graph` option:
147
152
 
148
- git rev-list --pretty=format:"%H§%P§%ad§%ae§%d§%s§" --topo-order -50 master
153
+ git log --pretty=format:"%H§%P§%ad§%ae§%d§%s§" --decorate=full --graph
154
+
155
+ Both of these will produce a graph that includes all ancestors to the current
156
+ HEAD. If you want everything - including branches not merged to the current
157
+ branch, use `--all`:
158
+
159
+ git log --pretty=format:"%H§%P§%ad§%ae§%d§%s§" --decorate=full --graph --all
149
160
 
150
161
  The name
151
162
  --------
data/bin/capillary CHANGED
@@ -1,6 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
2
3
  require "capillary/log_parser"
3
4
 
4
5
  parser = Capillary::LogParser.new
5
- $stdin.each { |line| parser << line }
6
- puts parser.to_json
6
+
7
+ if ARGV == ["-v"] || ARGV == ["--version"]
8
+ require "capillary/version"
9
+ puts "Capillary #{Capillary::VERSION}"
10
+ elsif ARGV == ["-h"] || ARGV == ["--help"]
11
+ puts "Convert git log on STDIN to JSON suitable for further processing by capillary.js"
12
+ puts ""
13
+ puts "Generate suitable log output from Git like this: (where --all is optional)"
14
+ puts "git log --pretty=format:\"%H§%P§%ad§%ae§%d§%s§\" --decorate=full --graph --all"
15
+ puts ""
16
+ puts "Generate ASCII graph if you have installed capillary.js:"
17
+ puts "git log --pretty=format:\"%H§%P§%ad§%ae§%d§%s§\" --decorate=full --graph --all | capillary | capillary-js"
18
+ else
19
+ $stdin.each { |line| parser << line }
20
+ puts parser.to_json
21
+ end
@@ -15,14 +15,20 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
+ require "json"
18
19
  require "time"
20
+ require "capillary/ref_collection"
19
21
 
20
22
  module Capillary
21
23
  class Commit
22
24
  attr_accessor :id, :parent_ids, :committed_at, :message, :committer_email, :seq_id
23
- attr_reader :ref_names
25
+ attr_reader :refs
24
26
  LOG_SEPARATOR = "§"
25
27
 
28
+ def initialize
29
+ @refs = RefCollection.new
30
+ end
31
+
26
32
  # Creates an instance from Git output
27
33
  def self.parse(git_line)
28
34
  git_line = git_line.gsub(/^[^a-f0-9]+/, "")
@@ -34,25 +40,17 @@ module Capillary
34
40
  result.parent_ids = parts[1].split(" ")
35
41
  result.committed_at = Time.parse(parts[2])
36
42
  result.committer_email = parts[3]
37
- result.ref_names = parts[4]
43
+ result.refs.parse(parts[4])
38
44
  result.message = parts[5]
39
45
  result
40
46
  end
41
47
 
42
- def ref_names=(spec)
43
- if spec == ""
44
- @ref_names = []
45
- else
46
- @ref_names = spec.gsub(/[\(\)]/,"").split(/,\s?/).collect(&:strip)
47
- end
48
- end
49
-
50
48
  def to_hash
51
49
  { "id" => id,
52
50
  "parent_ids" => parent_ids,
53
51
  "committed_at" => committed_at,
54
52
  "committer_email" => committer_email,
55
- "ref_names" => ref_names,
53
+ "refs" => refs.to_hash,
56
54
  "message" => message }
57
55
  end
58
56
 
@@ -61,7 +59,7 @@ module Capillary
61
59
  "parentIds" => parent_ids,
62
60
  "committedAt" => committed_at,
63
61
  "committerEmail" => committer_email,
64
- "refNames" => ref_names,
62
+ "refs" => refs.to_hash,
65
63
  "message" => message,
66
64
  "seqId" => seq_id})
67
65
  end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2011 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+ require "json"
19
+
20
+ module Capillary
21
+ class RefCollection
22
+ def initialize
23
+ @refs = {
24
+ "heads" => [],
25
+ "tags" => [],
26
+ "remotes" => {}
27
+ }
28
+ end
29
+
30
+ def self.parse(ref)
31
+ refs = new
32
+ refs.parse(ref)
33
+ refs
34
+ end
35
+
36
+ def parse(ref)
37
+ return if ref.nil? || ref == ""
38
+ ref.gsub(/[\(\)]/,"").split(/,\s?/).each { |r| self << r }
39
+ end
40
+
41
+ def <<(full_ref)
42
+ refs, type, *name = full_ref.strip.split("/")
43
+ return if type.nil?
44
+ type = type.gsub("-", "_")
45
+
46
+ if type == "remotes"
47
+ append_array_in_hash(@refs[type], name.shift, name)
48
+ else
49
+ append_array_in_hash(@refs, type, name)
50
+ end
51
+ end
52
+
53
+ def to_hash
54
+ @refs.dup
55
+ end
56
+
57
+ def to_json
58
+ JSON.unparse(@refs)
59
+ end
60
+
61
+ def method_missing(method, *args, &block)
62
+ key = method.to_s
63
+ return super if !@refs.key?(key) || args.length != 0
64
+ @refs[key]
65
+ end
66
+
67
+ private
68
+ def append_array_in_hash(hash, key, names)
69
+ hash[key] ||= []
70
+ hash[key] << names.join("/")
71
+ end
72
+ end
73
+ end
@@ -17,5 +17,5 @@
17
17
  #++
18
18
 
19
19
  module Capillary
20
- VERSION = "0.2.4"
20
+ VERSION = "0.3.0"
21
21
  end
@@ -15,7 +15,6 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
-
19
18
  require "json"
20
19
  require "test_helper"
21
20
  require "capillary/commit"
@@ -47,13 +46,12 @@ class CommitTest < MiniTest::Spec
47
46
  assert_equal "And this is commit 10 Merge branch 'topic'", @commit.message
48
47
  end
49
48
 
50
- should "include specified ref names" do
51
- assert_equal(["master","refactor"], @commit.ref_names)
49
+ should "include specified heads" do
50
+ assert_equal(["master","refactor"], @commit.refs.heads)
52
51
  end
53
52
 
54
- should "not include non-specified ref names" do
55
- @commit.ref_names = ""
56
- assert_equal [], @commit.ref_names
53
+ should "include specified tags" do
54
+ assert_equal(["v2.0.0"], @commit.refs.tags)
57
55
  end
58
56
 
59
57
  should "convert commit to JSON" do
@@ -62,7 +60,7 @@ class CommitTest < MiniTest::Spec
62
60
  "parentIds" => ["db75ad82d678d51b29709d26af64d4a85b6f8071"],
63
61
  "committedAt" => "Wed Jul 13 07:55:47 +0200 2011",
64
62
  "committerEmail" => "chris@example.com",
65
- "refNames" => ["master", "refactor"],
63
+ "refs" => { "heads" => ["master", "refactor"], "tags" => ["v2.0.0"], "remotes" => {} },
66
64
  "message" => "And this is commit 10 Merge branch 'topic'",
67
65
  "seqId" => nil
68
66
  }
@@ -26,20 +26,17 @@ class LogParserTest < MiniTest::Spec
26
26
  branches[num].collect { |c| c.id[0...7] }
27
27
  end
28
28
 
29
- def load_fixture(fixture, num = -1)
30
- parse_log(fixture(fixture), num)
29
+ def load_fixture(fixture)
30
+ parse_log(fixture(fixture))
31
31
  end
32
32
 
33
- def parse_log(log, num = -1)
33
+ def parse_log(log)
34
34
  @log_parser = Capillary::LogParser.new
35
35
  @lines = []
36
- i = 0
37
36
 
38
37
  log.split("\n").reject { |f| f.strip == "" }.each do |log|
39
- return if num >= 0 && i == num
40
38
  @lines << Capillary::Commit.parse(log)
41
39
  @log_parser << @lines.last
42
- i += 1
43
40
  end
44
41
  end
45
42
 
@@ -637,34 +634,6 @@ c4e7446e2a98f1bf28da51fc57bb42b532222942§c3e1d675667939e64ced1bb5b541c9042a1d60
637
634
  end
638
635
  end
639
636
 
640
- # 8ff4eb2
641
- # |
642
- # db060ee
643
- # | \
644
- # | 0bca89d
645
- # | |
646
- # | 1793145
647
- # | |
648
- # | f9e1735
649
- # | |
650
- # 4aee02f |
651
- # | |
652
- # | 07b25c9
653
- # | |
654
- context "Axis log" do
655
- setup do
656
- load_fixture("axis.txt", 50)
657
- end
658
-
659
- should "include correct commits in second branch" do
660
- assert_equal %w[db060ee 0bca89d 1793145 f9e1735], commits_for_branch(1)
661
- end
662
-
663
- should "include correct commits in fifth branch" do
664
- assert_equal %w[e2f706e 02edff1 3e54c31], commits_for_branch(5)
665
- end
666
- end
667
-
668
637
  context "Streaming parser" do
669
638
  setup do
670
639
  @lines = fixture("complex_graph_no_ff.txt").split("\n")
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2011 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+
19
+ require "test_helper"
20
+ require "capillary/ref_collection"
21
+
22
+ class RefCollectionTest < MiniTest::Spec
23
+ context "Parsing refs" do
24
+ should "ignore HEAD" do
25
+ refs = Capillary::RefCollection.parse("HEAD")
26
+
27
+ refute refs.to_hash.key?(nil)
28
+ assert_equal [], refs.heads
29
+ assert_equal [], refs.tags
30
+ end
31
+
32
+ should "find heads" do
33
+ refs = Capillary::RefCollection.parse("(HEAD, refs/heads/master)")
34
+
35
+ assert_equal ["master"], refs.heads
36
+ end
37
+
38
+ should "find tags" do
39
+ refs = Capillary::RefCollection.parse("(HEAD, refs/heads/master, refs/tags/v2.0.0)")
40
+
41
+ assert_equal ["v2.0.0"], refs.tags
42
+ end
43
+
44
+ should "find remotes" do
45
+ refs = Capillary::RefCollection.parse("(HEAD, refs/heads/master, refs/tags/v2.0.0, refs/remotes/origin/branch)")
46
+
47
+ assert_equal({ "origin" => ["branch"] }, refs.remotes)
48
+ end
49
+
50
+ should "find merge requests" do
51
+ refs = Capillary::RefCollection.parse("(HEAD, refs/merge-requests/1304)")
52
+
53
+ assert_equal ["1304"], refs.merge_requests
54
+ end
55
+ end
56
+ end
@@ -1 +1 @@
1
- a7cf78bfff06d52b5b0aa021508b44c00cad067a§db75ad82d678d51b29709d26af64d4a85b6f8071§2011-07-13 07:55:47 +0200§chris@example.com§ (master, refactor)§And this is commit 10 Merge branch 'topic'§
1
+ a7cf78bfff06d52b5b0aa021508b44c00cad067a§db75ad82d678d51b29709d26af64d4a85b6f8071§2011-07-13 07:55:47 +0200§chris@example.com§ (refs/heads/master, refs/heads/refactor, refs/tags/v2.0.0)§And this is commit 10 Merge branch 'topic'§
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capillary
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 4
10
- version: 0.2.4
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Marius Mathiesen
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-08-30 00:00:00 +02:00
19
+ date: 2011-08-31 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -86,9 +86,11 @@ files:
86
86
  - lib/capillary.rb
87
87
  - lib/capillary/commit.rb
88
88
  - lib/capillary/log_parser.rb
89
+ - lib/capillary/ref_collection.rb
89
90
  - lib/capillary/version.rb
90
91
  - test/capillary/commit_test.rb
91
92
  - test/capillary/log_parser_test.rb
93
+ - test/capillary/ref_collection_test.rb
92
94
  - test/fixtures/4x_dangling_branches.txt
93
95
  - test/fixtures/complex_graph.txt
94
96
  - test/fixtures/complex_graph_no_ff.txt