evrone-ci-router 0.2.0.pre22 → 0.2.0.pre23
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/evrone-ci-router.gemspec +4 -2
- data/lib/evrone/ci/router.rb +14 -15
- data/lib/evrone/ci/router/build.rb +3 -3
- data/lib/evrone/ci/router/script_builder.rb +5 -5
- data/lib/evrone/ci/router/script_builder/env.rb +1 -1
- data/lib/evrone/ci/router/script_builder/ruby.rb +1 -1
- data/lib/evrone/ci/router/script_builder/script.rb +2 -2
- data/lib/evrone/ci/router/script_builder/webdav_cache.rb +4 -4
- data/lib/evrone/ci/router/version.rb +1 -1
- data/spec/lib/build_spec.rb +2 -2
- data/spec/lib/router_spec.rb +7 -7
- data/spec/lib/script_builder/webdav_cache_spec.rb +2 -2
- data/spec/lib/script_builder_spec.rb +4 -4
- data/spec/support/create.rb +5 -5
- metadata +20 -13
- data/lib/evrone/ci/router/build_matrix.rb +0 -113
- data/lib/evrone/ci/router/travis.rb +0 -110
- data/lib/evrone/ci/router/travis/serializable.rb +0 -45
- data/spec/lib/build_matrix_spec.rb +0 -189
- data/spec/lib/travis_spec.rb +0 -183
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 857440d03ba3e8bf50be6caf1aa03368060c200a
|
4
|
+
data.tar.gz: ce9fd7abad14ebbdbb62c6249e6c1a5e034edcee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0e47b15e14ad3e615868ceb7e8b8ac90ca3696b42ff29e21a8ff7ab52ec455961f2182ad4cbef320e5653fea86979d0f36bd0a6ad221b3df28457958cf6cf13
|
7
|
+
data.tar.gz: 788a8ebb7646b4c4b00d62dc8502f7a01353c5f5b24a772685177c5e84144fce21069b6921ea70a8383ad4934a06e7b36495eebc35a8a81acab2f5abf33b2ae0
|
data/Gemfile
CHANGED
data/evrone-ci-router.gemspec
CHANGED
@@ -18,8 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_runtime_dependency 'evrone-ci-common',
|
22
|
-
spec.add_runtime_dependency 'evrone-ci-message',
|
21
|
+
spec.add_runtime_dependency 'evrone-ci-common', "= #{Evrone::CI::Router::VERSION}"
|
22
|
+
spec.add_runtime_dependency 'evrone-ci-message', "= #{Evrone::CI::Router::VERSION}"
|
23
|
+
spec.add_runtime_dependency 'evrone-ci-build_configuration', "= #{Evrone::CI::Router::VERSION}"
|
24
|
+
|
23
25
|
spec.add_runtime_dependency 'evrone-common-amqp', '~> 0.2.5'
|
24
26
|
spec.add_runtime_dependency 'hashr', '= 0.0.22'
|
25
27
|
|
data/lib/evrone/ci/router.rb
CHANGED
@@ -4,6 +4,7 @@ require 'fileutils'
|
|
4
4
|
require 'thread'
|
5
5
|
|
6
6
|
require 'evrone/ci/common/error_notifier'
|
7
|
+
require 'evrone/ci/build_configuration'
|
7
8
|
|
8
9
|
require File.expand_path("../..", __FILE__) + "/ci/router/ext/string.rb"
|
9
10
|
require File.expand_path("../..", __FILE__) + "/ci/router/ext/array.rb"
|
@@ -14,9 +15,7 @@ module Evrone
|
|
14
15
|
|
15
16
|
autoload :Configuration, File.expand_path("../router/configuration", __FILE__)
|
16
17
|
autoload :Build, File.expand_path("../router/build", __FILE__)
|
17
|
-
autoload :BuildMatrix, File.expand_path("../router/build_matrix", __FILE__)
|
18
18
|
autoload :ScriptBuilder, File.expand_path("../router/script_builder", __FILE__)
|
19
|
-
autoload :Travis, File.expand_path("../router/travis", __FILE__)
|
20
19
|
autoload :CLI, File.expand_path("../router/cli", __FILE__)
|
21
20
|
|
22
21
|
autoload :BuildLogsConsumer, File.expand_path("../router/consumers/build_logs_consumer", __FILE__)
|
@@ -70,17 +69,17 @@ module Evrone
|
|
70
69
|
include Helper::Logger
|
71
70
|
include Helper::Config
|
72
71
|
|
73
|
-
attr_reader :build, :
|
72
|
+
attr_reader :build, :configuration
|
74
73
|
|
75
74
|
def initialize(build)
|
76
|
-
@build
|
77
|
-
@
|
75
|
+
@build = build
|
76
|
+
@configuration = nil
|
78
77
|
end
|
79
78
|
|
80
79
|
def perform
|
81
80
|
log_build do
|
82
81
|
update_build_status do
|
83
|
-
|
82
|
+
load_configuration &&
|
84
83
|
create_and_delivery_build_matrix
|
85
84
|
end
|
86
85
|
end
|
@@ -88,24 +87,24 @@ module Evrone
|
|
88
87
|
end
|
89
88
|
|
90
89
|
def create_and_delivery_build_matrix
|
91
|
-
matrix =
|
92
|
-
build.jobs_count = matrix.
|
90
|
+
matrix = BuildConfiguration::Matrix.new configuration
|
91
|
+
build.jobs_count = matrix.configurations.size
|
93
92
|
|
94
|
-
matrix.
|
93
|
+
matrix.configurations.each_with_index do |c, idx|
|
95
94
|
number = idx + 1
|
96
|
-
message = build.to_perform_job_message
|
97
|
-
logger.info "delivery job #{message.id}.#{number} #{
|
95
|
+
message = build.to_perform_job_message c, number
|
96
|
+
logger.info "delivery job #{message.id}.#{number} #{c.to_matrix_s}"
|
98
97
|
JobsConsumer.publish message
|
99
98
|
|
100
|
-
publish_job_status_message build,
|
99
|
+
publish_job_status_message build, c, number
|
101
100
|
end
|
102
101
|
|
103
102
|
true
|
104
103
|
end
|
105
104
|
|
106
|
-
def
|
107
|
-
@
|
108
|
-
@
|
105
|
+
def load_configuration
|
106
|
+
@configuration = BuildConfiguration.from_yaml build.message.travis
|
107
|
+
@configuration
|
109
108
|
end
|
110
109
|
|
111
110
|
def log_build
|
@@ -27,8 +27,8 @@ module Evrone
|
|
27
27
|
output.close
|
28
28
|
end
|
29
29
|
|
30
|
-
def to_perform_job_message(
|
31
|
-
script_builder =
|
30
|
+
def to_perform_job_message(configuration, job_id)
|
31
|
+
script_builder = ScriptBuilder.new self, configuration
|
32
32
|
job_message = Message::PerformJob.new(
|
33
33
|
id: message.id,
|
34
34
|
name: message.name,
|
@@ -36,7 +36,7 @@ module Evrone
|
|
36
36
|
before_script: script_builder.to_before_script,
|
37
37
|
script: script_builder.to_script,
|
38
38
|
after_script: script_builder.to_after_script,
|
39
|
-
matrix_keys:
|
39
|
+
matrix_keys: configuration.matrix_keys,
|
40
40
|
)
|
41
41
|
job_message
|
42
42
|
end
|
@@ -24,11 +24,11 @@ module Evrone
|
|
24
24
|
use ScriptBuilder::Script
|
25
25
|
end
|
26
26
|
|
27
|
-
attr_reader :
|
27
|
+
attr_reader :configuration, :build
|
28
28
|
|
29
|
-
def initialize(build,
|
30
|
-
@
|
31
|
-
@build
|
29
|
+
def initialize(build, configuration)
|
30
|
+
@configuration = configuration
|
31
|
+
@build = build
|
32
32
|
end
|
33
33
|
|
34
34
|
def to_before_script
|
@@ -88,7 +88,7 @@ module Evrone
|
|
88
88
|
script: [],
|
89
89
|
after_script: [],
|
90
90
|
|
91
|
-
|
91
|
+
configuration: configuration,
|
92
92
|
build: build,
|
93
93
|
)
|
94
94
|
end
|
@@ -8,10 +8,10 @@ module Evrone
|
|
8
8
|
include Helper::TraceShCommand
|
9
9
|
|
10
10
|
def call(env)
|
11
|
-
env.
|
11
|
+
env.configuration.before_script.each do |c|
|
12
12
|
env.before_script << trace_sh_command(c)
|
13
13
|
end
|
14
|
-
env.
|
14
|
+
env.configuration.script.each do |c|
|
15
15
|
env.script << trace_sh_command(c)
|
16
16
|
end
|
17
17
|
app.call(env)
|
@@ -8,7 +8,7 @@ module Evrone
|
|
8
8
|
include Helper::Config
|
9
9
|
include Helper::Logger
|
10
10
|
|
11
|
-
CASHER_URL = "https://raw.github.com/travis-ci/casher/
|
11
|
+
CASHER_URL = "https://raw.github.com/travis-ci/casher/production/bin/casher"
|
12
12
|
CASHER_BIN = "$HOME/.casher/bin/casher"
|
13
13
|
|
14
14
|
def call(env)
|
@@ -29,7 +29,7 @@ module Evrone
|
|
29
29
|
name << env.build.message.name.dup
|
30
30
|
|
31
31
|
# convert keys from ["rvm:2.0.0"] to "rvm 2.0.0"
|
32
|
-
name += env.
|
32
|
+
name += env.configuration.matrix_keys.map{|i| i.split(":").join(" ") }
|
33
33
|
# replace non word chars to ' '
|
34
34
|
name = name.join("-").gsub(/[^a-z0-9_\-.]/, ' ')
|
35
35
|
|
@@ -52,11 +52,11 @@ module Evrone
|
|
52
52
|
|
53
53
|
def fetch(env)
|
54
54
|
env.init << "echo fetch cached content"
|
55
|
-
env.init << "#{CASHER_BIN} fetch #{env.webdav_cache_url}
|
55
|
+
env.init << "#{CASHER_BIN} fetch #{env.webdav_cache_url} || true"
|
56
56
|
end
|
57
57
|
|
58
58
|
def add(env)
|
59
|
-
env.init << "#{CASHER_BIN} add $HOME/cached
|
59
|
+
env.init << "#{CASHER_BIN} add $HOME/cached || true"
|
60
60
|
env.init << "unset CASHER_DIR"
|
61
61
|
end
|
62
62
|
|
data/spec/lib/build_spec.rb
CHANGED
@@ -98,9 +98,9 @@ describe Evrone::CI::Router::Build do
|
|
98
98
|
end
|
99
99
|
|
100
100
|
context ".to_perform_job_message" do
|
101
|
-
let(:
|
101
|
+
let(:config) { create :configuration }
|
102
102
|
let(:job_id) { 2 }
|
103
|
-
subject { build.to_perform_job_message
|
103
|
+
subject { build.to_perform_job_message config, job_id }
|
104
104
|
|
105
105
|
it { should be_an_instance_of Evrone::CI::Message::PerformJob }
|
106
106
|
|
data/spec/lib/router_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe Evrone::CI::Router do
|
|
8
8
|
subject { router }
|
9
9
|
|
10
10
|
context "just created" do
|
11
|
-
its(:build)
|
11
|
+
its(:build) { should eq build }
|
12
12
|
end
|
13
13
|
|
14
14
|
context "#perform" do
|
@@ -43,12 +43,12 @@ describe Evrone::CI::Router do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
context "#
|
47
|
-
subject { router.
|
46
|
+
context "#load_configuration" do
|
47
|
+
subject { router.load_configuration }
|
48
48
|
|
49
|
-
it "should build new
|
49
|
+
it "should build new BuildConfiguration instance from message" do
|
50
50
|
expect(subject).to be_true
|
51
|
-
expect(router.
|
51
|
+
expect(router.configuration).to be
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -57,10 +57,10 @@ describe Evrone::CI::Router do
|
|
57
57
|
let(:message) { messages.first }
|
58
58
|
subject { router.create_and_delivery_build_matrix }
|
59
59
|
before do
|
60
|
-
stub(router).
|
60
|
+
stub(router).configuration { create :configuration }
|
61
61
|
end
|
62
62
|
|
63
|
-
it "should create build matrix from source
|
63
|
+
it "should create build matrix from source configuration and delivery its to jobs" do
|
64
64
|
expect(subject).to be_true
|
65
65
|
expect(messages).to have(1).item
|
66
66
|
expect(message.job_id).to eq 1
|
@@ -6,8 +6,8 @@ describe Evrone::CI::Router::ScriptBuilder::WebdavCache do
|
|
6
6
|
let(:path) { '/tmp/.test' }
|
7
7
|
let(:app) { ->(_) { _ } }
|
8
8
|
let(:build) { create :build }
|
9
|
-
let(:
|
10
|
-
let(:env) { OpenStruct.new build: build, init: [],
|
9
|
+
let(:config) { create :configuration }
|
10
|
+
let(:env) { OpenStruct.new build: build, init: [], configuration: config, after_script: [] }
|
11
11
|
let(:mid) { described_class.new app }
|
12
12
|
|
13
13
|
subject { mid.call env }
|
@@ -2,13 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Evrone::CI::Router::ScriptBuilder do
|
4
4
|
let(:build) { create :build }
|
5
|
-
let(:
|
6
|
-
let(:script_builder) { described_class.new build,
|
5
|
+
let(:config) { create :configuration }
|
6
|
+
let(:script_builder) { described_class.new build, config }
|
7
7
|
subject { script_builder }
|
8
8
|
|
9
9
|
context "just created" do
|
10
|
-
its(:
|
11
|
-
its(:build)
|
10
|
+
its(:configuration) { should eq config }
|
11
|
+
its(:build) { should eq build }
|
12
12
|
end
|
13
13
|
|
14
14
|
context "to_before_script" do
|
data/spec/support/create.rb
CHANGED
@@ -9,13 +9,13 @@ def create(who, *args)
|
|
9
9
|
when :local_repo
|
10
10
|
Evrone::CI::Router.root.join("fixtures/repo").to_s
|
11
11
|
|
12
|
-
when :
|
13
|
-
klass = Evrone::CI::
|
14
|
-
|
12
|
+
when :configuration
|
13
|
+
klass = Evrone::CI::BuildConfiguration
|
14
|
+
configuration = nil
|
15
15
|
if options[:yaml]
|
16
|
-
|
16
|
+
configuration = klass.from_yaml options[:yaml]
|
17
17
|
elsif options[:attributes]
|
18
|
-
|
18
|
+
configuration = klass.from_attributes options[:attributes]
|
19
19
|
else
|
20
20
|
klass.from_yaml fixture("travis.yml")
|
21
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evrone-ci-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0.
|
4
|
+
version: 0.2.0.pre23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Galinsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: evrone-ci-common
|
@@ -16,28 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.2.0.
|
19
|
+
version: 0.2.0.pre23
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.2.0.
|
26
|
+
version: 0.2.0.pre23
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: evrone-ci-message
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.2.0.
|
33
|
+
version: 0.2.0.pre23
|
34
34
|
type: :runtime
|
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.2.0.
|
40
|
+
version: 0.2.0.pre23
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: evrone-ci-build_configuration
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.0.pre23
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.0.pre23
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: evrone-common-amqp
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,7 +155,6 @@ files:
|
|
141
155
|
- fixtures/travis.yml
|
142
156
|
- lib/evrone/ci/router.rb
|
143
157
|
- lib/evrone/ci/router/build.rb
|
144
|
-
- lib/evrone/ci/router/build_matrix.rb
|
145
158
|
- lib/evrone/ci/router/cli.rb
|
146
159
|
- lib/evrone/ci/router/configuration.rb
|
147
160
|
- lib/evrone/ci/router/consumers/build_logs_consumer.rb
|
@@ -162,17 +175,13 @@ files:
|
|
162
175
|
- lib/evrone/ci/router/script_builder/ruby.rb
|
163
176
|
- lib/evrone/ci/router/script_builder/script.rb
|
164
177
|
- lib/evrone/ci/router/script_builder/webdav_cache.rb
|
165
|
-
- lib/evrone/ci/router/travis.rb
|
166
|
-
- lib/evrone/ci/router/travis/serializable.rb
|
167
178
|
- lib/evrone/ci/router/version.rb
|
168
|
-
- spec/lib/build_matrix_spec.rb
|
169
179
|
- spec/lib/build_spec.rb
|
170
180
|
- spec/lib/configuration_spec.rb
|
171
181
|
- spec/lib/router_spec.rb
|
172
182
|
- spec/lib/script_builder/prepare_spec.rb
|
173
183
|
- spec/lib/script_builder/webdav_cache_spec.rb
|
174
184
|
- spec/lib/script_builder_spec.rb
|
175
|
-
- spec/lib/travis_spec.rb
|
176
185
|
- spec/spec_helper.rb
|
177
186
|
- spec/support/create.rb
|
178
187
|
- spec/support/fixture.rb
|
@@ -203,14 +212,12 @@ signing_key:
|
|
203
212
|
specification_version: 4
|
204
213
|
summary: ci router
|
205
214
|
test_files:
|
206
|
-
- spec/lib/build_matrix_spec.rb
|
207
215
|
- spec/lib/build_spec.rb
|
208
216
|
- spec/lib/configuration_spec.rb
|
209
217
|
- spec/lib/router_spec.rb
|
210
218
|
- spec/lib/script_builder/prepare_spec.rb
|
211
219
|
- spec/lib/script_builder/webdav_cache_spec.rb
|
212
220
|
- spec/lib/script_builder_spec.rb
|
213
|
-
- spec/lib/travis_spec.rb
|
214
221
|
- spec/spec_helper.rb
|
215
222
|
- spec/support/create.rb
|
216
223
|
- spec/support/fixture.rb
|
@@ -1,113 +0,0 @@
|
|
1
|
-
module Evrone
|
2
|
-
module CI
|
3
|
-
class Router
|
4
|
-
class BuildMatrix
|
5
|
-
|
6
|
-
KEYS = (Travis::LANGS + %w{ matrix_env:env }).freeze
|
7
|
-
NOT_MATRIX_KEYS = %w{ script before_script }
|
8
|
-
|
9
|
-
attr_reader :travis
|
10
|
-
|
11
|
-
def initialize(travis)
|
12
|
-
@travis = travis
|
13
|
-
end
|
14
|
-
|
15
|
-
def keys
|
16
|
-
extract_pair_of_key_and_values.map(&:first).sort
|
17
|
-
end
|
18
|
-
|
19
|
-
def travises
|
20
|
-
attributes_for_new_travises_with_merged_env.map do |attrs|
|
21
|
-
attrs = attrs.merge(
|
22
|
-
NOT_MATRIX_KEYS.inject({}) do |a,v|
|
23
|
-
a[v] = travis.public_send(v)
|
24
|
-
a
|
25
|
-
end
|
26
|
-
)
|
27
|
-
Travis.new attrs
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def attributes_for_new_travises_with_merged_env
|
32
|
-
attrs = attributes_for_new_travises
|
33
|
-
attrs = [{}] if attrs.empty?
|
34
|
-
attrs.map do |a|
|
35
|
-
e = a["env"]
|
36
|
-
a["env"] = {
|
37
|
-
"global" => Array(e) + travis.global_env,
|
38
|
-
"matrix" => e
|
39
|
-
}
|
40
|
-
a
|
41
|
-
end
|
42
|
-
attrs
|
43
|
-
end
|
44
|
-
|
45
|
-
def attributes_for_new_travises
|
46
|
-
permutate_and_build_values.inject([]) do |ac, values|
|
47
|
-
ac << values.inject({}) do |a,val|
|
48
|
-
a[val.key] = val.value
|
49
|
-
a
|
50
|
-
end
|
51
|
-
ac
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def permutate_and_build_values
|
56
|
-
values = extract_pair_of_key_and_values.map do |key, vals|
|
57
|
-
vals.map{|it| Value.new(key, it) }
|
58
|
-
end
|
59
|
-
if matrix_values?(values)
|
60
|
-
array_permutations(values).map do |it|
|
61
|
-
if it.is_a?(Array)
|
62
|
-
it.flatten
|
63
|
-
else
|
64
|
-
[it]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
else
|
68
|
-
values
|
69
|
-
end.sort_by(&:to_s)
|
70
|
-
end
|
71
|
-
|
72
|
-
def extract_pair_of_key_and_values
|
73
|
-
KEYS.map.inject([]) do |a, k|
|
74
|
-
k_method, k_name = k.split(":")
|
75
|
-
k_name ||= k_method
|
76
|
-
|
77
|
-
if (val = travis[k_method]) && !val.empty?
|
78
|
-
a << [k_name, val]
|
79
|
-
end
|
80
|
-
a
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def matrix_values?(values)
|
87
|
-
!values.all?{|i| i.size == 1 }
|
88
|
-
end
|
89
|
-
|
90
|
-
def array_permutations array, index=0
|
91
|
-
# index is 0 by default : start at the beginning, more elegant.
|
92
|
-
return array[-1] if index == array.size - 1 # Return last element if at end.
|
93
|
-
|
94
|
-
result = []
|
95
|
-
|
96
|
-
array[index].each do |element| # For each array
|
97
|
-
array_permutations(array, index + 1).each do |x| # Permute permute permute
|
98
|
-
result << [element, x]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
result
|
102
|
-
end
|
103
|
-
|
104
|
-
Value = Struct.new(:key, :value) do
|
105
|
-
def to_s
|
106
|
-
[key, value].join(":")
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
require File.expand_path("../travis/serializable", __FILE__)
|
2
|
-
|
3
|
-
module Evrone
|
4
|
-
module CI
|
5
|
-
class Router
|
6
|
-
class Travis
|
7
|
-
|
8
|
-
include Travis::Serializable
|
9
|
-
|
10
|
-
LANGS = %w{ rvm scala java go }.freeze
|
11
|
-
KEYS = %w{ before_script script }.freeze
|
12
|
-
AS_ARRAY = (KEYS + LANGS).freeze
|
13
|
-
|
14
|
-
attr_reader :attributes
|
15
|
-
alias_method :to_hash, :attributes
|
16
|
-
|
17
|
-
def initialize(attrs = {})
|
18
|
-
@attributes = normalize_attributes attrs
|
19
|
-
end
|
20
|
-
|
21
|
-
def [](val)
|
22
|
-
public_send(val)
|
23
|
-
end
|
24
|
-
|
25
|
-
def matrix_keys
|
26
|
-
@matrix_keys ||=
|
27
|
-
BuildMatrix::KEYS.inject([]) do |a,k|
|
28
|
-
k_method, k_name = k.split(":")
|
29
|
-
k_name ||= k_method
|
30
|
-
val = send(k_method)
|
31
|
-
unless val.empty?
|
32
|
-
a << val.map{|v| "#{k_name}:#{v}" }
|
33
|
-
end
|
34
|
-
a
|
35
|
-
end.flatten.sort
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_matrix_s
|
39
|
-
@to_matrix_s ||= matrix_keys.join(", ")
|
40
|
-
end
|
41
|
-
|
42
|
-
def to_script_builder(build)
|
43
|
-
ScriptBuilder.new(build, self)
|
44
|
-
end
|
45
|
-
|
46
|
-
def env
|
47
|
-
attributes["env"]
|
48
|
-
end
|
49
|
-
|
50
|
-
def matrix_env
|
51
|
-
attributes["env"]["matrix"]
|
52
|
-
end
|
53
|
-
|
54
|
-
def global_env
|
55
|
-
attributes["env"]["global"]
|
56
|
-
end
|
57
|
-
|
58
|
-
AS_ARRAY.each do |m|
|
59
|
-
define_method m do
|
60
|
-
@attributes[m] || []
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def merge(attrs = {})
|
65
|
-
self.class.from_attributes self.attributes.merge(attrs)
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def normalize_attributes(attributes)
|
71
|
-
attributes = attributes.inject({}) do |a,row|
|
72
|
-
k,v = row
|
73
|
-
if AS_ARRAY.include?(k.to_s)
|
74
|
-
v = Array(v)
|
75
|
-
end
|
76
|
-
a[k.to_s] = v
|
77
|
-
a
|
78
|
-
end
|
79
|
-
normalize_env_attribute attributes
|
80
|
-
end
|
81
|
-
|
82
|
-
def normalize_env_attribute(attributes)
|
83
|
-
env = (attributes['env'] || {}) .dup
|
84
|
-
case env
|
85
|
-
when Hash
|
86
|
-
attributes["env"] = {
|
87
|
-
"matrix" => Array(env['matrix']),
|
88
|
-
"global" => Array(env['global'])
|
89
|
-
}
|
90
|
-
else
|
91
|
-
attributes['env'] = {
|
92
|
-
"matrix" => Array(env).map(&:to_s),
|
93
|
-
"global" => []
|
94
|
-
}
|
95
|
-
end
|
96
|
-
freeze_normalized_attributes attributes
|
97
|
-
end
|
98
|
-
|
99
|
-
def freeze_normalized_attributes(attributes)
|
100
|
-
attributes.freeze
|
101
|
-
attributes['env'].freeze
|
102
|
-
attributes['env']['global'].freeze
|
103
|
-
attributes['env']['matrix'].freeze
|
104
|
-
attributes
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Evrone
|
5
|
-
module CI
|
6
|
-
class Router
|
7
|
-
class Travis
|
8
|
-
|
9
|
-
module Serializable
|
10
|
-
|
11
|
-
def self.included(base)
|
12
|
-
base.extend ClassMethods
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_yaml
|
16
|
-
YAML.dump(attributes)
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_hash
|
20
|
-
attributes
|
21
|
-
end
|
22
|
-
|
23
|
-
module ClassMethods
|
24
|
-
|
25
|
-
def from_file(file)
|
26
|
-
if File.readable? file
|
27
|
-
from_yaml File.read(file)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def from_yaml(yaml)
|
32
|
-
from_attributes YAML.load(yaml)
|
33
|
-
end
|
34
|
-
|
35
|
-
def from_attributes(attrs)
|
36
|
-
Travis.new attrs
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,189 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
describe Evrone::CI::Router::BuildMatrix do
|
5
|
-
let(:attributes) { {
|
6
|
-
env: %w{ FOO=1 BAR=2 },
|
7
|
-
rvm: %w{ 1.8.7 1.9.3 2.0.0 },
|
8
|
-
scala: %w{ 2.9.2 2.10.1 },
|
9
|
-
before_script: "echo before_script",
|
10
|
-
script: "echo script"
|
11
|
-
} }
|
12
|
-
let(:travis) { create :travis, attributes: attributes }
|
13
|
-
let(:matrix) { described_class.new travis }
|
14
|
-
|
15
|
-
subject { matrix }
|
16
|
-
|
17
|
-
context "just created" do
|
18
|
-
its(:travis) { should eq travis }
|
19
|
-
end
|
20
|
-
|
21
|
-
context "keys" do
|
22
|
-
subject { matrix.keys }
|
23
|
-
it { should eq %w{ env rvm scala } }
|
24
|
-
context "without matrix" do
|
25
|
-
let(:attributes) { {} }
|
26
|
-
|
27
|
-
it { should eq [] }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'travises' do
|
32
|
-
subject { matrix.travises }
|
33
|
-
|
34
|
-
it "should copy script from source" do
|
35
|
-
expect(subject.map(&:script).uniq).to eq [["echo script"]]
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should copy before_script from source" do
|
39
|
-
expect(subject.map(&:before_script).uniq).to eq [["echo before_script"]]
|
40
|
-
end
|
41
|
-
|
42
|
-
context "without any matrix keys" do
|
43
|
-
let(:attributes) { {
|
44
|
-
script: %w{ /bin/true },
|
45
|
-
} }
|
46
|
-
|
47
|
-
it { should have(1).item }
|
48
|
-
its("first.attributes") { should eq(
|
49
|
-
"env"=>{"matrix"=>[], "global"=>[]},
|
50
|
-
"script"=>["/bin/true"],
|
51
|
-
"before_script"=>[]
|
52
|
-
)}
|
53
|
-
end
|
54
|
-
|
55
|
-
context "values" do
|
56
|
-
|
57
|
-
it { should have(12).items }
|
58
|
-
|
59
|
-
context "attributes" do
|
60
|
-
subject { matrix.travises.map(&:to_matrix_s) }
|
61
|
-
|
62
|
-
it do
|
63
|
-
should eq [
|
64
|
-
"env:BAR=2, rvm:1.8.7, scala:2.10.1",
|
65
|
-
"env:FOO=1, rvm:1.8.7, scala:2.10.1",
|
66
|
-
"env:BAR=2, rvm:1.8.7, scala:2.9.2",
|
67
|
-
"env:FOO=1, rvm:1.8.7, scala:2.9.2",
|
68
|
-
"env:BAR=2, rvm:1.9.3, scala:2.10.1",
|
69
|
-
"env:FOO=1, rvm:1.9.3, scala:2.10.1",
|
70
|
-
"env:BAR=2, rvm:1.9.3, scala:2.9.2",
|
71
|
-
"env:FOO=1, rvm:1.9.3, scala:2.9.2",
|
72
|
-
"env:BAR=2, rvm:2.0.0, scala:2.10.1",
|
73
|
-
"env:FOO=1, rvm:2.0.0, scala:2.10.1",
|
74
|
-
"env:BAR=2, rvm:2.0.0, scala:2.9.2",
|
75
|
-
"env:FOO=1, rvm:2.0.0, scala:2.9.2"
|
76
|
-
]
|
77
|
-
end
|
78
|
-
|
79
|
-
context "without matrix" do
|
80
|
-
let(:attributes) { {
|
81
|
-
rvm: %w{ 2.0.0 },
|
82
|
-
} }
|
83
|
-
|
84
|
-
it { should eq ['rvm:2.0.0'] }
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "attributes_for_new_travises_with_merged_env" do
|
92
|
-
subject { matrix.attributes_for_new_travises_with_merged_env }
|
93
|
-
|
94
|
-
before do
|
95
|
-
attributes.merge!(
|
96
|
-
env: {
|
97
|
-
"global" => "FOO=1",
|
98
|
-
"matrix" => %w{ BAR=1 BAR=2 }
|
99
|
-
}
|
100
|
-
)
|
101
|
-
end
|
102
|
-
|
103
|
-
it { should have(12).items }
|
104
|
-
|
105
|
-
it "should merge matrix env to global env" do
|
106
|
-
expect(subject.map{|i| i["env"]["global"] }.uniq.sort).to eq([["BAR=1", "FOO=1"], ["BAR=2", "FOO=1"]])
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context 'attributes_for_new_travises' do
|
111
|
-
subject { matrix.attributes_for_new_travises }
|
112
|
-
|
113
|
-
it { should have(12).items }
|
114
|
-
|
115
|
-
its(:first) { should eq("rvm" => "1.8.7",
|
116
|
-
"scala" => "2.10.1",
|
117
|
-
"env" => "BAR=2") }
|
118
|
-
its(:last) { should eq("rvm" => "2.0.0",
|
119
|
-
"scala" => "2.9.2",
|
120
|
-
"env" => "FOO=1") }
|
121
|
-
end
|
122
|
-
|
123
|
-
context 'extract_pair_of_key_and_values' do
|
124
|
-
subject { matrix.extract_pair_of_key_and_values }
|
125
|
-
it {
|
126
|
-
should eq [
|
127
|
-
["rvm", %w{ 1.8.7 1.9.3 2.0.0 }],
|
128
|
-
["scala", %w{ 2.9.2 2.10.1 }],
|
129
|
-
["env", %w{ FOO=1 BAR=2 }]
|
130
|
-
]
|
131
|
-
}
|
132
|
-
end
|
133
|
-
|
134
|
-
context "permutate_and_build_values" do
|
135
|
-
subject { format_values matrix.permutate_and_build_values }
|
136
|
-
let(:expected) { [
|
137
|
-
%w{env:BAR=2 rvm:1.8.7 scala:2.10.1},
|
138
|
-
%w{env:BAR=2 rvm:1.8.7 scala:2.9.2},
|
139
|
-
%w{env:BAR=2 rvm:1.9.3 scala:2.10.1},
|
140
|
-
%w{env:BAR=2 rvm:1.9.3 scala:2.9.2},
|
141
|
-
%w{env:BAR=2 rvm:2.0.0 scala:2.10.1},
|
142
|
-
%w{env:BAR=2 rvm:2.0.0 scala:2.9.2},
|
143
|
-
%w{env:FOO=1 rvm:1.8.7 scala:2.10.1},
|
144
|
-
%w{env:FOO=1 rvm:1.8.7 scala:2.9.2},
|
145
|
-
%w{env:FOO=1 rvm:1.9.3 scala:2.10.1},
|
146
|
-
%w{env:FOO=1 rvm:1.9.3 scala:2.9.2},
|
147
|
-
%w{env:FOO=1 rvm:2.0.0 scala:2.10.1},
|
148
|
-
%w{env:FOO=1 rvm:2.0.0 scala:2.9.2},
|
149
|
-
] }
|
150
|
-
|
151
|
-
it { should eq expected }
|
152
|
-
|
153
|
-
context "with empty keys" do
|
154
|
-
let(:attributes) { {
|
155
|
-
env: %w{ FOO=1 BAR=2 },
|
156
|
-
rvm: %w{ 1.8.7 1.9.3 2.0.0 },
|
157
|
-
scala: %w{ 2.9.2 2.10.1 },
|
158
|
-
java: [],
|
159
|
-
go: nil
|
160
|
-
} }
|
161
|
-
it { should eq expected }
|
162
|
-
end
|
163
|
-
|
164
|
-
context "with one key" do
|
165
|
-
let(:attributes) { {
|
166
|
-
rvm: %w{ 1.9.3 2.0.0 },
|
167
|
-
} }
|
168
|
-
let(:expected) {[
|
169
|
-
%w{ rvm:1.9.3 },
|
170
|
-
%w{ rvm:2.0.0 }
|
171
|
-
]}
|
172
|
-
it { should eq expected }
|
173
|
-
end
|
174
|
-
|
175
|
-
context "without matrix" do
|
176
|
-
let(:attributes) { {
|
177
|
-
rvm: %w{ 2.0.0 },
|
178
|
-
} }
|
179
|
-
let(:expected) {[
|
180
|
-
%w{ rvm:2.0.0 }
|
181
|
-
]}
|
182
|
-
it { should eq expected }
|
183
|
-
end
|
184
|
-
|
185
|
-
def format_values(values)
|
186
|
-
values.map{|i| i.map(&:to_s).sort }.sort
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
data/spec/lib/travis_spec.rb
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Evrone::CI::Router::Travis do
|
4
|
-
let(:content) { YAML.load fixture('travis.yml') }
|
5
|
-
let(:travis) { described_class.from_attributes content }
|
6
|
-
subject { travis }
|
7
|
-
|
8
|
-
its(:attributes) { should be }
|
9
|
-
its(:rvm) { should eq %w{ 2.0.0 } }
|
10
|
-
its(:before_script) { should eq ["echo before_script"] }
|
11
|
-
its(:script) { should eq ["RAILS_ENV=test ls -1 && echo DONE!"] }
|
12
|
-
|
13
|
-
context "merge" do
|
14
|
-
let(:new_attrs) { { rvm: "replaced" } }
|
15
|
-
subject{ travis.merge new_attrs }
|
16
|
-
|
17
|
-
it "should build a new travis instance" do
|
18
|
-
expect(subject).to be_an_instance_of(described_class)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should replace attributes" do
|
22
|
-
expect(subject.attributes["rvm"]).to eq %w{ replaced }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "(serialization)" do
|
27
|
-
|
28
|
-
context "build new instance" do
|
29
|
-
let(:expected) { {
|
30
|
-
"rvm" => ["2.0.0"],
|
31
|
-
"before_script" => ["echo before_script"],
|
32
|
-
"script" => ["RAILS_ENV=test ls -1 && echo DONE!"],
|
33
|
-
"env" => {
|
34
|
-
"matrix" => [],
|
35
|
-
"global" => []
|
36
|
-
}
|
37
|
-
} }
|
38
|
-
|
39
|
-
context "from_yaml" do
|
40
|
-
subject { described_class.from_yaml(fixture('travis.yml')).attributes }
|
41
|
-
it { should eq expected }
|
42
|
-
end
|
43
|
-
|
44
|
-
context "form_file" do
|
45
|
-
subject { described_class.from_file('fixtures/travis.yml').attributes }
|
46
|
-
it { should eq expected }
|
47
|
-
end
|
48
|
-
|
49
|
-
context "from_attributes" do
|
50
|
-
let(:attrs) {{
|
51
|
-
rvm: "2.0.0",
|
52
|
-
before_script: "echo before_script",
|
53
|
-
script: "RAILS_ENV=test ls -1 && echo DONE!"
|
54
|
-
}}
|
55
|
-
subject { described_class.from_attributes(attrs).attributes }
|
56
|
-
it { should eq expected }
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context ".to_yaml" do
|
61
|
-
subject { travis.to_yaml }
|
62
|
-
it { should eq travis.attributes.to_yaml }
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "to_script_builder" do
|
67
|
-
let(:build) { create :build }
|
68
|
-
subject { travis.to_script_builder build }
|
69
|
-
it { should be }
|
70
|
-
end
|
71
|
-
|
72
|
-
context "to_matrix_s" do
|
73
|
-
subject { travis.to_matrix_s }
|
74
|
-
it { should eq 'rvm:2.0.0' }
|
75
|
-
|
76
|
-
context "when many items" do
|
77
|
-
before do
|
78
|
-
mock(travis).rvm { %w{ 1.9.3 2.0.0 } }
|
79
|
-
mock(travis).scala { %w{ 2.10.1 } }
|
80
|
-
end
|
81
|
-
it { should eq "rvm:1.9.3, rvm:2.0.0, scala:2.10.1" }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
context "matrix_keys" do
|
86
|
-
subject { travis.matrix_keys }
|
87
|
-
it { should eq %w{ rvm:2.0.0 } }
|
88
|
-
|
89
|
-
context "when many items" do
|
90
|
-
before do
|
91
|
-
mock(travis).rvm { %w{ 1.9.3 2.0.0 } }
|
92
|
-
mock(travis).scala { %w{ 2.10.1 } }
|
93
|
-
end
|
94
|
-
it { should eq %w{ rvm:1.9.3 rvm:2.0.0 scala:2.10.1 }}
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
it "empty attributes must be empty Array" do
|
100
|
-
expect(travis.scala).to eq([])
|
101
|
-
end
|
102
|
-
|
103
|
-
context "normalize_attributes" do
|
104
|
-
described_class::AS_ARRAY.each do |m|
|
105
|
-
context "convert #{m} attribute to Array" do
|
106
|
-
let(:content) { { m => m } }
|
107
|
-
subject { travis.__send__(m) }
|
108
|
-
it { should eq([m]) }
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "convert hash keys to strings" do
|
113
|
-
let(:content) { { rvm: "rvm" } }
|
114
|
-
subject { travis.attributes }
|
115
|
-
it { should include("rvm" => %w{rvm}) }
|
116
|
-
end
|
117
|
-
|
118
|
-
context "build env hash" do
|
119
|
-
subject { travis.attributes["env"] }
|
120
|
-
|
121
|
-
context "from String" do
|
122
|
-
let(:content) { { env: "FOO" } }
|
123
|
-
it { should eq( "global" => [], "matrix" => %w{ FOO } ) }
|
124
|
-
end
|
125
|
-
|
126
|
-
context "from Array" do
|
127
|
-
let(:content) { { env: %w{ FOO BAR } } }
|
128
|
-
it { should eq( 'global' => [], 'matrix' => %w{ FOO BAR } ) }
|
129
|
-
end
|
130
|
-
|
131
|
-
context "from empty Hash" do
|
132
|
-
let(:content) { { env: {} } }
|
133
|
-
it { should eq( 'global' => [], 'matrix' => [] ) }
|
134
|
-
end
|
135
|
-
|
136
|
-
context "from Hash" do
|
137
|
-
let(:content) { { env: { "global" => "1", 'matrix' => '2' } } }
|
138
|
-
it { should eq( 'global' => %w{1}, 'matrix' => %w{2} ) }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context "env" do
|
144
|
-
let(:content) { { env: env } }
|
145
|
-
subject { travis.env }
|
146
|
-
|
147
|
-
context "when attributes[env] is Array" do
|
148
|
-
let(:env) { %w{ FOO=1 BAR=2 } }
|
149
|
-
it { should eq("matrix"=>["FOO=1", "BAR=2"], "global"=>[]) }
|
150
|
-
end
|
151
|
-
|
152
|
-
context "when attributes[env] is Hash" do
|
153
|
-
let(:env) { { "matrix" => %w{ BAZ=1 } } }
|
154
|
-
it { should eq("matrix"=>["BAZ=1"], "global"=>[]) }
|
155
|
-
end
|
156
|
-
|
157
|
-
context "when attributes[env] is empty" do
|
158
|
-
let(:env) { {} }
|
159
|
-
it { should eq("matrix"=>[], "global"=>[]) }
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context "global_env" do
|
164
|
-
let(:content) { { env: env } }
|
165
|
-
subject { travis.global_env }
|
166
|
-
|
167
|
-
context "when attributes[env] is Array" do
|
168
|
-
let(:env) { %w{ FOO=1 } }
|
169
|
-
it { should eq([]) }
|
170
|
-
end
|
171
|
-
|
172
|
-
context "when attributes[env] is Hash" do
|
173
|
-
let(:env) { { "global" => %w{ FOO=1 } } }
|
174
|
-
it { should eq %w{ FOO=1 } }
|
175
|
-
end
|
176
|
-
|
177
|
-
context "when attributes[env] is empty" do
|
178
|
-
let(:env) { {} }
|
179
|
-
it { should eq([]) }
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
end
|