hastci 0.1.2 → 0.1.4
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/.rubocop.yml +7 -0
- data/README.md +68 -20
- data/bin/hastci-rspec +1 -1
- data/lib/hastci/ack_worker.rb +1 -1
- data/lib/hastci/adapters/rspec/runner.rb +21 -19
- data/lib/hastci/api_client.rb +8 -4
- data/lib/hastci/cli.rb +6 -3
- data/lib/hastci/config.rb +6 -2
- data/lib/hastci/session.rb +2 -2
- data/lib/hastci/task_buffer.rb +19 -13
- data/lib/hastci/version.rb +1 -1
- data/spec/pacts/hastci_rspec-hastci_api.json +56 -3
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea7c58f1b590502ae7258d6ded75619b5389d602ca474de3626de52ef65c1580
|
|
4
|
+
data.tar.gz: 8fe736f73a92b44e7d9f6a3e6b8fe569f48a3cf9114890e89e128132886cc2b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 69d3a81ad390852e5c28d4caf6900b4429a7d4d7d6781fd2eef97d8589b2027baef9b1241861fd7bf3001d5ecebc628aad4bf1c7373bcc92f51909798970df20
|
|
7
|
+
data.tar.gz: 54e1101e729ebf74cfbc06e857970c1d6966205f522d79b59e22ab93bd752c84ce74bc986c6cd05a6915253a2885ec0196ea0f9fe17ee74c88f543ad568f9b81
|
data/.rubocop.yml
ADDED
data/README.md
CHANGED
|
@@ -1,43 +1,91 @@
|
|
|
1
|
-
# HastCI
|
|
1
|
+
# HastCI RSpec
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/hastci`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
3
|
+
Distributed test execution for RSpec. Workers pull tests from a central queue, so faster workers automatically run more tests.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Add to your Gemfile:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
```ruby
|
|
10
|
+
group :development, :test do
|
|
11
|
+
gem "hastci-rspec"
|
|
12
|
+
end
|
|
13
|
+
```
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### GitHub Actions
|
|
18
|
+
|
|
19
|
+
HastCI auto-detects GitHub Actions and configures itself from the environment.
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
jobs:
|
|
23
|
+
test:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
strategy:
|
|
26
|
+
matrix:
|
|
27
|
+
ci_node_index: [0, 1, 2, 3]
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v6
|
|
31
|
+
- uses: ruby/setup-ruby@v1
|
|
32
|
+
with:
|
|
33
|
+
bundler-cache: true
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: bundle exec hastci-rspec
|
|
37
|
+
env:
|
|
38
|
+
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
|
|
39
|
+
HASTCI_API_KEY: ${{ secrets.HASTCI_API_KEY }}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For matrix builds with multiple dimensions (e.g., Ruby versions), use `HASTCI_SUBRUN_ID` to create separate test queues:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
strategy:
|
|
46
|
+
matrix:
|
|
47
|
+
ruby-version: ["3.2", "3.3", "3.4"]
|
|
48
|
+
ci_node_index: [0, 1]
|
|
49
|
+
|
|
50
|
+
# ...
|
|
51
|
+
|
|
52
|
+
env:
|
|
53
|
+
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
|
|
54
|
+
HASTCI_API_KEY: ${{ secrets.HASTCI_API_KEY }}
|
|
55
|
+
HASTCI_SUBRUN_ID: ruby-${{ matrix.ruby-version }}
|
|
15
56
|
```
|
|
16
57
|
|
|
17
|
-
|
|
58
|
+
### Generic CI
|
|
59
|
+
|
|
60
|
+
For other CI systems, set the required environment variables:
|
|
18
61
|
|
|
19
62
|
```bash
|
|
20
|
-
|
|
63
|
+
export HASTCI_API_KEY="your-api-key"
|
|
64
|
+
export HASTCI_RUN_KEY="unique-run-identifier" # e.g., build-123-abc
|
|
65
|
+
export CI_NODE_INDEX="0" # 0, 1, 2... for each parallel worker
|
|
66
|
+
|
|
67
|
+
bundle exec hastci-rspec
|
|
21
68
|
```
|
|
22
69
|
|
|
23
|
-
##
|
|
70
|
+
## Configuration
|
|
24
71
|
|
|
25
|
-
|
|
72
|
+
| Variable | Required | Description |
|
|
73
|
+
|----------|----------|-------------|
|
|
74
|
+
| `HASTCI_API_KEY` | Yes | API key for HastCI |
|
|
75
|
+
| `HASTCI_RUN_KEY` | Generic CI only | Unique identifier for this test run |
|
|
76
|
+
| `CI_NODE_INDEX` | Yes | Worker index (0, 1, 2...) |
|
|
77
|
+
| `HASTCI_WORKER_ID` | No | Custom worker ID (overrides `CI_NODE_INDEX`) |
|
|
78
|
+
| `HASTCI_SUBRUN_ID` | No | Distinguishes matrix variations (GitHub Actions) |
|
|
79
|
+
| `HASTCI_API_URL` | No | Custom API endpoint |
|
|
26
80
|
|
|
27
81
|
## Development
|
|
28
82
|
|
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
|
30
|
-
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
83
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
|
32
84
|
|
|
33
85
|
## Contributing
|
|
34
86
|
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/wojtodzio/hastci.
|
|
87
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/wojtodzio/hastci.
|
|
36
88
|
|
|
37
89
|
## License
|
|
38
90
|
|
|
39
91
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
40
|
-
|
|
41
|
-
## Code of Conduct
|
|
42
|
-
|
|
43
|
-
Everyone interacting in the HastCI project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/wojtodzio/hastci/blob/main/CODE_OF_CONDUCT.md).
|
data/bin/hastci-rspec
CHANGED
data/lib/hastci/ack_worker.rb
CHANGED
|
@@ -4,7 +4,7 @@ module HastCI
|
|
|
4
4
|
class AckWorker
|
|
5
5
|
DEFAULT_QUEUE_SIZE = 1000
|
|
6
6
|
DEFAULT_FLUSH_TIMEOUT = 10
|
|
7
|
-
EMPTY_QUEUE_POLL_INTERVAL = 0.
|
|
7
|
+
EMPTY_QUEUE_POLL_INTERVAL = 0.5
|
|
8
8
|
SHUTDOWN_TIMEOUT = 10
|
|
9
9
|
|
|
10
10
|
private_constant :DEFAULT_QUEUE_SIZE, :DEFAULT_FLUSH_TIMEOUT, :EMPTY_QUEUE_POLL_INTERVAL,
|
|
@@ -25,6 +25,7 @@ module HastCI
|
|
|
25
25
|
@clock = clock
|
|
26
26
|
|
|
27
27
|
@options = ::RSpec::Core::ConfigurationOptions.new(argv)
|
|
28
|
+
add_default_path_if_needed(@options, configuration)
|
|
28
29
|
@configuration = configuration
|
|
29
30
|
@world = world
|
|
30
31
|
end
|
|
@@ -147,27 +148,18 @@ module HastCI
|
|
|
147
148
|
end
|
|
148
149
|
|
|
149
150
|
def build_logs(failed_examples)
|
|
150
|
-
|
|
151
|
-
summary: summary_for(failed_examples),
|
|
152
|
-
failures: failed_examples.map { |example| failure_payload(example) }
|
|
153
|
-
}
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def summary_for(failed_examples)
|
|
157
|
-
return "passed" if failed_examples.empty?
|
|
151
|
+
return [] if failed_examples.empty?
|
|
158
152
|
|
|
159
|
-
|
|
160
|
-
|
|
153
|
+
failed_examples.map do |example|
|
|
154
|
+
exception = example.exception
|
|
161
155
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
backtrace: Array(exception&.backtrace)
|
|
170
|
-
}
|
|
156
|
+
{
|
|
157
|
+
file: example.metadata[:file_path],
|
|
158
|
+
line: example.metadata[:line_number],
|
|
159
|
+
message: exception&.message,
|
|
160
|
+
backtrace: Array(exception&.backtrace)
|
|
161
|
+
}
|
|
162
|
+
end
|
|
171
163
|
end
|
|
172
164
|
|
|
173
165
|
def ordered_task_names(example_groups)
|
|
@@ -199,6 +191,16 @@ module HastCI
|
|
|
199
191
|
end
|
|
200
192
|
# :nocov:
|
|
201
193
|
end
|
|
194
|
+
|
|
195
|
+
def add_default_path_if_needed(options, configuration)
|
|
196
|
+
files = options.options[:files_or_directories_to_run]
|
|
197
|
+
return unless files.empty?
|
|
198
|
+
|
|
199
|
+
default_path = configuration.default_path
|
|
200
|
+
return unless default_path
|
|
201
|
+
|
|
202
|
+
files << default_path
|
|
203
|
+
end
|
|
202
204
|
end
|
|
203
205
|
end
|
|
204
206
|
end
|
data/lib/hastci/api_client.rb
CHANGED
|
@@ -7,6 +7,8 @@ require "uri"
|
|
|
7
7
|
|
|
8
8
|
module HastCI
|
|
9
9
|
class ApiClient
|
|
10
|
+
OriginalNetHTTP = Net::HTTP
|
|
11
|
+
|
|
10
12
|
DEFAULT_MAX_RETRIES = 5
|
|
11
13
|
DEFAULT_INITIAL_BACKOFF = 0.5
|
|
12
14
|
DEFAULT_MAX_BACKOFF = 30
|
|
@@ -28,11 +30,13 @@ module HastCI
|
|
|
28
30
|
|
|
29
31
|
private_constant :API_PATH_PREFIX, :CONNECTION_DEFAULT, :CONNECTION_HEARTBEAT, :CONNECTION_ACK
|
|
30
32
|
|
|
31
|
-
def initialize(config:, sleeper: Kernel.method(:sleep), max_retries: nil, random: Random.new
|
|
33
|
+
def initialize(config:, sleeper: Kernel.method(:sleep), max_retries: nil, random: Random.new,
|
|
34
|
+
http_class: OriginalNetHTTP)
|
|
32
35
|
@config = config
|
|
33
36
|
@max_retries = max_retries || config.api_max_retries || DEFAULT_MAX_RETRIES
|
|
34
37
|
@sleeper = sleeper
|
|
35
38
|
@random = random
|
|
39
|
+
@http_class = http_class
|
|
36
40
|
|
|
37
41
|
@base_url = URI.parse(config.api_base_url)
|
|
38
42
|
@api_key = config.api_key
|
|
@@ -140,7 +144,7 @@ module HastCI
|
|
|
140
144
|
|
|
141
145
|
def get_json(path, pool: CONNECTION_DEFAULT)
|
|
142
146
|
uri = build_uri(path)
|
|
143
|
-
request =
|
|
147
|
+
request = @http_class::Get.new(uri)
|
|
144
148
|
request["Authorization"] = "Bearer #{@api_key}"
|
|
145
149
|
|
|
146
150
|
execute_request(request, pool: pool)
|
|
@@ -148,7 +152,7 @@ module HastCI
|
|
|
148
152
|
|
|
149
153
|
def post_json(path, body, pool: CONNECTION_DEFAULT)
|
|
150
154
|
uri = build_uri(path)
|
|
151
|
-
request =
|
|
155
|
+
request = @http_class::Post.new(uri)
|
|
152
156
|
request["Content-Type"] = "application/json"
|
|
153
157
|
request["Authorization"] = "Bearer #{@api_key}"
|
|
154
158
|
request.body = JSON.generate(body)
|
|
@@ -226,7 +230,7 @@ module HastCI
|
|
|
226
230
|
end
|
|
227
231
|
|
|
228
232
|
def create_connection
|
|
229
|
-
http =
|
|
233
|
+
http = @http_class.new(@base_url.host, @base_url.port)
|
|
230
234
|
http.use_ssl = @base_url.scheme == "https"
|
|
231
235
|
http.open_timeout = DEFAULT_OPEN_TIMEOUT
|
|
232
236
|
http.read_timeout = DEFAULT_READ_TIMEOUT
|
data/lib/hastci/cli.rb
CHANGED
|
@@ -86,12 +86,15 @@ module HastCI
|
|
|
86
86
|
private_class_method :configure_logging
|
|
87
87
|
|
|
88
88
|
# :nocov:
|
|
89
|
-
def self.setup_interrupt_handler(session, err, &on_interrupt)
|
|
89
|
+
def self.setup_interrupt_handler(session, err, signal_enqueuer: nil, &on_interrupt)
|
|
90
90
|
signals = Queue.new
|
|
91
91
|
signal_count = 0
|
|
92
|
+
enqueue_signal = signal_enqueuer || lambda do |queue, signal|
|
|
93
|
+
Thread.new { queue << signal }
|
|
94
|
+
end
|
|
92
95
|
|
|
93
|
-
trap("INT") { signals
|
|
94
|
-
trap("TERM") { signals
|
|
96
|
+
trap("INT") { enqueue_signal.call(signals, "SIGINT") }
|
|
97
|
+
trap("TERM") { enqueue_signal.call(signals, "SIGTERM") }
|
|
95
98
|
|
|
96
99
|
watcher = Thread.new do
|
|
97
100
|
loop do
|
data/lib/hastci/config.rb
CHANGED
|
@@ -5,7 +5,7 @@ require "securerandom"
|
|
|
5
5
|
module HastCI
|
|
6
6
|
class Config
|
|
7
7
|
DEFAULT_API_BASE_URL = "https://hastci.com"
|
|
8
|
-
DEFAULT_CLAIM_BATCH_SIZE =
|
|
8
|
+
DEFAULT_CLAIM_BATCH_SIZE = 2
|
|
9
9
|
DEFAULT_HEARTBEAT_INTERVAL = 15
|
|
10
10
|
DEFAULT_SEEDING_TIMEOUT = 300
|
|
11
11
|
DEFAULT_LOG_LEVEL = "INFO"
|
|
@@ -33,12 +33,16 @@ module HastCI
|
|
|
33
33
|
run_attempt = env.fetch("GITHUB_RUN_ATTEMPT")
|
|
34
34
|
commit_sha = env.fetch("GITHUB_SHA")
|
|
35
35
|
node_index = env.fetch("CI_NODE_INDEX")
|
|
36
|
+
subrun_id = env["HASTCI_SUBRUN_ID"]
|
|
37
|
+
|
|
38
|
+
base_run_key = "gha-#{run_id}-#{run_attempt}-#{commit_sha}"
|
|
39
|
+
run_key = subrun_id ? "#{base_run_key}-#{subrun_id}" : base_run_key
|
|
36
40
|
|
|
37
41
|
new(
|
|
38
42
|
api_key: env.fetch("HASTCI_API_KEY"),
|
|
39
43
|
api_base_url: env.fetch("HASTCI_API_URL", DEFAULT_API_BASE_URL),
|
|
40
44
|
api_max_retries: env["HASTCI_API_MAX_RETRIES"]&.to_i,
|
|
41
|
-
run_key:
|
|
45
|
+
run_key: run_key,
|
|
42
46
|
worker_id: "gha-worker-#{node_index}",
|
|
43
47
|
commit_sha: commit_sha,
|
|
44
48
|
claim_batch_size: env.fetch("HASTCI_CLAIM_BATCH_SIZE", DEFAULT_CLAIM_BATCH_SIZE).to_i,
|
data/lib/hastci/session.rb
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module HastCI
|
|
4
4
|
class Session
|
|
5
5
|
DEFAULT_POLL_INTERVAL = 0.5
|
|
6
|
-
DEFAULT_BUFFER_MIN_SIZE =
|
|
7
|
-
DEFAULT_BUFFER_MAX_SIZE =
|
|
6
|
+
DEFAULT_BUFFER_MIN_SIZE = 1
|
|
7
|
+
DEFAULT_BUFFER_MAX_SIZE = 2
|
|
8
8
|
DEFAULT_SEEDING_POLL_INTERVAL = 1.0
|
|
9
9
|
|
|
10
10
|
STOP_REASONS = %i[user_interrupt server_cancelled].freeze
|
data/lib/hastci/task_buffer.rb
CHANGED
|
@@ -54,20 +54,24 @@ module HastCI
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def next_task
|
|
57
|
-
|
|
58
|
-
raise error if error
|
|
59
|
-
|
|
60
|
-
task = @queue.pop
|
|
61
|
-
|
|
62
|
-
if task.nil?
|
|
57
|
+
loop do
|
|
63
58
|
error = @error_collector.first_error
|
|
64
59
|
raise error if error
|
|
65
60
|
|
|
66
|
-
return nil
|
|
67
|
-
|
|
61
|
+
return nil if queue_closed_and_empty?
|
|
62
|
+
|
|
63
|
+
begin
|
|
64
|
+
task = @queue.pop(true)
|
|
65
|
+
rescue ThreadError
|
|
66
|
+
@sleeper.call(@poll_interval)
|
|
67
|
+
next
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
return nil if task.nil?
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
signal_prefetch_if_needed
|
|
73
|
+
return task
|
|
74
|
+
end
|
|
71
75
|
end
|
|
72
76
|
|
|
73
77
|
def size
|
|
@@ -84,6 +88,10 @@ module HastCI
|
|
|
84
88
|
|
|
85
89
|
private
|
|
86
90
|
|
|
91
|
+
def queue_closed_and_empty?
|
|
92
|
+
@queue.respond_to?(:closed?) && @queue.closed? && @queue.empty?
|
|
93
|
+
end
|
|
94
|
+
|
|
87
95
|
def signal_prefetch_if_needed
|
|
88
96
|
@mutex.synchronize do
|
|
89
97
|
@prefetch_condition.signal if @queue.size < @min_size
|
|
@@ -117,9 +125,7 @@ module HastCI
|
|
|
117
125
|
|
|
118
126
|
def wait_for_prefetch_signal
|
|
119
127
|
@mutex.synchronize do
|
|
120
|
-
while @running && !@drained && @queue.size >= @min_size
|
|
121
|
-
@prefetch_condition.wait(@mutex, @poll_interval)
|
|
122
|
-
end
|
|
128
|
+
@prefetch_condition.wait(@mutex, @poll_interval) while @running && !@drained && @queue.size >= @min_size
|
|
123
129
|
end
|
|
124
130
|
end
|
|
125
131
|
|
data/lib/hastci/version.rb
CHANGED
|
@@ -373,16 +373,69 @@
|
|
|
373
373
|
"body": {
|
|
374
374
|
"status": "passed",
|
|
375
375
|
"duration_s": 1.5,
|
|
376
|
-
"logs":
|
|
377
|
-
"summary": "1 example, 0 failures",
|
|
378
|
-
"failures": [
|
|
376
|
+
"logs": [
|
|
379
377
|
]
|
|
378
|
+
},
|
|
379
|
+
"matchingRules": {
|
|
380
|
+
"$.path": {
|
|
381
|
+
"match": "regex",
|
|
382
|
+
"regex": "^\\/api\\/v1\\/tasks\\/\\d+\\/acknowledgment$"
|
|
380
383
|
}
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
"response": {
|
|
387
|
+
"status": 200,
|
|
388
|
+
"headers": {
|
|
389
|
+
"Content-Type": "application/json"
|
|
390
|
+
},
|
|
391
|
+
"body": {
|
|
392
|
+
"ok": true
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"description": "a request to ack a task with failures",
|
|
398
|
+
"providerState": "a task exists",
|
|
399
|
+
"request": {
|
|
400
|
+
"method": "post",
|
|
401
|
+
"path": "/api/v1/tasks/101/acknowledgment",
|
|
402
|
+
"headers": {
|
|
403
|
+
"Authorization": "Bearer test-api-key",
|
|
404
|
+
"Content-Type": "application/json"
|
|
405
|
+
},
|
|
406
|
+
"body": {
|
|
407
|
+
"status": "failed",
|
|
408
|
+
"duration_s": 2.0,
|
|
409
|
+
"logs": [
|
|
410
|
+
{
|
|
411
|
+
"file": "spec/models/user_spec.rb",
|
|
412
|
+
"line": 123,
|
|
413
|
+
"message": "Expected 1, got 2",
|
|
414
|
+
"backtrace": [
|
|
415
|
+
"spec/models/user_spec.rb:123:in `block'"
|
|
416
|
+
]
|
|
417
|
+
}
|
|
418
|
+
]
|
|
381
419
|
},
|
|
382
420
|
"matchingRules": {
|
|
383
421
|
"$.path": {
|
|
384
422
|
"match": "regex",
|
|
385
423
|
"regex": "^\\/api\\/v1\\/tasks\\/\\d+\\/acknowledgment$"
|
|
424
|
+
},
|
|
425
|
+
"$.body.logs[0].file": {
|
|
426
|
+
"match": "type"
|
|
427
|
+
},
|
|
428
|
+
"$.body.logs[0].line": {
|
|
429
|
+
"match": "type"
|
|
430
|
+
},
|
|
431
|
+
"$.body.logs[0].message": {
|
|
432
|
+
"match": "type"
|
|
433
|
+
},
|
|
434
|
+
"$.body.logs[0].backtrace": {
|
|
435
|
+
"min": 1
|
|
436
|
+
},
|
|
437
|
+
"$.body.logs[0].backtrace[*].*": {
|
|
438
|
+
"match": "type"
|
|
386
439
|
}
|
|
387
440
|
}
|
|
388
441
|
},
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hastci
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wojciech Wrona
|
|
@@ -46,6 +46,7 @@ extra_rdoc_files: []
|
|
|
46
46
|
files:
|
|
47
47
|
- ".envrc"
|
|
48
48
|
- ".rspec"
|
|
49
|
+
- ".rubocop.yml"
|
|
49
50
|
- ".standard.yml"
|
|
50
51
|
- ".zed/settings.json"
|
|
51
52
|
- CHANGELOG.md
|