ciquantum 0.0.3 → 0.0.6

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.
data/README.md CHANGED
@@ -24,12 +24,12 @@ At current moment gem uses Unfuddle adapter, and must be configured for proper w
24
24
  Expected options:
25
25
  -----------------
26
26
 
27
- git config --add ciquantum.runner "command to do on build"
28
- git config --add ciquantum.branch branch_name
29
- git config --add ciquantum.buildqueue true
30
- git config --add ciquantum.projectname project_name_to_show
31
- git config --add ciquantum.coverage_path relative_path_to_coverage_report
32
-
33
- *Unfuddle (default) adapter:*
34
- git config --add ciquantum.unfuddle.project unfuddle_user_name
35
- git config --add ciquantum.unfuddle.user unfuddle_project_id
27
+ git config --add ciquantum.runner "command to do on build"
28
+ git config --add ciquantum.branch branch_name
29
+ git config --add ciquantum.buildqueue true
30
+ git config --add ciquantum.projectname project_name_to_show
31
+ git config --add ciquantum.coverage_path relative_path_to_coverage_report
32
+
33
+ Unfuddle (default) adapter:
34
+ git config --add ciquantum.unfuddle.project unfuddle_user_name
35
+ git config --add ciquantum.unfuddle.user unfuddle_project_id
@@ -18,7 +18,7 @@ Choice.options do
18
18
  end
19
19
 
20
20
  option :port do
21
- d = 4567
21
+ d = 5555
22
22
  short '-p'
23
23
  long '--port=PORT'
24
24
  desc "The port to listen on (default #{d})"
@@ -24,6 +24,8 @@ Gem::Specification.new do |gem|
24
24
  gem.add_runtime_dependency 'tinder', '>= 1.4.0'
25
25
  gem.add_runtime_dependency 'sinatra'
26
26
  gem.add_runtime_dependency 'choice'
27
+ gem.add_runtime_dependency 'pony'
28
+ gem.add_runtime_dependency 'sq_auth', '>= 0.0.21'
27
29
  gem.add_development_dependency 'rack-test'
28
30
  gem.add_development_dependency 'mocha'
29
31
 
File without changes
File without changes
@@ -1,228 +1,16 @@
1
1
 
2
2
  require 'ciquantum/version'
3
3
  require 'ciquantum/config'
4
- require 'ciquantum/adapter'
4
+ require 'ciquantum/unfuddle'
5
+ require 'ciquantum/unfuddle/changeset'
5
6
  require 'ciquantum/commit'
6
7
  require 'ciquantum/build'
7
8
  require 'ciquantum/server'
8
9
  require 'ciquantum/queue'
10
+ require 'ciquantum/core'
9
11
 
10
-
11
- class CIQuantum
12
- attr_reader :user
13
- attr_reader :project
14
- attr_reader :url
15
- attr_reader :current_build
16
- attr_reader :last_build
17
- attr_reader :campfire
18
- attr_reader :projectname
19
- attr_reader :coverage_path
20
-
21
- def initialize(project_path)
22
- @project_path = File.expand_path(project_path)
23
-
24
- @user, @project = git_user_and_project
25
- @url = project_url
26
- @projectname = repo_config.projectname.to_s
27
- @coverage_path = repo_config.coveragepath.to_s
28
-
29
- @last_build = nil
30
- @current_build = nil
31
- @queue = Queue.new(!repo_config.buildqueue.to_s.empty?, true)
32
-
33
- trap("INT") { stop }
34
- end
35
-
36
- # is a build running?
37
- def building?
38
- !!@current_build
39
- end
40
-
41
- # the pid of the running child process
42
- def pid
43
- building? and current_build.pid
44
- end
45
-
46
- # kill the child and exit
47
- def stop
48
- Process.kill(9, pid) if pid
49
- exit!
50
- end
51
-
52
- # build callbacks
53
- def build_failed(output, error)
54
- finish_build :failed, "#{error}\n\n#{output}"
55
- run_hook "build-failed"
56
- end
57
-
58
- def build_worked(output)
59
- finish_build :worked, output
60
- run_hook "build-worked"
61
- end
62
-
63
- def finish_build(status, output)
64
- @current_build.finished_at = Time.now
65
- @current_build.status = status
66
- @current_build.output = output
67
- @last_build = @current_build
68
-
69
- @current_build = nil
70
- write_build 'current', @current_build
71
- write_build 'last', @last_build
72
-
73
- build(@queue.next_branch_to_build) if @queue.waiting?
74
- end
75
-
76
- # run the build but make sure only one is running
77
- # at a time (if new one comes in we will park it)
78
- def build(branch=nil)
79
- if building?
80
- @queue.append_unless_already_exists(branch)
81
- # leave anyway because a current build runs
82
- return
83
- end
84
- @current_build = Build.new(@project_path, @user, @project)
85
- write_build 'current', @current_build
86
- Thread.new { build!(branch) }
87
- end
88
-
89
- def open_pipe(cmd)
90
- read, write = IO.pipe
91
-
92
- pid = fork do
93
- read.close
94
- $stdout.reopen write
95
- exec cmd
96
- end
97
-
98
- write.close
99
-
100
- yield read, pid
101
- end
102
-
103
- # update git then run the build
104
- def build!(branch=nil)
105
- @git_branch = branch
106
- build = @current_build
107
- output = ''
108
- git_update
109
- build.sha = git_sha
110
- build.branch = git_branch
111
- write_build 'current', build
112
-
113
- open_pipe("cd #{@project_path} && #{runner_command} 2>&1") do |pipe, pid|
114
- puts "#{Time.now.to_i}: Building #{build.branch} at #{build.short_sha}: pid=#{pid}"
115
-
116
- build.pid = pid
117
- write_build 'current', build
118
- output = pipe.read
119
- end
120
-
121
- Process.waitpid(build.pid, 1)
122
- status = $?.exitstatus.to_i
123
- @current_build = build
124
- puts "#{Time.now.to_i}: Built #{build.short_sha}: status=#{status}"
125
-
126
- status == 0 ? build_worked(output) : build_failed('', output)
127
- rescue Object => e
128
- puts "Exception building: #{e.message} (#{e.class})"
129
- build_failed('', e.to_s)
130
- end
131
-
132
- # shellin' out
133
- def runner_command
134
- runner = repo_config.runner.to_s
135
- runner == '' ? "rake -s test:units" : runner
136
- end
137
-
138
- def git_sha
139
- `cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp
140
- end
141
-
142
- def git_update
143
- `cd #{@project_path} && git fetch origin && git reset --hard origin/#{git_branch}`
144
- run_hook "after-reset"
145
- end
146
-
147
- def git_user_and_project
148
- adapter_config = repo_config.send Adapter.default_adapter.name
149
- Adapter.default_adapter.git_user_and_project adapter_config
150
- end
151
-
152
- def project_url
153
- Adapter.default_adapter.project_url @user, @project
154
- end
155
-
156
- def git_branches
157
- branches = `cd #{@project_path} && git branch -r`.split("\n")
158
- branches.collect{|s| s =~ /(?:\s|^)origin\/(?!HEAD)(\w+)(?:\s|$)/ ? $1.strip : nil}.compact
159
- end
160
-
161
- def git_branch
162
- return @git_branch if @git_branch
163
- branch = repo_config.branch.to_s
164
- @git_branch = branch == '' ? "master" : branch
165
- end
166
-
167
- # massage our repo
168
- def run_hook(hook)
169
- if File.exists?(file=path_in_project(".git/hooks/#{hook}")) && File.executable?(file)
170
- data =
171
- if @last_build && @last_build.commit
172
- {
173
- "MESSAGE" => @last_build.commit.message,
174
- "AUTHOR" => @last_build.commit.author,
175
- "SHA" => @last_build.commit.sha,
176
- "OUTPUT" => @last_build.env_output
177
- }
178
- else
179
- {}
180
- end
181
-
182
- orig_ENV = ENV.to_hash
183
- ENV.clear
184
- data.each{ |k, v| ENV[k] = v }
185
- output = `cd #{@project_path} && #{file}`
186
-
187
- ENV.clear
188
- orig_ENV.to_hash.each{ |k, v| ENV[k] = v}
189
- output
190
- end
191
- end
192
-
193
- # restore current / last build state from disk.
194
- def restore
195
- @last_build = read_build('last')
196
- @current_build = read_build('current')
197
-
198
- Process.kill(0, @current_build.pid) if @current_build && @current_build.pid
199
- rescue Errno::ESRCH
200
- # build pid isn't running anymore. assume previous
201
- # server died and reset.
202
- @current_build = nil
203
- end
204
-
205
- def path_in_project(path)
206
- File.join(@project_path, path)
207
- end
208
-
209
- # write build info for build to file.
210
- def write_build(name, build)
211
- filename = path_in_project(".git/builds/#{name}")
212
- Dir.mkdir path_in_project('.git/builds') unless File.directory?(path_in_project('.git/builds'))
213
- if build
214
- build.dump filename
215
- elsif File.exist?(filename)
216
- File.unlink filename
217
- end
218
- end
219
-
220
- def repo_config
221
- Config.ciquantum(@project_path)
222
- end
223
-
224
- # load build info from file.
225
- def read_build(name)
226
- Build.load(path_in_project(".git/builds/#{name}"), @project_path)
12
+ module CIQuantum
13
+ def self.new *args
14
+ CIQuantum::Core.new *args
227
15
  end
