dco 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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