citrus-core 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.citrus/config.rb +1 -1
  3. data/.gitignore +2 -1
  4. data/.travis.yml +4 -5
  5. data/README.md +1 -1
  6. data/Rakefile +3 -6
  7. data/citrus-core.gemspec +4 -2
  8. data/examples/bootstrap.rb +17 -17
  9. data/examples/payload.json +128 -1
  10. data/lib/citrus/core.rb +4 -18
  11. data/lib/citrus/core/build.rb +4 -2
  12. data/lib/citrus/core/cached_code_fetcher.rb +6 -5
  13. data/lib/citrus/core/configuration_loader.rb +2 -2
  14. data/lib/citrus/core/execute_build.rb +42 -0
  15. data/lib/citrus/core/exit_code.rb +21 -0
  16. data/lib/citrus/core/result.rb +7 -0
  17. data/lib/citrus/core/test_output.rb +19 -0
  18. data/lib/citrus/core/test_runner.rb +4 -6
  19. data/lib/citrus/core/version.rb +1 -1
  20. data/lib/citrus/core/workspace_builder.rb +5 -5
  21. data/lib/citrus/core/world.rb +21 -0
  22. data/spec/citrus/core/build_spec.rb +16 -0
  23. data/spec/{cached_code_fetcher_spec.rb → citrus/core/cached_code_fetcher_spec.rb} +17 -16
  24. data/spec/{changeset_spec.rb → citrus/core/changeset_spec.rb} +0 -0
  25. data/spec/citrus/core/clean_ruby_spec.rb +17 -0
  26. data/spec/{commit_changes_spec.rb → citrus/core/commit_changes_spec.rb} +0 -0
  27. data/spec/{commit_spec.rb → citrus/core/commit_spec.rb} +0 -0
  28. data/spec/{cofiguration_loader_spec.rb → citrus/core/configuration_loader_spec.rb} +1 -1
  29. data/spec/{cofiguration_spec.rb → citrus/core/configuration_spec.rb} +0 -0
  30. data/spec/{cofiguration_validator_spec.rb → citrus/core/configuration_validator_spec.rb} +0 -0
  31. data/spec/{execute_build_service_spec.rb → citrus/core/execute_build_spec.rb} +20 -15
  32. data/spec/{test_result_spec.rb → citrus/core/exit_code_spec.rb} +7 -6
  33. data/spec/{github_adapter_spec.rb → citrus/core/github_adapter_spec.rb} +1 -1
  34. data/spec/{publisher_spec.rb → citrus/core/publisher_spec.rb} +1 -1
  35. data/spec/{repository_spec.rb → citrus/core/repository_spec.rb} +0 -0
  36. data/spec/citrus/core/test_output_spec.rb +16 -0
  37. data/spec/citrus/core/test_runner_spec.rb +55 -0
  38. data/spec/citrus/core/workspace_builder_spec.rb +37 -0
  39. data/spec/citrus/core/world_spec.rb +11 -0
  40. data/spec/spec_helper.rb +6 -2
  41. metadata +81 -47
  42. data/examples/web.rb +0 -53
  43. data/lib/citrus/core/execute_build_service.rb +0 -30
  44. data/lib/citrus/core/test_result.rb +0 -24
  45. data/spec/build_spec.rb +0 -13
  46. data/spec/citrus_spec.rb +0 -18
  47. data/spec/test_runner_spec.rb +0 -44
  48. data/spec/workspace_builder_spec.rb +0 -55
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Citrus::Core::World do
4
+
5
+ let(:world) { described_class.new(root) }
6
+ let(:root) { '/world' }
7
+
8
+ specify { expect(world.cache_root).to eq('/world/cache') }
9
+ specify { expect(world.build_root).to eq('/world/builds') }
10
+
11
+ end
@@ -1,11 +1,15 @@
1
- require 'bogus/rspec'
2
- require 'fakefs/spec_helpers'
3
1
  require 'citrus/core'
4
2
 
5
3
  RSpec.configure do |config|
6
4
  config.order = 'random'
7
5
  end
8
6
 
7
+ require 'bogus/rspec'
9
8
  Bogus.configure do |config|
10
9
  config.search_modules << Citrus::Core
11
10
  end
11
+
12
+ if ENV['CI']
13
+ require 'coveralls'
14
+ Coveralls.wear!
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citrus-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paweł Pacana
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-11 00:00:00.000000000 Z
11
+ date: 2013-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: childprocess
@@ -25,47 +25,75 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.9
27
27
  - !ruby/object:Gem::Dependency
28
- name: fakefs
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.2
33
+ version: '2.13'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: 0.4.2
40
+ version: '2.13'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: bogus
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '2.13'
47
+ version: '0.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '2.13'
54
+ version: '0.1'
55
55
  - !ruby/object:Gem::Dependency
