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 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
@@ -60,5 +60,6 @@ spec/fixtures/project_update.xml
60
60
  spec/fixtures/sample_project_dirs/no_scm/description
61
61
  spec/spec.opts
62
62
  spec/spec_helper.rb
63
+ tasks/contributor_tasks.rb
63
64
  tasks/cucumber.rake
64
65
  tasks/rspec.rake
data/README.txt CHANGED
@@ -1,9 +1,8 @@
1
1
  = codefumes
2
2
 
3
- * http://codefumes.rubyforge.org/codefumes
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
- desc "Set/read the build status of a project"
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-failure"
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 build_name.nil? && options[:status] && !options[:all]
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[:start] || options[:finished]
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 "'#{build_name}' build successfully marked as '#{new_status}'"
208
+ puts "Success!"
209
209
  elsif options[:finished] && QuickBuild.finish(build_name, options[:finished])
210
- puts "'#{build_name}' build successfully marked as '#{new_status}'"
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) && multiple_build_states?(options)
225
- puts "Specifying multiple states in the same command is not allowed"
226
- raise CodeFumes::Errors::InvalidCommandSyntax
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
@@ -12,5 +12,5 @@ require 'codefumes/source_control.rb'
12
12
  include CodeFumes::API
13
13
 
14
14
  module CodeFumes
15
- VERSION = '0.3.0' unless defined?(CodeFumes::VERSION)
15
+ VERSION = '0.4.0' unless defined?(CodeFumes::VERSION)
16
16
  end
@@ -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}': "
@@ -12,6 +12,9 @@ module CodeFumes
12
12
  class InvalidCommandSyntax < StandardError #:nodoc:
13
13
  end
14
14
 
15
+ class RetainFailedBuildState < StandardError #:nodoc:
16
+ end
17
+
15
18
  class NoUserApiKeyError < ArgumentError #:nodoc:
16
19
  end
17
20
 
@@ -9,6 +9,7 @@ module CodeFumes
9
9
  MISSING_DEPENDENCY = 6
10
10
  INVALID_BUILD_STATE = 7
11
11
  INVALID_COMMAND_SYNTAX = 8
12
+ STANDARD_BUILD_FAILURE = 9
12
13
  UNKNOWN = 100
13
14
  end
14
15
  end
@@ -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: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.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-09-13 00:00:00 -05:00
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://codefumes.rubyforge.org/codefumes
304
+ homepage: http://cosyn.github.com/codefumes
304
305
  licenses: []
305
306
 
306
307
  post_install_message: