attractor 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +14 -1
- data/attractor.gemspec +5 -1
- data/lib/attractor.rb +24 -12
- data/lib/attractor/calculators/base_calculator.rb +3 -2
- data/lib/attractor/calculators/js_calculator.rb +2 -2
- data/lib/attractor/calculators/ruby_calculator.rb +2 -2
- data/lib/attractor/cli.rb +38 -28
- data/lib/attractor/duration_parser.rb +27 -0
- data/lib/attractor/reporters/sinatra_reporter.rb +2 -0
- data/lib/attractor/suggester.rb +1 -1
- data/lib/attractor/version.rb +1 -1
- metadata +17 -6
- data/.all-contributorsrc +0 -25
- data/.github/workflows/ruby.yml +0 -25
- data/.rspec +0 -3
- data/.travis.yml +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67da9392099763d432b8bb74551259f5b6105cbbc4d7b370c41c1fe851102bf
|
4
|
+
data.tar.gz: 4fdd7358b4c073b52f517bd6933b2fcfc134549685dc42320ff055358971df86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd928f5288a2330156ef222277b34a3cfa9554529a8fcdd3fbf85e00ef38c140b6e3eaee990e8d9923a92da922546d0daaf7c139567ba7227245f9fb04d399c6
|
7
|
+
data.tar.gz: 341c7ba41ef4ac89021594d534f1c27f30d16e0f381a8e9106d09b68fdbec66c0ac8b738d916ff35323987d898a8a63043f4e74f19c186685c9d548ae58ff6c3
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -7,12 +7,15 @@
|
|
7
7
|
|
8
8
|
Many authors ([Michael Feathers](https://www.agileconnection.com/article/getting-empirical-about-refactoring), [Sandi Metz](https://www.sandimetz.com/blog/2017/9/13/breaking-up-the-behemoth)) have shown that an evaluation of churn vs complexity of files in software projects provide a valuable metric towards code quality. This is another take on the matter, for ruby code, using the `churn` and `flog` projects.
|
9
9
|
|
10
|
+
Here's an [article on medium](https://medium.com/better-programming/why-i-made-my-own-code-quality-tool-c44b40ceaafd) explaining the approach in greater detail.
|
11
|
+
|
10
12
|
## Table of Contents
|
11
13
|
|
12
14
|
* [Installation](#installation)
|
13
15
|
* [Usage](#usage)
|
14
16
|
+ [Live Reloading](#live-reloading)
|
15
17
|
* [CI Usage](#ci-usage)
|
18
|
+
+ [Github Action](#github-action)
|
16
19
|
+ [Gitlab Example](#gitlab-example)
|
17
20
|
* [CLI Commands and Options](#cli-commands-and-options)
|
18
21
|
* [Development](#development)
|
@@ -74,6 +77,10 @@ If you have `guard-livereload` (or a similar service) running on your project, y
|
|
74
77
|
|
75
78
|
To use this CLI in a CI environment, use the `--ci` option, which will suppress automatic opening of a browser window.
|
76
79
|
|
80
|
+
### Github Action
|
81
|
+
|
82
|
+
There is a dedicated [Github Action](https://github.com/julianrubisch/attractor-action) that will compile Attractor's output. Here's the action on the [Marketplace](https://github.com/marketplace/actions/attractor-action).
|
83
|
+
|
77
84
|
### Gitlab Example
|
78
85
|
|
79
86
|
The simplest use case is to store the `attractor_output` directory as an artifact.
|
@@ -101,6 +108,8 @@ Print a simple output to console:
|
|
101
108
|
$ --file_prefix|-p app/models
|
102
109
|
$ --type|-t rb|js
|
103
110
|
$ --watch|-w
|
111
|
+
$ --start_ago|-s (e.g. 5y, 3m, 7w)
|
112
|
+
$ --minimum_churn|-c (minimum times a file must have changed to be processed)
|
104
113
|
|
105
114
|
Generate a full report
|
106
115
|
|
@@ -109,6 +118,8 @@ Generate a full report
|
|
109
118
|
$ --type|-t rb|js
|
110
119
|
$ --watch|-w
|
111
120
|
$ --no-open-browser|--ci
|
121
|
+
$ --start_ago|-s (e.g. 5y, 3m, 7w)
|
122
|
+
$ --minimum_churn|-c (minimum times a file must have changed to be processed)
|
112
123
|
|
113
124
|
Serve the output on http://localhost:7890
|
114
125
|
|
@@ -116,6 +127,8 @@ Serve the output on http://localhost:7890
|
|
116
127
|
$ --file_prefix|-p app/models
|
117
128
|
$ --watch|-w
|
118
129
|
$ --no-open-browser|--ci
|
130
|
+
$ --start_ago|-s (e.g. 5y, 3m, 7w)
|
131
|
+
$ --minimum_churn|-c (minimum times a file must have changed to be processed)
|
119
132
|
|
120
133
|
## Development
|
121
134
|
|
@@ -153,4 +166,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
153
166
|
<!-- prettier-ignore-end -->
|
154
167
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
155
168
|
|
156
|
-
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
169
|
+
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
data/attractor.gemspec
CHANGED
@@ -28,7 +28,10 @@ Gem::Specification.new do |spec|
|
|
28
28
|
# Specify which files should be added to the gem when it is released.
|
29
29
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
30
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
31
|
-
`git ls-files -z`.split("\x0").reject
|
31
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
32
|
+
f.match(%r{^(src|tmp|test|spec|features|\.github)/}) ||
|
33
|
+
%w[.all-contributorsrc .rspec .rspec_status .travis.yml].include?(f)
|
34
|
+
end
|
32
35
|
end
|
33
36
|
spec.bindir = 'exe'
|
34
37
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -55,5 +58,6 @@ Gem::Specification.new do |spec|
|
|
55
58
|
spec.add_development_dependency 'rake', '~> 10.0'
|
56
59
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
57
60
|
spec.add_development_dependency 'sassc'
|
61
|
+
spec.add_development_dependency 'standard'
|
58
62
|
spec.add_development_dependency 'structured_changelog'
|
59
63
|
end
|
data/lib/attractor.rb
CHANGED
@@ -1,32 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'attractor/version'
|
4
|
+
require 'attractor/duration_parser'
|
4
5
|
require 'attractor/calculators/base_calculator'
|
5
|
-
require 'attractor/calculators/ruby_calculator'
|
6
|
-
require 'attractor/calculators/js_calculator'
|
7
6
|
require 'attractor/detectors/base_detector'
|
8
|
-
require 'attractor/detectors/ruby_detector'
|
9
|
-
require 'attractor/detectors/js_detector'
|
10
7
|
require 'attractor/reporters/base_reporter'
|
11
|
-
require 'attractor/reporters/console_reporter'
|
12
|
-
require 'attractor/reporters/html_reporter'
|
13
|
-
require 'attractor/reporters/sinatra_reporter'
|
14
8
|
require 'attractor/suggester'
|
15
9
|
require 'attractor/watcher'
|
16
10
|
|
11
|
+
Dir[File.join(__dir__, 'attractor', 'calculators', '*.rb')].each do |file|
|
12
|
+
next if file.start_with?('base')
|
13
|
+
|
14
|
+
require file
|
15
|
+
end
|
16
|
+
|
17
|
+
Dir[File.join(__dir__, 'attractor', 'detectors', '*.rb')].each do |file|
|
18
|
+
next if file.start_with?('base')
|
19
|
+
|
20
|
+
require file
|
21
|
+
end
|
22
|
+
|
23
|
+
Dir[File.join(__dir__, 'attractor', 'reporters', '*.rb')].each do |file|
|
24
|
+
next if file.start_with?('base')
|
25
|
+
|
26
|
+
require file
|
27
|
+
end
|
28
|
+
|
17
29
|
module Attractor
|
18
30
|
class Error < StandardError; end
|
19
31
|
|
20
|
-
def calculators_for_type(type,
|
32
|
+
def calculators_for_type(type, **options)
|
21
33
|
case type
|
22
34
|
when 'js'
|
23
|
-
{ 'js' => JsCalculator.new(
|
35
|
+
{ 'js' => JsCalculator.new(**options) }
|
24
36
|
when 'rb'
|
25
|
-
{ 'rb' => RubyCalculator.new(
|
37
|
+
{ 'rb' => RubyCalculator.new(**options) }
|
26
38
|
else
|
27
39
|
{}.tap do |hash|
|
28
|
-
hash['rb'] = RubyCalculator.new(
|
29
|
-
hash['js'] = JsCalculator.new(
|
40
|
+
hash['rb'] = RubyCalculator.new(**options) if RubyDetector.new.detect
|
41
|
+
hash['js'] = JsCalculator.new(**options) if JsDetector.new.detect
|
30
42
|
end
|
31
43
|
end
|
32
44
|
end
|
@@ -9,10 +9,11 @@ module Attractor
|
|
9
9
|
class BaseCalculator
|
10
10
|
attr_reader :type
|
11
11
|
|
12
|
-
def initialize(file_prefix: '', file_extension: 'rb', minimum_churn_count: 3)
|
12
|
+
def initialize(file_prefix: '', file_extension: 'rb', minimum_churn_count: 3, start_ago: '5y')
|
13
13
|
@file_prefix = file_prefix
|
14
14
|
@file_extension = file_extension
|
15
15
|
@minimum_churn_count = minimum_churn_count
|
16
|
+
@start_date = Date.today - Attractor::DurationParser.new(start_ago).duration
|
16
17
|
end
|
17
18
|
|
18
19
|
def calculate
|
@@ -20,7 +21,7 @@ module Attractor
|
|
20
21
|
file_extension: @file_extension,
|
21
22
|
file_prefix: @file_prefix,
|
22
23
|
minimum_churn_count: @minimum_churn_count,
|
23
|
-
start_date:
|
24
|
+
start_date: @start_date
|
24
25
|
).report(false)
|
25
26
|
|
26
27
|
churn[:churn][:changes].map do |change|
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Attractor
|
4
4
|
class JsCalculator < BaseCalculator
|
5
|
-
def initialize(file_prefix: '', minimum_churn_count: 3)
|
6
|
-
super(file_prefix: file_prefix, file_extension: '(js|jsx)', minimum_churn_count: minimum_churn_count)
|
5
|
+
def initialize(file_prefix: '', minimum_churn_count: 3, start_ago: 365 * 5)
|
6
|
+
super(file_prefix: file_prefix, file_extension: '(js|jsx)', minimum_churn_count: minimum_churn_count, start_ago: start_ago)
|
7
7
|
@type = "JavaScript"
|
8
8
|
end
|
9
9
|
|
@@ -4,8 +4,8 @@ require 'flog'
|
|
4
4
|
|
5
5
|
module Attractor
|
6
6
|
class RubyCalculator < BaseCalculator
|
7
|
-
def initialize(file_prefix: '', minimum_churn_count: 3)
|
8
|
-
super(file_prefix: file_prefix, file_extension: 'rb', minimum_churn_count: minimum_churn_count)
|
7
|
+
def initialize(file_prefix: '', minimum_churn_count: 3, start_ago: 365 * 5)
|
8
|
+
super(file_prefix: file_prefix, file_extension: 'rb', minimum_churn_count: minimum_churn_count, start_ago: start_ago)
|
9
9
|
@type = "Ruby"
|
10
10
|
end
|
11
11
|
|
data/lib/attractor/cli.rb
CHANGED
@@ -7,43 +7,48 @@ require 'attractor'
|
|
7
7
|
module Attractor
|
8
8
|
# contains methods implementing the CLI
|
9
9
|
class CLI < Thor
|
10
|
+
shared_options = [[:file_prefix, aliases: :p],
|
11
|
+
[:watch, aliases: :w, type: :boolean],
|
12
|
+
[:minimum_churn, aliases: :c, type: :numeric, default: 3],
|
13
|
+
[:start_ago, aliases: :s, type: :string, default: '5y'],
|
14
|
+
[:type, aliases: :t]]
|
15
|
+
|
16
|
+
advanced_options = [[:format, aliases: :f, default: 'html'],
|
17
|
+
[:no_open_browser, type: :boolean],
|
18
|
+
[:ci, type: :boolean]]
|
19
|
+
|
10
20
|
desc 'calc', 'Calculates churn and complexity for all ruby files in current directory'
|
11
|
-
|
12
|
-
|
13
|
-
|
21
|
+
shared_options.each do |shared_option|
|
22
|
+
option(*shared_option)
|
23
|
+
end
|
14
24
|
def calc
|
15
25
|
file_prefix = options[:file_prefix]
|
16
|
-
calculators = Attractor.calculators_for_type(options[:type], file_prefix)
|
17
26
|
if options[:watch]
|
18
27
|
puts 'Listening for file changes...'
|
19
|
-
Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators).watch
|
28
|
+
Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators(options)).watch
|
20
29
|
else
|
21
|
-
Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators).report
|
30
|
+
Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators(options)).report
|
22
31
|
end
|
23
32
|
rescue RuntimeError => e
|
24
33
|
puts "Runtime error: #{e.message}"
|
25
34
|
end
|
26
35
|
|
27
36
|
desc 'report', 'Generates an HTML report'
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
option :type, aliases: :t
|
32
|
-
option :no_open_browser, type: :boolean
|
33
|
-
option :ci, type: :boolean
|
37
|
+
(shared_options + advanced_options).each do |option|
|
38
|
+
option(*option)
|
39
|
+
end
|
34
40
|
def report
|
35
41
|
file_prefix = options[:file_prefix]
|
36
|
-
|
37
|
-
open_browser = !(options[:no_open_browser] || options[:ci])
|
42
|
+
open_browser = !(options[:no_open_browser] || options[:ci])
|
38
43
|
if options[:watch]
|
39
44
|
puts 'Listening for file changes...'
|
40
|
-
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).watch
|
45
|
+
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).watch
|
41
46
|
else
|
42
47
|
case options[:format]
|
43
48
|
when 'html'
|
44
|
-
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).report
|
49
|
+
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
|
45
50
|
else
|
46
|
-
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).report
|
51
|
+
Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
|
47
52
|
end
|
48
53
|
end
|
49
54
|
rescue RuntimeError => e
|
@@ -51,27 +56,32 @@ module Attractor
|
|
51
56
|
end
|
52
57
|
|
53
58
|
desc 'serve', 'Serves the report on localhost'
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
option :type, aliases: :t
|
58
|
-
option :no_open_browser, type: :boolean
|
59
|
-
option :ci, type: :boolean
|
59
|
+
(shared_options + advanced_options).each do |option|
|
60
|
+
option(*option)
|
61
|
+
end
|
60
62
|
def serve
|
61
63
|
file_prefix = options[:file_prefix]
|
62
|
-
open_browser = !(options[:no_open_browser] || options[:ci])
|
63
|
-
calculators = Attractor.calculators_for_type(options[:type], file_prefix)
|
64
|
+
open_browser = !(options[:no_open_browser] || options[:ci])
|
64
65
|
if options[:watch]
|
65
66
|
puts 'Listening for file changes...'
|
66
|
-
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).watch
|
67
|
+
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).watch
|
67
68
|
else
|
68
69
|
case options[:format]
|
69
70
|
when 'html'
|
70
|
-
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).report
|
71
|
+
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
|
71
72
|
else
|
72
|
-
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators, open_browser: open_browser).report
|
73
|
+
Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
|
73
74
|
end
|
74
75
|
end
|
75
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def calculators(options)
|
81
|
+
Attractor.calculators_for_type(options[:type],
|
82
|
+
file_prefix: options[:file_prefix],
|
83
|
+
minimum_churn_count: options[:minimum_churn],
|
84
|
+
start_ago: options[:start_ago])
|
85
|
+
end
|
76
86
|
end
|
77
87
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Attractor
|
4
|
+
# converts a duration string into an amount of days
|
5
|
+
class DurationParser
|
6
|
+
TOKENS = {
|
7
|
+
'd' => 1,
|
8
|
+
'w' => 7,
|
9
|
+
'm' => 30,
|
10
|
+
'y' => 365
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_reader :duration
|
14
|
+
|
15
|
+
def initialize(input)
|
16
|
+
@input = input
|
17
|
+
@duration = 0
|
18
|
+
parse
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse
|
22
|
+
@input.scan(/(\d+)(\w)/).each do |amount, measure|
|
23
|
+
@duration += amount.to_i * TOKENS[measure]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/attractor/suggester.rb
CHANGED
data/lib/attractor/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Rubisch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: churn
|
@@ -290,6 +290,20 @@ dependencies:
|
|
290
290
|
- - ">="
|
291
291
|
- !ruby/object:Gem::Version
|
292
292
|
version: '0'
|
293
|
+
- !ruby/object:Gem::Dependency
|
294
|
+
name: standard
|
295
|
+
requirement: !ruby/object:Gem::Requirement
|
296
|
+
requirements:
|
297
|
+
- - ">="
|
298
|
+
- !ruby/object:Gem::Version
|
299
|
+
version: '0'
|
300
|
+
type: :development
|
301
|
+
prerelease: false
|
302
|
+
version_requirements: !ruby/object:Gem::Requirement
|
303
|
+
requirements:
|
304
|
+
- - ">="
|
305
|
+
- !ruby/object:Gem::Version
|
306
|
+
version: '0'
|
293
307
|
- !ruby/object:Gem::Dependency
|
294
308
|
name: structured_changelog
|
295
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -316,14 +330,10 @@ executables:
|
|
316
330
|
extensions: []
|
317
331
|
extra_rdoc_files: []
|
318
332
|
files:
|
319
|
-
- ".all-contributorsrc"
|
320
333
|
- ".babelrc"
|
321
334
|
- ".eslintrc.json"
|
322
|
-
- ".github/workflows/ruby.yml"
|
323
335
|
- ".gitignore"
|
324
|
-
- ".rspec"
|
325
336
|
- ".rubocop.yml"
|
326
|
-
- ".travis.yml"
|
327
337
|
- CHANGELOG.md
|
328
338
|
- Gemfile
|
329
339
|
- Guardfile
|
@@ -350,6 +360,7 @@ files:
|
|
350
360
|
- lib/attractor/detectors/base_detector.rb
|
351
361
|
- lib/attractor/detectors/js_detector.rb
|
352
362
|
- lib/attractor/detectors/ruby_detector.rb
|
363
|
+
- lib/attractor/duration_parser.rb
|
353
364
|
- lib/attractor/reporters/.keep
|
354
365
|
- lib/attractor/reporters/base_reporter.rb
|
355
366
|
- lib/attractor/reporters/console_reporter.rb
|
data/.all-contributorsrc
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"files": [
|
3
|
-
"README.md"
|
4
|
-
],
|
5
|
-
"imageSize": 100,
|
6
|
-
"commit": false,
|
7
|
-
"contributors": [
|
8
|
-
{
|
9
|
-
"login": "julianrubisch",
|
10
|
-
"name": "Julian Rubisch",
|
11
|
-
"avatar_url": "https://avatars0.githubusercontent.com/u/4352208?v=4",
|
12
|
-
"profile": "http://www.julianrubisch.at",
|
13
|
-
"contributions": [
|
14
|
-
"code",
|
15
|
-
"doc"
|
16
|
-
]
|
17
|
-
}
|
18
|
-
],
|
19
|
-
"contributorsPerLine": 7,
|
20
|
-
"projectName": "attractor",
|
21
|
-
"projectOwner": "julianrubisch",
|
22
|
-
"repoType": "github",
|
23
|
-
"repoHost": "https://github.com",
|
24
|
-
"skipCi": true
|
25
|
-
}
|
data/.github/workflows/ruby.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
name: Ruby
|
2
|
-
|
3
|
-
on: [push]
|
4
|
-
|
5
|
-
jobs:
|
6
|
-
build:
|
7
|
-
|
8
|
-
runs-on: ubuntu-latest
|
9
|
-
|
10
|
-
strategy:
|
11
|
-
matrix:
|
12
|
-
ruby-version: [2.4.x, 2.5.x, 2.6.x]
|
13
|
-
|
14
|
-
steps:
|
15
|
-
- uses: actions/checkout@v1
|
16
|
-
- name: Set up Ruby ${{ matrix.ruby-version }}
|
17
|
-
uses: actions/setup-ruby@v1
|
18
|
-
with:
|
19
|
-
ruby-version: ${{ matrix.ruby-version }}
|
20
|
-
- name: Build and test with Rake
|
21
|
-
run: |
|
22
|
-
gem install bundler
|
23
|
-
bundle install --jobs 4 --retry 3
|
24
|
-
bundle exec rspec spec
|
25
|
-
bundle exec cucumber features
|
data/.rspec
DELETED