56
- name: bogus
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mutant
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.3.0.rc3
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.3.0.rc3
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - ~>
60
88
  - !ruby/object:Gem::Version
61
- version: 0.0.4
89
+ version: '0.7'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - ~>
67
95
  - !ruby/object:Gem::Version
68
- version: 0.0.4
96
+ version: '0.7'
69
97
  description: Citrus continous integration core components.
70
98
  email:
71
99
  - pawel.pacana@syswise.eu
@@ -84,7 +112,6 @@ files:
84
112
  - citrus-core.gemspec
85
113
  - examples/bootstrap.rb
86
114
  - examples/payload.json
87
- - examples/web.rb
88
115
  - lib/citrus/core.rb
89
116
  - lib/citrus/core/build.rb
90
117
  - lib/citrus/core/cached_code_fetcher.rb
@@ -94,34 +121,39 @@ files:
94
121
  - lib/citrus/core/configuration.rb
95
122
  - lib/citrus/core/configuration_loader.rb
96
123
  - lib/citrus/core/configuration_validator.rb
97
- - lib/citrus/core/execute_build_service.rb
124
+ - lib/citrus/core/execute_build.rb
125
+ - lib/citrus/core/exit_code.rb
98
126
  - lib/citrus/core/git_adapter.rb
99
127
  - lib/citrus/core/github_adapter.rb
100
128
  - lib/citrus/core/publisher.rb
101
129
  - lib/citrus/core/repository.rb
102
- - lib/citrus/core/test_result.rb
130
+ - lib/citrus/core/result.rb
131
+ - lib/citrus/core/test_output.rb
103
132
  - lib/citrus/core/test_runner.rb
104
133
  - lib/citrus/core/version.rb
105
134
  - lib/citrus/core/workspace_builder.rb
106
- - spec/build_spec.rb
107
- - spec/cached_code_fetcher_spec.rb
108
- - spec/changeset_spec.rb
109
- - spec/citrus_spec.rb
110
- - spec/cofiguration_loader_spec.rb
111
- - spec/cofiguration_spec.rb
112
- - spec/cofiguration_validator_spec.rb
113
- - spec/commit_changes_spec.rb
114
- - spec/commit_spec.rb
115
- - spec/execute_build_service_spec.rb
135
+ - lib/citrus/core/world.rb
136
+ - spec/citrus/core/build_spec.rb
137
+ - spec/citrus/core/cached_code_fetcher_spec.rb
138
+ - spec/citrus/core/changeset_spec.rb
139
+ - spec/citrus/core/clean_ruby_spec.rb
140
+ - spec/citrus/core/commit_changes_spec.rb
141
+ - spec/citrus/core/commit_spec.rb
142
+ - spec/citrus/core/configuration_loader_spec.rb
143
+ - spec/citrus/core/configuration_spec.rb
144
+ - spec/citrus/core/configuration_validator_spec.rb
145
+ - spec/citrus/core/execute_build_spec.rb
146
+ - spec/citrus/core/exit_code_spec.rb
147
+ - spec/citrus/core/github_adapter_spec.rb
148
+ - spec/citrus/core/publisher_spec.rb
149
+ - spec/citrus/core/repository_spec.rb
150
+ - spec/citrus/core/test_output_spec.rb
151
+ - spec/citrus/core/test_runner_spec.rb
152
+ - spec/citrus/core/workspace_builder_spec.rb
153
+ - spec/citrus/core/world_spec.rb
116
154
  - spec/fixtures/github_push_data.json
117
155
  - spec/fixtures/repo/.citrus/config.rb
118
- - spec/github_adapter_spec.rb
119
- - spec/publisher_spec.rb
120
- - spec/repository_spec.rb
121
156
  - spec/spec_helper.rb
122
- - spec/test_result_spec.rb
123
- - spec/test_runner_spec.rb
124
- - spec/workspace_builder_spec.rb
125
157
  homepage: http://citrus-ci.org
126
158
  licenses: []
127
159
  metadata: {}
@@ -141,27 +173,29 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
173
  version: '0'
142
174
  requirements: []
143
175
  rubyforge_project:
144
- rubygems_version: 2.0.3
176
+ rubygems_version: 2.0.6
145
177
  signing_key:
146
178
  specification_version: 4
147
179
  summary: Citrus continous integration core components.
148
180
  test_files:
