cijoe 0.4.0 → 0.5.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.
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