brigit 0.8.2 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +17 -0
- data/README.rdoc +9 -0
- data/Rakefile +2 -2
- data/bin/brigit +1 -3
- data/brigit.gemspec +125 -49
- data/help/grab.rdoc +16 -0
- data/help/hop.rdoc +36 -0
- data/help/map.rdoc +19 -0
- data/help/update.rdoc +9 -0
- data/lib/brigit/cli.rb +12 -43
- data/lib/brigit/commands/command.rb +43 -7
- data/lib/brigit/commands/grab_command.rb +23 -23
- data/lib/brigit/commands/hop_command.rb +91 -0
- data/lib/brigit/commands/map_command.rb +12 -9
- data/lib/brigit/commands/update_command.rb +4 -6
- data/lib/brigit/fallible.rb +1 -1
- data/lib/brigit/inventories/gitosis_inventory.rb +1 -1
- data/lib/brigit/listable.rb +1 -1
- data/lib/brigit/pretending.rb +25 -0
- data/lib/brigit/version.rb +2 -2
- data/lib/brigit.rb +33 -2
- data/test/brigit_test.rb +70 -0
- data/test/cli_test.rb +47 -0
- data/test/command_test.rb +47 -0
- data/test/fallible_test.rb +33 -0
- data/test/fixtures/gitosis-admin/gitosis.conf +16 -0
- data/test/fixtures/grab_command/existing_directory/stub +1 -0
- data/test/fixtures/submodule_methods/parent/submodule/foo.rb +1 -0
- data/test/gitosis_test.rb +40 -0
- data/test/grab_command_test.rb +55 -0
- data/test/inventory_test.rb +22 -0
- data/test/option_parser_test.rb +21 -0
- data/test/test_helper.rb +32 -1
- metadata +42 -6
@@ -5,10 +5,13 @@ module Brigit
|
|
5
5
|
|
6
6
|
class MapCommand < Command
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def run
|
9
|
+
open = false
|
10
|
+
super do |parser|
|
11
|
+
parser.on('-o', '--open', "Open as PNG in Preview.app (OSX only, requires `dot')") do
|
12
|
+
open = true
|
13
|
+
end
|
14
|
+
end
|
12
15
|
text = %|digraph G {\n|
|
13
16
|
# TODO: Allow customization
|
14
17
|
text << %|ranksep=.75; size = "12,12";\n|
|
@@ -21,7 +24,7 @@ module Brigit
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
text << %|}\n|
|
24
|
-
if
|
27
|
+
if open
|
25
28
|
IO.popen("dot -Tpng | open -f -a /Applications/Preview.app", 'w') do |file|
|
26
29
|
file.write text
|
27
30
|
end
|
@@ -36,18 +39,18 @@ module Brigit
|
|
36
39
|
|
37
40
|
def origin_at(path)
|
38
41
|
filename = File.join(path, '.git/config')
|
39
|
-
result =
|
42
|
+
result = config_parser.parse(File.readlines(filename))
|
40
43
|
result['remote "origin"']['url']
|
41
44
|
end
|
42
45
|
|
43
46
|
def submodules_at(path)
|
44
47
|
filename = File.join(path, '.gitmodules')
|
45
|
-
result =
|
48
|
+
result = config_parser.parse(File.readlines(filename))
|
46
49
|
result.values
|
47
50
|
end
|
48
51
|
|
49
|
-
def
|
50
|
-
@
|
52
|
+
def config_parser
|
53
|
+
@config_parser ||= ConfigParser.new
|
51
54
|
end
|
52
55
|
|
53
56
|
end
|
@@ -4,14 +4,12 @@ require 'find'
|
|
4
4
|
module Brigit
|
5
5
|
|
6
6
|
class UpdateCommand < Command
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def execute!
|
7
|
+
|
8
|
+
def run
|
11
9
|
super
|
12
10
|
Brigit.at_dot_gitmodules do |path|
|
13
|
-
|
14
|
-
|
11
|
+
sh "git submodule init"
|
12
|
+
sh "git submodule update"
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
data/lib/brigit/fallible.rb
CHANGED
data/lib/brigit/listable.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Brigit
|
2
|
+
|
3
|
+
module Pretending
|
4
|
+
|
5
|
+
def pretend!
|
6
|
+
@pretending = true
|
7
|
+
end
|
8
|
+
|
9
|
+
#######
|
10
|
+
private
|
11
|
+
#######
|
12
|
+
|
13
|
+
def add_pretend_to(parser)
|
14
|
+
parser.on('-p', '--pretend', "Just pretend to #{self.class.name}") do
|
15
|
+
pretend!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def pretending?
|
20
|
+
@pretending
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/brigit/version.rb
CHANGED
data/lib/brigit.rb
CHANGED
@@ -2,8 +2,8 @@ require 'find'
|
|
2
2
|
|
3
3
|
module Brigit
|
4
4
|
|
5
|
-
def self.at_dot_gitmodules
|
6
|
-
Find.find(
|
5
|
+
def self.at_dot_gitmodules(base = Dir.pwd)
|
6
|
+
Find.find(base) do |path|
|
7
7
|
if File.basename(path) == '.git' && File.directory?(path)
|
8
8
|
Find.prune
|
9
9
|
elsif File.file?(File.join(path, '.gitmodules'))
|
@@ -13,6 +13,37 @@ module Brigit
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
# Note: Doesn't validate against .gitmodules or .git/config
|
18
|
+
def self.parent_of(path)
|
19
|
+
components = path.split(File::SEPARATOR)
|
20
|
+
components.pop
|
21
|
+
matched = []
|
22
|
+
components.inject(['']) do |list, component|
|
23
|
+
list << component
|
24
|
+
check_path = File.join(*list.clone.push('.git'))
|
25
|
+
matched << File.dirname(check_path) if File.exists?(check_path)
|
26
|
+
list
|
27
|
+
end
|
28
|
+
matched.pop
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.submodule?(path)
|
32
|
+
parent_of(path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.at_repos(submodules = false, base = Dir.pwd)
|
36
|
+
Find.find(base) do |path|
|
37
|
+
if File.basename(path) == '.git' && File.directory?(path)
|
38
|
+
Find.prune
|
39
|
+
elsif File.directory?(File.join(path, '.git'))
|
40
|
+
Dir.chdir path do
|
41
|
+
yield path
|
42
|
+
end
|
43
|
+
Find.prune unless submodules
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
16
47
|
|
17
48
|
end
|
18
49
|
|
data/test/brigit_test.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class BrigitTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Brigit" do
|
6
|
+
|
7
|
+
context "at_dot_gitmodules method" do
|
8
|
+
|
9
|
+
should "find directories with .gitmodules" do
|
10
|
+
paths = []
|
11
|
+
Brigit.at_dot_gitmodules(File.dirname(__FILE__) << "/fixtures/dotgitmodules") do |path|
|
12
|
+
paths << path
|
13
|
+
end
|
14
|
+
assert_equal 2, paths.size
|
15
|
+
assert_equal %w(dotgitmodules bar), paths.map { |path| File.basename(path) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context ".git path methods" do
|
20
|
+
|
21
|
+
setup { locations.each { |loc| gitify!(loc) } }
|
22
|
+
teardown { locations.each { |loc| degitify!(loc) } }
|
23
|
+
|
24
|
+
context "submodule? method" do
|
25
|
+
should "find submodule" do
|
26
|
+
assert Brigit.submodule?(locations.last)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "parent_of method" do
|
31
|
+
should "description" do
|
32
|
+
parent, submodule = locations
|
33
|
+
assert_equal parent, Brigit.parent_of(submodule)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "at_repos method" do
|
38
|
+
setup { @paths = [] }
|
39
|
+
should "find only base repos if requested" do
|
40
|
+
find_repos(false)
|
41
|
+
assert_equal 1, @paths.size
|
42
|
+
assert_equal locations.first, @paths.first
|
43
|
+
end
|
44
|
+
should "find submodules also if requested" do
|
45
|
+
find_repos(true)
|
46
|
+
assert_equal locations, @paths
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
#######
|
55
|
+
private
|
56
|
+
#######
|
57
|
+
|
58
|
+
def find_repos(submodules)
|
59
|
+
Brigit.at_repos(submodules, base) { |path| @paths << path }
|
60
|
+
end
|
61
|
+
|
62
|
+
def base
|
63
|
+
File.expand_path(File.dirname(__FILE__) << "/fixtures/submodule_methods")
|
64
|
+
end
|
65
|
+
|
66
|
+
def locations
|
67
|
+
Dir[File.join(base, '**/*')].select { |path| File.directory?(path) }
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/test/cli_test.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class CLITest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class AbortedException; end
|
7
|
+
|
8
|
+
context "Brigit::CLI" do
|
9
|
+
|
10
|
+
setup do
|
11
|
+
mock_stderr!
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
restore_stderr!
|
16
|
+
end
|
17
|
+
|
18
|
+
should "parse valid command" do
|
19
|
+
parsing %w(hop) do |command, args|
|
20
|
+
assert_kind_of Brigit::HopCommand, command
|
21
|
+
assert command.args.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not parse invalid command" do
|
26
|
+
assert_raises SystemExit do
|
27
|
+
parse %w(this-does-not-exist)
|
28
|
+
end
|
29
|
+
assert !stderr_output.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have banner with version number" do
|
33
|
+
assert Brigit::CLI.banner.include?(Brigit::Version::STRING)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
#######
|
39
|
+
private
|
40
|
+
#######
|
41
|
+
|
42
|
+
def parsing(args)
|
43
|
+
yield(Brigit::CLI.new.parse(*args), args)
|
44
|
+
end
|
45
|
+
alias :parse :parsing
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class CommandTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Command" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@klass = Class.new(Brigit::Command) do
|
9
|
+
def self.to_s
|
10
|
+
'TestCommand'
|
11
|
+
end
|
12
|
+
def run
|
13
|
+
say 'foo'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "name class method" do
|
19
|
+
should "return downcased version of class name" do
|
20
|
+
assert_equal 'test', @klass.name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "say instance method" do
|
25
|
+
setup do
|
26
|
+
mock_stderr!
|
27
|
+
end
|
28
|
+
teardown do
|
29
|
+
restore_stderr!
|
30
|
+
end
|
31
|
+
should "output message" do
|
32
|
+
@klass.new.run
|
33
|
+
assert stderr_output.include?('foo')
|
34
|
+
assert !stderr_output.include?('PRETEND')
|
35
|
+
end
|
36
|
+
should "mention pretending if doing so" do
|
37
|
+
instance = @klass.new
|
38
|
+
instance.pretend!
|
39
|
+
instance.run
|
40
|
+
assert stderr_output.include?('foo')
|
41
|
+
assert stderr_output.include?('PRETEND')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
|
4
|
+
class FallibleTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "Fallible" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@klass = Class.new
|
10
|
+
@klass.send(:include, Brigit::Fallible)
|
11
|
+
mock_stderr!
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
restore_stderr!
|
16
|
+
end
|
17
|
+
|
18
|
+
context "fail method" do
|
19
|
+
setup do
|
20
|
+
@failed = "you totally failed"
|
21
|
+
end
|
22
|
+
should "output CLI banner and message" do
|
23
|
+
assert_raises SystemExit do
|
24
|
+
@klass.new.fail @failed
|
25
|
+
assert stderr_output.include?(Brigit::CLI.banner)
|
26
|
+
assert stderr_output.include?(@failed)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Just an empty file
|
@@ -0,0 +1 @@
|
|
1
|
+
# Nothing here but us comments
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class GitosisTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Gitosis" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
gitify!(location, url('gitosis-admin'))
|
9
|
+
@gitosis = Brigit::GitosisInventory.new(location)
|
10
|
+
end
|
11
|
+
|
12
|
+
teardown do
|
13
|
+
degitify!(location)
|
14
|
+
end
|
15
|
+
|
16
|
+
should "find all repos" do
|
17
|
+
assert_equal 4, @gitosis.repositories.size
|
18
|
+
end
|
19
|
+
|
20
|
+
should "find correct URLs for repos" do
|
21
|
+
@gitosis.repositories.each do |name, location|
|
22
|
+
assert_equal url(name), location
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
#######
|
29
|
+
private
|
30
|
+
#######
|
31
|
+
|
32
|
+
def url(name)
|
33
|
+
"foo@foo.com:#{name}.git"
|
34
|
+
end
|
35
|
+
|
36
|
+
def location
|
37
|
+
File.dirname(__FILE__) << "/fixtures/gitosis-admin"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class GrabCommandTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "GrabCommand" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
mock_stderr!
|
9
|
+
@command = Brigit::GrabCommand.new
|
10
|
+
end
|
11
|
+
|
12
|
+
teardown { restore_stderr! }
|
13
|
+
|
14
|
+
context "update instance method" do
|
15
|
+
setup do
|
16
|
+
@updated = []
|
17
|
+
flexmock(Brigit::UpdateCommand).new_instances do |mock|
|
18
|
+
mock.should_receive(:run).and_return { @updated << Dir.pwd }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
should "update existing directory" do
|
22
|
+
directory = File.join(location, 'existing_directory')
|
23
|
+
Dir.chdir location do
|
24
|
+
assert_nothing_raised do
|
25
|
+
update File.basename(directory)
|
26
|
+
end
|
27
|
+
assert_equal 1, @updated.size
|
28
|
+
assert @updated.include?(directory)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
should "gracefully ignore update on missing directory" do
|
32
|
+
Dir.chdir location do
|
33
|
+
assert_nothing_raised do
|
34
|
+
update 'missing_directory'
|
35
|
+
end
|
36
|
+
assert stderr_output.include?('skipping')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
#######
|
44
|
+
private
|
45
|
+
#######
|
46
|
+
|
47
|
+
def update(name)
|
48
|
+
@command.__send__(:update, name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def location
|
52
|
+
File.expand_path(File.dirname(__FILE__) << "/fixtures/grab_command")
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class InventoryTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Inventory" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@klass = Class.new(Brigit::Inventory)
|
9
|
+
end
|
10
|
+
|
11
|
+
context "repository method" do
|
12
|
+
should "be abstract" do
|
13
|
+
instance = @klass.new 'a-fake-path'
|
14
|
+
assert_raises NotImplementedError do
|
15
|
+
instance.repositories
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
|
3
|
+
class OptionParserExtensionTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "OptionParserExtension" do
|
6
|
+
|
7
|
+
context "separator" do
|
8
|
+
setup do
|
9
|
+
@separator = "foo\nbar\nbaz"
|
10
|
+
@opts = OptionParser.new do |opts|
|
11
|
+
opts.separator @separator
|
12
|
+
end
|
13
|
+
end
|
14
|
+
should "have not double newlines on assignment" do
|
15
|
+
assert @opts.to_s.include?(@separator)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,4 +3,35 @@ require 'rubygems'
|
|
3
3
|
require 'Shoulda'
|
4
4
|
require 'flexmock/test_unit'
|
5
5
|
|
6
|
-
require File.dirname(__FILE__) << "/../lib/brigit"
|
6
|
+
require File.dirname(__FILE__) << "/../lib/brigit"
|
7
|
+
|
8
|
+
class Test::Unit::TestCase
|
9
|
+
|
10
|
+
def gitify!(location, origin = nil)
|
11
|
+
Dir.chdir location do
|
12
|
+
`git init; git add .; git commit -a -m 'For test'`
|
13
|
+
if origin
|
14
|
+
`git remote add origin '#{origin}'`
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def degitify!(location)
|
20
|
+
FileUtils.rm_rf File.join(location, '.git') rescue nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def mock_stderr!
|
24
|
+
@old_stderr = $stderr
|
25
|
+
$stderr = StringIO.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def restore_stderr!
|
29
|
+
$stderr = @old_stderr
|
30
|
+
end
|
31
|
+
|
32
|
+
def stderr_output
|
33
|
+
$stderr.rewind
|
34
|
+
$stderr.read
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|