149
- - spec/build_spec.rb
150
- - spec/cached_code_fetcher_spec.rb
151
- - spec/changeset_spec.rb
152
- - spec/citrus_spec.rb
153
- - spec/cofiguration_loader_spec.rb
154
- - spec/cofiguration_spec.rb
155
- - spec/cofiguration_validator_spec.rb
156
- - spec/commit_changes_spec.rb
157
- - spec/commit_spec.rb
158
- - spec/execute_build_service_spec.rb
181
+ - spec/citrus/core/build_spec.rb
182
+ - spec/citrus/core/cached_code_fetcher_spec.rb
183
+ - spec/citrus/core/changeset_spec.rb
184
+ - spec/citrus/core/clean_ruby_spec.rb
185
+ - spec/citrus/core/commit_changes_spec.rb
186
+ - spec/citrus/core/commit_spec.rb
187
+ - spec/citrus/core/configuration_loader_spec.rb
188
+ - spec/citrus/core/configuration_spec.rb
189
+ - spec/citrus/core/configuration_validator_spec.rb
190
+ - spec/citrus/core/execute_build_spec.rb
191
+ - spec/citrus/core/exit_code_spec.rb
192
+ - spec/citrus/core/github_adapter_spec.rb
193
+ - spec/citrus/core/publisher_spec.rb
194
+ - spec/citrus/core/repository_spec.rb
195
+ - spec/citrus/core/test_output_spec.rb
196
+ - spec/citrus/core/test_runner_spec.rb
197
+ - spec/citrus/core/workspace_builder_spec.rb
198
+ - spec/citrus/core/world_spec.rb
159
199
  - spec/fixtures/github_push_data.json
160
200
  - spec/fixtures/repo/.citrus/config.rb
161
- - spec/github_adapter_spec.rb
162
- - spec/publisher_spec.rb
163
- - spec/repository_spec.rb
164
201
  - spec/spec_helper.rb