228
16
  end
@@ -1,6 +1,6 @@
1
1
  require 'yaml'
2
2
 
3
- class CIQuantum
3
+ module CIQuantum
4
4
  class Build < Struct.new(:project_path, :user, :project, :started_at, :finished_at, :sha, :status, :output, :pid, :branch)
5
5
  def initialize(*args)
6
6
  super
@@ -51,13 +51,14 @@ class CIQuantum
51
51
  @commit ||= Commit.new(sha, user, project, project_path)
52
52
  end
53
53
 
54
- def dump(file)
54
+ def dump file
55
55
  config = [user, project, started_at, finished_at, sha, status, output, pid, branch]
56
56
  data = YAML.dump(config)
57
57
  File.open(file, 'wb') { |io| io.write(data) }
58
58
  end
59
59
 
60
- def self.load(file, project_path)
60
+ def self.load file, project_path
61
+ puts "Loading build from file: #{file}"
61
62
  if File.exist?(file)
62
63
  config = YAML.load(File.read(file)).unshift(project_path)
63
64
  new *config
@@ -1,7 +1,7 @@
1
- class CIQuantum
1
+ module CIQuantum
2
2
  class Commit < Struct.new(:sha, :user, :project, :project_path)
3
3
  def url
4
- Adapter::default_adapter.commit_url self
4
+ Unfuddle.commit_url self
5
5
  end
6
6
 
7
7
  def author
@@ -1,4 +1,4 @@
1
- class CIQuantum
1
+ module CIQuantum
2
2
  class Config
3
3
  def self.method_missing(command, *args)
4
4
  new(command, *args)
