capillary 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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