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,230 @@
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 sign' 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 -m "first commit"',
27
+ 'echo two > testing',
28
+ 'git commit -a -m "second commit"',
29
+ 'git checkout -b mybranch',
30
+ ]
31
+ command cmds.join(' && ')
32
+ end
33
+
34
+ context 'with no commits in the branch' do
35
+ dco_command 'sign -y mybranch'
36
+
37
+ it do
38
+ expect(subject.exitstatus).to eq 1
39
+ expect(subject.stderr).to eq "Branch mybranch has no commits which require sign-off\n"
40
+ end
41
+ end # /context with no commits in the branch
42
+
43
+ context 'with one commit in the branch' do
44
+ before do
45
+ command 'echo three > testing && git commit -a -m "first branch commit"'
46
+ end
47
+ dco_command 'sign -y mybranch'
48
+
49
+ it do
50
+ expect(subject.exitstatus).to eq 0
51
+ expect(subject.stdout).to match /^Developer's Certificate of Origin 1\.1$/
52
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> first branch commit$/
53
+ expect(repo.log[0].message).to eq "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
54
+ expect(repo.log[1].message).to eq "second commit"
55
+ expect(repo.log[2].message).to eq "first commit"
56
+ end
57
+ end # /context with one commit in the branch
58
+
59
+ context 'with one commit in the branch without -y' do
60
+ before do
61
+ command 'echo three > testing && git commit -a -m "first branch commit"'
62
+ end
63
+ dco_command 'sign mybranch'
64
+
65
+ it do
66
+ expect(subject.exitstatus).to eq 1
67
+ expect(subject.stderr).to eq "Not signing off on commits without approval\n"
68
+ end
69
+ end # /context with one commit in the branch without -y
70
+
71
+ context 'with two commits in the branch' do
72
+ before do
73
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing && git commit -a -m "second branch commit"'
74
+ end
75
+ dco_command 'sign -y mybranch'
76
+
77
+ it do
78
+ expect(subject.exitstatus).to eq 0
79
+ expect(subject.stdout).to match /^Developer's Certificate of Origin 1\.1$/
80
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> second branch commit\n\* \h{7} Alan Smithee <asmithee@example\.com> first branch commit$/
81
+ expect(repo.log[0].message).to eq "second branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
82
+ expect(repo.log[1].message).to eq "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
83
+ expect(repo.log[2].message).to eq "second commit"
84
+ expect(repo.log[3].message).to eq "first commit"
85
+ end
86
+ end # /context with two commits in the branch
87
+
88
+ context 'with a branch that has a merge commit' do
89
+ before do
90
+ command('echo three > other && ' \
91
+ 'git add other && ' \
92
+ 'git commit -a -m "first branch commit" && ' \
93
+ 'git checkout master && ' \
94
+ 'echo three > testing && ' \
95
+ 'git commit -a -m "third commit" && ' \
96
+ 'git checkout mybranch && ' \
97
+ 'git merge master && ' \
98
+ 'echo four > other && ' \
99
+ 'git commit -a -m "second branch commit"')
100
+ end
101
+ dco_command 'sign -y mybranch'
102
+
103
+ it do
104
+ expect(subject.exitstatus).to eq 0
105
+ expect(subject.stdout).to match /^Developer's Certificate of Origin 1\.1$/
106
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> second branch commit\n\* \h{7} Alan Smithee <asmithee@example\.com> Merge branch 'master' into mybranch\n\* \h{7} Alan Smithee <asmithee@example\.com> first branch commit$/
107
+ # Ordering is unstable because of the merge.
108
+ commits = repo.log.map {|c| c.message }
109
+ expect(commits.size).to eq 6
110
+ expect(commits).to include "second branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
111
+ expect(commits).to include "Merge branch 'master' into mybranch\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
112
+ expect(commits).to include "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
113
+ expect(commits).to include "third commit"
114
+ expect(commits).to include "second commit"
115
+ expect(commits).to include "first commit"
116
+ end
117
+ end # /context with a branch that has a merge commit
118
+
119
+ context 'with behalf mode enabled' do
120
+ before do
121
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing && git commit -a -m "second branch commit"'
122
+ git_init(name: 'Commiter McCommiterface', email: 'other@example.com')
123
+ end
124
+ dco_command 'sign -y mybranch -b https://github.com/chef/chef/pulls/1234'
125
+
126
+ it do
127
+ expect(subject.exitstatus).to eq 0
128
+ expect(subject.stdout).to_not match /^Developer's Certificate of Origin 1\.1$/
129
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> second branch commit\n\* \h{7} Alan Smithee <asmithee@example\.com> first branch commit$/
130
+ expect(repo.log[0].message).to eq "second branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\nSign-off-executed-by: Commiter McCommiterface <other@example.com>\nApproved-at: https://github.com/chef/chef/pulls/1234"
131
+ expect(repo.log[1].message).to eq "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>\nSign-off-executed-by: Commiter McCommiterface <other@example.com>\nApproved-at: https://github.com/chef/chef/pulls/1234"
132
+ expect(repo.log[2].message).to eq "second commit"
133
+ expect(repo.log[3].message).to eq "first commit"
134
+ end
135
+ end # /context with behalf mode enabled
136
+
137
+ context 'with someone elses commits' do
138
+ before do
139
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing && git commit -a -m "second branch commit"'
140
+ git_init(name: 'Commiter McCommiterface', email: 'other@example.com')
141
+ end
142
+ dco_command 'sign -y mybranch'
143
+
144
+ it do
145
+ expect(subject.exitstatus).to eq 1
146
+ expect(subject.stderr).to eq "Branch mybranch contains commits not authored by you. Please use the --behalf flag when signing off for another contributor\n"
147
+ end
148
+ end # /context with someone elses commits
149
+
150
+ context 'with an invalid branch' do
151
+ dco_command 'sign -y master'
152
+
153
+ it do
154
+ expect(subject.exitstatus).to eq 1
155
+ expect(subject.stderr).to eq "Cannot use master for both the base and target branch\n"
156
+ end
157
+ end # /context with an invalid branch
158
+
159
+ context 'with an implicit branch' do
160
+ before do
161
+ command 'echo three > testing && git commit -a -m "first branch commit"'
162
+ end
163
+ dco_command 'sign -y'
164
+
165
+ it do
166
+ expect(subject.exitstatus).to eq 0
167
+ expect(subject.stdout).to match /^Developer's Certificate of Origin 1\.1$/
168
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> first branch commit$/
169
+ expect(repo.log[0].message).to eq "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
170
+ expect(repo.log[1].message).to eq "second commit"
171
+ expect(repo.log[2].message).to eq "first commit"
172
+ end
173
+ end # /context with an implicit branch
174
+
175
+ context 'with an implicit invalid branch' do
176
+ before { command 'git checkout master' }
177
+ dco_command 'sign -y'
178
+
179
+ it do
180
+ expect(subject.exitstatus).to eq 1
181
+ expect(subject.stderr).to eq "Cannot use master for both the base and target branch\n"
182
+ end
183
+ end # /context with an implicit invalid branch
184
+
185
+ context 'with an existing backup pointer' do
186
+ before do
187
+ command 'echo three > testing && git commit -a -m "first branch commit"'
188
+ dco_command 'sign -y mybranch'
189
+ command 'echo four > testing && git commit -a -m "second branch commit"'
190
+ end
191
+ dco_command 'sign -y mybranch'
192
+
193
+ it do
194
+ expect(subject.exitstatus).to eq 0
195
+ expect(subject.stdout).to match /^Developer's Certificate of Origin 1\.1$/
196
+ expect(subject.stdout).to match /^Going to sign-off the following commits:\n\* \h{7} Alan Smithee <asmithee@example\.com> second branch commit$/
197
+ expect(repo.log[0].message).to eq "second branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
198
+ expect(repo.log[1].message).to eq "first branch commit\n\nSigned-off-by: Alan Smithee <asmithee@example.com>"
199
+ expect(repo.log[2].message).to eq "second commit"
200
+ expect(repo.log[3].message).to eq "first commit"
201
+ end
202
+ end # /context with an existing backup pointer
203
+
204
+ context 'with an existing backup pointer without -y' do
205
+ before do
206
+ command 'echo three > testing && git commit -a -m "first branch commit"'
207
+ dco_command 'sign -y mybranch'
208
+ command 'echo four > testing && git commit -a -m "second branch commit"'
209
+ end
210
+ dco_command 'sign mybranch'
211
+
212
+ it do
213
+ expect(subject.exitstatus).to eq 1
214
+ expect(subject.stderr).to eq "Backup ref present, not continuing\n"
215
+ end
216
+ end # /context with an existing backup pointer without -y
217
+
218
+ context 'with uncommitted changes' do
219
+ before do
220
+ command 'echo three > testing && git commit -a -m "first branch commit" && echo four > testing'
221
+ end
222
+ dco_command 'sign -y mybranch'
223
+
224
+ it do
225
+ expect(subject.exitstatus).to eq 0
226
+ expect(subject.stdout).to match /^Stashing uncommited changes before continuing$/
227
+ expect(IO.read(File.join(temp_path, 'testing')).strip).to eq "four"
228
+ end
229
+ end # /context with uncommitted changes
230
+ end
@@ -0,0 +1,91 @@
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 'rspec'
18
+ require 'rspec_command'
19
+ require 'simplecov'
20
+ require 'git'
21
+ require 'shellwords'
22
+
23
+ # Check for coverage stuffs
24
+ if ENV['CODECOV_TOKEN'] || ENV['TRAVIS']
25
+ require 'codecov'
26
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
27
+ end
28
+
29
+ SimpleCov.start do
30
+ # Don't get coverage on the test cases themselves.
31
+ add_filter '/spec/'
32
+ add_filter '/test/'
33
+ # Codecov doesn't automatically ignore vendored files.
34
+ add_filter '/vendor/'
35
+ end
36
+
37
+ require 'dco'
38
+
39
+ module DcoSpecHelper
40
+ extend RSpec::SharedContext
41
+
42
+ def dco_command *args
43
+ cwd = Dir.pwd
44
+ begin
45
+ Dir.chdir(temp_path)
46
+ capture_output do
47
+ args = Shellwords.split(args.first) if args.length == 1 && args.first.is_a?(String)
48
+ Dco::CLI.start(args)
49
+ end
50
+ ensure
51
+ Dir.chdir(cwd)
52
+ end
53
+ rescue Exception => e
54
+ status = e.is_a?(SystemExit) ? e.status : 1
55
+ e.output_so_far.define_singleton_method(:exitstatus) { status }
56
+ e.output_so_far
57
+ end
58
+
59
+ def git_init(name: 'Alan Smithee', email: 'asmithee@example.com')
60
+ command "git init && git config user.name \"#{name}\" && git config user.email \"#{email}\""
61
+ end
62
+
63
+ let(:repo) { Git.open(temp_path) }
64
+
65
+ module ClassMethods
66
+ def dco_command *args
67
+ subject { dco_command(*args) }
68
+ end
69
+
70
+ def git_init(*args)
71
+ before { git_init(*args) }
72
+ end
73
+ end
74
+ end
75
+
76
+ RSpec.configure do |config|
77
+ # Basic configuraiton
78
+ config.run_all_when_everything_filtered = true
79
+ config.filter_run(:focus)
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = 'random'
86
+
87
+ config.include RSpecCommand
88
+
89
+ config.include DcoSpecHelper
90
+ config.extend DcoSpecHelper::ClassMethods
91
+ end
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dco
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Noah Kantrowitz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: git
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.19'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.19'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-command
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: fuubar
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.8'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: codecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.0'
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 0.0.2
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: '0.0'
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 0.0.2
145
+ - !ruby/object:Gem::Dependency
146
+ name: pry
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ description: A command line tool to help manage Developer Certificate of Origin projects.
160
+ email:
161
+ - noah@coderanger.net
162
+ executables:
163
+ - dco
164
+ extensions: []
165
+ extra_rdoc_files: []
166
+ files:
167
+ - ".gitignore"
168
+ - ".travis.yml"
169
+ - ".yardopts"
170
+ - CHANGELOG.md
171
+ - Gemfile
172
+ - LICENSE
173
+ - README.md
174
+ - Rakefile
175
+ - appveyor.yml
176
+ - bin/dco
177
+ - dco.gemspec
178
+ - gemfiles/master.gemfile
179
+ - gemfiles/release.gemfile
180
+ - lib/dco.rb
181
+ - lib/dco/cli.rb
182
+ - lib/dco/version.rb
183
+ - spec/baseline_spec.rb
184
+ - spec/check_spec.rb
185
+ - spec/disable_spec.rb
186
+ - spec/enable_spec.rb
187
+ - spec/process_commit_message_spec.rb
188
+ - spec/sign_spec.rb
189
+ - spec/spec_helper.rb
190
+ homepage: https://github.com/coderanger/dco
191
+ licenses:
192
+ - Apache-2.0
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements: []
209
+ rubyforge_project:
210
+ rubygems_version: 2.6.4
211
+ signing_key:
212
+ specification_version: 4
213
+ summary: A command line tool to help manage Developer Certificate of Origin projects.
214
+ test_files:
215
+ - spec/baseline_spec.rb
216
+ - spec/check_spec.rb
217
+ - spec/disable_spec.rb
218
+ - spec/enable_spec.rb
219
+ - spec/process_commit_message_spec.rb
220
+ - spec/sign_spec.rb
221
+ - spec/spec_helper.rb