hudson 0.2.4 → 0.2.5.pre2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ Hudson
2
+ ======
3
+
4
+ Hudson is a sweet CI server. Hudson.rb makes it easy
5
+ to run ruby builds by bundling all the ruby-centric plugins
6
+ (ruby, rake, git, github) and wrapping them in a super simple
7
+ executeable.
8
+
9
+ Install
10
+ =======
11
+
12
+ gem install hudson
13
+ gem install hudson --pre (bleeding edge)
14
+
15
+ Example
16
+ =======
17
+
18
+ Hudson.rb is continuously tested using Hudson at [http://hudson.thefrontside.net/job/hudson.rb/](http://hudson.thefrontside.net/job/hudson.rb/).
19
+
20
+ The `hudson` application allows you to see the projects/jobs and their statuses:
21
+
22
+ $ hudson list --host hudson.thefrontside.net --port 80
23
+ hudson.rb - http://hudson.thefrontside.net/job/hudson.rb/
24
+ TheRubyRacer - http://hudson.thefrontside.net/job/TheRubyRacer/
25
+
26
+ # alternately use environment variables
27
+ $ HUDSON_HOST=hudson.thefrontside.net HUDSON_PORT=80 hudson list
28
+
29
+ Usage
30
+ =====
31
+
32
+ To run Hudson server:
33
+
34
+ Usage: hudson server [HUDSON_HOME] [options]
35
+ -d, --daemon fork into background and run as daemon
36
+ -p, --port [3001] run hudson on specified port
37
+ -c, --control-port [3002] set the shutdown/control port
38
+ -k, --kill send shutdown signal to control port
39
+ -v, --version show version information
40
+ -h, --help
41
+
42
+ Note: HUDSON_HOME defaults to ~/.hudson
43
+
44
+ To list Jobs/Projects on a Hudson server:
45
+
46
+ Usage: hudson list [project_path] [options]
47
+ -p, --port [3001] find hudson on specified port
48
+ --host [localhost] find hudson on specified host
49
+ -h, --help
50
+
51
+ To add Project (create a Job) on a Hudson server:
52
+
53
+ Usage: hudson create [project_path] [options]
54
+ -n, --name [dir_name] name of hudson job
55
+ -p, --port [3001] find hudson on specified port
56
+ --host [localhost] find hudson on specified host
57
+ -h, --help
58
+
59
+ For all commands, if flags for `host:port` are not provided, it will use `$HUDSON_HOST` and `$HUDSON_PORT` if available.
60
+
61
+ License
62
+ =======
63
+
64
+ (The MIT License)
65
+
66
+ Copyright (c) 2010 Charles Lowell, cowboyd@thefrontside.net
67
+
68
+ Permission is hereby granted, free of charge, to any person obtaining
69
+ a copy of this software and associated documentation files (the
70
+ 'Software'), to deal in the Software without restriction, including
71
+ without limitation the rights to use, copy, modify, merge, publish,
72
+ distribute, sublicense, and/or sell copies of the Software, and to
73
+ permit persons to whom the Software is furnished to do so, subject to
74
+ the following conditions:
75
+
76
+ The above copyright notice and this permission notice shall be
77
+ included in all copies or substantial portions of the Software.
78
+
79
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
80
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
81
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
82
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
83
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
84
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
85
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,120 @@
1
+ $:.unshift('lib')
2
+ require 'hudson'
3
+ require 'rubygems'
4
+
5
+ Gem::Specification.new do |s|
6
+ $gemspec = s
7
+ s.name = s.rubyforge_project = "hudson"
8
+ s.version = Hudson::VERSION
9
+ s.summary = "Painless Continuous Integration with Hudson Server"
10
+ s.description = "A suite of utilities for bringing continous integration to your projects (not the other way around) with hudson CI"
11
+ s.email = ["cowboyd@thefrontside.net", "drnicwilliams@gmail.com"]
12
+ s.homepage = "http://github.com/cowboyd/hudson.rb"
13
+ s.authors = ["Charles Lowell", "Dr Nic Williams"]
14
+ s.executables = ["hudson"]
15
+ s.require_paths = ["lib"]
16
+ s.files = Rake::FileList.new("**/*").tap do |manifest|
17
+ manifest.exclude "tmp", "**/*.gem"
18
+ end.to_a
19
+ s.add_dependency("term-ansicolor", [">= 1.0.4"])
20
+ s.add_dependency("yajl-ruby", [">= 0.7.6"])
21
+ s.add_dependency("httparty", ["~> 0.5.2"])
22
+ s.add_dependency("builder", ["~> 2.1.2"])
23
+ s.add_dependency("thor", ["~> 0.13.6"])
24
+ s.add_dependency("hpricot")
25
+ s.add_development_dependency("cucumber", ["~> 0.7.3"])
26
+ s.add_development_dependency("rspec", ["~> 1.3.0"])
27
+ s.add_development_dependency("json", ["~>1.4.0"])
28
+ end
29
+
30
+ desc "Build gem"
31
+ task :gem => :gemspec do
32
+ Gem::Builder.new($gemspec).build
33
+ end
34
+
35
+ desc "Build gemspec"
36
+ task :gemspec => :clean do
37
+ File.open("#{$gemspec.name}.gemspec", "w") do |f|
38
+ f.write($gemspec.to_ruby)
39
+ end
40
+ end
41
+
42
+ desc "Clean up"
43
+ task :clean do
44
+ sh "rm -rf *.gem"
45
+ end
46
+
47
+ namespace :cucumber do
48
+ require 'cucumber/rake/task'
49
+ Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
50
+ t.cucumber_opts = "--tags @wip"
51
+ end
52
+ Cucumber::Rake::Task.new(:ok, 'Run features that should be working') do |t|
53
+ t.cucumber_opts = "--tags ~@wip"
54
+ end
55
+ task :all => [:ok, :wip]
56
+ end
57
+
58
+ desc 'Alias for cucumber:ok'
59
+ task :cucumber => 'cucumber:ok'
60
+
61
+ desc "Start test server; Run cucumber:ok; Kill Test Server;"
62
+ task :default => ["hudson:server:killtest", "hudson:server:test"] do
63
+ require 'socket'
64
+ print "waiting for at most 30 seconds for the server to start"
65
+ tries = 1
66
+ begin
67
+ print "."; $stdout.flush
68
+ tries += 1
69
+ Net::HTTP.start("localhost", "3010") { |http| http.get('/') }
70
+ sleep(10)
71
+ puts ""
72
+ Rake::Task["cucumber:ok"].invoke
73
+ rescue Exception => e
74
+ if tries <= 15
75
+ sleep 2
76
+ retry
77
+ end
78
+ raise
79
+ ensure
80
+ Rake::Task["hudson:server:killtest"].tap do |task|
81
+ task.reenable
82
+ task.invoke
83
+ end
84
+ end
85
+ end
86
+
87
+ namespace :hudson do
88
+ namespace :server do
89
+ require 'fileutils'
90
+
91
+ desc "Run a server for tests"
92
+ task :test do
93
+ port = 3010
94
+ control = 3011
95
+
96
+ FileUtils.chdir(File.dirname(__FILE__)) do
97
+ logfile = File.join("/tmp", "test_hudson.log")
98
+ puts "Launching hudson test server at http://localhost:#{port}..."
99
+ puts " output will be logged to #{logfile}"
100
+ `ruby bin/hudson server --home /tmp/test_hudson --port #{port} --control #{control} --daemon --logfile #{logfile}`
101
+ end
102
+ end
103
+
104
+ desc "Kill hudson test server if it is running."
105
+ task :killtest do
106
+ FileUtils.chdir(File.dirname(__FILE__)) do
107
+ puts "Killing any running server processes..."
108
+ `ruby bin/hudson server --control 3011 --kill 2>/dev/null`
109
+ end
110
+ end
111
+
112
+ desc "Grab the latest hudson.war from hudson-ci.org"
113
+ task :getwar do
114
+ sh "cd lib/hudson && rm hudson.war && wget http://hudson-ci.org/latest/hudson.war"
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+
data/bin/hudson CHANGED
@@ -1,58 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ $:.unshift(File.expand_path(File.dirname(File.dirname(__FILE__) + "/../lib/hudson.rb")))
2
4
  require File.dirname(__FILE__) + '/../lib/hudson'
3
- require 'un'
4
- require 'optparse'
5
-
6
-
7
- options = {
8
- :port => 3001,
9
- :control => 3002,
10
- :home => File.join(ENV['HOME'], '.hudson')
11
- }
12
- args = ARGV.dup
13
-
14
- opts = OptionParser.new do |opts|
15
- opts.banner = "Usage: hudson [options] [HUDSON_HOME]"
16
-
17
- opts.on("-d", "--daemon", "fork into background and run as daemon") do
18
- options[:daemon] = true
19
- end
20
-
21
- opts.on("-p", "--port [3001]", "run hudson on specified port ") do |port|
22
- options[:port] = port
23
- end
24
-
25
- opts.on("-c", "--control-port [3002]", Integer, "set the shutdown/control port") do |port|
26
- options[:control] = cport
27
- end
28
-
29
- opts.on_tail("-k", "--kill", "send shutdown signal to control port") do
30
- require 'socket'
31
- TCPSocket.open("localhost", options[:control]) do |sock|
32
- sock.write("0")
33
- end
34
- exit
35
- end
36
-
37
- opts.on_tail("-v", "--version", "show version information") do
38
- puts "#{Hudson::VERSION} (Hudson Server #{Hudson::HUDSON_VERSION})"
39
- exit
40
- end
41
- opts.on_tail("-h", "--help") do
42
- puts opts
43
- exit
44
- end
45
-
46
- end
47
- opts.parse!(args)
48
- dir = args.shift || options[:home]
49
- FileUtils.mkdir_p dir
50
- FileUtils.cp_r Hudson::PLUGINS, dir
51
- ENV['HUDSON_HOME'] = dir
52
- cmd = ["java", "-jar", Hudson::WAR]
53
- cmd << "--httpPort=#{options[:port]}"
54
- cmd << "--controlPort=#{options[:control]}"
55
- cmd << "--daemon" if options[:daemon]
56
- puts cmd.join(" ")
57
- exec(*cmd)
5
+ require 'hudson/cli'
58
6
 
7
+ Hudson::CLI.start
@@ -0,0 +1,22 @@
1
+ Feature: Create jobs
2
+ In order to reduce cost of getting a new project up onto Hudson
3
+ As a project developer
4
+ I want to add a new project to Hudson as a job
5
+
6
+ Background:
7
+ Given I have a Hudson server running
8
+ And the Hudson server has no current jobs
9
+
10
+ Scenario: Discover Ruby project, on git scm, and create job
11
+ Given I am in the "ruby" project folder
12
+ And the project uses "git" scm
13
+ When I run local executable "hudson" with arguments "create . --host localhost --port 3010"
14
+ Then I should see "Added project 'ruby' to Hudson."
15
+ Then I should see "http://localhost:3010/job/ruby/build"
16
+ When I run local executable "hudson" with arguments "list --host localhost --port 3010"
17
+ Then I should see "ruby"
18
+
19
+ Scenario: Attempt to create project without scm
20
+ Given I am in the "ruby" project folder
21
+ When I run local executable "hudson" with arguments "create . --host localhost --port 3010"
22
+ Then I should see "Cannot determine project SCM. Currently supported:"
@@ -0,0 +1,14 @@
1
+ Feature: Development processes of hudson itself (rake tasks)
2
+
3
+ As a Newgem maintainer or contributor
4
+ I want rake tasks to maintain and release the gem
5
+ So that I can spend time on the tests and code, and not excessive time on maintenance processes
6
+
7
+ Scenario: Generate RubyGem
8
+ Given this project is active project folder
9
+ When I invoke task "rake clean" so that I start with nothing
10
+ And I invoke task "rake gem"
11
+ Then file with name matching "hudson-*.gem" is created
12
+ And file with name matching "hudson.gemspec" is created
13
+ And the file "hudson.gemspec" is a valid gemspec
14
+
@@ -0,0 +1,4 @@
1
+ desc "Default task runs tests"
2
+ task :default do
3
+ puts "Tests ran successfully!"
4
+ end
@@ -0,0 +1,31 @@
1
+ @wip
2
+ Feature: Managing remote servers
3
+ In order to reduce cost of referencing remote servers by explicit --host/--port options
4
+ As a user
5
+ I want a directory of remote servers I frequently use
6
+
7
+ Background:
8
+ Given I have a Hudson server running
9
+ And the Hudson server has no current jobs
10
+
11
+ Scenario: No remote servers
12
+ When I run local executable "hudson" with arguments "list"
13
+ Then I should see "Either use --host or add remote servers."
14
+
15
+ Scenario: Add a remote server
16
+ When I run local executable "hudson" with arguments "remotes add --host localhost --port 3010"
17
+ And I run local executable "hudson" with arguments "remotes add --host localhost --port 3011"
18
+ And I run local executable "hudson" with arguments "list"
19
+ Then I should not see "Either use --host or add remote servers."
20
+ And I should see "localhost:3010 -"
21
+ And I should see "No jobs"
22
+ And I should see "localhost:3011 - no connection"
23
+
24
+ Scenario: Add a remote server and access by abbreviation
25
+ When I run local executable "hudson" with arguments "remotes add --host localhost --port 3010"
26
+ When I run local executable "hudson" with arguments "remotes add --host another.server"
27
+ And I run local executable "hudson" with arguments "list --server local"
28
+ And I should see "localhost:3010 -"
29
+ And I should see "No jobs"
30
+ And I should not see "another.server"
31
+
@@ -0,0 +1,16 @@
1
+ Feature: Running a Hudson Server
2
+ As a hudson server administrator
3
+ I want to be able to easily control a hudson server
4
+ In order to spend my time on how the process operates, not how to start stop and control it.
5
+
6
+ Scenario: Start a Hudson Server
7
+ Given env variable $HOME set to project path "home"
8
+ And "home/.hudson" folder is deleted
9
+ And there is nothing listening on port 5001
10
+ And there is nothing listening on port 5002
11
+ And I cleanup any hudson processes with control port 5002
12
+ When I run hudson server with arguments "--port 5001 --control 5002 --daemon --logfile=server.log"
13
+ Then I should see a hudson server on port 5001
14
+ And folder "home/.hudson/server" is created
15
+ And folder "home/.hudson/server/javatmp" is created
16
+
@@ -0,0 +1,181 @@
1
+ Given /^this project is active project folder/ do
2
+ @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
3
+ end
4
+
5
+ Given /^env variable \$([\w_]+) set to( project path |)"(.*)"/ do |env_var, path, value|
6
+ in_project_folder {
7
+ value = File.expand_path(value)
8
+ } unless path.empty?
9
+ ENV[env_var] = value
10
+ end
11
+
12
+ Given /"(.*)" folder is deleted/ do |folder|
13
+ in_project_folder { FileUtils.rm_rf folder }
14
+ end
15
+
16
+ When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
17
+ @stdout = StringIO.new
18
+ in_project_folder do
19
+ if Object.const_defined?("APP_ROOT")
20
+ APP_ROOT.replace(FileUtils.pwd)
21
+ else
22
+ APP_ROOT = FileUtils.pwd
23
+ end
24
+ run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
25
+ end
26
+ File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
27
+ @stdout.rewind
28
+ f << @stdout.read
29
+ end
30
+ end
31
+
32
+ When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
33
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
34
+ in_project_folder do
35
+ system "#{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
36
+ end
37
+ end
38
+
39
+ When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
40
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
41
+ in_project_folder do
42
+ system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
43
+ end
44
+ end
45
+
46
+ When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
47
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
48
+ executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
49
+ in_project_folder do
50
+ system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
51
+ end
52
+ end
53
+
54
+ When /^I invoke task "rake (.*)"/ do |task|
55
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
56
+ in_project_folder do
57
+ system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
58
+ end
59
+ end
60
+
61
+ Then /^folder "(.*)" (is|is not) created/ do |folder, is|
62
+ in_project_folder do
63
+ File.exists?(folder).should(is == 'is' ? be_true : be_false)
64
+ end
65
+ end
66
+
67
+ Then /^file "(.*)" (is|is not) created/ do |file, is|
68
+ in_project_folder do
69
+ File.exists?(file).should(is == 'is' ? be_true : be_false)
70
+ end
71
+ end
72
+
73
+ Then /^file with name matching "(.*)" is created/ do |pattern|
74
+ in_project_folder do
75
+ Dir[pattern].should_not be_empty
76
+ end
77
+ end
78
+
79
+ Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
80
+ in_project_folder do
81
+ actual_output = File.read(file)
82
+ (does == 'does') ?
83
+ actual_output.should(match(/#{regex}/)) :
84
+ actual_output.should_not(match(/#{regex}/))
85
+ end
86
+ end
87
+
88
+ Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
89
+ File.exists?(gem_file).should be_true
90
+ File.exists?(project_file).should be_true
91
+ gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
92
+ project_file_contents = File.read(File.join(@active_project_folder, project_file))
93
+ project_file_contents.should == gem_file_contents
94
+ end
95
+
96
+ Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
97
+ actual_output = File.read(@stdout)
98
+ does_invoke == "does" ?
99
+ actual_output.should(match(/dependency\s+#{generator}/)) :
100
+ actual_output.should_not(match(/dependency\s+#{generator}/))
101
+ end
102
+
103
+ Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
104
+ actual_output = File.read(@stdout)
105
+ actual_output.should match(/#{opt1}/)
106
+ actual_output.should match(/#{opt2}/)
107
+ end
108
+
109
+ Then /^I should see "([^\"]*)"$/ do |text|
110
+ actual_output = File.read(@stdout)
111
+ actual_output.should contain(text)
112
+ end
113
+
114
+ Then /^I should not see "([^\"]*)"$/ do |text|
115
+ actual_output = File.read(@stdout)
116
+ actual_output.should_not contain(text)
117
+ end
118
+
119
+ Then /^I should see$/ do |text|
120
+ actual_output = File.read(@stdout)
121
+ actual_output.should contain(text)
122
+ end
123
+
124
+ Then /^I should not see$/ do |text|
125
+ actual_output = File.read(@stdout)
126
+ actual_output.should_not contain(text)
127
+ end
128
+
129
+ Then /^I should see exactly$/ do |text|
130
+ actual_output = File.read(@stdout)
131
+ actual_output.should == text
132
+ end
133
+
134
+ Then /^I should see all (\d+) tests pass/ do |expected_test_count|
135
+ expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
136
+ actual_output = File.read(@stdout)
137
+ actual_output.should match(expected)
138
+ end
139
+
140
+ Then /^I should see all (\d+) examples pass/ do |expected_test_count|
141
+ expected = %r{^#{expected_test_count} examples?, 0 failures}
142
+ actual_output = File.read(@stdout)
143
+ actual_output.should match(expected)
144
+ end
145
+
146
+ Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
147
+ in_project_folder do
148
+ yaml = eval yaml
149
+ YAML.load(File.read(file)).should == yaml
150
+ end
151
+ end
152
+
153
+ Then /^Rakefile can display tasks successfully/ do
154
+ @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
155
+ in_project_folder do
156
+ system "rake -T > #{@stdout} 2> #{@stdout}"
157
+ end
158
+ actual_output = File.read(@stdout)
159
+ actual_output.should match(/^rake\s+\w+\s+#\s.*/)
160
+ end
161
+
162
+ Then /^task "rake (.*)" is executed successfully/ do |task|
163
+ @stdout.should_not be_nil
164
+ actual_output = File.read(@stdout)
165
+ actual_output.should_not match(/^Don't know how to build task '#{task}'/)
166
+ actual_output.should_not match(/Error/i)
167
+ end
168
+
169
+ Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
170
+ in_project_folder do
171
+ gem_file = Dir["pkg/*.gem"].first
172
+ gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
173
+ spec_value = gem_spec.send(key.to_sym)
174
+ spec_value.to_s.should match(/#{regex}/)
175
+ end
176
+ end
177
+
178
+ Then /^the file "([^\"]*)" is a valid gemspec$/ do |filename|
179
+ spec = eval(File.read(filename))
180
+ spec.validate
181
+ end
@@ -0,0 +1,8 @@
1
+ Given /^I am in the "([^\"]*)" project folder$/ do |project|
2
+ project_folder = File.expand_path(File.dirname(__FILE__) + "/../fixtures/projects/#{project}")
3
+ in_tmp_folder do
4
+ FileUtils.cp_r(project_folder, project)
5
+ setup_active_project_folder(project)
6
+ end
7
+ end
8
+
@@ -0,0 +1,71 @@
1
+ Given /^I have a Hudson server running$/ do
2
+ unless ENV['HUDSON_PORT']
3
+ port = 3010
4
+ begin
5
+ res = Net::HTTP.start("localhost", port) { |http| http.get('/api/json') }
6
+ rescue Errno::ECONNREFUSED => e
7
+ puts "\n\n\nERROR: To run tests, launch hudson in test mode: 'rake hudson:server:test'\n\n\n"
8
+ exit
9
+ end
10
+ ENV['HUDSON_PORT'] = port.to_s
11
+ ENV['HUDSON_HOST'] = 'localhost'
12
+ end
13
+ end
14
+
15
+ Given /^the Hudson server has no current jobs$/ do
16
+ if port = ENV['HUDSON_PORT']
17
+ require "open-uri"
18
+ require "yajl"
19
+ hudson_info = Yajl::Parser.new.parse(open("http://localhost:#{ENV['HUDSON_PORT']}/api/json"))
20
+
21
+ hudson_info['jobs'].each do |job|
22
+ job_url = job['url']
23
+ res = Net::HTTP.start("localhost", port) { |http| http.post("#{job_url}doDelete/api/json", {}) }
24
+ end
25
+ hudson_info = Yajl::Parser.new.parse(open("http://localhost:#{ENV['HUDSON_PORT']}/api/json"))
26
+ hudson_info['jobs'].should == []
27
+ else
28
+ puts "WARNING: Run 'I have a Hudson server running' step first."
29
+ end
30
+ end
31
+
32
+ Given /^there is nothing listening on port (\d+)$/ do |port|
33
+ lambda {
34
+ TCPSocket.open("localhost", port) {}
35
+ }.should raise_error
36
+ end
37
+
38
+ Given /^I cleanup any hudson processes with control port (\d+)$/ do |port|
39
+ @hudson_cleanup << port
40
+ end
41
+
42
+ def try(times, interval = 1)
43
+ begin
44
+ times -= 1
45
+ return yield
46
+ rescue Exception => e
47
+ if times >= 0
48
+ sleep(interval)
49
+ retry
50
+ end
51
+ raise e
52
+ end
53
+ end
54
+
55
+ When /^I run hudson server with arguments "(.*)"/ do |arguments|
56
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
57
+ executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin","hudson"))
58
+ in_project_folder do
59
+ system "ruby #{executable} server #{arguments} > #{@stdout} 2>#{@stdout}"
60
+ end
61
+ end
62
+
63
+
64
+ Then /^I should see a hudson server on port (\d+)$/ do |port|
65
+ require 'json'
66
+ try(15, 2) do
67
+ res = Net::HTTP.start("localhost", port) { |http| http.get('/api/json') }
68
+ JSON.parse(res.body)['nodeDescription'].should == "the master Hudson node"
69
+ end
70
+ end
71
+
@@ -0,0 +1,10 @@
1
+ Given /^the project uses "git" scm$/ do
2
+ repo = "git://some.host/drnic/ruby.git"
3
+ in_project_folder do
4
+ %x[ git init ]
5
+ %x[ git add . ]
6
+ %x[ git commit -m "initial commit" ]
7
+ %x[ git remote add origin #{repo} ]
8
+ end
9
+ end
10
+
@@ -0,0 +1,29 @@
1
+ module CommonHelpers
2
+ def in_tmp_folder(&block)
3
+ FileUtils.chdir(@tmp_root, &block)
4
+ end
5
+
6
+ def in_project_folder(&block)
7
+ project_folder = @active_project_folder || @tmp_root
8
+ FileUtils.chdir(project_folder, &block)
9
+ end
10
+
11
+ def in_home_folder(&block)
12
+ FileUtils.chdir(@home_path, &block)
13
+ end
14
+
15
+ def force_local_lib_override(project_name = @project_name)
16
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
17
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
18
+ f << "$:.unshift('#{@lib_path}')\n"
19
+ f << rakefile
20
+ end
21
+ end
22
+
23
+ def setup_active_project_folder project_name
24
+ @active_project_folder = File.join(@tmp_root, project_name)
25
+ @project_name = project_name
26
+ end
27
+ end
28
+
29
+ World(CommonHelpers)
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.expand_path(File.dirname(File.dirname(__FILE__) + "/../../lib/hudson.rb")))
2
+ require File.dirname(__FILE__) + "/../../lib/hudson.rb"
3
+
4
+ gem 'cucumber'
5
+ require 'cucumber'
6
+ gem 'rspec'
7
+ require 'spec'
8
+
9
+ Before do
10
+ @tmp_root = File.dirname(__FILE__) + "/../../tmp"
11
+ @home_path = File.expand_path(File.join(@tmp_root, "home"))
12
+ @lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
13
+ FileUtils.rm_rf @tmp_root
14
+ FileUtils.mkdir_p @home_path
15
+ ENV['HOME'] = @home_path
16
+ end