dco 1.0.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.
@@ -0,0 +1,21 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module Dco
19
+ # dco gem version.
20
+ VERSION = '1.0.0'
21
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ describe 'baseline' do
20
+ # The most recent commit object.
21
+ subject { repo.log.first }
22
+
23
+ # Check that the test harness is working.
24
+ git_init
25
+ file 'testing'
26
+ before do
27
+ command 'git add testing'
28
+ command 'git commit -m "harness test"'
29
+ end
30
+
31
+ its(:message) { is_expected.to eq 'harness test' }
32
+ its('author.name') { is_expected.to eq 'Alan Smithee' }
33
+ its('author.email') { is_expected.to eq 'asmithee@example.com' }
34
+ end
@@ -0,0 +1,172 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ describe 'dco check' do
20
+ # Create a branch structure for all tests.
21
+ git_init
22
+ file 'testing', 'one'
23
+ before do
24
+ cmds = [
25
+ 'git add testing',
26
+ 'git commit -s -m "first commit"',
27
+ 'echo two > testing',
28
+ 'git commit -s -a -m "second commit"',
29
+ 'git checkout -b mybranch',
30
+ ]
31
+ command cmds.join(' && ')
32
+ end
33
+ dco_command 'check mybranch'
34
+
35
+ context 'with no commits in the branch' do
36
+ it do
37
+ expect(subject.exitstatus).to eq 0
38
+ expect(subject.stdout).to eq "All commits are signed off\n"
39
+ end
40
+ end # /context with no commits in the branch
41
+
42
+ context 'with one signed commit in the branch' do
43
+ before do
44
+ command 'echo three > testing && git commit -s -a -m "first branch commit"'
45
+ end
46
+
47
+ it do
48
+ expect(subject.exitstatus).to eq 0
49
+ expect(subject.stdout).to eq "All commits are signed off\n"
50
+ end
51
+ end # /context with one signed commit in the branch
52
+
53
+ context 'with one unsigned commit in the branch' do
54
+ before do
55
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing && git commit -s -a -m "second branch commit"'
56
+ end
57
+
58
+ it do
59
+ expect(subject.exitstatus).to eq 1
60
+ expect(subject.stdout).to match /^N \h{7} Alan Smithee <asmithee@example.com> first branch commit$/
61
+ end
62
+ end # /context with one unsigned commit in the branch
63
+
64
+ context 'with two signed commits in the branch' do
65
+ before do
66
+ command 'echo three > testing && git commit -s -a -m "first branch commit" && echo four > testing && git commit -s -a -m "second branch commit"'
67
+ end
68
+
69
+ it do
70
+ expect(subject.exitstatus).to eq 0
71
+ expect(subject.stdout).to eq "All commits are signed off\n"
72
+ end
73
+ end # /context with two signed commits in the branch
74
+
75
+ context 'with an implicit branch' do
76
+ before do
77
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing && git commit -s -a -m "second branch commit"'
78
+ end
79
+ dco_command 'check'
80
+
81
+ it do
82
+ expect(subject.exitstatus).to eq 1
83
+ expect(subject.stdout).to match /^N \h{7} Alan Smithee <asmithee@example.com> first branch commit$/
84
+ end
85
+ end # /context with an implicit branch
86
+
87
+ context 'with a branch that has a merge commit' do
88
+ before do
89
+ command('echo three > other && ' \
90
+ 'git add other && ' \
91
+ 'git commit -s -a -m "first branch commit" && ' \
92
+ 'git checkout master && ' \
93
+ 'echo three > testing && ' \
94
+ 'git commit -a -m "third commit" && ' \
95
+ 'git checkout mybranch && ' \
96
+ 'git merge master && ' \
97
+ 'echo four > other && ' \
98
+ 'git commit -a -m "second branch commit"')
99
+ end
100
+
101
+ it do
102
+ expect(subject.exitstatus).to eq 1
103
+ expect(subject.stdout).to match /^N \h{7} Alan Smithee <asmithee@example.com> second branch commit$/
104
+ expect(subject.stdout).to_not match /^N \h{7} Alan Smithee <asmithee@example.com> third commit$/
105
+ # TODO What should the check behavior on merge commits be? https://github.com/coderanger/dco/issues/1
106
+ end
107
+ end # /context with a branch that has a merge commit
108
+
109
+ context 'with --quiet' do
110
+ dco_command 'check --quiet'
111
+
112
+ context 'with no bad commits' do
113
+ before { command 'echo three > testing && git commit -s -a -m "first branch commit"' }
114
+
115
+ it do
116
+ expect(subject.exitstatus).to eq 0
117
+ expect(subject.stdout).to eq ''
118
+ expect(subject.stderr).to eq ''
119
+ end
120
+ end # /context with no bad commits
121
+
122
+ context 'with bad commits' do
123
+ before { command 'echo three > testing && git commit -a -m "first branch commit"' }
124
+
125
+ it do
126
+ expect(subject.exitstatus).to eq 1
127
+ expect(subject.stdout).to eq ''
128
+ expect(subject.stderr).to eq ''
129
+ end
130
+ end # /context with bad commits
131
+ end # /context with --quiet
132
+
133
+ context 'with the master branch' do
134
+ before do
135
+ command('echo three > other && ' \
136
+ 'git add other && ' \
137
+ 'git commit -s -a -m "first branch commit" && ' \
138
+ 'git checkout master && ' \
139
+ 'echo three > testing && ' \
140
+ 'git commit -a -m "third commit"')
141
+ end
142
+ dco_command 'check master'
143
+
144
+ it do
145
+ expect(subject.exitstatus).to eq 1
146
+ expect(subject.stdout).to match /^N \h{7} Alan Smithee <asmithee@example.com> third commit$/
147
+ expect(subject.stdout).to_not match /^N \h{7} Alan Smithee <asmithee@example.com> first branch commit$/
148
+ end
149
+ end # /context with the master branch
150
+
151
+ context 'with an author mismatch' do
152
+ file 'msg', "first branch commit\n\nSigned-off-by: Commiter McCommiterface <other@example.com>\n"
153
+ before do
154
+ command 'echo three > testing && git commit -a -F msg'
155
+ end
156
+
157
+ it do
158
+ expect(subject.exitstatus).to eq 1
159
+ expect(subject.stdout).to match /^M \h{7} Alan Smithee <asmithee@example.com> first branch commit$/
160
+ end
161
+
162
+ context 'with --allow-author-mismatch' do
163
+ dco_command 'check --allow-author-mismatch mybranch'
164
+
165
+ it do
166
+ expect(subject.exitstatus).to eq 0
167
+ expect(subject.stdout).to eq "All commits are signed off\n"
168
+ end
169
+
170
+ end # /context with --allow-author-mismatch
171
+ end # /context with an author mismatch
172
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ describe 'dco disable' do
20
+ # The most recent commit object.
21
+ subject { repo.log.first }
22
+
23
+ context 'with a normal commit' do
24
+ git_init
25
+ file 'testing'
26
+ before do
27
+ dco_command 'enable -y'
28
+ dco_command 'disable'
29
+ command 'git add testing'
30
+ command 'git commit -m "test commit"'
31
+ end
32
+
33
+ its(:message) { is_expected.to eq "test commit" }
34
+ end # /context with a normal commit
35
+
36
+ context 'with disable called twice' do
37
+ git_init
38
+ file 'testing'
39
+ before do
40
+ dco_command 'enable -y'
41
+ dco_command 'disable'
42
+ dco_command 'disable'
43
+ command 'git add testing'
44
+ command 'git commit -m "test commit"'
45
+ end
46
+
47
+ its(:message) { is_expected.to eq "test commit" }
48
+ end # /context with disable called twice
49
+
50
+ context 'with an external commit-msg script' do
51
+ git_init
52
+ file '.git/hooks/commit-msg', 'SOMETHING ELSE'
53
+ dco_command 'disable'
54
+
55
+ it do
56
+ expect(subject.exitstatus).to eq 1
57
+ expect(subject.stdout).to eq ''
58
+ expect(subject.stderr).to match /^commit-msg hook is external, not removing$/
59
+ end
60
+ end # /context with an existing commit-msg script
61
+ end
@@ -0,0 +1,104 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ describe 'dco enable' do
20
+ # The most recent commit object.
21
+ subject { repo.log.first }
22
+
23
+ context 'without a git repository' do
24
+ dco_command 'enable -y'
25
+
26
+ it do
27
+ expect(subject.exitstatus).to eq 1
28
+ expect(subject.stdout).to eq ''
29
+ expect(subject.stderr).to match /does not appear to be a git repository$/
30
+ end
31
+ end # /context without a git repository
32
+
33
+ context 'with an unwritable git repository' do
34
+ git_init
35
+ before { File.chmod(00544, File.join(temp_path, '.git')) }
36
+ dco_command 'enable -y'
37
+ after { File.chmod(00744, File.join(temp_path, '.git')) }
38
+
39
+ it do
40
+ expect(subject.exitstatus).to eq 1
41
+ expect(subject.stdout).to eq ''
42
+ expect(subject.stderr).to match /^Git repository at.*? is read-only$/
43
+ end
44
+ end # /context with an unwritable git repository
45
+
46
+ context 'with an existing commit-msg script' do
47
+ git_init
48
+ file '.git/hooks/commit-msg', 'SOMETHING ELSE'
49
+ dco_command 'enable -y'
50
+
51
+ it do
52
+ expect(subject.exitstatus).to eq 1
53
+ expect(subject.stdout).to eq ''
54
+ expect(subject.stderr).to match /^commit-msg hook already exists, not overwriting$/
55
+ end
56
+ end # /context with an existing commit-msg script
57
+
58
+ context 'with a normal commit' do
59
+ git_init
60
+ file 'testing'
61
+ before do
62
+ dco_command 'enable -y'
63
+ command 'git add testing'
64
+ command 'git commit -m "test commit"'
65
+ end
66
+
67
+ its(:message) { is_expected.to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>" }
68
+ end # /context with a normal commit
69
+
70
+ context 'with a signed-off commit' do
71
+ git_init
72
+ file 'testing'
73
+ before do
74
+ dco_command 'enable -y'
75
+ command 'git add testing'
76
+ command 'git commit -s -m "test commit"'
77
+ end
78
+
79
+ its(:message) { is_expected.to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>" }
80
+ end # /context with a signed-off commit
81
+
82
+ context 'with enable called twice' do
83
+ git_init
84
+ file 'testing'
85
+ before do
86
+ dco_command 'enable -y'
87
+ dco_command 'enable -y'
88
+ command 'git add testing'
89
+ command 'git commit -m "test commit"'
90
+ end
91
+
92
+ its(:message) { is_expected.to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>" }
93
+ end # /context with enable called twice
94
+
95
+ context 'without -y' do
96
+ git_init
97
+ dco_command 'enable'
98
+
99
+ it do
100
+ expect(subject.exitstatus).to eq 1
101
+ expect(subject.stderr).to eq "Not enabling auto-sign-off without approval\n"
102
+ end
103
+ end # /context without -y
104
+ end
@@ -0,0 +1,132 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ describe 'dco process_commit_message' do
20
+ around do |ex|
21
+ begin
22
+ ENV['GIT_COMMIT'] = 'abcd123'
23
+ ENV['GIT_AUTHOR_NAME'] = 'Alan Smithee'
24
+ ENV['GIT_AUTHOR_EMAIL'] = 'asmithee@example.com'
25
+ ex.run
26
+ ensure
27
+ ENV.delete('GIT_COMMIT')
28
+ ENV.delete('GIT_AUTHOR_NAME')
29
+ ENV.delete('GIT_AUTHOR_EMAIL')
30
+ end
31
+ end
32
+
33
+ context 'hook mode' do
34
+ dco_command 'process_commit_message msg'
35
+
36
+ RSpec.shared_examples 'process_commit_message hook mode' do |input, output|
37
+ file 'msg', input
38
+
39
+ it do
40
+ expect(subject.exitstatus).to eq 0
41
+ expect(subject.stdout).to eq ''
42
+ expect(subject.stderr).to eq ''
43
+ expect(IO.read(File.join(temp_path, 'msg'))).to eq output
44
+ end
45
+ end
46
+
47
+ context 'with a normal commit' do
48
+ it_behaves_like 'process_commit_message hook mode', "test commit\n", "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\n"
49
+ end # /context with a normal commit
50
+
51
+ context 'with no trailing newline' do
52
+ it_behaves_like 'process_commit_message hook mode', "test commit", "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\n"
53
+ end # /context with no trailing newline
54
+
55
+ context 'with existing sign-off' do
56
+ it_behaves_like 'process_commit_message hook mode', "test commit\n\nSigned-off-by: Someone Else <other@example.com>\n", "test commit\n\nSigned-off-by: Someone Else <other@example.com>\n"
57
+ end # /context with existing sign-off
58
+
59
+ context 'with two existing sign-offs' do
60
+ it_behaves_like 'process_commit_message hook mode', "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\nSigned-off-by: Someone Else <other@example.com>\n", "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\nSigned-off-by: Someone Else <other@example.com>\n"
61
+ end # /context with two existing sign-offs
62
+ end # /context hook mode
63
+
64
+ context 'filter mode' do
65
+ let(:input) { '' }
66
+ let(:git_ident) { {} }
67
+ let(:stdin) { double('STDIN', read: input) }
68
+ before do
69
+ # Use a let variable instead of calling git_init again in a later before
70
+ # block because we need to all command running before the STDIN stub.
71
+ git_init git_ident
72
+ stub_const('STDIN', stdin)
73
+ end
74
+
75
+ context 'with a normal commit' do
76
+ let(:input) { "test commit\n" }
77
+ dco_command 'process_commit_message'
78
+
79
+ it do
80
+ expect(subject.exitstatus).to eq 0
81
+ expect(subject.stdout).to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\n"
82
+ expect(subject.stderr).to eq ''
83
+ end
84
+ end # /context with a normal commit
85
+
86
+ context 'with existing sign-off' do
87
+ let(:input) { "test commit\n\nSigned-off-by: Someone Else <other@example.com>\n" }
88
+ dco_command 'process_commit_message'
89
+
90
+ it do
91
+ expect(subject.exitstatus).to eq 0
92
+ expect(subject.stdout).to eq "test commit\n\nSigned-off-by: Someone Else <other@example.com>\n"
93
+ expect(subject.stderr).to eq ''
94
+ end
95
+ end # /context with existing sign-off
96
+
97
+ context 'with --behalf' do
98
+ let(:input) { "test commit\n" }
99
+ let(:git_ident) { {name: 'Someone Else', email: 'other@example.com'} }
100
+ dco_command 'process_commit_message --behalf http://example.com/'
101
+
102
+ it do
103
+ expect(subject.exitstatus).to eq 0
104
+ expect(subject.stdout).to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\nSign-off-executed-by: Someone Else <other@example.com>\nApproved-at: http://example.com/\n"
105
+ expect(subject.stderr).to eq ''
106
+ end
107
+ end # /context with --behalf
108
+
109
+ context 'with someone elses commit' do
110
+ let(:input) { "test commit\n" }
111
+ let(:git_ident) { {name: 'Someone Else', email: 'other@example.com'} }
112
+ dco_command 'process_commit_message'
113
+
114
+ it do
115
+ expect(subject.exitstatus).to eq 1
116
+ expect(subject.stdout).to eq "test commit\n"
117
+ expect(subject.stderr).to eq "Author mismatch on commit abcd123: asmithee@example.com vs other@example.com\n"
118
+ end
119
+ end # /context with someone elses commit
120
+
121
+ context 'with --repo' do
122
+ let(:input) { "test commit\n" }
123
+ subject { dco_command "process_commit_message --repo '#{temp_path}'" }
124
+
125
+ it do
126
+ expect(subject.exitstatus).to eq 0
127
+ expect(subject.stdout).to eq "test commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\n"
128
+ expect(subject.stderr).to eq ''
129
+ end
130
+ end # /context with --repo
131
+ end # /context filter mode
132
+ end