git-duet 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby-version +1 -1
- data/.simplecov +2 -6
- data/.travis.yml +15 -5
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +3 -0
- data/Rakefile +2 -2
- data/lib/git/duet/author_mapper.rb +2 -2
- data/lib/git/duet/cli.rb +13 -11
- data/lib/git/duet/command_methods.rb +7 -8
- data/lib/git/duet/duet_command.rb +14 -10
- data/lib/git/duet/pre_commit_command.rb +1 -1
- data/lib/git/duet/solo_command.rb +1 -1
- data/lib/git/duet/version.rb +1 -1
- data/spec/integration/end_to_end_spec.rb +23 -9
- data/spec/lib/git/duet/author_mapper_spec.rb +3 -2
- data/spec/spec_helper.rb +2 -0
- metadata +32 -17
- checksums.yaml +0 -7
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.0
|
data/.simplecov
CHANGED
data/.travis.yml
CHANGED
@@ -1,16 +1,26 @@
|
|
1
|
-
---
|
2
1
|
language: ruby
|
3
2
|
env:
|
4
3
|
global:
|
5
|
-
-
|
4
|
+
- COVERAGE=1
|
6
5
|
matrix:
|
7
6
|
allow_failures:
|
8
7
|
- rvm: jruby-19mode
|
9
8
|
rvm:
|
10
9
|
- 1.9.3
|
11
10
|
- 2.0.0
|
11
|
+
- 2.1.0
|
12
12
|
- jruby-19mode
|
13
13
|
notifications:
|
14
|
-
email:
|
15
|
-
|
16
|
-
|
14
|
+
email: github+git-duet@modcloth.com
|
15
|
+
deploy:
|
16
|
+
provider: rubygems
|
17
|
+
api_key:
|
18
|
+
secure: aW7HYNkTGp3N8awbuJtDfko1CXBDTzElggAOQsA4p//V06Q/qH7ZTNZxPTf5/bPlmjDRgttMVv+zm3YGgb4pFdHzSWI+McLf+eI6g2I8s/Sp/GZQ2+dxH1wBqPtMhSI/Rv7R+J6GznALjKhM/PnNpPl6gsWePFbMebhKgKUvcHo=
|
19
|
+
gem: git-duet
|
20
|
+
on:
|
21
|
+
tags: true
|
22
|
+
repo: modcloth/git-duet
|
23
|
+
addons:
|
24
|
+
code_climate:
|
25
|
+
repo_token:
|
26
|
+
secure: A/K+dw6//V8WkB4PapKa1BqEGbwxWbhvHSCFKe+CnHSJ19vDbij2C1x8uzh3NpYTI+B9a5/p9r0B8AmVFI2hKU5CIdGiqMd+sEMM/OzSBeMTIO8d0NKJRfJEGH9yRSlka3cpwLMKmbdPorYnI0iKdVvWLabPhzneK8qYCgHMSWw=
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/git-duet.png)](http://badge.fury.io/rb/git-duet)
|
4
4
|
[![Build Status](https://travis-ci.org/modcloth/git-duet.png?branch=master)](https://travis-ci.org/modcloth/git-duet)
|
5
|
+
[![Code Climate](https://codeclimate.com/repos/52b6ea7089af7e2ddc0b1f3c/badges/cc96e2278280922e2a3f/gpa.png)](https://codeclimate.com/repos/52b6ea7089af7e2ddc0b1f3c/feed)
|
6
|
+
[![Dependency
|
7
|
+
Status](https://gemnasium.com/modcloth/git-duet.png)](https://gemnasium.com/modcloth/git-duet)
|
5
8
|
|
6
9
|
Pair harmoniously! Working in a pair doesn't mean you've both lost your
|
7
10
|
identity. Git Duet helps with blaming/praising by using stuff that's
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
# vim:fileencoding=utf-8
|
3
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
4
|
|
5
5
|
require 'rspec/core/rake_task'
|
6
6
|
|
@@ -13,4 +13,4 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
|
13
13
|
t.rspec_opts = '--format documentation'
|
14
14
|
end
|
15
15
|
|
16
|
-
task :
|
16
|
+
task default: [:rubocop, :spec]
|
@@ -53,7 +53,7 @@ class Git::Duet::AuthorMapper
|
|
53
53
|
return ERB.new(email_template).result(binding)
|
54
54
|
rescue StandardError => e
|
55
55
|
$stderr.puts("git-duet: email template rendering error: #{e.message}")
|
56
|
-
raise Git::Duet::ScriptDieError
|
56
|
+
raise Git::Duet::ScriptDieError, 8
|
57
57
|
end
|
58
58
|
|
59
59
|
def author_map
|
@@ -76,6 +76,6 @@ class Git::Duet::AuthorMapper
|
|
76
76
|
@cfg ||= YAML.load(IO.read(authors_file))
|
77
77
|
rescue StandardError => e
|
78
78
|
$stderr.puts("git-duet: Missing or corrupt authors file: #{e.message}")
|
79
|
-
raise Git::Duet::ScriptDieError
|
79
|
+
raise Git::Duet::ScriptDieError, 3
|
80
80
|
end
|
81
81
|
end
|
data/lib/git/duet/cli.rb
CHANGED
@@ -11,7 +11,7 @@ class Git::Duet::Cli
|
|
11
11
|
send(method_name, parse_options(method_name, argv.clone))
|
12
12
|
0
|
13
13
|
rescue NoMethodError
|
14
|
-
raise ScriptError
|
14
|
+
raise ScriptError, 'How did you get here???'
|
15
15
|
rescue Git::Duet::ScriptDieError => e
|
16
16
|
e.exit_code
|
17
17
|
end
|
@@ -40,26 +40,28 @@ class Git::Duet::Cli
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def parse_solo_options(argv)
|
43
|
-
|
44
|
-
argv, '
|
45
|
-
|
46
|
-
opts.on('-g', '--global', 'Change global git config') do |g|
|
47
|
-
options_hash[:global] = true
|
48
|
-
end
|
43
|
+
parse_options_with_positional_args(
|
44
|
+
argv, '<soloist-initials>') do |leftover_argv, options|
|
45
|
+
options[:soloist] = leftover_argv.first
|
49
46
|
end
|
50
|
-
options[:soloist] = leftover_argv.first
|
51
|
-
options
|
52
47
|
end
|
53
48
|
|
54
49
|
def parse_duet_options(argv)
|
50
|
+
parse_options_with_positional_args(
|
51
|
+
argv, '<alpha-initials> <omega-initials>') do |leftover_argv, options|
|
52
|
+
options[:alpha], options[:omega] = leftover_argv[0..1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_options_with_positional_args(argv, usage)
|
55
57
|
leftover_argv, options = with_common_opts(
|
56
|
-
argv, 'Usage: __PROG__ [options]
|
58
|
+
argv, 'Usage: __PROG__ [options] ' << usage
|
57
59
|
) do |opts, options_hash|
|
58
60
|
opts.on('-g', '--global', 'Change global git config') do |g|
|
59
61
|
options_hash[:global] = true
|
60
62
|
end
|
61
63
|
end
|
62
|
-
|
64
|
+
yield leftover_argv, options
|
63
65
|
options
|
64
66
|
end
|
65
67
|
|
@@ -4,7 +4,6 @@ require 'git/duet'
|
|
4
4
|
require 'git/duet/script_die_error'
|
5
5
|
|
6
6
|
module Git::Duet::CommandMethods
|
7
|
-
|
8
7
|
private
|
9
8
|
|
10
9
|
def report_env_vars
|
@@ -31,24 +30,24 @@ module Git::Duet::CommandMethods
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def author_env_vars_set?
|
34
|
-
%x(#{
|
33
|
+
%x(#{author_name_command} && #{author_email_command})
|
35
34
|
$CHILD_STATUS == 0
|
36
35
|
end
|
37
36
|
|
38
|
-
def
|
37
|
+
def author_name_command
|
39
38
|
"git config --get #{Git::Duet::Config.namespace}.git-author-name"
|
40
39
|
end
|
41
40
|
|
42
|
-
def
|
41
|
+
def author_email_command
|
43
42
|
"git config --get #{Git::Duet::Config.namespace}.git-author-email"
|
44
43
|
end
|
45
44
|
|
46
|
-
def
|
45
|
+
def current_config_command
|
47
46
|
"git config --get-regexp #{Git::Duet::Config.namespace}"
|
48
47
|
end
|
49
48
|
|
50
49
|
def show_current_config
|
51
|
-
info(exec_check(
|
50
|
+
info(exec_check(current_config_command))
|
52
51
|
end
|
53
52
|
|
54
53
|
def dump_env_vars
|
@@ -78,7 +77,7 @@ module Git::Duet::CommandMethods
|
|
78
77
|
if author_env_vars_set?
|
79
78
|
exec 'git commit ' << signoff_arg << quoted_passthrough_args
|
80
79
|
else
|
81
|
-
|
80
|
+
fail Git::Duet::ScriptDieError, 17
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
@@ -92,7 +91,7 @@ module Git::Duet::CommandMethods
|
|
92
91
|
output = `#{command}`
|
93
92
|
unless okay_statuses.include?($CHILD_STATUS.exitstatus)
|
94
93
|
error("Command #{command.inspect} exited with #{$CHILD_STATUS.to_i}")
|
95
|
-
|
94
|
+
fail Git::Duet::ScriptDieError, 1
|
96
95
|
end
|
97
96
|
output
|
98
97
|
end
|
@@ -28,8 +28,11 @@ class Git::Duet::DuetCommand
|
|
28
28
|
attr_accessor :alpha, :omega, :author_mapper
|
29
29
|
|
30
30
|
def set_alpha_as_git_config_user
|
31
|
-
|
32
|
-
|
31
|
+
%w(name email).each do |setting|
|
32
|
+
exec_check(
|
33
|
+
"#{git_config} user.#{setting} '#{alpha_info[setting.to_sym]}'"
|
34
|
+
)
|
35
|
+
end
|
33
36
|
end
|
34
37
|
|
35
38
|
def var_map
|
@@ -42,20 +45,21 @@ class Git::Duet::DuetCommand
|
|
42
45
|
end
|
43
46
|
|
44
47
|
def alpha_info
|
45
|
-
|
46
|
-
rescue KeyError, IndexError => e
|
47
|
-
error("git-duet: Failed to find author: #{e}")
|
48
|
-
raise Git::Duet::ScriptDieError.new(86)
|
48
|
+
fetch_info(alpha, 'author')
|
49
49
|
end
|
50
50
|
|
51
51
|
def omega_info
|
52
|
-
|
52
|
+
fetch_info(omega, 'committer')
|
53
|
+
end
|
54
|
+
|
55
|
+
def fetch_info(which, desc)
|
56
|
+
alpha_omega_info.fetch(which)
|
53
57
|
rescue KeyError, IndexError => e
|
54
|
-
error("git-duet: Failed to find
|
55
|
-
raise Git::Duet::ScriptDieError
|
58
|
+
error("git-duet: Failed to find #{desc}: #{e}")
|
59
|
+
raise Git::Duet::ScriptDieError, 86
|
56
60
|
end
|
57
61
|
|
58
62
|
def alpha_omega_info
|
59
|
-
@alpha_omega_info ||= author_mapper.map(
|
63
|
+
@alpha_omega_info ||= author_mapper.map(alpha, omega)
|
60
64
|
end
|
61
65
|
end
|
@@ -21,7 +21,7 @@ class Git::Duet::PreCommitCommand
|
|
21
21
|
def explode!
|
22
22
|
error('Your git duet settings are stale, human!')
|
23
23
|
error('Update them with `git duet` or `git solo`.')
|
24
|
-
|
24
|
+
fail Git::Duet::ScriptDieError, 1
|
25
25
|
end
|
26
26
|
|
27
27
|
def env_cache_exists?
|
@@ -57,6 +57,6 @@ class Git::Duet::SoloCommand
|
|
57
57
|
@soloist_info ||= author_mapper.map(@soloist).fetch(@soloist)
|
58
58
|
rescue KeyError, IndexError => e
|
59
59
|
error("git-solo: Failed to find author: #{e}")
|
60
|
-
raise Git::Duet::ScriptDieError
|
60
|
+
raise Git::Duet::ScriptDieError, 86
|
61
61
|
end
|
62
62
|
end
|
data/lib/git/duet/version.rb
CHANGED
@@ -12,26 +12,32 @@ describe 'git-duet end to end', integration: true do
|
|
12
12
|
EOF
|
13
13
|
|
14
14
|
def install_hook
|
15
|
-
Dir.chdir(@repo_dir)
|
16
|
-
|
15
|
+
Dir.chdir(@repo_dir) do
|
16
|
+
`git duet-install-hook -q`
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def uninstall_hook
|
20
|
-
|
21
|
+
Dir.chdir(@repo_dir) do
|
22
|
+
FileUtils.rm_f('.git/hooks/pre-commit')
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
def make_an_edit
|
24
|
-
Dir.chdir(@repo_dir)
|
25
|
-
|
26
|
-
|
27
|
+
Dir.chdir(@repo_dir) do
|
28
|
+
File.open('file.txt', 'w') { |f| f.puts "foo-#{rand(100_000)}" }
|
29
|
+
`git add file.txt`
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
before :all do
|
30
34
|
ENV['GIT_DUET_CONFIG_NAMESPACE'] = 'foo.bar'
|
35
|
+
|
31
36
|
@startdir = Dir.pwd
|
32
37
|
@tmpdir = Dir.mktmpdir('git-duet-specs')
|
33
38
|
@git_authors = File.join(@tmpdir, '.git-authors')
|
34
39
|
@email_lookup_path = File.join(@tmpdir, 'email-lookup')
|
40
|
+
|
35
41
|
File.open(@git_authors, 'w') do |f|
|
36
42
|
f.puts YAML.dump(
|
37
43
|
'pairs' => {
|
@@ -48,13 +54,17 @@ describe 'git-duet end to end', integration: true do
|
|
48
54
|
)
|
49
55
|
end
|
50
56
|
ENV['GIT_DUET_AUTHORS_FILE'] = @git_authors
|
57
|
+
|
51
58
|
top_bin = File.expand_path('../../../bin', __FILE__)
|
52
59
|
ENV['PATH'] = "#{top_bin}:#{ENV['PATH']}"
|
60
|
+
|
53
61
|
File.open(@email_lookup_path, 'w') { |f| f.puts EMAIL_LOOKUP_SCRIPT }
|
54
62
|
FileUtils.chmod(0755, @email_lookup_path)
|
63
|
+
|
55
64
|
@repo_dir = File.join(@tmpdir, 'foo')
|
56
|
-
Dir.chdir(@tmpdir)
|
57
|
-
|
65
|
+
Dir.chdir(@tmpdir) do
|
66
|
+
`git init #{@repo_dir}`
|
67
|
+
end
|
58
68
|
end
|
59
69
|
|
60
70
|
after :all do
|
@@ -69,7 +79,11 @@ describe 'git-duet end to end', integration: true do
|
|
69
79
|
end
|
70
80
|
|
71
81
|
context 'when installing the pre-commit hook' do
|
72
|
-
before(:each)
|
82
|
+
before(:each) do
|
83
|
+
Dir.chdir(@repo_dir)
|
84
|
+
install_hook
|
85
|
+
end
|
86
|
+
|
73
87
|
after(:each) { uninstall_hook }
|
74
88
|
|
75
89
|
it 'writes the hook to the `pre-commit` hook file' do
|
@@ -3,7 +3,8 @@ require 'git/duet/author_mapper'
|
|
3
3
|
|
4
4
|
describe Git::Duet::AuthorMapper do
|
5
5
|
before :each do
|
6
|
-
subject.instance_variable_set(
|
6
|
+
subject.instance_variable_set(
|
7
|
+
:@cfg,
|
7
8
|
'authors' => {
|
8
9
|
'jd' => 'Jane Doe; jdoe',
|
9
10
|
'fb' => 'Frances Bar; frances',
|
@@ -16,7 +17,7 @@ describe Git::Duet::AuthorMapper do
|
|
16
17
|
'email_addresses' => {
|
17
18
|
'jd' => 'jane@awesome.biz'
|
18
19
|
}
|
19
|
-
|
20
|
+
)
|
20
21
|
end
|
21
22
|
|
22
23
|
after :each do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-duet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Dan Buch
|
@@ -11,76 +12,86 @@ authors:
|
|
11
12
|
autorequire:
|
12
13
|
bindir: bin
|
13
14
|
cert_chain: []
|
14
|
-
date:
|
15
|
+
date: 2014-02-23 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: rake
|
18
19
|
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
19
21
|
requirements:
|
20
|
-
- - '>='
|
22
|
+
- - ! '>='
|
21
23
|
- !ruby/object:Gem::Version
|
22
24
|
version: '0'
|
23
25
|
type: :development
|
24
26
|
prerelease: false
|
25
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
26
29
|
requirements:
|
27
|
-
- - '>='
|
30
|
+
- - ! '>='
|
28
31
|
- !ruby/object:Gem::Version
|
29
32
|
version: '0'
|
30
33
|
- !ruby/object:Gem::Dependency
|
31
34
|
name: rspec
|
32
35
|
requirement: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
33
37
|
requirements:
|
34
|
-
- - '>='
|
38
|
+
- - ! '>='
|
35
39
|
- !ruby/object:Gem::Version
|
36
40
|
version: '0'
|
37
41
|
type: :development
|
38
42
|
prerelease: false
|
39
43
|
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
40
45
|
requirements:
|
41
|
-
- - '>='
|
46
|
+
- - ! '>='
|
42
47
|
- !ruby/object:Gem::Version
|
43
48
|
version: '0'
|
44
49
|
- !ruby/object:Gem::Dependency
|
45
50
|
name: rubocop
|
46
51
|
requirement: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
47
53
|
requirements:
|
48
|
-
- - '>='
|
54
|
+
- - ! '>='
|
49
55
|
- !ruby/object:Gem::Version
|
50
56
|
version: '0'
|
51
57
|
type: :development
|
52
58
|
prerelease: false
|
53
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
54
61
|
requirements:
|
55
|
-
- - '>='
|
62
|
+
- - ! '>='
|
56
63
|
- !ruby/object:Gem::Version
|
57
64
|
version: '0'
|
58
65
|
- !ruby/object:Gem::Dependency
|
59
66
|
name: pry
|
60
67
|
requirement: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
61
69
|
requirements:
|
62
|
-
- - '>='
|
70
|
+
- - ! '>='
|
63
71
|
- !ruby/object:Gem::Version
|
64
72
|
version: '0'
|
65
73
|
type: :development
|
66
74
|
prerelease: false
|
67
75
|
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
68
77
|
requirements:
|
69
|
-
- - '>='
|
78
|
+
- - ! '>='
|
70
79
|
- !ruby/object:Gem::Version
|
71
80
|
version: '0'
|
72
81
|
- !ruby/object:Gem::Dependency
|
73
82
|
name: simplecov
|
74
83
|
requirement: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
75
85
|
requirements:
|
76
|
-
- - '>='
|
86
|
+
- - ! '>='
|
77
87
|
- !ruby/object:Gem::Version
|
78
88
|
version: '0'
|
79
89
|
type: :development
|
80
90
|
prerelease: false
|
81
91
|
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
82
93
|
requirements:
|
83
|
-
- - '>='
|
94
|
+
- - ! '>='
|
84
95
|
- !ruby/object:Gem::Version
|
85
96
|
version: '0'
|
86
97
|
description: Pair programming git identity thingy
|
@@ -140,26 +151,30 @@ files:
|
|
140
151
|
homepage: https://github.com/modcloth/git-duet
|
141
152
|
licenses:
|
142
153
|
- MIT
|
143
|
-
metadata: {}
|
144
154
|
post_install_message:
|
145
155
|
rdoc_options: []
|
146
156
|
require_paths:
|
147
157
|
- lib
|
148
158
|
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
149
160
|
requirements:
|
150
|
-
- - '>='
|
161
|
+
- - ! '>='
|
151
162
|
- !ruby/object:Gem::Version
|
152
163
|
version: 1.9.3
|
153
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
154
166
|
requirements:
|
155
|
-
- - '>='
|
167
|
+
- - ! '>='
|
156
168
|
- !ruby/object:Gem::Version
|
157
169
|
version: '0'
|
170
|
+
segments:
|
171
|
+
- 0
|
172
|
+
hash: -3828941408143458487
|
158
173
|
requirements: []
|
159
174
|
rubyforge_project:
|
160
|
-
rubygems_version:
|
175
|
+
rubygems_version: 1.8.23
|
161
176
|
signing_key:
|
162
|
-
specification_version:
|
177
|
+
specification_version: 3
|
163
178
|
summary: Pair harmoniously! Decide who's driving. Commit along the way. Don't make
|
164
179
|
a mess of the repository history.
|
165
180
|
test_files:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 46323bd5392d627ae8bed46e4cd89f2bf8803885
|
4
|
-
data.tar.gz: b78bc212d1b95a47e28c8337b19cd5b3ebb38072
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 28d686c6d459b9104b5c9279e98cc49b6119461bf6b19cf88b41c71b053465fc8c2bb8e66cc856571fc909206a6e4ea7946d2b0f090ae29c38ce50761635d5ba
|
7
|
-
data.tar.gz: ec5038f060832c4f7ed5ad35243ba9ef43498a07eff2722ac2d65e2846c10460d2c5fe879e1750dc1e913d624ebfdb3ce43732345534a3f86b5ce22b1003f03c
|