brigit 0.8.2 → 0.9.1
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/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
|