matrixeval-ruby 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +102 -2
- data/lib/matrixeval/ruby/target.rb +87 -0
- data/lib/matrixeval/ruby/templates/matrixeval.yml +22 -4
- data/lib/matrixeval/ruby/version.rb +1 -3
- data/lib/matrixeval/ruby.rb +5 -20
- metadata +8 -53
- data/exe/matrixeval +0 -5
- data/exe/meval +0 -5
- data/lib/matrixeval/ruby/command_line/parse_context_arguments.rb +0 -85
- data/lib/matrixeval/ruby/command_line.rb +0 -53
- data/lib/matrixeval/ruby/config/yaml.rb +0 -40
- data/lib/matrixeval/ruby/config.rb +0 -60
- data/lib/matrixeval/ruby/container.rb +0 -15
- data/lib/matrixeval/ruby/context/find_by_command_options.rb +0 -67
- data/lib/matrixeval/ruby/context.rb +0 -77
- data/lib/matrixeval/ruby/docker_compose/yaml.rb +0 -77
- data/lib/matrixeval/ruby/docker_compose.rb +0 -53
- data/lib/matrixeval/ruby/gemfile_locks.rb +0 -23
- data/lib/matrixeval/ruby/gitignore.rb +0 -54
- data/lib/matrixeval/ruby/runner.rb +0 -204
- data/lib/matrixeval/ruby/variant.rb +0 -58
- data/lib/matrixeval/ruby/vector.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b38c89479923e7c9b607eff588ef02e9b4af821899b45b3a55a995e5673c9a9f
|
4
|
+
data.tar.gz: d2984e75182192bf0c80fced8062a019754c6d1ef042b757074e014e2851c6bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec71cc460fe724eb580b95da0af5e42e9324a7f789ab951af5082871cf45a8e5906545a3ce60ec31993da95872d76ae8cdae5372ed58b5ecae603e6c4d42ced3
|
7
|
+
data.tar.gz: bf8be870710b0f433319e9be0360e69bdd23625d078661d288ef23b3b5c8cef61535e5baca49eff4013abf88a8769ab6030d7840a77f8f74fda92b452c480d7e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.4.0] - 2022-02-27
|
4
|
+
|
5
|
+
- Refactor this gem as a plugin of matrixeval
|
6
|
+
|
7
|
+
## [0.3.1] - 2022-02-21
|
8
|
+
|
9
|
+
- Add `.matrixeval/docker-compose` to `.gitignore`
|
10
|
+
|
11
|
+
## [0.3.0] - 2022-02-21
|
12
|
+
|
13
|
+
- Support add extra docker compose services and volumes
|
14
|
+
- Isolate each job with docker compose project name and network
|
15
|
+
|
3
16
|
## [0.2.2] - 2022-02-11
|
4
17
|
|
5
18
|
- Auto remove containers
|
data/README.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# matrixeval-ruby
|
2
2
|
|
3
|
-
Test your ruby code against multiple versions of dependencies like Ruby, Rails, Env ...
|
3
|
+
It's a plugin of [matrixeval](https://github.com/MatrixEval/matrixeval-ruby) for Ruby. Test your ruby code against multiple versions of dependencies like Ruby, Rails, Env ...
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- Parallel test your ruby code against multiple versions of dependencies combinations.
|
10
|
+
- Test your ruby code against a specific dependencies combination.
|
11
|
+
- Choose any docker image you like for each job.
|
12
|
+
- Easy to use CLI to speed up your development efficiency
|
4
13
|
## Installation
|
5
14
|
|
6
15
|
Add this line to your application's Gemfile:
|
@@ -22,7 +31,7 @@ Or install it yourself as:
|
|
22
31
|
Initialize
|
23
32
|
|
24
33
|
```bash
|
25
|
-
matrixeval init
|
34
|
+
matrixeval init -t ruby
|
26
35
|
```
|
27
36
|
|
28
37
|
Customize `matrixeval.yml` file and run commands like:
|
@@ -36,6 +45,97 @@ matrixeval bash
|
|
36
45
|
```
|
37
46
|
Run `matrixeval --help` for more details
|
38
47
|
|
48
|
+

|
49
|
+
|
50
|
+
### Configuration Example
|
51
|
+
|
52
|
+
Here is the configuration file `matrixeval.yml` which will auto created by `matrixeval init`
|
53
|
+
|
54
|
+
```yaml
|
55
|
+
version: 0.4
|
56
|
+
target: ruby
|
57
|
+
project_name: REPLACE_ME
|
58
|
+
parallel_workers: number_of_processors
|
59
|
+
# commands:
|
60
|
+
# - ps
|
61
|
+
# - top
|
62
|
+
# - an_additional_command
|
63
|
+
# mounts:
|
64
|
+
# - /a/path/need/to/mount:/a/path/mount/to
|
65
|
+
matrix:
|
66
|
+
ruby:
|
67
|
+
variants:
|
68
|
+
- key: 2.7
|
69
|
+
container:
|
70
|
+
image: ruby:2.7.1
|
71
|
+
- key: 3.0
|
72
|
+
default: true
|
73
|
+
container:
|
74
|
+
image: ruby:3.0.0
|
75
|
+
- key: 3.1
|
76
|
+
container:
|
77
|
+
image: ruby:3.1.0
|
78
|
+
# - key: jruby-9.3
|
79
|
+
# container:
|
80
|
+
# image: jruby:9.3
|
81
|
+
# env:
|
82
|
+
# PATH: "/opt/jruby/bin:/app/bin:/bundle/bin:$PATH"
|
83
|
+
# mounts:
|
84
|
+
# - /a/path/need/to/mount:/a/path/mount/to
|
85
|
+
|
86
|
+
# rails:
|
87
|
+
# variants:
|
88
|
+
# - key: 6.1
|
89
|
+
# default: true
|
90
|
+
# env:
|
91
|
+
# RAILS_VERSION: "~> 6.1.0"
|
92
|
+
# - key: 7.0
|
93
|
+
# env:
|
94
|
+
# RAILS_VERSION: "~> 7.0.0"
|
95
|
+
# another:
|
96
|
+
# variants:
|
97
|
+
# - key: key1
|
98
|
+
# default: true
|
99
|
+
# env:
|
100
|
+
# ENV_KEY: 1
|
101
|
+
# - key: key2
|
102
|
+
# env:
|
103
|
+
# ENV_KEY: 2
|
104
|
+
|
105
|
+
exclude:
|
106
|
+
# - ruby: 3.0
|
107
|
+
# rails: 4.2
|
108
|
+
# - ruby: jruby-9.3
|
109
|
+
# rails: 7.0
|
110
|
+
|
111
|
+
docker-compose-extend:
|
112
|
+
# services:
|
113
|
+
# postgres:
|
114
|
+
# image: postgres:12.8
|
115
|
+
# volumes:
|
116
|
+
# - postgres12:/var/lib/postgresql/data
|
117
|
+
# environment:
|
118
|
+
# POSTGRES_HOST_AUTH_METHOD: trust
|
119
|
+
|
120
|
+
# redis:
|
121
|
+
# image: redis:6.2-alpine
|
122
|
+
|
123
|
+
# volumes:
|
124
|
+
# postgres12:
|
125
|
+
```
|
126
|
+
|
127
|
+
### Gemfile configuration example
|
128
|
+
|
129
|
+
Here is an example from [ruby-trello](https://github.com/jeremytregunna/ruby-trello)
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
if active_model_version = ENV['ACTIVE_MODEL_VERSION']
|
133
|
+
gem 'activemodel', active_model_version
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
You can also check its corresponding [`matrixeval.yml`](https://github.com/jeremytregunna/ruby-trello/blob/master/matrixeval.yml)
|
138
|
+
|
39
139
|
## Development
|
40
140
|
|
41
141
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Matrixeval
|
2
|
+
module Ruby
|
3
|
+
class Target < Matrixeval::Target
|
4
|
+
|
5
|
+
def version
|
6
|
+
Matrixeval::Ruby::VERSION
|
7
|
+
end
|
8
|
+
|
9
|
+
def matrixeval_yml_template_path
|
10
|
+
Matrixeval::Ruby.root.join("lib/matrixeval/ruby/templates/matrixeval.yml")
|
11
|
+
end
|
12
|
+
|
13
|
+
def vector_key
|
14
|
+
"ruby"
|
15
|
+
end
|
16
|
+
|
17
|
+
def env(context)
|
18
|
+
{
|
19
|
+
"BUNDLE_PATH" => "/bundle",
|
20
|
+
"GEM_HOME" => "/bundle",
|
21
|
+
"BUNDLE_APP_CONFIG" => "/bundle",
|
22
|
+
"BUNDLE_BIN" => "/bundle/bin",
|
23
|
+
"PATH" => "/app/bin:/bundle/bin:$PATH"
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def mounts(context)
|
28
|
+
bundle_volume = bundle_volume(context)
|
29
|
+
|
30
|
+
[
|
31
|
+
"#{bundle_volume}:/bundle",
|
32
|
+
"../gemfile_locks/#{context.id}:/app/Gemfile.lock"
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
def volumes(context)
|
37
|
+
bundle_volume = bundle_volume(context)
|
38
|
+
|
39
|
+
{
|
40
|
+
bundle_volume => {
|
41
|
+
"name" => bundle_volume
|
42
|
+
}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def gitignore_paths
|
47
|
+
[
|
48
|
+
".matrixeval/gemfile_locks"
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def support_commands
|
53
|
+
[
|
54
|
+
'ruby', 'rake', 'rails', 'rspec', 'bundle',
|
55
|
+
'bin/rake', 'bin/rails', 'bin/rspec', 'bin/test'
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
def cli_example_lines
|
60
|
+
[
|
61
|
+
"",
|
62
|
+
"Example:",
|
63
|
+
" matrixeval --all bundle install",
|
64
|
+
" matrixeval --ruby 3.0 rspec a_spec.rb",
|
65
|
+
" matrixeval --ruby 3.1 --active_model 7.0 rake test",
|
66
|
+
" matrixeval bash"
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_files
|
71
|
+
gemfile_lock_folder = Matrixeval.working_dir.join(".matrixeval/gemfile_locks")
|
72
|
+
FileUtils.mkdir_p gemfile_lock_folder
|
73
|
+
|
74
|
+
Context.all.each do |context|
|
75
|
+
FileUtils.touch gemfile_lock_folder.join(context.id)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def bundle_volume(context)
|
82
|
+
docker_image = context.main_variant.container.image
|
83
|
+
"bundle_#{docker_image.gsub(/[^A-Za-z0-9]/,'_')}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
|
-
version: 0.
|
1
|
+
version: 0.4
|
2
2
|
target: ruby
|
3
|
+
project_name: REPLACE_ME
|
3
4
|
parallel_workers: number_of_processors
|
4
5
|
# commands:
|
5
6
|
# - ps
|
6
7
|
# - top
|
7
8
|
# - an_additional_command
|
9
|
+
# mounts:
|
10
|
+
# - /a/path/need/to/mount:/a/path/mount/to
|
8
11
|
matrix:
|
9
12
|
ruby:
|
10
|
-
# mounts:
|
11
|
-
# - /a/path/need/to/mount:/a/path/mount/to
|
12
13
|
variants:
|
13
14
|
- key: 2.7
|
14
15
|
container:
|
@@ -23,8 +24,10 @@ matrix:
|
|
23
24
|
# - key: jruby-9.3
|
24
25
|
# container:
|
25
26
|
# image: jruby:9.3
|
26
|
-
#
|
27
|
+
# env:
|
27
28
|
# PATH: "/opt/jruby/bin:/app/bin:/bundle/bin:$PATH"
|
29
|
+
# mounts:
|
30
|
+
# - /a/path/need/to/mount:/a/path/mount/to
|
28
31
|
|
29
32
|
# rails:
|
30
33
|
# variants:
|
@@ -50,3 +53,18 @@ exclude:
|
|
50
53
|
# rails: 4.2
|
51
54
|
# - ruby: jruby-9.3
|
52
55
|
# rails: 7.0
|
56
|
+
|
57
|
+
docker-compose-extend:
|
58
|
+
# services:
|
59
|
+
# postgres:
|
60
|
+
# image: postgres:12.8
|
61
|
+
# volumes:
|
62
|
+
# - postgres12:/var/lib/postgresql/data
|
63
|
+
# environment:
|
64
|
+
# POSTGRES_HOST_AUTH_METHOD: trust
|
65
|
+
|
66
|
+
# redis:
|
67
|
+
# image: redis:6.2-alpine
|
68
|
+
|
69
|
+
# volumes:
|
70
|
+
# postgres12:
|
data/lib/matrixeval/ruby.rb
CHANGED
@@ -1,29 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative
|
4
|
-
require 'rainbow'
|
5
|
-
require 'matrixeval/ruby/docker_compose'
|
6
|
-
require 'matrixeval/ruby/context'
|
7
|
-
require 'matrixeval/ruby/gemfile_locks'
|
8
|
-
require 'matrixeval/ruby/runner'
|
9
|
-
require 'matrixeval/ruby/gitignore'
|
1
|
+
require 'matrixeval'
|
2
|
+
require_relative 'ruby/version'
|
3
|
+
require_relative 'ruby/target'
|
10
4
|
|
11
5
|
module Matrixeval
|
12
6
|
module Ruby
|
13
|
-
class Error < StandardError; end
|
14
|
-
|
15
7
|
module_function
|
16
8
|
def root
|
17
9
|
Pathname.new("#{__dir__}/../..")
|
18
10
|
end
|
19
11
|
end
|
20
|
-
|
21
|
-
module_function
|
22
|
-
def start(argv)
|
23
|
-
Ruby::Runner.start(argv)
|
24
|
-
end
|
25
|
-
|
26
|
-
def working_dir
|
27
|
-
Pathname.new(Dir.getwd)
|
28
|
-
end
|
29
12
|
end
|
13
|
+
|
14
|
+
Matrixeval.register_target(:ruby, Matrixeval::Ruby::Target)
|
metadata
CHANGED
@@ -1,63 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matrixeval-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hopper Gee
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: matrixeval
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.4.2
|
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:
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: concurrent-ruby
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
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: terminal-table
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
26
|
+
version: 0.4.2
|
55
27
|
description: MatrixEval-Ruby
|
56
28
|
email:
|
57
29
|
- hopper.gee@hey.com
|
58
|
-
executables:
|
59
|
-
- matrixeval
|
60
|
-
- meval
|
30
|
+
executables: []
|
61
31
|
extensions: []
|
62
32
|
extra_rdoc_files: []
|
63
33
|
files:
|
@@ -70,24 +40,9 @@ files:
|
|
70
40
|
- bin/console
|
71
41
|
- bin/setup
|
72
42
|
- bin/test
|
73
|
-
- exe/matrixeval
|
74
|
-
- exe/meval
|
75
43
|
- lib/matrixeval/ruby.rb
|
76
|
-
- lib/matrixeval/ruby/
|
77
|
-
- lib/matrixeval/ruby/command_line/parse_context_arguments.rb
|
78
|
-
- lib/matrixeval/ruby/config.rb
|
79
|
-
- lib/matrixeval/ruby/config/yaml.rb
|
80
|
-
- lib/matrixeval/ruby/container.rb
|
81
|
-
- lib/matrixeval/ruby/context.rb
|
82
|
-
- lib/matrixeval/ruby/context/find_by_command_options.rb
|
83
|
-
- lib/matrixeval/ruby/docker_compose.rb
|
84
|
-
- lib/matrixeval/ruby/docker_compose/yaml.rb
|
85
|
-
- lib/matrixeval/ruby/gemfile_locks.rb
|
86
|
-
- lib/matrixeval/ruby/gitignore.rb
|
87
|
-
- lib/matrixeval/ruby/runner.rb
|
44
|
+
- lib/matrixeval/ruby/target.rb
|
88
45
|
- lib/matrixeval/ruby/templates/matrixeval.yml
|
89
|
-
- lib/matrixeval/ruby/variant.rb
|
90
|
-
- lib/matrixeval/ruby/vector.rb
|
91
46
|
- lib/matrixeval/ruby/version.rb
|
92
47
|
homepage: https://github.com/MatrixEval/matrixeval-ruby
|
93
48
|
licenses:
|
data/exe/matrixeval
DELETED
data/exe/meval
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
module Matrixeval
|
2
|
-
module Ruby
|
3
|
-
class CommandLine
|
4
|
-
class ParseContextArguments
|
5
|
-
class << self
|
6
|
-
def call(context_arguments)
|
7
|
-
new(context_arguments).call
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_reader :context_arguments, :options
|
12
|
-
|
13
|
-
def initialize(context_arguments)
|
14
|
-
@context_arguments = context_arguments
|
15
|
-
@options = {}
|
16
|
-
end
|
17
|
-
|
18
|
-
def call
|
19
|
-
parse!
|
20
|
-
options
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def parse!
|
26
|
-
OptionParser.new do |opts|
|
27
|
-
opts.version = Matrixeval::Ruby::VERSION
|
28
|
-
opts.program_name = ""
|
29
|
-
opts.banner = <<~USAGE
|
30
|
-
Usage:
|
31
|
-
matrixeval(meval) [OPTIONS] COMMAND
|
32
|
-
USAGE
|
33
|
-
|
34
|
-
opts.separator ""
|
35
|
-
opts.separator "Options:"
|
36
|
-
|
37
|
-
opts.on "-a", "--all", "# Run the COMMAND against all matrix combinations"
|
38
|
-
|
39
|
-
Config.vectors.each do |vector|
|
40
|
-
# short = "-#{vector.short_key}"
|
41
|
-
long = "--#{vector.key} [VERSION]"
|
42
|
-
desc = [
|
43
|
-
"# Run the COMMAND against a specific #{vector.key} version",
|
44
|
-
"# Options: #{vector.variants.map(&:key).join("/")}",
|
45
|
-
"# Default: #{vector.default_variant.key}",
|
46
|
-
"# Customizable"
|
47
|
-
]
|
48
|
-
opts.separator ""
|
49
|
-
opts.on(long, *desc)
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.separator ""
|
53
|
-
opts.separator "Commands: #{Config.commands.join("/")} (Customizable)"
|
54
|
-
|
55
|
-
opts.separator ""
|
56
|
-
opts.separator "MatrixEval Options:"
|
57
|
-
|
58
|
-
opts.on("-h", "--help", "# Show help") do
|
59
|
-
puts opts.help
|
60
|
-
exit
|
61
|
-
end
|
62
|
-
|
63
|
-
opts.on("-v", "--version", "# Show version") do
|
64
|
-
puts opts.version
|
65
|
-
exit
|
66
|
-
end
|
67
|
-
|
68
|
-
opts.separator ""
|
69
|
-
opts.separator "Customizations:"
|
70
|
-
opts.separator " You can customize all options in matrixeval.yml"
|
71
|
-
|
72
|
-
opts.separator ""
|
73
|
-
opts.separator "Example:"
|
74
|
-
opts.separator " matrixeval --all bundle install"
|
75
|
-
opts.separator " matrixeval --ruby 3.0 rspec a_spec.rb"
|
76
|
-
opts.separator " matrixeval --ruby 3.1 --active_model 7.0 rake test"
|
77
|
-
opts.separator " matrixeval bash"
|
78
|
-
|
79
|
-
end.parse!(context_arguments, into: options)
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require_relative "./command_line/parse_context_arguments"
|
2
|
-
|
3
|
-
module Matrixeval
|
4
|
-
module Ruby
|
5
|
-
COMMANDS = ['rake', 'rspec', 'bundle', 'bash']
|
6
|
-
|
7
|
-
class CommandLine
|
8
|
-
|
9
|
-
attr_reader :argv
|
10
|
-
|
11
|
-
def initialize(argv)
|
12
|
-
@argv = argv
|
13
|
-
end
|
14
|
-
|
15
|
-
def valid?
|
16
|
-
init? ||
|
17
|
-
!context_options.empty? ||
|
18
|
-
!seperator_index.nil?
|
19
|
-
end
|
20
|
-
|
21
|
-
def init?
|
22
|
-
@argv[0] == 'init'
|
23
|
-
end
|
24
|
-
|
25
|
-
def all?
|
26
|
-
context_options[:all]
|
27
|
-
end
|
28
|
-
|
29
|
-
def context_options
|
30
|
-
@context_options ||= ParseContextArguments.call(context_arguments)
|
31
|
-
end
|
32
|
-
|
33
|
-
def context_arguments
|
34
|
-
arguments = @argv[0...seperator_index]
|
35
|
-
arguments << "-h" if @argv.empty?
|
36
|
-
arguments
|
37
|
-
end
|
38
|
-
|
39
|
-
def rest_arguments
|
40
|
-
@argv[seperator_index..-1]
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def seperator_index
|
46
|
-
@argv.index do |argument|
|
47
|
-
Config.commands.include?(argument)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Matrixeval
|
2
|
-
module Ruby
|
3
|
-
class Config
|
4
|
-
class YAML
|
5
|
-
|
6
|
-
class MissingError < StandardError; end
|
7
|
-
|
8
|
-
class << self
|
9
|
-
|
10
|
-
def create
|
11
|
-
return if File.exist?(path)
|
12
|
-
|
13
|
-
FileUtils.cp(template_path, path)
|
14
|
-
end
|
15
|
-
|
16
|
-
def template_path
|
17
|
-
Matrixeval::Ruby.root.join(
|
18
|
-
"lib/matrixeval/ruby/templates/matrixeval.yml"
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
def path
|
23
|
-
Matrixeval.working_dir.join("matrixeval.yml")
|
24
|
-
end
|
25
|
-
|
26
|
-
def [](key)
|
27
|
-
yaml[key]
|
28
|
-
end
|
29
|
-
|
30
|
-
def yaml
|
31
|
-
raise MissingError unless File.exist?(path)
|
32
|
-
|
33
|
-
::YAML.load File.read(path)
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require_relative "./vector"
|
3
|
-
require_relative "./config/yaml"
|
4
|
-
|
5
|
-
module Matrixeval
|
6
|
-
module Ruby
|
7
|
-
class Config
|
8
|
-
class << self
|
9
|
-
|
10
|
-
def version
|
11
|
-
YAML["version"]
|
12
|
-
end
|
13
|
-
|
14
|
-
def target
|
15
|
-
YAML["target"]
|
16
|
-
end
|
17
|
-
|
18
|
-
def vectors
|
19
|
-
@vectors = YAML["matrix"].map do |key, vector_config|
|
20
|
-
Vector.new(key, vector_config)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def main_vector
|
25
|
-
vectors.find(&:main?)
|
26
|
-
end
|
27
|
-
|
28
|
-
def rest_vectors
|
29
|
-
vectors.reject(&:main?)
|
30
|
-
end
|
31
|
-
|
32
|
-
def variant_combinations
|
33
|
-
main_vector_variants.product(*rest_vector_variants_matrix)
|
34
|
-
end
|
35
|
-
|
36
|
-
def main_vector_variants
|
37
|
-
main_vector.variants
|
38
|
-
end
|
39
|
-
|
40
|
-
def rest_vector_variants_matrix
|
41
|
-
rest_vectors.map(&:variants)
|
42
|
-
end
|
43
|
-
|
44
|
-
def exclusions
|
45
|
-
YAML["exclude"] || []
|
46
|
-
end
|
47
|
-
|
48
|
-
def parallel_workers
|
49
|
-
YAML["parallel_workers"] || "number_of_processors"
|
50
|
-
end
|
51
|
-
|
52
|
-
def commands
|
53
|
-
cmds = YAML["commands"] || []
|
54
|
-
COMMANDS + cmds
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
module Matrixeval
|
2
|
-
module Ruby
|
3
|
-
class Context
|
4
|
-
class FindByCommandOptions
|
5
|
-
class << self
|
6
|
-
def call(options)
|
7
|
-
new(options).call
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_reader :options
|
12
|
-
|
13
|
-
def initialize(options)
|
14
|
-
@options = options
|
15
|
-
end
|
16
|
-
|
17
|
-
def call
|
18
|
-
context = Context.all.find do |context|
|
19
|
-
context.main_variant == main_variant &&
|
20
|
-
context.rest_variants == rest_variants
|
21
|
-
end
|
22
|
-
|
23
|
-
raise Error.new("Can't find a corresponding matrix") if context.nil?
|
24
|
-
|
25
|
-
context
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def main_variant
|
31
|
-
dig_variant Config.main_vector
|
32
|
-
end
|
33
|
-
|
34
|
-
def rest_variants
|
35
|
-
Config.rest_vectors.map do |vector|
|
36
|
-
dig_variant vector
|
37
|
-
end.sort do |v1, v2|
|
38
|
-
v1.id <=> v2.id
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def dig_variant(vector)
|
43
|
-
if option_key?(vector.key)
|
44
|
-
find_variant(vector)
|
45
|
-
else
|
46
|
-
vector.default_variant
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def find_variant(vector)
|
51
|
-
vector.variants.find do |variant|
|
52
|
-
option(vector.key) == variant.key
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def option(key)
|
57
|
-
options[key.to_sym] || options[key.to_s]
|
58
|
-
end
|
59
|
-
|
60
|
-
def option_key?(key)
|
61
|
-
options.key?(key.to_sym) || options.key?(key.to_s)
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require_relative "./context/find_by_command_options"
|
2
|
-
|
3
|
-
module Matrixeval
|
4
|
-
module Ruby
|
5
|
-
class Context
|
6
|
-
|
7
|
-
class << self
|
8
|
-
|
9
|
-
def find_by_command_options!(options)
|
10
|
-
FindByCommandOptions.call(options)
|
11
|
-
end
|
12
|
-
|
13
|
-
def all
|
14
|
-
Config.variant_combinations.map do |variants|
|
15
|
-
Context.new(
|
16
|
-
main_variant: variants.find { |v| v.vector.main? },
|
17
|
-
rest_variants: variants.reject { |v| v.vector.main? }
|
18
|
-
)
|
19
|
-
end.select do |context|
|
20
|
-
Config.exclusions.none? do |exclusion|
|
21
|
-
context.match_exclusion?(exclusion)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
attr_reader :main_variant, :rest_variants
|
29
|
-
|
30
|
-
def initialize(main_variant:, rest_variants:)
|
31
|
-
@main_variant = main_variant
|
32
|
-
@rest_variants = (rest_variants || []).sort do |v1, v2|
|
33
|
-
v1.id <=> v2.id
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def name
|
38
|
-
variants.map(&:name).join(", ")
|
39
|
-
end
|
40
|
-
|
41
|
-
def id
|
42
|
-
[[main_variant.id] + rest_variants.map(&:id)].join("_")
|
43
|
-
end
|
44
|
-
|
45
|
-
def env
|
46
|
-
rest_variants.map(&:env).reduce({}, &:merge)
|
47
|
-
.merge(main_variant.env)
|
48
|
-
end
|
49
|
-
|
50
|
-
def docker_compose_service_name
|
51
|
-
main_variant.id
|
52
|
-
end
|
53
|
-
|
54
|
-
def gemfile_lock_path
|
55
|
-
Matrixeval.working_dir.join(".matrixeval/Gemfile.lock.#{id}")
|
56
|
-
end
|
57
|
-
|
58
|
-
def variants
|
59
|
-
[main_variant] + rest_variants
|
60
|
-
end
|
61
|
-
|
62
|
-
def match_exclusion?(exclusion)
|
63
|
-
return false if exclusion.empty?
|
64
|
-
|
65
|
-
variants.all? do |variant|
|
66
|
-
vector_key = variant.vector.key
|
67
|
-
if exclusion.key?(vector_key)
|
68
|
-
exclusion[vector_key].to_s == variant.key
|
69
|
-
else
|
70
|
-
true
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require "erb"
|
2
|
-
|
3
|
-
module Matrixeval
|
4
|
-
module Ruby
|
5
|
-
class DockerCompose
|
6
|
-
class YAML
|
7
|
-
class << self
|
8
|
-
|
9
|
-
def create
|
10
|
-
FileUtils.mkdir_p dot_matrixeval_folder
|
11
|
-
|
12
|
-
File.open(path, 'w+') do |file|
|
13
|
-
file.puts build_content
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def build_content
|
20
|
-
{
|
21
|
-
"version" => "3",
|
22
|
-
"services" => services_json,
|
23
|
-
"volumes" => volumes_json
|
24
|
-
}.to_yaml.sub(/---\n/, "")
|
25
|
-
end
|
26
|
-
|
27
|
-
def services_json
|
28
|
-
services = {}
|
29
|
-
|
30
|
-
Config.main_vector_variants.map do |variant|
|
31
|
-
services[variant.docker_compose_service_name] = {
|
32
|
-
"image" => variant.container.image,
|
33
|
-
"volumes" => mounts(variant),
|
34
|
-
"environment" => {
|
35
|
-
"BUNDLE_PATH" => "/bundle",
|
36
|
-
"GEM_HOME" => "/bundle",
|
37
|
-
"BUNDLE_APP_CONFIG" => "/bundle",
|
38
|
-
"BUNDLE_BIN" => "/bundle/bin",
|
39
|
-
"PATH" => "/app/bin:/bundle/bin:$PATH"
|
40
|
-
}.merge(variant.container.env),
|
41
|
-
"working_dir" => "/app"
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
services
|
46
|
-
end
|
47
|
-
|
48
|
-
def volumes_json
|
49
|
-
bundle_volumes.map do |volume|
|
50
|
-
[volume, {"name" => volume}]
|
51
|
-
end.to_h
|
52
|
-
end
|
53
|
-
|
54
|
-
def bundle_volumes
|
55
|
-
Config.main_vector_variants.map(&:bundle_volume_name)
|
56
|
-
end
|
57
|
-
|
58
|
-
def mounts(variant)
|
59
|
-
[
|
60
|
-
"..:/app:cached",
|
61
|
-
"#{variant.bundle_volume_name}:/bundle",
|
62
|
-
] + Config.main_vector.mounts
|
63
|
-
end
|
64
|
-
|
65
|
-
def path
|
66
|
-
dot_matrixeval_folder.join("docker-compose.yml")
|
67
|
-
end
|
68
|
-
|
69
|
-
def dot_matrixeval_folder
|
70
|
-
Matrixeval.working_dir.join(".matrixeval")
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative "./docker_compose/yaml"
|
3
|
-
|
4
|
-
module Matrixeval
|
5
|
-
module Ruby
|
6
|
-
class DockerCompose
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def clean_containers
|
10
|
-
system("docker compose -f .matrixeval/docker-compose.yml rm --all -f >> /dev/null 2>&1")
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_reader :context
|
15
|
-
|
16
|
-
def initialize(context)
|
17
|
-
@context = context
|
18
|
-
end
|
19
|
-
|
20
|
-
def run(arguments)
|
21
|
-
forward_arguments = arguments.join(" ")
|
22
|
-
|
23
|
-
system(
|
24
|
-
<<~DOCKER_COMPOSE_COMMAND
|
25
|
-
docker compose -f .matrixeval/docker-compose.yml \
|
26
|
-
run --rm \
|
27
|
-
#{env} \
|
28
|
-
#{gemfile_mount} \
|
29
|
-
#{docker_compose_service_name} \
|
30
|
-
#{forward_arguments}
|
31
|
-
DOCKER_COMPOSE_COMMAND
|
32
|
-
)
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def env
|
38
|
-
context.env.map do |k, v|
|
39
|
-
"-e #{k}='#{v}'"
|
40
|
-
end.join(" ")
|
41
|
-
end
|
42
|
-
|
43
|
-
def gemfile_mount
|
44
|
-
"-v ./.matrixeval/Gemfile.lock.#{context.id}:/app/Gemfile.lock"
|
45
|
-
end
|
46
|
-
|
47
|
-
def docker_compose_service_name
|
48
|
-
context.docker_compose_service_name
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Matrixeval
|
2
|
-
module Ruby
|
3
|
-
class GemfileLocks
|
4
|
-
class << self
|
5
|
-
|
6
|
-
def create
|
7
|
-
FileUtils.mkdir_p dot_matrixeval_folder
|
8
|
-
|
9
|
-
Context.all.each do |context|
|
10
|
-
FileUtils.touch context.gemfile_lock_path
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def dot_matrixeval_folder
|
17
|
-
Matrixeval.working_dir.join(".matrixeval")
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module Matrixeval
|
2
|
-
module Ruby
|
3
|
-
class Gitignore
|
4
|
-
class << self
|
5
|
-
|
6
|
-
def update
|
7
|
-
add_docker_compose
|
8
|
-
add_gemfile_locks
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def add_docker_compose
|
14
|
-
return if docker_compose_included?
|
15
|
-
|
16
|
-
File.open(gitignore_path, 'a+') do |file|
|
17
|
-
file.puts docker_compose_yaml
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_gemfile_locks
|
22
|
-
return if gemfile_locks_included?
|
23
|
-
|
24
|
-
File.open(gitignore_path, 'a+') do |file|
|
25
|
-
file.puts gemfile_locks
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def docker_compose_included?
|
30
|
-
File.exist?(gitignore_path) &&
|
31
|
-
File.read(gitignore_path).include?(docker_compose_yaml)
|
32
|
-
end
|
33
|
-
|
34
|
-
def gemfile_locks_included?
|
35
|
-
File.exist?(gitignore_path) &&
|
36
|
-
File.read(gitignore_path).include?(gemfile_locks)
|
37
|
-
end
|
38
|
-
|
39
|
-
def docker_compose_yaml
|
40
|
-
".matrixeval/docker-compose.yml"
|
41
|
-
end
|
42
|
-
|
43
|
-
def gemfile_locks
|
44
|
-
".matrixeval/Gemfile.lock.*"
|
45
|
-
end
|
46
|
-
|
47
|
-
def gitignore_path
|
48
|
-
Matrixeval.working_dir.join(".gitignore")
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,204 +0,0 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'pathname'
|
3
|
-
require 'fileutils'
|
4
|
-
require 'matrixeval/ruby/config'
|
5
|
-
require 'matrixeval/ruby/command_line'
|
6
|
-
require "concurrent/utility/processor_counter"
|
7
|
-
require 'terminal-table'
|
8
|
-
|
9
|
-
module Matrixeval
|
10
|
-
module Ruby
|
11
|
-
class Runner
|
12
|
-
class << self
|
13
|
-
def start(argv)
|
14
|
-
new(argv).start
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
attr_reader :argv, :command
|
19
|
-
|
20
|
-
def initialize(argv)
|
21
|
-
@argv = argv
|
22
|
-
@command = CommandLine.new(argv)
|
23
|
-
@threads ||= []
|
24
|
-
@matrixeval_results ||= []
|
25
|
-
end
|
26
|
-
|
27
|
-
def start
|
28
|
-
validates
|
29
|
-
|
30
|
-
if command.init?
|
31
|
-
init
|
32
|
-
elsif command.all?
|
33
|
-
run_all_contexts
|
34
|
-
else
|
35
|
-
run_a_specific_context
|
36
|
-
end
|
37
|
-
rescue OptionParser::InvalidOption => e
|
38
|
-
puts <<~ERROR
|
39
|
-
#{e.message}
|
40
|
-
See 'matrixeval --help'
|
41
|
-
ERROR
|
42
|
-
exit
|
43
|
-
rescue Config::YAML::MissingError
|
44
|
-
puts "Please run 'matrixeval init' first to generate matrixeval.yml"
|
45
|
-
exit
|
46
|
-
ensure
|
47
|
-
turn_on_stty_opost
|
48
|
-
DockerCompose.clean_containers
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def validates
|
54
|
-
return if command.valid?
|
55
|
-
|
56
|
-
puts <<~ERROR
|
57
|
-
matrixeval: '#{argv.join(' ')}' is not a MatrixEval command.
|
58
|
-
See 'matrixeval --help'
|
59
|
-
ERROR
|
60
|
-
exit
|
61
|
-
end
|
62
|
-
|
63
|
-
def init
|
64
|
-
Config::YAML.create
|
65
|
-
Gitignore.update
|
66
|
-
end
|
67
|
-
|
68
|
-
def run_all_contexts
|
69
|
-
Config::YAML.create
|
70
|
-
DockerCompose::YAML.create
|
71
|
-
GemfileLocks.create
|
72
|
-
Gitignore.update
|
73
|
-
|
74
|
-
pull_all_images
|
75
|
-
|
76
|
-
if workers_count == 1
|
77
|
-
run_all_contexts_sequentially
|
78
|
-
else
|
79
|
-
run_all_contexts_in_parallel
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def run_all_contexts_sequentially
|
84
|
-
Context.all.each do |context|
|
85
|
-
puts Rainbow("[ MatrixEval ] ").blue.bright + Rainbow(" #{context.name} ").white.bright.bg(:blue)
|
86
|
-
puts Rainbow("[ MatrixEval ] Run \"#{command.rest_arguments.join(" ")}\"").blue.bright
|
87
|
-
|
88
|
-
docker_compose = DockerCompose.new(context)
|
89
|
-
success = docker_compose.run(command.rest_arguments)
|
90
|
-
|
91
|
-
@matrixeval_results << [context, !!success]
|
92
|
-
end
|
93
|
-
|
94
|
-
report
|
95
|
-
end
|
96
|
-
|
97
|
-
def run_all_contexts_in_parallel
|
98
|
-
parallel(contexts) do |sub_contexts|
|
99
|
-
Thread.current[:matrixeval_results] = []
|
100
|
-
|
101
|
-
sub_contexts.each do |context|
|
102
|
-
docker_compose = DockerCompose.new(context)
|
103
|
-
success = docker_compose.run(command.rest_arguments)
|
104
|
-
|
105
|
-
Thread.current[:matrixeval_results] << [context, !!success]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
report
|
110
|
-
end
|
111
|
-
|
112
|
-
def run_a_specific_context
|
113
|
-
Config::YAML.create
|
114
|
-
DockerCompose::YAML.create
|
115
|
-
GemfileLocks.create
|
116
|
-
Gitignore.update
|
117
|
-
|
118
|
-
context = Context.find_by_command_options!(command.context_options)
|
119
|
-
|
120
|
-
puts Rainbow("[ MatrixEval ] ").blue.bright + Rainbow(" #{context.name} ").white.bright.bg(:blue)
|
121
|
-
puts Rainbow("[ MatrixEval ] Run \"#{command.rest_arguments.join(" ")}\"").blue.bright
|
122
|
-
|
123
|
-
docker_compose = DockerCompose.new(context)
|
124
|
-
docker_compose.run(command.rest_arguments)
|
125
|
-
end
|
126
|
-
|
127
|
-
def pull_all_images
|
128
|
-
parallel(Config.main_vector_variants) do |sub_variants|
|
129
|
-
sub_variants.each do |variant|
|
130
|
-
puts "Docker image check/pull #{variant.container.image}"
|
131
|
-
image_exists = system %Q{[ -n "$(docker images -q #{variant.container.image})" ]}
|
132
|
-
next if image_exists
|
133
|
-
|
134
|
-
system "docker pull #{variant.container.image}"
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def report
|
140
|
-
turn_on_stty_opost
|
141
|
-
|
142
|
-
table = Terminal::Table.new(title: Rainbow("MatrixEval").blue.bright + " Summary", alignment: :center) do |table|
|
143
|
-
|
144
|
-
headers = Config.vectors.map(&:key) + ['result']
|
145
|
-
table.add_row headers.map { |value| { value: value, alignment: :center } }
|
146
|
-
table.add_separator
|
147
|
-
|
148
|
-
@matrixeval_results.each do |context, success|
|
149
|
-
success_cell = [success ? Rainbow('Success').green : Rainbow('Failed').red]
|
150
|
-
row = (context.variants.map(&:key) + success_cell).map do |value|
|
151
|
-
{ value: value, alignment: :center }
|
152
|
-
end
|
153
|
-
|
154
|
-
table.add_row row
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
puts table
|
160
|
-
end
|
161
|
-
|
162
|
-
def parallel(collection)
|
163
|
-
@threads = [] unless @threads.empty?
|
164
|
-
@matrixeval_results = [] unless @matrixeval_results.empty?
|
165
|
-
|
166
|
-
collection.each_slice(per_worker_contexts_count) do |sub_collection|
|
167
|
-
@threads << Thread.new do
|
168
|
-
yield sub_collection
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
@threads.each(&:join)
|
173
|
-
|
174
|
-
@threads.each do |thread|
|
175
|
-
@matrixeval_results += (thread[:matrixeval_results] || [])
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
def per_worker_contexts_count
|
181
|
-
[(contexts.count / workers_count), 1].max
|
182
|
-
end
|
183
|
-
|
184
|
-
def contexts
|
185
|
-
@contexts ||= Context.all
|
186
|
-
end
|
187
|
-
|
188
|
-
def workers_count
|
189
|
-
count = if Config.parallel_workers == "number_of_processors"
|
190
|
-
Concurrent.physical_processor_count
|
191
|
-
else
|
192
|
-
Integer(Config.parallel_workers)
|
193
|
-
end
|
194
|
-
|
195
|
-
[count, 1].max
|
196
|
-
end
|
197
|
-
|
198
|
-
def turn_on_stty_opost
|
199
|
-
system("stty opost")
|
200
|
-
end
|
201
|
-
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require_relative "./container"
|
2
|
-
|
3
|
-
module Matrixeval
|
4
|
-
module Ruby
|
5
|
-
class Variant
|
6
|
-
class << self
|
7
|
-
def default(key, vector)
|
8
|
-
self.new({"key" => key}, vector)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :key, :env, :vector, :default, :container
|
13
|
-
|
14
|
-
def initialize(config = {}, vector)
|
15
|
-
raise Error.new("Variant#key is missing") if config["key"].nil?
|
16
|
-
|
17
|
-
@vector = vector
|
18
|
-
@key = config["key"].to_s
|
19
|
-
@container = Container.new(config["container"])
|
20
|
-
@env = config["env"] || {}
|
21
|
-
@default = config["default"] || false
|
22
|
-
end
|
23
|
-
|
24
|
-
def name
|
25
|
-
"#{vector.key}: #{key}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def bundle_volume_name
|
29
|
-
"bundle_#{container.image.gsub(/[^A-Za-z0-9]/,'_')}"
|
30
|
-
end
|
31
|
-
|
32
|
-
def id
|
33
|
-
"#{vector.id}_#{key.to_s.gsub(/[^A-Za-z0-9]/,'_')}"
|
34
|
-
end
|
35
|
-
|
36
|
-
def docker_compose_service_name
|
37
|
-
id
|
38
|
-
end
|
39
|
-
|
40
|
-
def pathname
|
41
|
-
id
|
42
|
-
end
|
43
|
-
|
44
|
-
def default?
|
45
|
-
default
|
46
|
-
end
|
47
|
-
|
48
|
-
def match_command_options?(options)
|
49
|
-
options[vector.key] == key.to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
def ==(variant)
|
53
|
-
vector.key == variant.vector.key &&
|
54
|
-
key == variant.key
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require_relative "./variant"
|
2
|
-
|
3
|
-
module Matrixeval
|
4
|
-
module Ruby
|
5
|
-
class Vector
|
6
|
-
attr_reader :key, :variants, :mounts
|
7
|
-
|
8
|
-
def initialize(key, config)
|
9
|
-
@key = key.to_s
|
10
|
-
@mounts = config["mounts"] || []
|
11
|
-
@variants = (config["variants"] || []).map do |variant_config|
|
12
|
-
config = if variant_config.is_a?(Hash)
|
13
|
-
variant_config
|
14
|
-
else
|
15
|
-
{ "key" => variant_config.to_s }
|
16
|
-
end
|
17
|
-
|
18
|
-
Variant.new(config, self)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def main?
|
23
|
-
key == "ruby"
|
24
|
-
end
|
25
|
-
|
26
|
-
def id
|
27
|
-
"#{key.to_s.gsub(/[^A-Za-z0-9]/,'_')}"
|
28
|
-
end
|
29
|
-
|
30
|
-
def default_variant
|
31
|
-
variant = variants.find(&:default?)
|
32
|
-
if variant.nil?
|
33
|
-
raise Error.new("Please set a default variant for matrix #{key}")
|
34
|
-
end
|
35
|
-
|
36
|
-
variant
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|