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 +1 -1
- data/README +21 -10
- data/bin/capillary +17 -2
- data/lib/capillary/commit.rb +10 -12
- data/lib/capillary/ref_collection.rb +73 -0
- data/lib/capillary/version.rb +1 -1
- data/test/capillary/commit_test.rb +5 -7
- data/test/capillary/log_parser_test.rb +3 -34
- data/test/capillary/ref_collection_test.rb +56 -0
- data/test/fixtures/first_commit.txt +1 -1
- metadata +7 -5
data/Gemfile.lock
CHANGED
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
|
-
"
|
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
|
-
"
|
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
|
-
*
|
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
|
-
|
144
|
-
|
145
|
-
|
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
|
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
|
-
|
6
|
-
|
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
|
data/lib/capillary/commit.rb
CHANGED
@@ -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 :
|
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.
|
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
|
-
"
|
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
|
-
"
|
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
|
data/lib/capillary/version.rb
CHANGED
@@ -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
|
51
|
-
assert_equal(["master","refactor"], @commit.
|
49
|
+
should "include specified heads" do
|
50
|
+
assert_equal(["master","refactor"], @commit.refs.heads)
|
52
51
|
end
|
53
52
|
|
54
|
-
should "
|
55
|
-
@commit.
|
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
|
-
"
|
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
|
30
|
-
parse_log(fixture(fixture)
|
29
|
+
def load_fixture(fixture)
|
30
|
+
parse_log(fixture(fixture))
|
31
31
|
end
|
32
32
|
|
33
|
-
def parse_log(log
|
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:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
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
|