vx-build_configuration 0.2.0.pre28

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9f1d298c0ad670107dfd295924ae5565fda5f971
4
+ data.tar.gz: 89ff0cdff4db1211561086db4af51013c582fdad
5
+ SHA512:
6
+ metadata.gz: 2992c8d65e22651378e36701d41e828bd861c0dceeca96abb7b47650db87998ef7bfcc272583b01350e92337f4e8abd538fe2f555a35896bc0b703cdbaecbc5d
7
+ data.tar.gz: 79a59ce92743ee85d9a8824d87d90f1f5c4cdefb30ae74609da4f9d863624e769216a47f2b7a8c4e067da70782f6901901b5659a6f81fc9e23fd9cba75d95700
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --order=rand
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vx-build_configuration.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,276 @@
1
+ Copyright (c) 2013 Dmitry Galinsky
2
+
3
+ The GNU General Public License, Version 2, June 1991 (GPLv2)
4
+ ============================================================
5
+
6
+ > Copyright (C) 1989, 1991 Free Software Foundation, Inc.
7
+ > 59 Temple Place, Suite 330
8
+ > Boston, MA 02111-1307 USA
9
+
10
+ Everyone is permitted to copy and distribute verbatim copies of this license
11
+ document, but changing it is not allowed.
12
+
13
+
14
+ Preamble
15
+ --------
16
+
17
+ The licenses for most software are designed to take away your freedom to share
18
+ and change it. By contrast, the GNU General Public License is intended to
19
+ guarantee your freedom to share and change free software--to make sure the
20
+ software is free for all its users. This General Public License applies to most
21
+ of the Free Software Foundation's software and to any other program whose
22
+ authors commit to using it. (Some other Free Software Foundation software is
23
+ covered by the GNU Library General Public License instead.) You can apply it to
24
+ your programs, too.
25
+
26
+ When we speak of free software, we are referring to freedom, not price. Our
27
+ General Public Licenses are designed to make sure that you have the freedom to
28
+ distribute copies of free software (and charge for this service if you wish),
29
+ that you receive source code or can get it if you want it, that you can change
30
+ the software or use pieces of it in new free programs; and that you know you can
31
+ do these things.
32
+
33
+ To protect your rights, we need to make restrictions that forbid anyone to deny
34
+ you these rights or to ask you to surrender the rights. These restrictions
35
+ translate to certain responsibilities for you if you distribute copies of the
36
+ software, or if you modify it.
37
+
38
+ For example, if you distribute copies of such a program, whether gratis or for a
39
+ fee, you must give the recipients all the rights that you have. You must make
40
+ sure that they, too, receive or can get the source code. And you must show them
41
+ these terms so they know their rights.
42
+
43
+ We protect your rights with two steps: (1) copyright the software, and (2) offer
44
+ you this license which gives you legal permission to copy, distribute and/or
45
+ modify the software.
46
+
47
+ Also, for each author's protection and ours, we want to make certain that
48
+ everyone understands that there is no warranty for this free software. If the
49
+ software is modified by someone else and passed on, we want its recipients to
50
+ know that what they have is not the original, so that any problems introduced by
51
+ others will not reflect on the original authors' reputations.
52
+
53
+ Finally, any free program is threatened constantly by software patents. We wish
54
+ to avoid the danger that redistributors of a free program will individually
55
+ obtain patent licenses, in effect making the program proprietary. To prevent
56
+ this, we have made it clear that any patent must be licensed for everyone's free
57
+ use or not licensed at all.
58
+
59
+ The precise terms and conditions for copying, distribution and modification
60
+ follow.
61
+
62
+
63
+ Terms And Conditions For Copying, Distribution And Modification
64
+ ---------------------------------------------------------------
65
+ 0. This License applies to any program or other work which contains a notice
66
+ placed by the copyright holder saying it may be distributed under the terms
67
+ of this General Public License. The "Program", below, refers to any such
68
+ program or work, and a "work based on the Program" means either the Program
69
+ or any derivative work under copyright law: that is to say, a work
70
+ containing the Program or a portion of it, either verbatim or with
71
+ modifications and/or translated into another language. (Hereinafter,
72
+ translation is included without limitation in the term "modification".)
73
+ Each licensee is addressed as "you".
74
+
75
+ Activities other than copying, distribution and modification are not
76
+ covered by this License; they are outside its scope. The act of running the
77
+ Program is not restricted, and the output from the Program is covered only
78
+ if its contents constitute a work based on the Program (independent of
79
+ having been made by running the Program). Whether that is true depends on
80
+ what the Program does.
81
+
82
+ 1. You may copy and distribute verbatim copies of the Program's source code as
83
+ you receive it, in any medium, provided that you conspicuously and
84
+ appropriately publish on each copy an appropriate copyright notice and
85
+ disclaimer of warranty; keep intact all the notices that refer to this
86
+ License and to the absence of any warranty; and give any other recipients
87
+ of the Program a copy of this License along with the Program.
88
+
89
+ You may charge a fee for the physical act of transferring a copy, and you
90
+ may at your option offer warranty protection in exchange for a fee.
91
+
92
+ 2. You may modify your copy or copies of the Program or any portion of it,
93
+ thus forming a work based on the Program, and copy and distribute such
94
+ modifications or work under the terms of Section 1 above, provided that you
95
+ also meet all of these conditions:
96
+
97
+ a) You must cause the modified files to carry prominent notices stating
98
+ that you changed the files and the date of any change.
99
+
100
+ b) You must cause any work that you distribute or publish, that in whole
101
+ or in part contains or is derived from the Program or any part thereof,
102
+ to be licensed as a whole at no charge to all third parties under the
103
+ terms of this License.
104
+
105
+ c) If the modified program normally reads commands interactively when run,
106
+ you must cause it, when started running for such interactive use in the
107
+ most ordinary way, to print or display an announcement including an
108
+ appropriate copyright notice and a notice that there is no warranty (or
109
+ else, saying that you provide a warranty) and that users may
110
+ redistribute the program under these conditions, and telling the user
111
+ how to view a copy of this License. (Exception: if the Program itself
112
+ is interactive but does not normally print such an announcement, your
113
+ work based on the Program is not required to print an announcement.)
114
+
115
+ These requirements apply to the modified work as a whole. If identifiable
116
+ sections of that work are not derived from the Program, and can be
117
+ reasonably considered independent and separate works in themselves, then
118
+ this License, and its terms, do not apply to those sections when you
119
+ distribute them as separate works. But when you distribute the same
120
+ sections as part of a whole which is a work based on the Program, the
121
+ distribution of the whole must be on the terms of this License, whose
122
+ permissions for other licensees extend to the entire whole, and thus to
123
+ each and every part regardless of who wrote it.
124
+
125
+ Thus, it is not the intent of this section to claim rights or contest your
126
+ rights to work written entirely by you; rather, the intent is to exercise
127
+ the right to control the distribution of derivative or collective works
128
+ based on the Program.
129
+
130
+ In addition, mere aggregation of another work not based on the Program with
131
+ the Program (or with a work based on the Program) on a volume of a storage
132
+ or distribution medium does not bring the other work under the scope of
133
+ this License.
134
+
135
+ 3. You may copy and distribute the Program (or a work based on it, under
136
+ Section 2) in object code or executable form under the terms of Sections 1
137
+ and 2 above provided that you also do one of the following:
138
+
139
+ a) Accompany it with the complete corresponding machine-readable source
140
+ code, which must be distributed under the terms of Sections 1 and 2
141
+ above on a medium customarily used for software interchange; or,
142
+
143
+ b) Accompany it with a written offer, valid for at least three years, to
144
+ give any third party, for a charge no more than your cost of physically
145
+ performing source distribution, a complete machine-readable copy of the
146
+ corresponding source code, to be distributed under the terms of
147
+ Sections 1 and 2 above on a medium customarily used for software
148
+ interchange; or,
149
+
150
+ c) Accompany it with the information you received as to the offer to
151
+ distribute corresponding source code. (This alternative is allowed only
152
+ for noncommercial distribution and only if you received the program in
153
+ object code or executable form with such an offer, in accord with
154
+ Subsection b above.)
155
+
156
+ The source code for a work means the preferred form of the work for making
157
+ modifications to it. For an executable work, complete source code means all
158
+ the source code for all modules it contains, plus any associated interface
159
+ definition files, plus the scripts used to control compilation and
160
+ installation of the executable. However, as a special exception, the source
161
+ code distributed need not include anything that is normally distributed (in
162
+ either source or binary form) with the major components (compiler, kernel,
163
+ and so on) of the operating system on which the executable runs, unless
164
+ that component itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering access to
167
+ copy from a designated place, then offering equivalent access to copy the
168
+ source code from the same place counts as distribution of the source code,
169
+ even though third parties are not compelled to copy the source along with
170
+ the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program except as
173
+ expressly provided under this License. Any attempt otherwise to copy,
174
+ modify, sublicense or distribute the Program is void, and will
175
+ automatically terminate your rights under this License. However, parties
176
+ who have received copies, or rights, from you under this License will not
177
+ have their licenses terminated so long as such parties remain in full
178
+ compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not signed it.
181
+ However, nothing else grants you permission to modify or distribute the
182
+ Program or its derivative works. These actions are prohibited by law if you
183
+ do not accept this License. Therefore, by modifying or distributing the
184
+ Program (or any work based on the Program), you indicate your acceptance of
185
+ this License to do so, and all its terms and conditions for copying,
186
+ distributing or modifying the Program or works based on it.
187
+
188
+ 6. Each time you redistribute the Program (or any work based on the Program),
189
+ the recipient automatically receives a license from the original licensor
190
+ to copy, distribute or modify the Program subject to these terms and
191
+ conditions. You may not impose any further restrictions on the recipients'
192
+ exercise of the rights granted herein. You are not responsible for
193
+ enforcing compliance by third parties to this License.
194
+
195
+ 7. If, as a consequence of a court judgment or allegation of patent
196
+ infringement or for any other reason (not limited to patent issues),
197
+ conditions are imposed on you (whether by court order, agreement or
198
+ otherwise) that contradict the conditions of this License, they do not
199
+ excuse you from the conditions of this License. If you cannot distribute so
200
+ as to satisfy simultaneously your obligations under this License and any
201
+ other pertinent obligations, then as a consequence you may not distribute
202
+ the Program at all. For example, if a patent license would not permit
203
+ royalty-free redistribution of the Program by all those who receive copies
204
+ directly or indirectly through you, then the only way you could satisfy
205
+ both it and this License would be to refrain entirely from distribution of
206
+ the Program.
207
+
208
+ If any portion of this section is held invalid or unenforceable under any
209
+ particular circumstance, the balance of the section is intended to apply
210
+ and the section as a whole is intended to apply in other circumstances.
211
+
212
+ It is not the purpose of this section to induce you to infringe any patents
213
+ or other property right claims or to contest validity of any such claims;
214
+ this section has the sole purpose of protecting the integrity of the free
215
+ software distribution system, which is implemented by public license
216
+ practices. Many people have made generous contributions to the wide range
217
+ of software distributed through that system in reliance on consistent
218
+ application of that system; it is up to the author/donor to decide if he or
219
+ she is willing to distribute software through any other system and a
220
+ licensee cannot impose that choice.
221
+
222
+ This section is intended to make thoroughly clear what is believed to be a
223
+ consequence of the rest of this License.
224
+
225
+ 8. If the distribution and/or use of the Program is restricted in certain
226
+ countries either by patents or by copyrighted interfaces, the original
227
+ copyright holder who places the Program under this License may add an
228
+ explicit geographical distribution limitation excluding those countries, so
229
+ that distribution is permitted only in or among countries not thus excluded.
230
+ In such case, this License incorporates the limitation as if written in
231
+ the body of this License.
232
+
233
+ 9. The Free Software Foundation may publish revised and/or new versions of the
234
+ General Public License from time to time. Such new versions will be similar
235
+ in spirit to the present version, but may differ in detail to address new
236
+ problems or concerns.
237
+
238
+ Each version is given a distinguishing version number. If the Program
239
+ specifies a version number of this License which applies to it and "any
240
+ later version", you have the option of following the terms and conditions
241
+ either of that version or of any later version published by the Free
242
+ Software Foundation. If the Program does not specify a version number of
243
+ this License, you may choose any version ever published by the Free
244
+ Software Foundation.
245
+
246
+ 10. If you wish to incorporate parts of the Program into other free programs
247
+ whose distribution conditions are different, write to the author to ask for
248
+ permission. For software which is copyrighted by the Free Software
249
+ Foundation, write to the Free Software Foundation; we sometimes make
250
+ exceptions for this. Our decision will be guided by the two goals of
251
+ preserving the free status of all derivatives of our free software and of
252
+ promoting the sharing and reuse of software generally.
253
+
254
+
255
+ No Warranty
256
+ -----------
257
+
258
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
259
+ THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
260
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
261
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
262
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
263
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
264
+ THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
265
+ PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
266
+ CORRECTION.
267
+
268
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
269
+ ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
270
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
271
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
272
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
273
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
274
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
275
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
276
+ SUCH DAMAGES.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require
4
+ require 'rspec/core/rake_task'
5
+ require "bundler/gem_tasks"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ desc "run spec"
10
+ task :default => [:spec]
11
+
12
+ desc "run travis build"
13
+ task :travis do
14
+ exec "bundle exec rake SPEC_OPTS='--format documentation'"
15
+ end
16
+
@@ -0,0 +1,106 @@
1
+ require File.expand_path("../build_configuration/version", __FILE__)
2
+ require File.expand_path("../build_configuration/constants", __FILE__)
3
+ require File.expand_path("../build_configuration/serializable", __FILE__)
4
+ require File.expand_path("../build_configuration/matrix", __FILE__)
5
+
6
+ module Vx
7
+ class BuildConfiguration
8
+
9
+ include BuildConfiguration::Serializable
10
+
11
+ attr_reader :attributes
12
+ alias_method :to_hash, :attributes
13
+
14
+ def initialize(attrs = {})
15
+ @attributes = normalize_attributes attrs
16
+ end
17
+
18
+ def [](val)
19
+ public_send(val)
20
+ end
21
+
22
+ def matrix_keys
23
+ @matrix_keys ||=
24
+ Matrix::KEYS.inject([]) do |a,k|
25
+ k_method, k_name = k.split(":")
26
+ k_name ||= k_method
27
+ val = send(k_method)
28
+ unless val.empty?
29
+ a << val.map{|v| "#{k_name}:#{v}" }
30
+ end
31
+ a
32
+ end.flatten.sort
33
+ end
34
+
35
+ def to_matrix_s
36
+ @to_matrix_s ||= matrix_keys.join(", ")
37
+ end
38
+
39
+ def to_script_builder(build)
40
+ ScriptBuilder.new(build, self)
41
+ end
42
+
43
+ def env
44
+ attributes["env"]
45
+ end
46
+
47
+ def matrix_env
48
+ attributes["env"]["matrix"]
49
+ end
50
+
51
+ def global_env
52
+ attributes["env"]["global"]
53
+ end
54
+
55
+ AS_ARRAY.each do |m|
56
+ define_method m do
57
+ @attributes[m] || []
58
+ end
59
+ end
60
+
61
+ def merge(attrs = {})
62
+ self.class.from_attributes self.attributes.merge(attrs)
63
+ end
64
+
65
+ private
66
+
67
+ def normalize_attributes(attributes)
68
+ attributes = attributes.inject({}) do |a,row|
69
+ k,v = row
70
+ if AS_ARRAY.include?(k.to_s)
71
+ v = Array(v)
72
+ end
73
+ a[k.to_s] = v
74
+ a
75
+ end
76
+ normalize_env_attribute attributes
77
+ end
78
+
79
+ def normalize_env_attribute(attributes)
80
+ env = (attributes['env'] || {}) .dup
81
+ case env
82
+ when Hash
83
+ attributes["env"] = {
84
+ "matrix" => Array(env['matrix']),
85
+ "global" => Array(env['global'])
86
+ }
87
+ else
88
+ attributes['env'] = {
89
+ "matrix" => Array(env).map(&:to_s),
90
+ "global" => []
91
+ }
92
+ end
93
+ freeze_normalized_attributes attributes
94
+ end
95
+
96
+ def freeze_normalized_attributes(attributes)
97
+ attributes.freeze
98
+ attributes['env'].freeze
99
+ attributes['env']['global'].freeze
100
+ attributes['env']['matrix'].freeze
101
+ attributes
102
+ end
103
+
104
+ end
105
+ end
106
+
@@ -0,0 +1,9 @@
1
+ module Vx
2
+ class BuildConfiguration
3
+
4
+ LANGS = %w{ rvm scala java go }.freeze
5
+ KEYS = %w{ before_script script }.freeze
6
+ AS_ARRAY = (KEYS + LANGS).freeze
7
+
8
+ end
9
+ end
@@ -0,0 +1,111 @@
1
+ module Vx
2
+ class BuildConfiguration
3
+ class Matrix
4
+
5
+ KEYS = (BuildConfiguration::LANGS + %w{ matrix_env:env }).freeze
6
+ NOT_MATRIX_KEYS = %w{ script before_script }
7
+
8
+ attr_reader :source
9
+
10
+ def initialize(build_configuration)
11
+ @source = build_configuration
12
+ end
13
+
14
+ def keys
15
+ extract_pair_of_key_and_values.map(&:first).sort
16
+ end
17
+
18
+ def configurations
19
+ attributes_for_new_configurations_with_merged_env.map do |attrs|
20
+ attrs = attrs.merge(
21
+ NOT_MATRIX_KEYS.inject({}) do |a,v|
22
+ a[v] = source.public_send(v)
23
+ a
24
+ end
25
+ )
26
+ BuildConfiguration.new attrs
27
+ end
28
+ end
29
+
30
+ def attributes_for_new_configurations_with_merged_env
31
+ attrs = attributes_for_new_configurations
32
+ attrs = [{}] if attrs.empty?
33
+ attrs.map do |a|
34
+ e = a["env"]
35
+ a["env"] = {
36
+ "global" => Array(e) + source.global_env,
37
+ "matrix" => e
38
+ }
39
+ a
40
+ end
41
+ attrs
42
+ end
43
+
44
+ def attributes_for_new_configurations
45
+ permutate_and_build_values.inject([]) do |ac, values|
46
+ ac << values.inject({}) do |a,val|
47
+ a[val.key] = val.value
48
+ a
49
+ end
50
+ ac
51
+ end
52
+ end
53
+
54
+ def permutate_and_build_values
55
+ values = extract_pair_of_key_and_values.map do |key, vals|
56
+ vals.map{|it| Value.new(key, it) }
57
+ end
58
+ if matrix_values?(values)
59
+ array_permutations(values).map do |it|
60
+ if it.is_a?(Array)
61
+ it.flatten
62
+ else
63
+ [it]
64
+ end
65
+ end
66
+ else
67
+ [values.flatten]
68
+ end.sort_by(&:to_s)
69
+ end
70
+
71
+ def extract_pair_of_key_and_values
72
+ KEYS.map.inject([]) do |a, k|
73
+ k_method, k_name = k.split(":")
74
+ k_name ||= k_method
75
+
76
+ if (val = source[k_method]) && !val.empty?
77
+ a << [k_name, val]
78
+ end
79
+ a
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def matrix_values?(values)
86
+ !values.all?{|i| i.size == 1 }
87
+ end
88
+
89
+ def array_permutations array, index=0
90
+ # index is 0 by default : start at the beginning, more elegant.
91
+ return array[-1] if index == array.size - 1 # Return last element if at end.
92
+
93
+ result = []
94
+
95
+ array[index].each do |element| # For each array
96
+ array_permutations(array, index + 1).each do |x| # Permute permute permute
97
+ result << [element, x]
98
+ end
99
+ end
100
+ result
101
+ end
102
+
103
+ Value = Struct.new(:key, :value) do
104
+ def to_s
105
+ [key, value].join(":")
106
+ end
107
+ end
108
+
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,41 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ module Vx
5
+ class BuildConfiguration
6
+
7
+ module Serializable
8
+
9
+ def self.included(base)
10
+ base.extend ClassMethods
11
+ end
12
+
13
+ def to_yaml
14
+ YAML.dump(attributes)
15
+ end
16
+
17
+ def to_hash
18
+ attributes
19
+ end
20
+
21
+ module ClassMethods
22
+
23
+ def from_file(file)
24
+ if File.readable? file
25
+ from_yaml File.read(file)
26
+ end
27
+ end
28
+
29
+ def from_yaml(yaml)
30
+ from_attributes YAML.load(yaml)
31
+ end
32
+
33
+ def from_attributes(attrs)
34
+ BuildConfiguration.new attrs
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ module Vx
2
+ class BuildConfiguration
3
+ VERSION = "0.2.0.pre28"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 2.0.0
3
+ before_script:
4
+ - "echo before_script"
5
+ script: "RAILS_ENV=test ls -1 && echo DONE!"
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - "2.0.0"
4
+
5
+ env:
6
+ - DB=postgresql
7
+
8
+ before_script:
9
+ - cp config/samples/secret_token.rb config/initializers/secret_token.rb
10
+ - cp config/database.travis.yml config/database.yml
11
+ - bundle exec rake db:setup
12
+
13
+ script:
14
+ - bundle exec rake
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vx::BuildConfiguration do
4
+ let(:content) { YAML.load fixture('travis.yml') }
5
+ let(:config) { described_class.from_attributes content }
6
+ subject { config }
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{ config.merge new_attrs }
16
+
17
+ it "should build a new BuildConfiguration 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('spec/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 { config.to_yaml }
62
+ it { should eq config.attributes.to_yaml }
63
+ end
64
+ end
65
+
66
+ context "to_matrix_s" do
67
+ subject { config.to_matrix_s }
68
+ it { should eq 'rvm:2.0.0' }
69
+
70
+ context "when many items" do
71
+ before do
72
+ mock(config).rvm { %w{ 1.9.3 2.0.0 } }
73
+ mock(config).scala { %w{ 2.10.1 } }
74
+ end
75
+ it { should eq "rvm:1.9.3, rvm:2.0.0, scala:2.10.1" }
76
+ end
77
+ end
78
+
79
+ context "matrix_keys" do
80
+ subject { config.matrix_keys }
81
+ it { should eq %w{ rvm:2.0.0 } }
82
+
83
+ context "when many items" do
84
+ before do
85
+ mock(config).rvm { %w{ 1.9.3 2.0.0 } }
86
+ mock(config).scala { %w{ 2.10.1 } }
87
+ end
88
+ it { should eq %w{ rvm:1.9.3 rvm:2.0.0 scala:2.10.1 }}
89
+ end
90
+ end
91
+
92
+
93
+ it "empty attributes must be empty Array" do
94
+ expect(config.scala).to eq([])
95
+ end
96
+
97
+ context "normalize_attributes" do
98
+ described_class::AS_ARRAY.each do |m|
99
+ context "convert #{m} attribute to Array" do
100
+ let(:content) { { m => m } }
101
+ subject { config.__send__(m) }
102
+ it { should eq([m]) }
103
+ end
104
+ end
105
+
106
+ context "convert hash keys to strings" do
107
+ let(:content) { { rvm: "rvm" } }
108
+ subject { config.attributes }
109
+ it { should include("rvm" => %w{rvm}) }
110
+ end
111
+
112
+ context "build env hash" do
113
+ subject { config.attributes["env"] }
114
+
115
+ context "from String" do
116
+ let(:content) { { env: "FOO" } }
117
+ it { should eq( "global" => [], "matrix" => %w{ FOO } ) }
118
+ end
119
+
120
+ context "from Array" do
121
+ let(:content) { { env: %w{ FOO BAR } } }
122
+ it { should eq( 'global' => [], 'matrix' => %w{ FOO BAR } ) }
123
+ end
124
+
125
+ context "from empty Hash" do
126
+ let(:content) { { env: {} } }
127
+ it { should eq( 'global' => [], 'matrix' => [] ) }
128
+ end
129
+
130
+ context "from Hash" do
131
+ let(:content) { { env: { "global" => "1", 'matrix' => '2' } } }
132
+ it { should eq( 'global' => %w{1}, 'matrix' => %w{2} ) }
133
+ end
134
+ end
135
+ end
136
+
137
+ context "env" do
138
+ let(:content) { { env: env } }
139
+ subject { config.env }
140
+
141
+ context "when attributes[env] is Array" do
142
+ let(:env) { %w{ FOO=1 BAR=2 } }
143
+ it { should eq("matrix"=>["FOO=1", "BAR=2"], "global"=>[]) }
144
+ end
145
+
146
+ context "when attributes[env] is Hash" do
147
+ let(:env) { { "matrix" => %w{ BAZ=1 } } }
148
+ it { should eq("matrix"=>["BAZ=1"], "global"=>[]) }
149
+ end
150
+
151
+ context "when attributes[env] is empty" do
152
+ let(:env) { {} }
153
+ it { should eq("matrix"=>[], "global"=>[]) }
154
+ end
155
+ end
156
+
157
+ context "global_env" do
158
+ let(:content) { { env: env } }
159
+ subject { config.global_env }
160
+
161
+ context "when attributes[env] is Array" do
162
+ let(:env) { %w{ FOO=1 } }
163
+ it { should eq([]) }
164
+ end
165
+
166
+ context "when attributes[env] is Hash" do
167
+ let(:env) { { "global" => %w{ FOO=1 } } }
168
+ it { should eq %w{ FOO=1 } }
169
+ end
170
+
171
+ context "when attributes[env] is empty" do
172
+ let(:env) { {} }
173
+ it { should eq([]) }
174
+ end
175
+ end
176
+
177
+ end
@@ -0,0 +1,201 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+
4
+ describe Vx::BuildConfiguration::Matrix 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(:config) { Vx::BuildConfiguration.from_attributes attributes }
13
+ let(:matrix) { described_class.new config }
14
+
15
+ subject { matrix }
16
+
17
+ context "just created" do
18
+ its(:source) { should eq config }
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 'configurations' do
32
+ subject { matrix.configurations }
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 "with one env and one rvm key" do
56
+ let(:config) { Vx::BuildConfiguration.from_file fixture_path("travis_bug_1.yml") }
57
+
58
+ it{ should have(1).item }
59
+
60
+ context "attributes" do
61
+ subject { matrix.configurations.map(&:to_matrix_s) }
62
+
63
+ it { should eq ["env:DB=postgresql, rvm:2.0.0"] }
64
+ end
65
+ end
66
+
67
+ context "values" do
68
+
69
+ it { should have(12).items }
70
+
71
+ context "attributes" do
72
+ subject { matrix.configurations.map(&:to_matrix_s) }
73
+
74
+ it do
75
+ should eq [
76
+ "env:BAR=2, rvm:1.8.7, scala:2.10.1",
77
+ "env:FOO=1, rvm:1.8.7, scala:2.10.1",
78
+ "env:BAR=2, rvm:1.8.7, scala:2.9.2",
79
+ "env:FOO=1, rvm:1.8.7, scala:2.9.2",
80
+ "env:BAR=2, rvm:1.9.3, scala:2.10.1",
81
+ "env:FOO=1, rvm:1.9.3, scala:2.10.1",
82
+ "env:BAR=2, rvm:1.9.3, scala:2.9.2",
83
+ "env:FOO=1, rvm:1.9.3, scala:2.9.2",
84
+ "env:BAR=2, rvm:2.0.0, scala:2.10.1",
85
+ "env:FOO=1, rvm:2.0.0, scala:2.10.1",
86
+ "env:BAR=2, rvm:2.0.0, scala:2.9.2",
87
+ "env:FOO=1, rvm:2.0.0, scala:2.9.2"
88
+ ]
89
+ end
90
+
91
+ context "without matrix" do
92
+ let(:attributes) { {
93
+ rvm: %w{ 2.0.0 },
94
+ } }
95
+
96
+ it { should eq ['rvm:2.0.0'] }
97
+ end
98
+
99
+ end
100
+ end
101
+ end
102
+
103
+ context "attributes_for_new_confgurations_with_merged_env" do
104
+ subject { matrix.attributes_for_new_configurations_with_merged_env }
105
+
106
+ before do
107
+ attributes.merge!(
108
+ env: {
109
+ "global" => "FOO=1",
110
+ "matrix" => %w{ BAR=1 BAR=2 }
111
+ }
112
+ )
113
+ end
114
+
115
+ it { should have(12).items }
116
+
117
+ it "should merge matrix env to global env" do
118
+ expect(subject.map{|i| i["env"]["global"] }.uniq.sort).to eq([["BAR=1", "FOO=1"], ["BAR=2", "FOO=1"]])
119
+ end
120
+ end
121
+
122
+ context 'attributes_for_new_configurations' do
123
+ subject { matrix.attributes_for_new_configurations }
124
+
125
+ it { should have(12).items }
126
+
127
+ its(:first) { should eq("rvm" => "1.8.7",
128
+ "scala" => "2.10.1",
129
+ "env" => "BAR=2") }
130
+ its(:last) { should eq("rvm" => "2.0.0",
131
+ "scala" => "2.9.2",
132
+ "env" => "FOO=1") }
133
+ end
134
+
135
+ context 'extract_pair_of_key_and_values' do
136
+ subject { matrix.extract_pair_of_key_and_values }
137
+ it {
138
+ should eq [
139
+ ["rvm", %w{ 1.8.7 1.9.3 2.0.0 }],
140
+ ["scala", %w{ 2.9.2 2.10.1 }],
141
+ ["env", %w{ FOO=1 BAR=2 }]
142
+ ]
143
+ }
144
+ end
145
+
146
+ context "permutate_and_build_values" do
147
+ subject { format_values matrix.permutate_and_build_values }
148
+ let(:expected) { [
149
+ %w{env:BAR=2 rvm:1.8.7 scala:2.10.1},
150
+ %w{env:BAR=2 rvm:1.8.7 scala:2.9.2},
151
+ %w{env:BAR=2 rvm:1.9.3 scala:2.10.1},
152
+ %w{env:BAR=2 rvm:1.9.3 scala:2.9.2},
153
+ %w{env:BAR=2 rvm:2.0.0 scala:2.10.1},
154
+ %w{env:BAR=2 rvm:2.0.0 scala:2.9.2},
155
+ %w{env:FOO=1 rvm:1.8.7 scala:2.10.1},
156
+ %w{env:FOO=1 rvm:1.8.7 scala:2.9.2},
157
+ %w{env:FOO=1 rvm:1.9.3 scala:2.10.1},
158
+ %w{env:FOO=1 rvm:1.9.3 scala:2.9.2},
159
+ %w{env:FOO=1 rvm:2.0.0 scala:2.10.1},
160
+ %w{env:FOO=1 rvm:2.0.0 scala:2.9.2},
161
+ ] }
162
+
163
+ it { should eq expected }
164
+
165
+ context "with empty keys" do
166
+ let(:attributes) { {
167
+ env: %w{ FOO=1 BAR=2 },
168
+ rvm: %w{ 1.8.7 1.9.3 2.0.0 },
169
+ scala: %w{ 2.9.2 2.10.1 },
170
+ java: [],
171
+ go: nil
172
+ } }
173
+ it { should eq expected }
174
+ end
175
+
176
+ context "with one key" do
177
+ let(:attributes) { {
178
+ rvm: %w{ 1.9.3 2.0.0 },
179
+ } }
180
+ let(:expected) {[
181
+ %w{ rvm:1.9.3 },
182
+ %w{ rvm:2.0.0 }
183
+ ]}
184
+ it { should eq expected }
185
+ end
186
+
187
+ context "without matrix" do
188
+ let(:attributes) { {
189
+ rvm: %w{ 2.0.0 },
190
+ } }
191
+ let(:expected) {[
192
+ %w{ rvm:2.0.0 }
193
+ ]}
194
+ it { should eq expected }
195
+ end
196
+
197
+ def format_values(values)
198
+ values.map{|i| i.map(&:to_s).sort }.sort
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path '../../lib/vx/build_configuration', __FILE__
2
+
3
+ Bundler.require(:test)
4
+ require 'rspec/autorun'
5
+
6
+ Dir[File.expand_path("../..", __FILE__) + "/spec/support/**/*.rb"].each {|f| require f}
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rr
10
+
11
+ config.before(:each) do
12
+ end
13
+ end
14
+
@@ -0,0 +1,7 @@
1
+ def fixture(name)
2
+ File.read fixture_path(name)
3
+ end
4
+
5
+ def fixture_path(name)
6
+ File.expand_path("../../fixtures/#{name}", __FILE__)
7
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require File.expand_path('../lib/vx/build_configuration/version.rb', __FILE__)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vx-build_configuration"
8
+ spec.version = Vx::BuildConfiguration::VERSION
9
+ spec.authors = ["Dmitry Galinsky"]
10
+ spec.email = ["dima.exe@gmail.com"]
11
+ spec.description = %q{ description }
12
+ spec.summary = %q{ summary }
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "rr"
25
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vx-build_configuration
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0.pre28
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Galinsky
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rr
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
+ description: ' description '
70
+ email:
71
+ - dima.exe@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - Rakefile
81
+ - lib/vx/build_configuration.rb
82
+ - lib/vx/build_configuration/constants.rb
83
+ - lib/vx/build_configuration/matrix.rb
84
+ - lib/vx/build_configuration/serializable.rb
85
+ - lib/vx/build_configuration/version.rb
86
+ - spec/fixtures/travis.yml
87
+ - spec/fixtures/travis_bug_1.yml
88
+ - spec/lib/build_configuration_spec.rb
89
+ - spec/lib/matrix_spec.rb
90
+ - spec/spec_helper.rb
91
+ - spec/support/fixture.rb
92
+ - vx-build_configuration.gemspec
93
+ homepage: ''
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>'
109
+ - !ruby/object:Gem::Version
110
+ version: 1.3.1
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.1.11
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: summary
117
+ test_files:
118
+ - spec/fixtures/travis.yml
119
+ - spec/fixtures/travis_bug_1.yml
120
+ - spec/lib/build_configuration_spec.rb
121
+ - spec/lib/matrix_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/support/fixture.rb