165
- - spec/test_result_spec.rb
166
- - spec/test_runner_spec.rb
167
- - spec/workspace_builder_spec.rb
@@ -1,53 +0,0 @@
1
- require 'sinatra'
2
- require 'citrus/core'
3
-
4
- class ConsoleNotifier
5
- attr_reader :io
6
-
7
- def initialize(io = STDOUT)
8
- @io = io
9
- end
10
-
11
- def build_succeeded(build, output); io.puts "[#{build.uuid}] Build has succeeded."; end
12
- def build_failed(build, output); io.puts "[#{build.uuid}] Build has failed."; end
13
- def build_aborted(build, error) ; io.puts "[#{build.uuid}] Build has been aborted."; end
14
- def build_started(build); io.puts "[#{build.uuid}] Build has started."; end
15
- def output_received(data); io.print data; end
16
- end
17
-
18
- class QueuedBuilder
19
- include Citrus::Core
20
-
21
- attr_reader :queue, :service
22
-
23
- def initialize(queue, subscriber)
24
- workspace_builder = WorkspaceBuilder.new
25
- configuration_loader = ConfigurationLoader.new
26
- test_runner = TestRunner.new
27
- test_runner.add_subscriber(subscriber)
28
- @queue = queue
29
- @service = ExecuteBuildService.new(workspace_builder, configuration_loader, test_runner)
30
- @service.add_subscriber(subscriber)
31
- end
32
-
33
- def run
34
- Thread.new do
35
- loop do
36
- build = queue.pop
37
- service.start(build)
38
- end
39
- end
40
- end
41
- end
42
-
43
- queue = Queue.new
44
- builder = QueuedBuilder.new(queue, ConsoleNotifier.new)
45
- builder.run
46
-
47
- post '/github_push' do
48
- adapter = Citrus::Core::GithubAdapter.new
49
- changeset = adapter.create_changeset_from_push_data(params[:payload])
50
- build = Citrus::Core::Build.new(changeset)
51
- queue << build
52
- status 200
53
- end
@@ -1,30 +0,0 @@
1
- require 'citrus/core'
2
-
3
- module Citrus
4
- module Core
5
- class ExecuteBuildService
6
- include Publisher
7
-
8
- attr_reader :workspace_builder, :configuration_loader, :test_runner
9
-
10
- def initialize(workspace_builder = WorkspaceBuilder.new, configuration_loader = ConfigurationLoader.new, test_runner = TestRunner.new)
11
- @workspace_builder = workspace_builder
12
- @configuration_loader = configuration_loader
13
- @test_runner = test_runner
14
- end
15
-
16
- def start(build)
17
- path = workspace_builder.create_workspace(build)
18
- configuration = configuration_loader.load_from_path(path)
19
- publish(:build_started, build)
20
- result = test_runner.start(configuration, path)
21
- publish(:build_succeeded, build, result.output) if result.success?
22
- publish(:build_failed, build, result.output) if result.failure?
23
- rescue ConfigurationError => error
24
- publish(:build_aborted, build, error)
25
- raise error
26
- end
27
-
28
- end
29
- end
30
- end
@@ -1,24 +0,0 @@
1
- require 'stringio'
2
-
3
- module Citrus
4
- module Core
5
- class TestResult
6
-
7
- attr_reader :value, :output
8
-
9
- def initialize(value, output = StringIO.new)
10
- @value = value.to_i
11
- @output = output
12
- end
13
-
14
- def success?
15
- value == 0
16
- end
17
-
18
- def failure?
19
- !success?
20
- end
21
-
22
- end
23
- end
24
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Citrus::Core::Build do
4
-
5
- subject { described_class.new(changeset, uuid) }
6
-
7
- let(:changeset) { fake(:changeset) }
8
- let(:uuid) { SecureRandom.uuid }
9
-
10
- it { should respond_to(:changeset) }
11
- it { should respond_to(:uuid) }
12
-
13
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Citrus::Core do
4
-
5
- subject { described_class }
6
- before { stub(subject).root { Pathname.new('/dummy') } }
7
-
8
- context '.cache_root' do
9
- specify { expect(subject.cache_root.to_s).to match /cache\Z/ }
10
- specify { expect(subject.cache_root.to_s).to match /\A#{described_class.root}/ }
11
- end
12
-
13
- context '.build_root' do
14
- specify { expect(subject.build_root.to_s).to match /builds\Z/ }
15
- specify { expect(subject.build_root.to_s).to match /\A#{described_class.root}/ }
16
- end
17
-
18
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class Subscriber
4
- def output_received(data); end
5
- end
6
-
7
- describe Citrus::Core::TestRunner do
8
-
9
- subject { described_class.new }
10
-
11
- let(:configuration) { fake(:configuration, build_script: 'hostname') }
12
- let(:path) { Pathname.new('/') }
13
- let(:process) { fake { ChildProcess::AbstractProcess } }
14
- let(:subscriber) { fake(:subscriber) }
15
-
16
- context '#start' do
17
- context do
18
- before { stub(ChildProcess).build(configuration.build_script) { process } }
19
-
20
- it 'spawns child process' do
21
- expect(process).to have_received.start
22
- end
23
-
24
- it 'should return test result' do
25
- expect(subject.start(configuration, path)).to be_kind_of(Citrus::Core::TestResult)
26
- end
27
-
28
- it 'should wait for process to finish' do
29
- expect(process).to have_received.wait
30
- end
31
- end
32
-
33
- it 'should publish output_received event when process produced output' do
34
- subject.add_subscriber(subscriber)
35
- subject.start(configuration, path)
36
- expect(subscriber).to have_received.output_received(`hostname`)
37
- end
38
- end
39
-
40
- it 'should allow adding subscribers' do
41
- expect(subject).to respond_to(:add_subscriber)
42
- end
43
-
44
- end
@@ -1,55 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Citrus::Core::WorkspaceBuilder do
4
-
5
- subject { described_class.new(build_root, code_fetcher) }
6
-
7
- let(:build) { fake(:build) }
8
- let(:changeset) { fake(:changeset) }
9
- let(:code_fetcher) { fake(:cached_code_fetcher) }
10
-
11
- context '#create_workspace' do
12
- include FakeFS::SpecHelpers
13
-
14
- let(:result) { subject.create_workspace(build) }
15
-
16
- context do
17
- let(:build_root) { fake(:pathname) }
18
- let(:workspace_path) { fake(:pathname) }
19
-
20
- before do
21
- stub(build_root).join(any_args) { workspace_path }
22
- stub(build).changeset { changeset }
23
- result
24
- end
25
-
26
- it 'should return workspace path' do
27
- expect(result).to eql(workspace_path)
28
- end
29
-
30
- it 'should fetch code needed for build into workspace' do
31
- expect(code_fetcher).to have_received.fetch(changeset, workspace_path)
32
- end
33
- end
34
-
35
- context do
36
- let(:build_root) { Pathname.new('/build_root') }
37
- let(:uuid) { SecureRandom.uuid }
38
-
39
- before { stub(build).uuid { uuid } }
40
-
41
- it 'should create build directory under build root' do
42
- expect(result.to_s).to match %r{\A#{build_root}}
43
- end
44
-
45
- it 'should create workspace in directories partitioned by date' do
46
- expect(result.dirname.to_s).to match %r{\A/build_root/\d{4}/\d{2}/\d{2}\Z}
47
- end
48
-
49
- it 'should create workspace named after builds uuid' do
50
- expect(result.basename.to_s).to eql(uuid)
51
- end
52
- end
53
- end
54
-
55
- end