git-duet 0.1.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.
@@ -0,0 +1,46 @@
1
+ require 'git/duet/cli'
2
+ require 'git/duet/solo_command'
3
+ require 'git/duet/duet_command'
4
+ require 'git/duet/pre_commit_command'
5
+
6
+ describe Git::Duet::Cli do
7
+ subject { described_class }
8
+
9
+ it 'should respond to .main`' do
10
+ subject.should respond_to(:run)
11
+ end
12
+
13
+ it 'should require the prog name and argv array' do
14
+ expect { subject.run }.to raise_error(ArgumentError)
15
+ end
16
+
17
+ it 'should explode on unknown prog names' do
18
+ expect { subject.run('bork', []) }.to raise_error(ScriptError)
19
+ end
20
+
21
+ it 'should return the exit status from any script error deaths' do
22
+ subject.stub(:solo).and_raise(Git::Duet::ScriptDieError.new(99))
23
+ subject.run('git-solo', %w(ty -q)).should == 99
24
+ end
25
+
26
+ it 'should run `solo` when the progname matches /solo$/' do
27
+ Git::Duet::SoloCommand.stub(:new => double('solo').tap do |solo|
28
+ solo.should_receive(:execute!)
29
+ end)
30
+ subject.run('git-solo', %w(jd -q))
31
+ end
32
+
33
+ it 'should run `duet` when progname matches /duet$/' do
34
+ Git::Duet::DuetCommand.stub(:new => double('duet').tap do |duet|
35
+ duet.should_receive(:execute!)
36
+ end)
37
+ subject.run('git-duet', %w(jd fb -q))
38
+ end
39
+
40
+ it 'should run `pre_commit` when progname matches /pre-commit$/' do
41
+ Git::Duet::PreCommitCommand.stub(:new => double('pre-commit').tap do |pc|
42
+ pc.should_receive(:execute!)
43
+ end)
44
+ subject.run('git-duet-pre-commit', %w(-q))
45
+ end
46
+ end
@@ -0,0 +1,51 @@
1
+ require 'git/duet/command_methods'
2
+
3
+ describe Git::Duet::CommandMethods do
4
+ subject do
5
+ Class.new do
6
+ include Git::Duet::CommandMethods
7
+
8
+ def var_map
9
+ {
10
+ 'FIZZLE_BAZ' => 'awesome',
11
+ 'OH_SNARF' => 'mumra'
12
+ }
13
+ end
14
+ end.new
15
+ end
16
+
17
+ before :each do
18
+ [:info, :error].each do |m|
19
+ subject.stub(m)
20
+ end
21
+ subject.stub(:in_repo_root) do |&block|
22
+ block.call
23
+ end
24
+ end
25
+
26
+ it 'should write env vars to a custom git config tree' do
27
+ subject.should_receive(:`).with("git config duet.env.fizzle-baz 'awesome'")
28
+ subject.should_receive(:`).with("git config duet.env.oh-snarf 'mumra'")
29
+ subject.should_receive(:`).with(/^git config duet\.env\.mtime \d+/)
30
+ subject.send(:write_env_vars)
31
+ end
32
+
33
+ it 'should explode if a subshell returns non-zero' do
34
+ subject.stub(:`)
35
+ $?.should_receive(:exitstatus).and_return(1)
36
+ expect { subject.send(:exec_check, 'ls hamsters') }.to raise_error(StandardError)
37
+ end
38
+
39
+ context 'when configured to operate on the global config' do
40
+ before :each do
41
+ subject.instance_variable_set(:@global, true)
42
+ end
43
+
44
+ it 'should write env vars to a custom global git config tree' do
45
+ subject.should_receive(:`).with("git config --global duet.env.fizzle-baz 'awesome'")
46
+ subject.should_receive(:`).with("git config --global duet.env.oh-snarf 'mumra'")
47
+ subject.should_receive(:`).with(/^git config --global duet\.env\.mtime \d+/)
48
+ subject.send(:write_env_vars)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ require 'git/duet/duet_command'
2
+ require 'support/author_mapper_helper'
3
+
4
+ describe Git::Duet::DuetCommand do
5
+ include SpecSupport::AuthorMapperHelper
6
+
7
+ let :alpha do
8
+ random_author
9
+ end
10
+
11
+ let :omega do
12
+ random_author
13
+ end
14
+
15
+ subject do
16
+ described_class.new(alpha, omega)
17
+ end
18
+
19
+ before :each do
20
+ subject.stub(:author_mapper => double('author mapper').tap do |am|
21
+ am.stub(:map => author_mapping)
22
+ end)
23
+ subject.stub(:` => '')
24
+ subject.stub(:report_env_vars)
25
+ Dir.stub(:chdir) do |&block|
26
+ block.call
27
+ end
28
+ File.stub(:open) do |filename,mode,&block|
29
+ block.call(double('outfile').as_null_object)
30
+ end
31
+ end
32
+
33
+ it 'should require alpha and omega sets of initials' do
34
+ expect { described_class.new }.to raise_error(ArgumentError)
35
+ end
36
+
37
+ it 'should respond to `execute!`' do
38
+ subject.should respond_to(:execute!)
39
+ end
40
+
41
+ it 'should (privately) respond to `write_env_vars`' do
42
+ subject.private_methods.map(&:to_sym).should include(:write_env_vars)
43
+ end
44
+
45
+ it 'should set the alpha name as git config user.name' do
46
+ subject.stub(:`).with(/git config user\.email/)
47
+ subject.should_receive(:`).with("git config user.name '#{author_mapping[alpha][:name]}'")
48
+ subject.execute!
49
+ end
50
+
51
+ it 'should set the alpha email as git config user.email' do
52
+ subject.stub(:`).with(/git config user\.name/)
53
+ subject.should_receive(:`).with("git config user.email '#{author_mapping[alpha][:email]}'")
54
+ subject.execute!
55
+ end
56
+
57
+ it 'should report env vars to STDOUT' do
58
+ subject.unstub(:report_env_vars)
59
+ STDOUT.should_receive(:puts).with(/^GIT_AUTHOR_NAME='#{author_mapping[alpha][:name]}'/)
60
+ STDOUT.should_receive(:puts).with(/^GIT_AUTHOR_EMAIL='#{author_mapping[alpha][:email]}'/)
61
+ STDOUT.should_receive(:puts).with(/^GIT_COMMITTER_NAME='#{author_mapping[omega][:name]}'/)
62
+ STDOUT.should_receive(:puts).with(/^GIT_COMMITTER_EMAIL='#{author_mapping[omega][:email]}'/)
63
+ subject.execute!
64
+ end
65
+
66
+ it 'should set the alpha as author and omega as committer in custom git config' do
67
+ subject.should_receive(:write_env_vars)
68
+ subject.execute!
69
+ end
70
+
71
+ context 'when configured to operate on the global config' do
72
+ subject do
73
+ described_class.new(alpha, omega, false, true)
74
+ end
75
+
76
+ it 'should set the alpha name as global git config user.name' do
77
+ subject.stub(:`).with(/git config --global user\.email/)
78
+ subject.should_receive(:`).with("git config --global user.name '#{author_mapping[alpha][:name]}'")
79
+ subject.execute!
80
+ end
81
+
82
+ it 'should set the alpha email as global git config user.email' do
83
+ subject.stub(:`).with(/git config --global user\.name/)
84
+ subject.should_receive(:`).with("git config --global user.email '#{author_mapping[alpha][:email]}'")
85
+ subject.execute!
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,36 @@
1
+ require 'git/duet/pre_commit_command'
2
+
3
+ describe Git::Duet::PreCommitCommand do
4
+ subject do
5
+ described_class.new(true)
6
+ end
7
+
8
+ before :each do
9
+ subject.stub(:in_repo_root) do |&block|
10
+ block.call
11
+ end
12
+ @old_seconds_ago_stale = ENV.delete('GIT_DUET_SECONDS_AGO_STALE')
13
+ ENV['GIT_DUET_SECONDS_AGO_STALE'] = '300'
14
+ end
15
+
16
+ after :each do
17
+ ENV['GIT_DUET_SECONDS_AGO_STALE'] = @old_seconds_ago_stale
18
+ end
19
+
20
+ it 'should not require any params to initialize' do
21
+ expect { described_class.new }.to_not raise_error(ArgumentError)
22
+ end
23
+
24
+ it 'should do nothing if the env cache is not stale' do
25
+ subject.stub(:exec_check).with(/git config duet\.env\.git/)
26
+ subject.stub(:exec_check).with('git config duet.env.mtime').and_return(Time.now.to_i)
27
+ subject.should_not_receive(:explode!)
28
+ subject.execute!
29
+ end
30
+
31
+ it 'should explode if the env cache does not exist' do
32
+ subject.stub(:exec_check).with(/git config duet\.env\.git/)
33
+ subject.stub(:exec_check).with('git config duet.env.mtime').and_raise(StandardError)
34
+ expect { subject.execute! }.to raise_error(Git::Duet::ScriptDieError)
35
+ end
36
+ end
@@ -0,0 +1,115 @@
1
+ require 'git/duet/solo_command'
2
+ require 'support/author_mapper_helper'
3
+
4
+ describe Git::Duet::SoloCommand do
5
+ include SpecSupport::AuthorMapperHelper
6
+
7
+ let :soloist do
8
+ random_author
9
+ end
10
+
11
+ subject do
12
+ described_class.new(soloist)
13
+ end
14
+
15
+ before :each do
16
+ subject.stub(:author_mapper => double('author mapper').tap do |am|
17
+ am.stub(:map => author_mapping)
18
+ end)
19
+ subject.stub(:` => '')
20
+ subject.stub(:report_env_vars)
21
+ subject.stub(:in_repo_root) do |&block|
22
+ block.call
23
+ end
24
+ end
25
+
26
+ it 'should require soloist initials' do
27
+ expect { described_class.new }.to raise_error(ArgumentError)
28
+ end
29
+
30
+ it 'should respond to `execute!`' do
31
+ subject.should respond_to(:execute!)
32
+ end
33
+
34
+ it 'should (privately) respond to `write_env_vars`' do
35
+ subject.private_methods.map(&:to_sym).should include(:write_env_vars)
36
+ end
37
+
38
+ it 'should set the soloist name as git config user.name' do
39
+ subject.stub(:`).with(/git config user\.email/)
40
+ subject.stub(:`).with(/git config --unset-all duet\.env/)
41
+ subject.should_receive(:`).with("git config user.name '#{author_mapping[soloist][:name]}'")
42
+ subject.execute!
43
+ end
44
+
45
+ it 'should set the soloist email as git config user.email' do
46
+ subject.stub(:`).with(/git config user\.name/)
47
+ subject.stub(:`).with(/git config --unset-all duet\.env/)
48
+ subject.should_receive(:`).with("git config user.email '#{author_mapping[soloist][:email]}'")
49
+ subject.execute!
50
+ end
51
+
52
+ it 'should unset the committer name' do
53
+ subject.stub(:`).with(/git config user\.name/)
54
+ subject.stub(:`).with(/git config user\.email/)
55
+ subject.stub(:`).with(/git config --unset-all duet\.env\.git-committer-email/)
56
+ subject.should_receive(:`).with('git config --unset-all duet.env.git-committer-name')
57
+ subject.execute!
58
+ end
59
+
60
+ it 'should unset the committer email' do
61
+ subject.stub(:`).with(/git config user\.name/)
62
+ subject.stub(:`).with(/git config user\.email/)
63
+ subject.stub(:`).with(/git config --unset-all duet\.env\.git-committer-name/)
64
+ subject.should_receive(:`).with('git config --unset-all duet.env.git-committer-email')
65
+ subject.execute!
66
+ end
67
+
68
+ it 'should report env vars to STDOUT' do
69
+ subject.unstub(:report_env_vars)
70
+ STDOUT.should_receive(:puts).with(/^GIT_AUTHOR_NAME='#{author_mapping[soloist][:name]}'/)
71
+ STDOUT.should_receive(:puts).with(/^GIT_AUTHOR_EMAIL='#{author_mapping[soloist][:email]}'/)
72
+ subject.execute!
73
+ end
74
+
75
+ it 'should set the soloist as author in custom git config' do
76
+ subject.should_receive(:write_env_vars)
77
+ subject.execute!
78
+ end
79
+
80
+ context 'when configured to operate on the global config' do
81
+ subject do
82
+ described_class.new(soloist, false, true)
83
+ end
84
+
85
+ it 'should set the soloist name as global git config user.name' do
86
+ subject.stub(:`).with(/git config --global user\.email/)
87
+ subject.stub(:`).with(/git config --global --unset-all duet\.env/)
88
+ subject.should_receive(:`).with("git config --global user.name '#{author_mapping[soloist][:name]}'")
89
+ subject.execute!
90
+ end
91
+
92
+ it 'should set the soloist email as global git config user.email' do
93
+ subject.stub(:`).with(/git config --global user\.name/)
94
+ subject.stub(:`).with(/git config --global --unset-all duet\.env/)
95
+ subject.should_receive(:`).with("git config --global user.email '#{author_mapping[soloist][:email]}'")
96
+ subject.execute!
97
+ end
98
+
99
+ it 'should unset the global committer name' do
100
+ subject.stub(:`).with(/git config --global user\.name/)
101
+ subject.stub(:`).with(/git config --global user\.email/)
102
+ subject.stub(:`).with(/git config --global --unset-all duet\.env\.git-committer-email/)
103
+ subject.should_receive(:`).with('git config --global --unset-all duet.env.git-committer-name')
104
+ subject.execute!
105
+ end
106
+
107
+ it 'should unset the global committer email' do
108
+ subject.stub(:`).with(/git config --global user\.name/)
109
+ subject.stub(:`).with(/git config --global user\.email/)
110
+ subject.stub(:`).with(/git config --global --unset-all duet\.env\.git-committer-name/)
111
+ subject.should_receive(:`).with('git config --global --unset-all duet.env.git-committer-email')
112
+ subject.execute!
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'rbconfig'
5
+ require 'simplecov'
6
+
7
+ RSpec.configure do |c|
8
+ if !ENV['TRAVIS']
9
+ if RbConfig::CONFIG['host_os'] =~ /darwin/i
10
+ c.formatter = 'NyanCatMusicFormatter'
11
+ else
12
+ # No music allowed for neckbeards or polo shirts.
13
+ c.formatter = 'NyanCatFormatter'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ module SpecSupport
2
+ module AuthorMapperHelper
3
+ def random_author
4
+ author_mapping.keys.send(RUBY_VERSION < '1.9' ? :choice : :sample)
5
+ end
6
+
7
+ def author_mapping
8
+ {
9
+ 'jd' => {
10
+ :name => 'Jane Doe',
11
+ :email => 'jane@awesome.biz'
12
+ },
13
+ 'fb' => {
14
+ :name => 'Frances Bar',
15
+ :email => 'frances@awesometown.me'
16
+ },
17
+ 'qx' => {
18
+ :name => 'Quincy Xavier',
19
+ :email => 'qx@awesometown.me'
20
+ },
21
+ 'hb' => {
22
+ :name => 'Hampton Bones',
23
+ :email => 'h.bones@awesometown.me'
24
+ }
25
+ }
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-duet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dan Buch
9
+ - Jesse Szwedko
10
+ - Rafe Colton
11
+ - Sheena McCoy
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2012-12-12 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: nyan-cat-formatter
19
+ requirement: !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ! '>='
23
+ - !ruby/object:Gem::Version
24
+ version: 0.2.0
25
+ type: :development
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.2.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.2.2
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: 0.9.2.2
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ requirement: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: 2.0.0
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: 2.0.0
65
+ - !ruby/object:Gem::Dependency
66
+ name: simplecov
67
+ requirement: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: 0.7.0
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: 0.7.0
81
+ description: Pair programming git identity thingy
82
+ email:
83
+ - d.buch@modcloth.com
84
+ - j.szwedko@modcloth.com
85
+ - r.colton@modcloth.com
86
+ - sp.mccoy@modcloth.com
87
+ executables:
88
+ - git-duet
89
+ - git-duet-commit
90
+ - git-duet-install-hook
91
+ - git-duet-pre-commit
92
+ - git-duet-pre-commit-tk
93
+ - git-solo
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - .gitignore
98
+ - .jrubyrc
99
+ - .rbenv-version
100
+ - .rspec
101
+ - .simplecov
102
+ - .travis.yml
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - bin/git-duet
108
+ - bin/git-duet-commit
109
+ - bin/git-duet-install-hook
110
+ - bin/git-duet-pre-commit
111
+ - bin/git-duet-pre-commit-tk
112
+ - bin/git-solo
113
+ - git-duet.gemspec
114
+ - lib/git-duet.rb
115
+ - lib/git/duet.rb
116
+ - lib/git/duet/author_mapper.rb
117
+ - lib/git/duet/cli.rb
118
+ - lib/git/duet/command_methods.rb
119
+ - lib/git/duet/commit_command.rb
120
+ - lib/git/duet/duet_command.rb
121
+ - lib/git/duet/install_hook_command.rb
122
+ - lib/git/duet/key_error.rb
123
+ - lib/git/duet/pre_commit_command.rb
124
+ - lib/git/duet/script_die_error.rb
125
+ - lib/git/duet/solo_command.rb
126
+ - lib/git/duet/version.rb
127
+ - spec/integration/end_to_end_spec.rb
128
+ - spec/lib/git/duet/author_mapper_spec.rb
129
+ - spec/lib/git/duet/cli_spec.rb
130
+ - spec/lib/git/duet/command_methods_spec.rb
131
+ - spec/lib/git/duet/duet_command_spec.rb
132
+ - spec/lib/git/duet/pre_commit_command_spec.rb
133
+ - spec/lib/git/duet/solo_command_spec.rb
134
+ - spec/spec_helper.rb
135
+ - spec/support/author_mapper_helper.rb
136
+ homepage: ''
137
+ licenses:
138
+ - MIT
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: 1.8.7
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 1.8.23
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: Pair harmoniously! Decide who's driving. Commit along the way. Don't make
161
+ a mess of the repository history.
162
+ test_files:
163
+ - spec/integration/end_to_end_spec.rb
164
+ - spec/lib/git/duet/author_mapper_spec.rb
165
+ - spec/lib/git/duet/cli_spec.rb
166
+ - spec/lib/git/duet/command_methods_spec.rb
167
+ - spec/lib/git/duet/duet_command_spec.rb
168
+ - spec/lib/git/duet/pre_commit_command_spec.rb
169
+ - spec/lib/git/duet/solo_command_spec.rb
170
+ - spec/spec_helper.rb
171
+ - spec/support/author_mapper_helper.rb
172
+ has_rdoc: