cijoe 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/Rakefile CHANGED
@@ -1,37 +1,3 @@
1
- desc "Build a gem"
2
- task :gem => [ :gemspec, :build ]
3
-
4
- begin
5
- require 'jeweler'
6
-
7
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
8
- require 'cijoe/version'
9
-
10
- Jeweler::Tasks.new do |gemspec|
11
- gemspec.name = "cijoe"
12
- gemspec.summary = "CI Joe is a simple Continuous Integration server."
13
- gemspec.description = "CI Joe is a simple Continuous Integration server."
14
- gemspec.email = "chris@ozmm.org"
15
- gemspec.homepage = "http://github.com/defunkt/cijoe"
16
- gemspec.authors = ["Chris Wanstrath"]
17
- gemspec.add_dependency 'choice'
18
- gemspec.add_dependency 'sinatra'
19
- gemspec.add_development_dependency 'rack-test'
20
- gemspec.version = CIJoe::Version.to_s
21
- end
22
- rescue LoadError
23
- puts "Jeweler not available."
24
- puts "Install it with: gem install jeweler"
25
- end
26
-
27
- desc "Publish a RubyGem"
28
- task :publish => :gem do
29
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
30
- require 'cijoe/version'
31
-
32
- sh "gem push pkg/cijoe-#{CIJoe::Version}.gem"
33
- end
34
-
35
1
  require 'rake/testtask'
36
2
  Rake::TestTask.new(:test) do |test|
37
3
  test.libs << 'lib' << 'test'
data/bin/cijoe CHANGED
@@ -45,8 +45,7 @@ Choice.options do
45
45
  end
46
46
 
47
47
  options = Choice.choices
48
- $project_path = File.expand_path(Choice.rest[0])
49
48
 
50
49
  require 'cijoe'
51
50
 
52
- CIJoe::Server.start(options[:host], options[:port], $project_path)
51
+ CIJoe::Server.start(options[:host], options[:port], File.expand_path(Choice.rest[0]))
@@ -24,8 +24,7 @@ class CIJoe
24
24
  attr_reader :user, :project, :url, :current_build, :last_build
25
25
 
26
26
  def initialize(project_path)
27
- project_path = File.expand_path(project_path)
28
- Dir.chdir(project_path)
27
+ @project_path = File.expand_path(project_path)
29
28
 
30
29
  @user, @project = git_user_and_project
31
30
  @url = "http://github.com/#{@user}/#{@project}"
@@ -49,9 +48,9 @@ class CIJoe
49
48
  # kill the child and exit
50
49
  def stop
51
50
  # another build waits
52
- if Config.cijoe.buildallfile && File.exist?(Config.cijoe.buildallfile.to_s)
51
+ if !repo_config.buildallfile.to_s.empty? && File.exist?(repo_config.buildallfile.to_s)
53
52
  # clean out on stop
54
- FileUtils.rm(Config.cijoe.buildallfile.to_s)
53
+ FileUtils.rm(repo_config.buildallfile.to_s)
55
54
  end
56
55
 
57
56
  Process.kill(9, pid) if pid
@@ -81,9 +80,9 @@ class CIJoe
81
80
  @last_build.notify if @last_build.respond_to? :notify
82
81
 
83
82
  # another build waits
84
- if Config.cijoe.buildallfile && File.exist?(Config.cijoe.buildallfile.to_s)
83
+ if !repo_config.buildallfile.to_s.empty? && File.exist?(repo_config.buildallfile.to_s)
85
84
  # clean out before new build
86
- FileUtils.rm(Config.cijoe.buildallfile.to_s)
85
+ FileUtils.rm(repo_config.buildallfile.to_s)
87
86
  build
88
87
  end
89
88
  end
@@ -93,16 +92,16 @@ class CIJoe
93
92
  def build
94
93
  if building?
95
94
  # only if switched on to build all incoming requests
96
- if Config.cijoe.buildallfile
95
+ if !repo_config.buildallfile.to_s.empty?
97
96
  # and there is no previous request
98
- return if File.exist?(Config.cijoe.buildallfile.to_s)
97
+ return if File.exist?(repo_config.buildallfile.to_s)
99
98
  # we will mark awaiting builds
100
- FileUtils.touch(Config.cijoe.buildallfile.to_s)
99
+ FileUtils.touch(repo_config.buildallfile.to_s)
101
100
  end
102
101
  # leave anyway because a current build runs
103
102
  return
104
103
  end
105
- @current_build = Build.new(@user, @project)
104
+ @current_build = Build.new(@project_path, @user, @project)
106
105
  write_build 'current', @current_build
107
106
  Thread.new { build! }
108
107
  end
@@ -129,7 +128,7 @@ class CIJoe
129
128
  build.sha = git_sha
130
129
  write_build 'current', build
131
130
 
132
- open_pipe("#{runner_command} 2>&1") do |pipe, pid|
131
+ open_pipe("cd #{@project_path} && #{runner_command} 2>&1") do |pipe, pid|
133
132
  puts "#{Time.now.to_i}: Building #{build.short_sha}: pid=#{pid}"
134
133
 
135
134
  build.pid = pid
@@ -149,44 +148,47 @@ class CIJoe
149
148
 
150
149
  # shellin' out
151
150
  def runner_command
152
- runner = Config.cijoe.runner.to_s
151
+ runner = repo_config.runner.to_s
153
152
  runner == '' ? "rake -s test:units" : runner
154
153
  end
155
154
 
156
155
  def git_sha
157
- `git rev-parse origin/#{git_branch}`.chomp
156
+ `cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp
158
157
  end
159
158
 
160
159
  def git_update
161
- `git fetch origin && git reset --hard origin/#{git_branch}`
160
+ `cd #{@project_path} && git fetch origin && git reset --hard origin/#{git_branch}`
162
161
  run_hook "after-reset"
163
162
  end
164
163
 
165
164
  def git_user_and_project
166
- Config.remote.origin.url.to_s.chomp('.git').split(':')[-1].split('/')[-2, 2]
165
+ Config.remote(@project_path).origin.url.to_s.chomp('.git').split(':')[-1].split('/')[-2, 2]
167
166
  end
168
167
 
169
168
  def git_branch
170
- branch = Config.cijoe.branch.to_s
169
+ branch = repo_config.branch.to_s
171
170
  branch == '' ? "master" : branch
172
171
  end
173
172
 
174
173
  # massage our repo
175
174
  def run_hook(hook)
176
- if File.exists?(file=".git/hooks/#{hook}") && File.executable?(file)
175
+ if File.exists?(file=path_in_project(".git/hooks/#{hook}")) && File.executable?(file)
177
176
  data =
178
177
  if @last_build && @last_build.commit
179
178
  {
180
179
  "MESSAGE" => @last_build.commit.message,
181
180
  "AUTHOR" => @last_build.commit.author,
182
181
  "SHA" => @last_build.commit.sha,
183
- "OUTPUT" => @last_build.clean_output
182
+ "OUTPUT" => @last_build.env_output
184
183
  }
185
184
  else
186
185
  {}
187
186
  end
187
+
188
188
  data.each{ |k, v| ENV[k] = v }
189
- `sh #{file}`
189
+ ret = `cd #{@project_path} && sh #{file}`
190
+ data.each{ |k, v| ENV[k] = nil }
191
+ ret
190
192
  end
191
193
  end
192
194
 
@@ -207,10 +209,14 @@ class CIJoe
207
209
  @current_build = nil
208
210
  end
209
211
 
212
+ def path_in_project(path)
213
+ File.join(@project_path, path)
214
+ end
215
+
210
216
  # write build info for build to file.
211
217
  def write_build(name, build)
212
- filename = ".git/builds/#{name}"
213
- Dir.mkdir '.git/builds' unless File.directory?('.git/builds')
218
+ filename = path_in_project(".git/builds/#{name}")
219
+ Dir.mkdir path_in_project('.git/builds') unless File.directory?(path_in_project('.git/builds'))
214
220
  if build
215
221
  build.dump filename
216
222
  elsif File.exist?(filename)
@@ -218,8 +224,12 @@ class CIJoe
218
224
  end
219
225
  end
220
226
 
227
+ def repo_config
228
+ Config.cijoe(@project_path)
229
+ end
230
+
221
231
  # load build info from file.
222
232
  def read_build(name)
223
- Build.load(".git/builds/#{name}")
233
+ Build.load(path_in_project(".git/builds/#{name}"), @project_path)
224
234
  end
225
235
  end
@@ -1,7 +1,7 @@
1
1
  require 'yaml'
2
2
 
3
3
  class CIJoe
4
- class Build < Struct.new(:user, :project, :started_at, :finished_at, :sha, :status, :output, :pid)
4
+ class Build < Struct.new(:project_path, :user, :project, :started_at, :finished_at, :sha, :status, :output, :pid)
5
5
  def initialize(*args)
6
6
  super
7
7
  self.started_at ||= Time.now
@@ -41,9 +41,14 @@ class CIJoe
41
41
  output.gsub(/\e\[.+?m/, '').strip
42
42
  end
43
43
 
44
+ def env_output
45
+ out = clean_output
46
+ out.size > 100_000 ? out[-100_000,100_000] : out
47
+ end
48
+
44
49
  def commit
45
50
  return if sha.nil?
46
- @commit ||= Commit.new(sha, user, project)
51
+ @commit ||= Commit.new(sha, user, project, project_path)
47
52
  end
48
53
 
49
54
  def dump(file)
@@ -52,9 +57,9 @@ class CIJoe
52
57
  File.open(file, 'wb') { |io| io.write(data) }
53
58
  end
54
59
 
55
- def self.load(file)
60
+ def self.load(file, project_path)
56
61
  if File.exist?(file)
57
- config = YAML.load(File.read(file))
62
+ config = YAML.load(File.read(file)).unshift(project_path)
58
63
  new *config
59
64
  end
60
65
  end
@@ -47,10 +47,10 @@ class CIJoe
47
47
  def room
48
48
  @room ||= begin
49
49
  config = Campfire.config
50
- options = {}
51
- options[:ssl] = config[:ssl] ? true : false
52
- campfire = Tinder::Campfire.new(config[:subdomain], options)
53
- campfire.login(config[:user], config[:pass])
50
+ campfire = Tinder::Campfire.new(config[:subdomain],
51
+ :username => config[:user],
52
+ :password => config[:pass],
53
+ :ssl => config[:ssl] || false)
54
54
  campfire.find_room_by_name(config[:room])
55
55
  end
56
56
  end
@@ -1,5 +1,5 @@
1
1
  class CIJoe
2
- class Commit < Struct.new(:sha, :user, :project)
2
+ class Commit < Struct.new(:sha, :user, :project, :project_path)
3
3
  def url
4
4
  "http://github.com/#{user}/#{project}/commit/#{sha}"
5
5
  end
@@ -17,7 +17,7 @@ class CIJoe
17
17
  end
18
18
 
19
19
  def raw_commit
20
- @raw_commit ||= `git show #{sha}`.chomp
20
+ @raw_commit ||= `cd #{project_path} && git show #{sha}`.chomp
21
21
  end
22
22
 
23
23
  def raw_commit_lines
@@ -1,17 +1,17 @@
1
1
  class CIJoe
2
2
  class Config
3
3
  def self.method_missing(command, *args)
4
- new(command)
4
+ new(command, args)
5
5
  end
6
6
 
7
- def initialize(command, parent = nil)
7
+ def initialize(command, project_path = nil, parent = nil)
8
8
  @command = command
9
9
  @parent = parent
10
- @project_path = $project_path || File.join(File.dirname(__FILE__), '../../')
10
+ @project_path = project_path || File.join(File.dirname(__FILE__), '../../')
11
11
  end
12
12
 
13
13
  def method_missing(command, *args)
14
- Config.new(command, self)
14
+ Config.new(command, @project_path, self)
15
15
  end
16
16
 
17
17
  def to_s
@@ -22,7 +22,7 @@ class CIJoe
22
22
  if successful_command?(process_status) || config_command_with_empty_value?(result,process_status)
23
23
  return result
24
24
  else
25
- raise "Error calling git config, is a recent version of git installed? Command: #{git_command}, Error: #{result}"
25
+ raise "Error calling git config, is a recent version of git installed? Command: #{git_command.inspect}, Error: #{result.inspect}, Status: #{process_status.inspect}"
26
26
  end
27
27
  end
28
28
 
@@ -34,13 +34,6 @@ class CIJoe
34
34
  redirect request.path
35
35
  end
36
36
 
37
- user, pass = Config.cijoe.user.to_s, Config.cijoe.pass.to_s
38
- if user != '' && pass != ''
39
- use Rack::Auth::Basic do |username, password|
40
- [ username, password ] == [ user, pass ]
41
- end
42
- puts "Using HTTP basic auth"
43
- end
44
37
 
45
38
  helpers do
46
39
  include Rack::Utils
@@ -76,6 +69,17 @@ class CIJoe
76
69
  CIJoe::Server.run! :host => host, :port => port
77
70
  end
78
71
 
72
+ def self.project_path=(project_path)
73
+ user, pass = Config.cijoe(project_path).user.to_s, Config.cijoe(project_path).pass.to_s
74
+ if user != '' && pass != ''
75
+ use Rack::Auth::Basic do |username, password|
76
+ [ username, password ] == [ user, pass ]
77
+ end
78
+ puts "Using HTTP basic auth"
79
+ end
80
+ set :project_path, Proc.new{project_path}
81
+ end
82
+
79
83
  def check_project
80
84
  if options.project_path.nil? || !File.exists?(File.expand_path(options.project_path))
81
85
  puts "Whoops! I need the path to a Git repo."
@@ -1,3 +1,3 @@
1
1
  class CIJoe
2
- Version = "0.4.0"
2
+ Version = VERSION = "0.5.0"
3
3
  end
@@ -30,7 +30,11 @@
30
30
 
31
31
  <% if joe.last_build %>
32
32
  <li>
33
- <span class="date"><%= pretty_time(joe.last_build.finished_at) %></span> &raquo; Built <a href="<%= joe.last_build.commit.url %>"><%= joe.last_build.short_sha %></a> <span class="<%= joe.last_build.status %>">(<%= joe.last_build.status %>)</span>
33
+ <span class="date"><%= pretty_time(joe.last_build.finished_at) %></span> &raquo;
34
+ <% if joe.last_build.sha %>
35
+ Built <a href="<%= joe.last_build.commit.url %>"><%= joe.last_build.short_sha %></a>
36
+ <% end %>
37
+ <span class="<%= joe.last_build.status %>">(<%= joe.last_build.status %>)</span>
34
38
  <% if joe.last_build.duration %>
35
39
  in <span class="duration"><%= joe.last_build.duration %></span> seconds.
36
40
  <% end %>
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cijoe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Chris Wanstrath
@@ -9,60 +14,57 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-04-07 00:00:00 -07:00
13
- default_executable: cijoe
17
+ date: 2010-07-24 00:00:00 -07:00
18
+ default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: choice
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
23
29
  version: "0"
24
- version:
30
+ type: :runtime
31
+ version_requirements: *id001
25
32
  - !ruby/object:Gem::Dependency
26
33
  name: sinatra
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
33
41
  version: "0"
34
- version:
42
+ type: :runtime
43
+ version_requirements: *id002
35
44
  - !ruby/object:Gem::Dependency
36
45
  name: rack-test
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
40
48
  requirements:
41
49
  - - ">="
42
50
  - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
43
53
  version: "0"
44
- version:
45
- description: CI Joe is a simple Continuous Integration server.
54
+ type: :development
55
+ version_requirements: *id003
56
+ description: " cijoe is a sinatra-based continuous integration server. It's like an\n old rusty pickup truck: it might be smelly and gross, but it gets the\n job done.\n"
46
57
  email: chris@ozmm.org
47
58
  executables:
48
59
  - cijoe
49
60
  extensions: []
50
61
 
51
- extra_rdoc_files:
52
- - LICENSE
53
- - README.markdown
62
+ extra_rdoc_files: []
63
+
54
64
  files:
55
- - .gitignore
56
- - LICENSE
57
- - README.markdown
65
+ - README.md
58
66
  - Rakefile
59
- - bin/cijoe
60
- - deps.rip
61
- - examples/build-failed
62
- - examples/build-worked
63
- - examples/cijoe.ru
64
- - examples/cijoed
65
- - lib/cijoe.rb
67
+ - LICENSE
66
68
  - lib/cijoe/build.rb
67
69
  - lib/cijoe/campfire.rb
68
70
  - lib/cijoe/commit.rb
@@ -73,6 +75,8 @@ files:
73
75
  - lib/cijoe/server.rb
74
76
  - lib/cijoe/version.rb
75
77
  - lib/cijoe/views/template.erb
78
+ - lib/cijoe.rb
79
+ - bin/cijoe
76
80
  - test/helper.rb
77
81
  - test/test_cijoe.rb
78
82
  - test/test_cijoe_server.rb
@@ -81,30 +85,30 @@ homepage: http://github.com/defunkt/cijoe
81
85
  licenses: []
82
86
 
83
87
  post_install_message:
84
- rdoc_options:
85
- - --charset=UTF-8
88
+ rdoc_options: []
89
+
86
90
  require_paths:
87
91
  - lib
88
92
  required_ruby_version: !ruby/object:Gem::Requirement
89
93
  requirements:
90
94
  - - ">="
91
95
  - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
92
98
  version: "0"
93
- version:
94
99
  required_rubygems_version: !ruby/object:Gem::Requirement
95
100
  requirements:
96
101
  - - ">="
97
102
  - !ruby/object:Gem::Version
103
+ segments:
104
+ - 0
98
105
  version: "0"
99
- version:
100
106
  requirements: []
101
107
 
102
108
  rubyforge_project:
103
- rubygems_version: 1.3.5
109
+ rubygems_version: 1.3.6
104
110
  signing_key:
105
111
  specification_version: 3
106
- summary: CI Joe is a simple Continuous Integration server.
107
- test_files:
108
- - test/helper.rb
109
- - test/test_cijoe.rb
110
- - test/test_cijoe_server.rb
112
+ summary: cijoe builds your builds.
113
+ test_files: []
114
+
data/.gitignore DELETED
@@ -1,6 +0,0 @@
1
- .DS_Store
2
- rdoc
3
- pkg
4
- *.tmproj
5
- tmp/**/*
6
- tmp/*
data/deps.rip DELETED
@@ -1,4 +0,0 @@
1
- git://github.com/collectiveidea/tinder.git 1.2.0
2
- git://github.com/sinatra/sinatra.git 0.9.4
3
- git://github.com/rack/rack.git 1.0
4
- git://github.com/defunkt/choice.git 8b125564
@@ -1,22 +0,0 @@
1
- #!/bin/sh
2
- #
3
- # Put this file to $PROJECT/.git/hooks/ for email notifications.
4
- #
5
- # You should have mail command provided by mailutils package on Debian
6
- # based systems.
7
- #
8
- # sudo apt-get install mailutils
9
- #
10
- # You should have mail server running
11
- #
12
- # Do not forget: chmod +x build-failed
13
- #
14
- echo "
15
- Visit http://ci.example.org/ for details
16
-
17
- Author: $AUTHOR
18
- Message:
19
- $MESSAGE
20
-
21
- $OUTPUT
22
- " | mail -s "[example.org] BUILD FAILED $SHA" --to first@gmail.com second@gmail.com
@@ -1,22 +0,0 @@
1
- #!/bin/sh
2
- #
3
- # Put this file to $PROJECT/.git/hooks/ for email notifications.
4
- #
5
- # You should have mail command provided by mailutils package on Debian
6
- # based systems.
7
- #
8
- # sudo apt-get install mailutils
9
- #
10
- # You should have mail server running
11
- #
12
- # Do not forget: chmod +x build-worked
13
- #
14
- echo "
15
- Visit http://ci.example.org/ for details
16
-
17
- Author: $AUTHOR
18
- Message:
19
- $MESSAGE
20
-
21
- " | mail -s "[example.org] build OK" --to first@gmail.com second@gmail.com
22
-
@@ -1,15 +0,0 @@
1
- # Example CI Joe rackup config. Drop a cijoe.ru file
2
- # in your projects direct
3
- require 'cijoe'
4
-
5
- # setup middleware
6
- use Rack::CommonLogger
7
-
8
- # configure joe
9
- CIJoe::Server.configure do |config|
10
- config.set :project_path, File.dirname(__FILE__)
11
- config.set :show_exceptions, true
12
- config.set :lock, true
13
- end
14
-
15
- run CIJoe::Server
@@ -1,53 +0,0 @@
1
- #!/bin/sh
2
- ### BEGIN INIT INFO
3
- # Provides: cijoe
4
- # Required-Start: $syslog $local_fs $network
5
- # Required-Stop: $syslog $local_fs $network
6
- # Default-Start: 2 3 4 5
7
- # Default-Stop: 0 1
8
- # Description: Run the CIJoe CI server. Yo Joe!!
9
- ### END INIT INFO
10
-
11
- . /lib/lsb/init-functions
12
-
13
- REPO=/path/to/your/git/repository
14
- PORT=4567
15
-
16
- NAME=cijoe
17
- INSTALL_DIR=/usr/sbin
18
- DAEMON=$INSTALL_DIR/$NAME
19
- DAEMON_ARGS="-p $PORT $REPO"
20
- PIDFILE=/var/run/$NAME.pid
21
- DAEMON_USER=www-data
22
- DAEMON_GROUP=$DAEMON_USER
23
-
24
- # test -f $DAEMON || exit 0
25
- # test -f $PROJECT_DIR || exit 0
26
-
27
- case "$1" in
28
- start)
29
- log_daemon_msg "Starting cijoe" "cijoe"
30
- start-stop-daemon --background --make-pidfile --exec $DAEMON --start --name $NAME --pidfile $PIDFILE --chuid $DAEMON_USER:$DAEMON_GROUP -- $DAEMON_ARGS
31
- log_end_msg $?
32
- ;;
33
- stop)
34
- log_daemon_msg "Stopping cijoe" "cijoe"
35
- start-stop-daemon --stop --pidfile $PIDFILE --quiet --retry 10
36
- log_end_msg $?
37
- ;;
38
- restart)
39
- log_daemon_msg "Restarting cijoe" "cijoe"
40
- start-stop-daemon --stop --pidfile $PIDFILE --quiet --retry 10
41
- start-stop-daemon --background --make-pidfile --exec $DAEMON --start --name $NAME --pidfile $PIDFILE --chuid $DAEMON_USER:$DAEMON_GROUP -- $DAEMON_ARGS
42
- log_end_msg $?
43
- ;;
44
- status)
45
- status_of_proc $DAEMON $NAME && exit 0 || exit $?
46
- ;;
47
- *)
48
- log_action_msg "Usage: /etc/init.d/cijoe (start|stop|restart)"
49
- exit 2
50
- ;;
51
- esac
52
-
53
- exit 0