codefumes 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +26 -0
- data/Manifest.txt +1 -0
- data/README.txt +36 -3
- data/Rakefile +3 -1
- data/bin/fumes +58 -16
- data/features/managing_project_build_status.feature +42 -2
- data/lib/codefumes.rb +1 -1
- data/lib/codefumes/cli_helpers.rb +21 -0
- data/lib/codefumes/errors.rb +3 -0
- data/lib/codefumes/exit_codes.rb +1 -0
- data/tasks/contributor_tasks.rb +64 -0
- metadata +6 -5
data/History.txt
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
=== NEXT
|
2
|
+
|
3
|
+
NEW FEATURES:
|
4
|
+
* Added --exec flag to 'fumes build' command to simplify incorporating
|
5
|
+
into an existing build server setup
|
6
|
+
* Expects your build command an argument to --exec and wraps that
|
7
|
+
command with the 'start' and (appropriate) 'finished' commands for
|
8
|
+
the specified build (assumes your build command uses an exit status
|
9
|
+
of '0' as a successful build, and anything else as a failure)
|
10
|
+
Example:
|
11
|
+
$ fumes build --exec="bundle install && rake db:migrate && rake spec" build-name
|
12
|
+
# Issues 'fumes build --start build-name'
|
13
|
+
# Issues "bundle install && rake db:migrate && rake spec"
|
14
|
+
|
15
|
+
# ...if the command exited with a status of '0'
|
16
|
+
# Issues 'fumes build --finished="successful" build-name'
|
17
|
+
|
18
|
+
# ...if the command exited with a non-zero status
|
19
|
+
# Issues 'fumes build --finished="failed" build-name'
|
20
|
+
|
21
|
+
BUG FIXES/UPDATES:
|
22
|
+
* Fixed error when no build name was specified with the '--start',
|
23
|
+
'--finished', or '--exec' options to 'fumes build'
|
24
|
+
* Corrected output from "fumes help build" to be in sync with expected usage
|
25
|
+
* Updated links in README
|
26
|
+
|
1
27
|
=== 0.3.0 / 2010-09-12
|
2
28
|
|
3
29
|
NEW FEATURES:
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
= codefumes
|
2
2
|
|
3
|
-
* http://
|
3
|
+
* http://cosyn.github.com/codefumes
|
4
4
|
* Wiki: https://github.com/cosyn/codefumes/wikis
|
5
5
|
* Repository: https://github.com/cosyn/codefumes
|
6
|
-
* Official CodeFumes.com gems: http://codefumes.rubyforge.org/
|
7
6
|
* Website: http://www.codefumes.com
|
8
7
|
|
9
8
|
== DESCRIPTION:
|
@@ -44,6 +43,8 @@ other libraries & and applications.
|
|
44
43
|
|
45
44
|
== SYNOPSIS:
|
46
45
|
|
46
|
+
=== In your own Ruby code:
|
47
|
+
|
47
48
|
require 'codefumes'
|
48
49
|
|
49
50
|
# Creating & finding a CodeFumes project
|
@@ -57,6 +58,13 @@ other libraries & and applications.
|
|
57
58
|
c.identifier # => git commit SHA (svn support coming soon)
|
58
59
|
c.short_message # => commit message
|
59
60
|
|
61
|
+
# Build Management
|
62
|
+
# QuickBuild grabs local commit head & current time to start build
|
63
|
+
QuickBuild.start('build-name-here')
|
64
|
+
|
65
|
+
# QuickBuild grabs local commit head & current time to finish build
|
66
|
+
QuickBuild.finish('build-name-here', 'successful')
|
67
|
+
|
60
68
|
# Custom attributes associated with a commit
|
61
69
|
c.custom_attributes[:coverage] # => "80"
|
62
70
|
|
@@ -64,6 +72,26 @@ other libraries & and applications.
|
|
64
72
|
content = Payload.prepare(payload_content)
|
65
73
|
content.each {|chunk| chunk.save}
|
66
74
|
|
75
|
+
|
76
|
+
=== From the command line:
|
77
|
+
|
78
|
+
$ fumes sync # <- synchronizes local repository with CodeFumes.com
|
79
|
+
$ fumes build --start ie7
|
80
|
+
$ fumes build --finish=successful ie7
|
81
|
+
$ fumes build --status --all
|
82
|
+
|
83
|
+
# Link to your CodeFumes account
|
84
|
+
$ fumes api-key [your-api-key]
|
85
|
+
$ fumes claim
|
86
|
+
|
87
|
+
# Release the project (unlink from your account)
|
88
|
+
$ fumes release
|
89
|
+
|
90
|
+
# Delete the project entirely from CodeFumes.com
|
91
|
+
$ fumes delete
|
92
|
+
|
93
|
+
See 'fumes --help' for more information on available commands and options.
|
94
|
+
|
67
95
|
== REQUIREMENTS:
|
68
96
|
|
69
97
|
* httparty (0.4.3)
|
@@ -81,5 +109,10 @@ From Gemcutter:
|
|
81
109
|
|
82
110
|
Refer to the LICENSE file
|
83
111
|
|
84
|
-
== Contributors
|
112
|
+
== Contributors (sorted alphabetically)
|
113
|
+
|
114
|
+
* Dan Nawara
|
85
115
|
* Joe Banks
|
116
|
+
* Joseph Leddy
|
117
|
+
* Leah Welty-Rieger
|
118
|
+
* Roy Kolak
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler.setup
|
3
3
|
|
4
|
-
%w[hoe rake rake/clean fileutils].each { |f| require f }
|
4
|
+
%w[hoe rake rake/clean fileutils tasks/contributor_tasks].each { |f| require f }
|
5
5
|
|
6
6
|
$LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
|
7
7
|
require 'lib/codefumes'
|
@@ -35,6 +35,8 @@ $hoe = Hoe.spec('codefumes') do
|
|
35
35
|
developer('Tom Kersten', 'tom.kersten@codefumes.com')
|
36
36
|
end
|
37
37
|
|
38
|
+
ContributorTasks.new
|
39
|
+
|
38
40
|
Dir['tasks/**/*.rake'].each { |t| load t}
|
39
41
|
|
40
42
|
task :default => [:spec]
|
data/bin/fumes
CHANGED
@@ -155,35 +155,35 @@ command :open do |c|
|
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
-
|
158
|
+
arg_name "(build_name | -a/--all)"
|
159
|
+
desc "Set & retrieve the build status of a project"
|
159
160
|
command :build do |c|
|
160
161
|
c.desc 'Start the specified build'
|
161
|
-
c.default_value false
|
162
162
|
c.switch [:start]
|
163
163
|
|
164
164
|
c.desc 'Mark the specified build with the supplied result'
|
165
|
-
c.arg_name "successful-or-
|
165
|
+
c.arg_name "successful-or-failed"
|
166
166
|
c.default_value nil
|
167
167
|
c.flag [:finished]
|
168
168
|
|
169
169
|
c.desc 'Retrieve the build status of the specified build'
|
170
|
-
c.default_value false
|
171
170
|
c.switch [:status, :s]
|
172
171
|
|
173
172
|
c.desc 'Retrieve the the status of all builds associated with the latest commit'
|
174
173
|
c.default_value false
|
175
174
|
c.switch [:all, :a]
|
176
175
|
|
176
|
+
c.desc 'Wrap the specified shell command with build start & finished commands (uses exit code of "0" as "success")'
|
177
|
+
c.arg_name "shell-command-to-execute"
|
178
|
+
c.default_value nil
|
179
|
+
c.flag [:exec]
|
180
|
+
|
181
|
+
# TODO: refactor this...some smelly stuff here
|
177
182
|
c.action do |global_options, options, args|
|
178
183
|
project_public_key = options[:public_key] || SourceControl.new('./').public_key
|
179
184
|
build_name = args.first
|
180
185
|
|
181
|
-
if
|
182
|
-
puts "You must specify a build name or the --all/-a switch."
|
183
|
-
raise Errors::InvalidCommandSyntax
|
184
|
-
end
|
185
|
-
|
186
|
-
if options[:status]
|
186
|
+
if checking_build_status?(options)
|
187
187
|
puts "Retrieving build status for '#{project_public_key}' project..."
|
188
188
|
project = Project.find(project_public_key)
|
189
189
|
commit = Commit.latest(project)
|
@@ -199,17 +199,27 @@ command :build do |c|
|
|
199
199
|
puts "\t'#{build.name}' build: #{build.state}"
|
200
200
|
end
|
201
201
|
end
|
202
|
-
elsif options
|
202
|
+
elsif updating_build_state?(options)
|
203
203
|
new_status = options[:finished] ? options[:finished] : "started"
|
204
204
|
msg = "Setting '#{build_name}' build status to '#{new_status}'"
|
205
205
|
|
206
206
|
issue_project_commands(msg, [project_public_key]) do |project|
|
207
207
|
if options[:start] && QuickBuild.start(build_name)
|
208
|
-
puts "
|
208
|
+
puts "Success!"
|
209
209
|
elsif options[:finished] && QuickBuild.finish(build_name, options[:finished])
|
210
|
-
puts "
|
210
|
+
puts "Success!"
|
211
|
+
else
|
212
|
+
puts "BUILD STATUS UPDATE REQUEST FAILED!"
|
211
213
|
end
|
212
214
|
end
|
215
|
+
elsif options[:exec]
|
216
|
+
commands[:build].execute(global_options, {:start => true}, build_name)
|
217
|
+
|
218
|
+
puts "Executing: '#{options[:exec]}'..."
|
219
|
+
build_result = system(options[:exec]) ? "successful" : "failed"
|
220
|
+
|
221
|
+
commands[:build].execute(global_options, {:finished => build_result}, build_name)
|
222
|
+
raise(Errors::RetainFailedBuildState) if build_result == "failed"
|
213
223
|
else
|
214
224
|
commands[:help].execute(global_options, options, ['build'])
|
215
225
|
end
|
@@ -221,10 +231,39 @@ pre do |global,command,options,args|
|
|
221
231
|
print_api_mode_notification
|
222
232
|
end
|
223
233
|
|
224
|
-
if issuing_build_command?(command)
|
225
|
-
|
226
|
-
|
234
|
+
if issuing_build_command?(command)
|
235
|
+
unless actionable_flag_specified?(options)
|
236
|
+
commands[:help].execute(global, options, ['build'])
|
237
|
+
raise Errors::InvalidCommandSyntax
|
238
|
+
end
|
239
|
+
|
240
|
+
if !options[:status] && !build_name_specified?(args)
|
241
|
+
puts options.inspect
|
242
|
+
puts "You must include a build name with the '--start', '--finished', and '--exec' flags."
|
243
|
+
raise Errors::InvalidCommandSyntax
|
244
|
+
end
|
245
|
+
|
246
|
+
if options[:status] && (!build_name_specified?(args) && !scoped_to_all_builds?(options))
|
247
|
+
puts "You must specify a build name or the --all/-a switch."
|
248
|
+
raise Errors::InvalidCommandSyntax
|
249
|
+
end
|
250
|
+
|
251
|
+
if options[:exec] && (options[:start] || options[:finished])
|
252
|
+
option_specified = options[:start] ? "start" : "finished"
|
253
|
+
puts "Specifying both the '--exec' and the '--#{option_specified}' flags in the same command"
|
254
|
+
puts "is neither necessary nor supported."
|
255
|
+
puts ""
|
256
|
+
puts "If you use the same command but omit the '--#{option_specified}' flag, you should be "
|
257
|
+
puts "set ('--exec' takes care of '--#{option_specified}' for you)."
|
258
|
+
raise Errors::InvalidCommandSyntax
|
259
|
+
end
|
260
|
+
|
261
|
+
if multiple_build_states?(options)
|
262
|
+
puts "Specifying multiple states in the same command is not allowed"
|
263
|
+
raise CodeFumes::Errors::InvalidCommandSyntax
|
264
|
+
end
|
227
265
|
end
|
266
|
+
|
228
267
|
true
|
229
268
|
end
|
230
269
|
|
@@ -277,6 +316,9 @@ on_error do |exception|
|
|
277
316
|
when Errors::InvalidCommandSyntax
|
278
317
|
puts "Exiting..."
|
279
318
|
exit(ExitCodes::INVALID_COMMAND_SYNTAX)
|
319
|
+
when Errors::RetainFailedBuildState
|
320
|
+
puts "Exiting..."
|
321
|
+
exit(ExitCodes::STANDARD_BUILD_FAILURE)
|
280
322
|
when RuntimeError
|
281
323
|
# allow default handler to take over when invalid arguments are passed in
|
282
324
|
else
|
@@ -9,7 +9,6 @@ Feature: Managing a project's build status
|
|
9
9
|
And I cd to "project_1/"
|
10
10
|
When I run "#{@bin_path}/fumes build --start ie7"
|
11
11
|
Then the output should contain "Setting 'ie7' build status to 'started'"
|
12
|
-
And the output should contain "'ie7' build successfully marked as 'started'"
|
13
12
|
And the exit status should be "SUCCESS"
|
14
13
|
|
15
14
|
Scenario: Setting a project build status to 'failure'
|
@@ -18,7 +17,6 @@ Feature: Managing a project's build status
|
|
18
17
|
And I run "#{@bin_path}/fumes build --start ie7"
|
19
18
|
When I run "#{@bin_path}/fumes build --finished=failed ie7"
|
20
19
|
Then the output should contain "Setting 'ie7' build status to 'failed'"
|
21
|
-
And the output should contain "'ie7' build successfully marked as 'failed'"
|
22
20
|
And the exit status should be "SUCCESS"
|
23
21
|
|
24
22
|
Scenario: Setting a project build status to an invalid state
|
@@ -60,4 +58,46 @@ Feature: Managing a project's build status
|
|
60
58
|
When I run "#{@bin_path}/fumes build"
|
61
59
|
Then the output should contain "build [options]"
|
62
60
|
Then the output should contain "Options:"
|
61
|
+
And the exit status should be "INVALID_COMMAND_SYNTAX"
|
62
|
+
|
63
|
+
Scenario: Wrapping a successful build command with build start & stop information
|
64
|
+
Given I have cloned and synchronized 1 project
|
65
|
+
And I cd to "project_1/"
|
66
|
+
And I run "#{@bin_path}/fumes build --exec='ls ./' ie7"
|
67
|
+
Then the output should contain "Executing: 'ls ./'"
|
68
|
+
And the output should contain "Setting 'ie7' build status to 'started'"
|
63
69
|
And the exit status should be "SUCCESS"
|
70
|
+
|
71
|
+
Scenario: Wrapping a failing build command with build start & stop information
|
72
|
+
Given I have cloned and synchronized 1 project
|
73
|
+
And I cd to "project_1/"
|
74
|
+
And I run "#{@bin_path}/fumes build --exec='lr ./' ie7"
|
75
|
+
Then the output should contain "Executing: 'lr ./'"
|
76
|
+
And the output should contain "Setting 'ie7' build status to 'started'"
|
77
|
+
And the exit status should be "STANDARD_BUILD_FAILURE"
|
78
|
+
|
79
|
+
Scenario: Specifying --start AND --exec in the same command
|
80
|
+
Given I have cloned and synchronized 1 project
|
81
|
+
And I cd to "project_1/"
|
82
|
+
And I run "#{@bin_path}/fumes build --start --exec='lr ./' ie7"
|
83
|
+
Then the output should contain "'--exec' and the '--start' flags"
|
84
|
+
And the output should not contain "Executing: 'lr ./'"
|
85
|
+
And the output should not contain "Setting 'ie7' build status to 'started'"
|
86
|
+
And the exit status should be "INVALID_COMMAND_SYNTAX"
|
87
|
+
|
88
|
+
Scenario: Specifying --finished AND --exec in the same command
|
89
|
+
Given I have cloned and synchronized 1 project
|
90
|
+
And I cd to "project_1/"
|
91
|
+
And I run "#{@bin_path}/fumes build --finished='failed' --exec='lr ./' ie7"
|
92
|
+
Then the output should contain "'--exec' and the '--finished' flags"
|
93
|
+
And the output should not contain "Executing: 'lr ./'"
|
94
|
+
And the output should not contain "Setting 'ie7' build status to 'started'"
|
95
|
+
And the exit status should be "INVALID_COMMAND_SYNTAX"
|
96
|
+
|
97
|
+
Scenario: Starting a build for a project without specifying a build name
|
98
|
+
Given I have cloned and synchronized 1 project
|
99
|
+
And I cd to "project_1/"
|
100
|
+
When I run "#{@bin_path}/fumes build --start"
|
101
|
+
Then the output should contain "include a build name"
|
102
|
+
And the output should not contain "build status to 'started'"
|
103
|
+
And the exit status should be "INVALID_COMMAND_SYNTAX"
|
data/lib/codefumes.rb
CHANGED
@@ -14,6 +14,27 @@ module CodeFumes
|
|
14
14
|
command && command.name.to_sym == :build
|
15
15
|
end
|
16
16
|
|
17
|
+
def build_name_specified?(args)
|
18
|
+
!args.first.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def actionable_flag_specified?(options)
|
22
|
+
actionable_flags = [:finished, :status, :start, :exec]
|
23
|
+
!actionable_flags.select {|flag| options[flag]}.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def updating_build_state?(options)
|
27
|
+
!!(options[:start] || options[:finished])
|
28
|
+
end
|
29
|
+
|
30
|
+
def checking_build_status?(options)
|
31
|
+
!!(options[:status])
|
32
|
+
end
|
33
|
+
|
34
|
+
def scoped_to_all_builds?(options)
|
35
|
+
options[:all]
|
36
|
+
end
|
37
|
+
|
17
38
|
def issue_project_commands(message, public_keys, &block)
|
18
39
|
public_keys.each do |public_key|
|
19
40
|
print "#{message}...'#{public_key}': "
|
data/lib/codefumes/errors.rb
CHANGED
data/lib/codefumes/exit_codes.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
class ContributorTasks < Rake::TaskLib
|
5
|
+
def initialize
|
6
|
+
define
|
7
|
+
end
|
8
|
+
|
9
|
+
def define
|
10
|
+
desc "Update contributors list in README"
|
11
|
+
task :update_contributors do
|
12
|
+
if new_contributors?
|
13
|
+
puts "New contributors!"
|
14
|
+
new_contributors.each {|name| puts "- #{name}"}
|
15
|
+
puts ""
|
16
|
+
|
17
|
+
print "Updating the 'Contributors' section of README..."
|
18
|
+
|
19
|
+
File.open("README.txt", "w+") do |file|
|
20
|
+
file.puts readme_without_contributors_section
|
21
|
+
file.puts "== Contributors (sorted alphabetically)"
|
22
|
+
file.puts ""
|
23
|
+
committers.each {|name| file.puts "* #{name}"}
|
24
|
+
end
|
25
|
+
puts "done!"
|
26
|
+
else
|
27
|
+
puts "No new contributors."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def all_committers
|
34
|
+
all_names = `git shortlog -s |cut -s -f2`
|
35
|
+
all_names.gsub!(/\sand\s/, "\n").split("\n").uniq!.sort!
|
36
|
+
end
|
37
|
+
|
38
|
+
def committers
|
39
|
+
excluded_committers = ["Tom Kersten", "Leah Rieger"]
|
40
|
+
@committers ||= all_committers - excluded_committers
|
41
|
+
end
|
42
|
+
|
43
|
+
def readme_file_contents
|
44
|
+
@readme_contents ||= `cat README.txt`
|
45
|
+
end
|
46
|
+
|
47
|
+
def existing_contributors
|
48
|
+
existing_contributors = readme_file_contents[/== Contributors(.|\n)*/].strip.split("\n* ")
|
49
|
+
existing_contributors.shift # remove "Contributors..." line
|
50
|
+
existing_contributors
|
51
|
+
end
|
52
|
+
|
53
|
+
def new_contributors
|
54
|
+
@new_contributors ||= committers - existing_contributors
|
55
|
+
end
|
56
|
+
|
57
|
+
def new_contributors?
|
58
|
+
!new_contributors.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
def readme_without_contributors_section
|
62
|
+
readme_file_contents.sub(/== Contributors(.|\n)*/, '')
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codefumes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tom Kersten
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-10 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -297,10 +297,11 @@ files:
|
|
297
297
|
- spec/fixtures/sample_project_dirs/no_scm/description
|
298
298
|
- spec/spec.opts
|
299
299
|
- spec/spec_helper.rb
|
300
|
+
- tasks/contributor_tasks.rb
|
300
301
|
- tasks/cucumber.rake
|
301
302
|
- tasks/rspec.rake
|
302
303
|
has_rdoc: true
|
303
|
-
homepage: http://
|
304
|
+
homepage: http://cosyn.github.com/codefumes
|
304
305
|
licenses: []
|
305
306
|
|
306
307
|
post_install_message:
|