@@ -0,0 +1,268 @@
1
+ module CIQuantum
2
+ class Core
3
+ attr_reader :user
4
+ attr_reader :project
5
+ attr_reader :url
6
+ attr_reader :current_build
7
+ attr_reader :last_build
8
+ attr_reader :campfire
9
+ attr_reader :projectname
10
+ attr_reader :coverage_path
11
+
12
+ HistoryLimit = 10
13
+
14
+ def initialize(project_path)
15
+ @project_path = File.expand_path(project_path)
16
+
17
+ @user, @project = git_user_and_project
18
+ @url = project_url
19
+ @projectname = repo_config.projectname.to_s
20
+ @coverage_path = repo_config.coveragepath.to_s
21
+
22
+ @last_build = nil
23
+ @current_build = nil
24
+ @queue = Queue.new(!repo_config.buildqueue.to_s.empty?, true)
25
+
26
+ trap("INT") { stop }
27
+ end
28
+
29
+ # is a build running?
30
+ def building?
31
+ !!@current_build
32
+ end
33
+
34
+ # the pid of the running child process
35
+ def pid
36
+ building? and current_build.pid
37
+ end
38
+
39
+ # kill the child and exit
40
+ def stop
41
+ Process.kill(9, pid) if pid
42
+ exit!
43
+ end
44
+
45
+ # build callbacks
46
+ def build_failed(output, error)
47
+ finish_build :failed, "#{error}\n\n#{output}"
48
+ run_hook "build-failed"
49
+ end
50
+
51
+ def build_worked(output)
52
+ finish_build :worked, output
53
+ run_hook "build-worked"
54
+ end
55
+
56
+ def finish_build(status, output)
57
+ @current_build.finished_at = Time.now
58
+ @current_build.status = status
59
+ @current_build.output = output
60
+ @last_build = @current_build
61
+
62
+ @current_build = nil
63
+ write_current_build
64
+ write_last_build
65
+ run_hook "postbuild"
66
+
67
+ build(@queue.next_branch_to_build) if @queue.waiting?
68
+ end
69
+
70
+ def build(branch=nil)
71
+ if building?
72
+ @queue.append_unless_already_exists(branch)
73
+ # leave anyway because a current build runs
74
+ return
75
+ end
76
+ @current_build = Build.new(@project_path, @user, @project)
77
+ write_current_build
78
+
79
+ Thread.new {
80
+ build!(branch)
81
+ }
82
+
83
+ end
84
+
85
+ def open_pipe(cmd)
86
+ read, write = IO.pipe
87
+
88
+ pid = fork do
89
+ read.close
90
+ $stdout.reopen write
91
+ exec cmd
92
+ end
93
+
94
+ write.close
95
+
96
+ yield read, pid
97
+ end
98
+
99
+ # update git then run the build
100
+ def build!(branch=nil)
101
+ @git_branch = branch
102
+ build = @current_build
103
+ run_hook "prebuild"
104
+ git_update
105
+ output = ''
106
+ build.sha = git_sha
107
+ build.branch = git_branch
108
+ write_build 'current', build
109
+
110
+ open_pipe("cd #{@project_path} && #{runner_command} 2>&1") do |pipe, pid|
111
+ puts "#{Time.now.to_i}: Building #{build.branch} at #{build.short_sha}: pid=#{pid}"
112
+
113
+ build.pid = pid
114
+ write_build 'current', build
115
+ output = pipe.read
116
+ end
117
+
118
+ Process.waitpid(build.pid, 1)
119
+ status = $?.exitstatus.to_i
120
+ @current_build = build
121
+ puts "#{Time.now.to_i}: Built #{build.short_sha}: status=#{status}"
122
+
123
+ status == 0 ? build_worked(output) : build_failed('', output)
124
+ rescue Object => e
125
+ puts "Exception building: #{e.message} (#{e.class})"
126
+ build_failed('', e.to_s)
127
+ end
128
+
129
+ # shellin' out
130
+ def runner_command
131
+ runner = repo_config.runner.to_s
132
+ runner == '' ? "rake -s test:units" : runner
133
+ end
134
+
135
+ def git_update
136
+ `cd #{@project_path} && git fetch origin && git reset --hard origin/#{git_branch}`
137
+ run_hook "after-reset"
138
+ end
139
+
140
+ def git_user_and_project
141
+ config = repo_config.send Unfuddle.name
142
+ Unfuddle.git_user_and_project config
143
+ end
144
+
145
+ def project_url
146
+ Unfuddle.project_url @user, @project
147
+ end
148
+
149
+ # massage our repo
150
+ def run_hook(hook)
151
+ if File.exists?(file=path_in_project(".git/hooks/#{hook}")) && File.executable?(file)
152
+ data =
153
+ if @last_build && @last_build.commit
154
+ {
155
+ "MESSAGE" => @last_build.commit.message,
156
+ "AUTHOR" => @last_build.commit.author,
157
+ "SHA" => @last_build.commit.sha,
158
+ "URL" => @last_build.commit.url,
159
+ "OUTPUT" => @last_build.env_output
160
+ }
161
+ else
162
+ {}
163
+ end
164
+
165
+ orig_ENV = ENV.to_hash
166
+ # ENV.clear
167
+ data.each{ |k, v| ENV[k] = v }
168
+ puts "Executing hook: #{file}"
169
+ output = `cd #{@project_path} && #{file}`
170
+
171
+ ENV.clear
172
+ orig_ENV.to_hash.each{ |k, v| ENV[k] = v}
173
+ output
174
+ end
175
+ end
176
+
177
+ # restore current / last build state from disk.
178
+ def restore
179
+ @last_build = read_last_build
180
+ @current_build = read_current_build
181
+
182
+ Process.kill(0, @current_build.pid) if @current_build && @current_build.pid
183
+ rescue Errno::ESRCH
184
+ @current_build = nil
185
+ end
186
+
187
+ def path_in_project(path)
188
+ File.join(@project_path, path)
189
+ end
190
+
191
+ def repo_config
192
+ Config.ciquantum(@project_path)
193
+ end
194
+
195
+ def swith_branch branch
196
+ repo_config.branch.set branch if git_branches.include? branch
197
+ end
198
+
199
+ def git_branches
200
+ branches = `cd #{@project_path} && git branch -r`.split("\n")
201
+ branches.collect{|s| s =~ /(?:\s|^)origin\/(?!HEAD)(\w+)(?:\s|$)/ ? $1.strip : nil}.compact
202
+ end
203
+
204
+ def git_branch
205
+ return @git_branch if @git_branch
206
+ branch = repo_config.branch.to_s
207
+ @git_branch = (branch == '' ? "master" : branch)
208
+ end
209
+
210
+ def git_sha
211
+ `cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp
212
+ end
213
+
214
+ def read_build(name)
215
+ Build.load(path_in_project(".git/builds/#{name}"), @project_path)
216
+ end
217
+
218
+ def read_last_build
219
+ read_build_by_index 0
220
+ end
221
+
222
+ def read_current_build
223
+ read_build 'current'
224
+ end
225
+
226
+ def read_build_by_index index
227
+ read_build old_builds[index] if old_builds[index]
228
+ end
229
+
230
+ def old_builds
231
+ Dir.glob(path_in_project(".git/builds/*")).collect do |f|
232
+ File.basename(f)
233
+ end.select do |f|
234
+ f =~ /\d+/
235
+ end.sort.reverse
236
+ end
237
+
238
+ def write_last_build
239
+ write_build @last_build.finished_at.to_i.to_s, @last_build
240
+ end
241
+
242
+ def write_current_build
243
+ write_build 'current', @current_build
244
+ end
245
+
246
+ def write_build(name, build)
247
+ filename = path_in_project(".git/builds/#{name}")
248
+ Dir.mkdir path_in_project('.git/builds') unless File.directory?(path_in_project('.git/builds'))
249
+ if build
250
+ build.dump filename
251
+ elsif File.exist?(filename)
252
+ File.unlink filename
253
+ end
254
+ remove_unused_build
255
+ end
256
+
257
+ def remove_unused_build
258
+ builds = old_builds
259
+ if builds.size > HistoryLimit
260
+ builds[HistoryLimit..builds.size].each do |file|
261
+ file = path_in_project(".git/builds/#{file}")
262
+ File.delete file if File.exists? file
263
+ end
264
+ end
265
+ end
266
+
267
+ end
268
+ end
@@ -1,8 +1,5 @@
1
- class CIQuantum
2
- # An in memory queue used for maintaining an order list of requested
3
- # builds.
1
+ module CIQuantum
4
2
  class Queue
5
- # enabled - determines whether builds should be queued or not.
6
3
  def initialize(enabled, verbose=false)
7
4
  @enabled = enabled
8
5
  @verbose = verbose
@@ -11,13 +8,6 @@ class CIQuantum
11
8
  log("Build queueing enabled") if enabled
12
9
  end
13
10
 
14
- # Public: Appends a branch to be built, unless it already exists
15
- # within the queue.
16
- #
17
- # branch - the name of the branch to build or nil if the default
18
- # should be built.
19
- #
20
- # Returns nothing
21
11
  def append_unless_already_exists(branch)
22
12
  return unless enabled?
23
13
  unless @queue.include? branch
@@ -26,15 +16,12 @@ class CIQuantum
26
16
  end
27
17
  end
28
18
 
29
- # Returns a String of the next branch to build
30
19
  def next_branch_to_build
31
20
  branch = @queue.shift
32
21
  log "#{Time.now.to_i}: De-queueing #{branch}"
33
22
  branch
34
23
  end
35
24
 
36
- # Returns true if there are requested builds waiting and false
37
- # otherwise.
38
25
  def waiting?
39
26
  if enabled?
40
27
  not @queue.empty?
@@ -1,9 +1,16 @@
1
- require 'sinatra/base'
2
1
  require 'erb'
3
2
  require 'json'
4
3
 
5
- class CIQuantum
4
+ require 'sinatra'
5
+ require 'sq_auth'
6
+
7
+ module CIQuantum
6
8
  class Server < Sinatra::Base
9
+
10
+ SqAuth.connect(host: "sqauth.socialquantum.com", port: 443) do |config|
11
+ config.project_name = "Enchanted"
12
+ end
13
+
7
14
  attr_reader :quantum
8
15
 
9
16
  dir = File.dirname(File.expand_path(__FILE__))
@@ -13,6 +20,9 @@ class CIQuantum
13
20
  set :static, true
14
21
  set :lock, true
15
22
 
23
+ enable :static
24
+ enable :sessions
25
+
16
26
  before { quantum.restore }
17
27
 
18
28
  get '/ping' do
@@ -23,33 +33,35 @@ class CIQuantum
23
33
  quantum.last_build.sha
24
34
  end
25
35
 
26
- get '/?' do
27
- erb(:template, {}, :quantum => quantum)
36
+ get ["ci::view", "ci::change_branch"], '/?' do
37
+ erb(:template, {}, :quantum => quantum, :can_change_branch => accessed_by?("ci::change_branch"))
28
38
  end
29
39
 
30
- post '/?' do
31
- puts params
32
- unless params[:rebuild]
33
- payload = JSON.parse(params[:payload])
34
- pushed_branch = payload["ref"].split('/').last
40
+ sq_auth_access do
41
+ access_action "/build" do
42
+ execute_for "ci::view"
35
43
  end
36
-
37
- # Only build if we were given an explicit branch via `?branch=blah`
38
- # or the payload exists and the "ref" property matches our
39
- # specified build branch.
40
- if params[:branch] || params[:rebuild] || pushed_branch == quantum.git_branch
41
- quantum.build(params[:branch])
44
+ access_action "/switch_branch" do
45
+ execute_for "ci::admin"
42
46
  end
47
+ end
43
48
 
44
- if params[:switch] == "Switch branch"
45
- quantum.repo_config.branch.set params[:branch] if quantum.git_branches.include? params[:branch]
46
- end
49
+ post '/build' do
50
+ quantum.build quantum.repo_config.branch
51
+
52
+ link_coverage_path
53
+ redirect '/'
54
+ end
47
55
 
56
+ post '/switch_branch' do
57
+ quantum.swith_branch params[:branch]
58
+ quantum.build params[:branch]
48
59
 
49
- redirect request.path
60
+ link_coverage_path
61
+ redirect '/'
50
62
  end
51
63
 
52
- get '/api/json' do
64
+ get ["ci::view"], '/api/json' do
53
65
  response = [200, {'Content-Type' => 'application/json'}]
54
66
  response_json = erb(:json, {}, :quantum => quantum)
55
67
  if params[:jsonp]
@@ -60,8 +72,20 @@ class CIQuantum
60
72
  response
61
73
  end
62
74
 
63
- get '/coverage' do
64
- redirect quantum.coverage_path
75
+ post '/push' do
76
+ begin
77
+ xml = request.body.read
78
+ changeset = Unfuddle::Changeset.new(xml)
79
+ quantum.build quantum.repo_config.branch
80
+ link_coverage_path
81
+ rescue Unfuddle::ChangesetError => e
82
+ logger.error "[error] Changeset error: #{e.inspect}, Content: #{xml.inspect}"
83
+ halt 400, "Changeset Error: #{e.message}"
84
+ end
85
+ end
86
+
87
+ get ["ci::view"], '/coverage?' do
88
+ redirect "coverage/index.html"
65
89
  end
66
90
 
67
91
  helpers do
@@ -83,6 +107,7 @@ class CIQuantum
83
107
  root = "" if root == "/"
84
108
  root
85
109
  end
110
+
86
111
  end
87
112
 
88
113
  def initialize(*args)
@@ -101,14 +126,17 @@ class CIQuantum
101
126
  self.new
102
127
  end
103
128
 
104
- def self.project_path=(project_path)
105
- user, pass = Config.ciquantum(project_path).user.to_s, Config.ciquantum(project_path).pass.to_s
106
- if user != '' && pass != ''
107
- use Rack::Auth::Basic do |username, password|
108
- [ username, password ] == [ user, pass ]
109
- end
110
- puts "Using HTTP basic auth"
129
+ def link_coverage_path
130
+ public_coverage_path = File.join settings.public_folder, "coverage"
131
+ project_coverage_path = File.join settings.project_path, quantum.coverage_path
132
+
133
+ File.unlink public_coverage_path if File.exists? public_coverage_path
134
+ if !quantum.coverage_path.empty? and File.exists? project_coverage_path
135
+ File.symlink project_coverage_path, public_coverage_path
111
136
  end
137
+ end
138
+
139
+ def self.project_path=(project_path)
112
140
  set :project_path, Proc.new{project_path}, true
113
141
  end
114
142
 
@@ -1,5 +1,5 @@
1
- class CIQuantum
2
- class UnfuddleAdapter
1
+ module CIQuantum
2
+ module Unfuddle
3
3
 
4
4
  def self.name
5
5
  "unfuddle"
@@ -10,12 +10,12 @@ class CIQuantum
10
10
  end
11
11
 
12
12
  def self.git_user_and_project config
13
- [ (config.user.empty? ? "linkfeed" : config.user), (config.project.empty? ? "17607" : config.project)]
13
+ [ config.user, config.project ]
14
14
  end
15
15
 
16
16
  def self.project_url user, project
17
- "https://#{user}.unfuddle.com/a#/repositories/#{project}/browse"
17
+ "https://#{user}.unfuddle.com/a#/repositories/#{project}/browse"
18
18
  end
19
19
 
20
20
  end
21
- end
21
+ end
@@ -0,0 +1,44 @@
1
+ require 'active_support/core_ext'
2
+
3
+ module CIQuantum
4
+ module Unfuddle
5
+ class ChangesetError < StandardError ; end
6
+
7
+ class Changeset
8
+ FIELDS = %w(repository_id revision message committer_name committer_date).freeze
9
+
10
+ attr_reader :author
11
+ attr_reader :message
12
+ attr_reader :date
13
+ attr_reader :commit
14
+ attr_reader :repo
15
+ attr_reader :xml
16
+
17
+ def initialize(xml)
18
+ xml = xml.to_s.strip
19
+ raise ChangesetError, 'Changeset XML required!' if xml.empty?
20
+
21
+ begin
22
+ @data = Hash.from_xml(xml)
23
+ rescue REXML::ParseException
24
+ raise ChangesetError, 'Invalid XML data!'
25
+ end
26
+
27
+ raise ChangesetError, 'Invalid changeset!' unless @data.key?('changeset')
28
+
29
+ @xml = xml
30
+ @data = @data['changeset']
31
+
32
+ unless (FIELDS & @data.keys).size == FIELDS.size
33
+ raise ChangesetError, 'Invalid changeset!'
34
+ end
35
+
36
+ @commit = @data['revision']
37
+ @author = @data['committer_name']
38
+ @message = @data['message']
39
+ @date = @data['committer_date']
40
+ @repo = @data['repository_id']
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
- class CIQuantum
2
- Version = VERSION = "0.0.3"
1
+ module CIQuantum
2
+ Version = VERSION = "0.0.6"
3
3
  end
@@ -2,7 +2,6 @@
2
2
  <html>
3
3
  <head>
4
4
  <link href="<%= ciquantum_root %>/screen.css" media="screen" rel="stylesheet" type="text/css" />
5
- <link rel="shortcut icon" href="<%= ciquantum_root %>/favicon.ico" type="image/x-icon" />
6
5
  <title><%= h(quantum.projectname) %>: CI Quantum</title>
7
6
  </head>
8
7
  <body>
@@ -26,16 +25,22 @@
26
25
  </li>
27
26
  <% else %>
28
27
  <li>
29
- <form method="POST">
30
- <input type="hidden", name="rebuild" value="true">
28
+ <form method="POST" action="/build">
29
+ <span class="branch">Current branch: <%= quantum.git_branch %></span>
30
+ <input type="submit" name="switch" value="Build"/>
31
+ </form>
32
+ </li>
33
+ <li>
34
+ <% if can_change_branch %>
35
+ <form method="POST" action="/switch_branch">
31
36
  <select name="branch">
32
37
  <% for @branch in quantum.git_branches %>
33
38
  <option value="<%= @branch %>" <%= "selected=\"selected\"" if (@branch == quantum.git_branch) %> >"<%= @branch %>"</option>
34
39
  <% end %>
35
40
  </select>
36
- <input type="submit" name="switch" value="Build once"/>
37
- <input type="submit" name="switch" value="Switch branch"/>
41
+ <input type="submit" name="switch" value="Switch branch and build"/>
38
42
  </form>
43
+ <% end %>
39
44
  </li>
40
45
  <% end %>
41
46
 
@@ -61,30 +66,6 @@
61
66
  <% end %>
62
67
  </ul>
63
68
  </div>
64
-
65
- <div class="footer">
66
- <div class="contact">
67
- <p>
68
- <a href="https://github.com/meredian/ciquantum#readme">Documentation</a><br/>
69
- <a href="https://github.com/meredian/ciquantum">Source</a><br/>
70
- <a href="https://github.com/meredian/ciquantum/issues">Issues</a><br/>
71
- <a href="https://github.com/meredian/ciquantum/tree/v<%= CIQuantum::VERSION %>">v<%= CIQuantum::VERSION %></a>
72
- </p>
73
- </div>
74
- <div class="contact">
75
- <p>
76
- Designed by <a href="http://tom.preston-werner.com/">Tom Preston-Werner</a><br/>
77
- Influenced by <a href="http://integrityapp.com/">Integrity</a><br/>
78
- Built with <a href="http://sinatrarb.com/">Sinatra</a><br/>
79
- Keep it simple, Sam.
80
- </p>
81
- </div>
82
- <div class="rss">
83
- <a href="http://github.com/meredian/ciquantum">
84
- <img src="<%= ciquantum_root %>/octocat.png" alt="Octocat!" />
85
- </a>
86
- </div>
87
- </div>
88
69
  </div>
89
70
  </body>
90
71
  </html>
@@ -0,0 +1,15 @@
1
+ require 'sinatra'
2
+ require 'sq_auth'
3
+
4
+ class Server < Sinatra::Base
5
+ enable :sessions
6
+ set :port, 5555
7
+
8
+ SqAuth.connect(host: "sqauth.socialquantum.com", port: 443) do |config|
9
+ config.project_name = "Enchanted"
10
+ end
11
+
12
+ get ["ci::view"], '/?' do
13
+ "Hello world. Authorize_info: #{access_for("ci::view"){"You can see it"}}"
14
+ end
15
+ end
@@ -18,19 +18,21 @@ class File
18
18
  end
19
19
 
20
20
  # #mock file to be the file I want
21
- class CIQuantum
22
- attr_writer :last_build
23
- alias orig_path_in_project path_in_project
24
- alias orig_git_user_and_project git_user_and_project
21
+ module CIQuantum
22
+ class Core
23
+ attr_writer :last_build
24
+ alias orig_path_in_project path_in_project
25
+ alias orig_git_user_and_project git_user_and_project
25
26
 
26
- def path_in_project(f)
27
- return '/tmp/test' if $hook_override
28
- orig_path_in_project
29
- end
27
+ def path_in_project(f)
28
+ return '/tmp/test' if $hook_override
29
+ orig_path_in_project
30
+ end
30
31
 
31
- def git_user_and_project
32
- return ['mine','yours'] if $hook_override
33
- orig_git_user_and_project
32
+ def git_user_and_project
33
+ return ['mine','yours'] if $hook_override
34
+ orig_git_user_and_project
35
+ end
34
36
  end
35
37
  end
36
38
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ciquantum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-04-23 00:00:00.000000000 Z
14
+ date: 2012-05-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -109,6 +109,38 @@ dependencies:
109
109
  - - ! '>='
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: pony
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :runtime
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: sq_auth
130
+ requirement: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: 0.0.21
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: 0.0.21
112
144
  - !ruby/object:Gem::Dependency
113
145
  name: rack-test
114
146
  requirement: !ruby/object:Gem::Requirement
@@ -158,22 +190,22 @@ files:
158
190
  - ciquantum.gemspec
159
191
  - examples/build-failed
160
192
  - examples/build-worked
161
- - examples/cijoe.ru
162
- - examples/cijoed
193
+ - examples/ciquantum.ru
194
+ - examples/ciquantumd
163
195
  - lib/ciquantum.rb
164
- - lib/ciquantum/adapter.rb
165
196
  - lib/ciquantum/build.rb
166
197
  - lib/ciquantum/commit.rb
167
198
  - lib/ciquantum/config.rb
168
- - lib/ciquantum/public/favicon.ico
169
- - lib/ciquantum/public/octocat.png
199
+ - lib/ciquantum/core.rb
170
200
  - lib/ciquantum/public/screen.css
171
201
  - lib/ciquantum/queue.rb
172
202
  - lib/ciquantum/server.rb
173
- - lib/ciquantum/unfuddle_adapter.rb
203
+ - lib/ciquantum/unfuddle.rb
204
+ - lib/ciquantum/unfuddle/changeset.rb
174
205
  - lib/ciquantum/version.rb
175
206
  - lib/ciquantum/views/json.erb
176
207
  - lib/ciquantum/views/template.erb
208
+ - sample.rb
177
209
  - test/fixtures/payload.json
178
210
  - test/helper.rb
179
211
  - test/test_ciquantum_queue.rb
@@ -1,15 +0,0 @@
1
- require 'ciquantum/unfuddle_adapter'
2
-
3
- class CIQuantum
4
- class Adapter
5
- class << self
6
-
7
- attr_writer :default_adapter
8
-
9
- def default_adapter
10
- @default_adapter ||= CIQuantum::UnfuddleAdapter
11
- end
12
-
13
- end
14
- end
15
- end