enruby 0.1.0.pre.3 → 0.1.0.pre.3.pr80.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da457dba90f350a8065578cd84a7b702ac76bd50c25b8143a446bccb246c0a4d
4
- data.tar.gz: a3f87d86893880a630a43b04932707dfce9e9bb70587e94c3f3aca921a0c56bf
3
+ metadata.gz: 3432969e6552e52155548d00337ceb5d800b27f35c2dda47f67245cb89652866
4
+ data.tar.gz: c726ad8eff7ee4f1889e4f7c47ec197b82214dffc866e783d1a1a9a3a06f65f7
5
5
  SHA512:
6
- metadata.gz: d0401f734bed4be729849ca67358534762d58c84041ab0b6275dda1b0cfbcd988a620e3b008dde910063854dbf629d46823b5b2d28f3a334a1710039ddb835c7
7
- data.tar.gz: 80fa07d55d8e45e35916412fa48017f6a7c805b20fb48c8202fb3f0b5961eed533159716a26a99b758d64135f43151b024fd6fdd22dd83893eb7f52c9dfdee63
6
+ metadata.gz: 8ab5465ebb35651ef80515f7494cdc4da7a7fdc133d1b73472b0cb9628bd12f628779ccf39769ea6ef48ccb0fd3cf03cc999390f5481d8b3556467224f86e4c4
7
+ data.tar.gz: 94335d974813cf8fddea438196985f4ebcb232135e8820536d9dfd1ddccd969a7c04a1dee67c5c98105d91266ca21bcb52ea6de74a411ee8e26c5b1bdf1495ad
data/Gemfile.lock CHANGED
@@ -1,56 +1,63 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- enruby (0.1.0.pre.3)
4
+ enruby (0.1.0.pre.3.pr80.1.1)
5
5
  immutable-struct (~> 2.4)
6
- lino (>= 3, < 5)
6
+ lino (>= 4.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (7.1.3.4)
11
+ activesupport (8.1.3)
12
12
  base64
13
13
  bigdecimal
14
- concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ concurrent-ruby (~> 1.0, >= 1.3.1)
15
15
  connection_pool (>= 2.2.5)
16
16
  drb
17
17
  i18n (>= 1.6, < 2)
18
+ json
19
+ logger (>= 1.4.2)
18
20
  minitest (>= 5.1)
19
- mutex_m
20
- tzinfo (~> 2.0)
21
- addressable (2.8.7)
22
- public_suffix (>= 2.0.2, < 7.0)
23
- ast (2.4.2)
24
- base64 (0.2.0)
25
- bigdecimal (3.1.8)
21
+ securerandom (>= 0.3)
22
+ tzinfo (~> 2.0, >= 2.0.5)
23
+ uri (>= 0.13.1)
24
+ addressable (2.9.0)
25
+ public_suffix (>= 2.0.2, < 8.0)
26
+ ast (2.4.3)
27
+ base64 (0.3.0)
28
+ bigdecimal (4.1.2)
26
29
  childprocess (5.0.0)
27
30
  coderay (1.1.3)
28
31
  colored2 (3.1.2)
29
- concurrent-ruby (1.3.3)
30
- connection_pool (2.4.1)
31
- diff-lcs (1.5.1)
32
- docile (1.4.0)
33
- drb (2.2.1)
34
- excon (0.111.0)
35
- faker (3.4.2)
32
+ concurrent-ruby (1.3.8)
33
+ connection_pool (3.0.2)
34
+ diff-lcs (1.6.2)
35
+ docile (1.4.1)
36
+ drb (2.2.3)
37
+ excon (0.112.0)
38
+ faker (3.8.0)
36
39
  i18n (>= 1.8.11, < 2)
37
- faraday (2.10.0)
38
- faraday-net_http (>= 2.0, < 3.2)
40
+ faraday (2.14.3)
41
+ faraday-net_http (>= 2.0, < 3.5)
42
+ json
39
43
  logger
40
- faraday-net_http (3.1.0)
41
- net-http
42
- ffi (1.17.0-aarch64-linux-gnu)
43
- ffi (1.17.0-arm64-darwin)
44
- ffi (1.17.0-x86_64-darwin)
45
- ffi (1.17.0-x86_64-linux-gnu)
46
- formatador (1.1.0)
47
- gem-release (2.2.2)
44
+ faraday-net_http (3.4.4)
45
+ net-http (~> 0.5)
46
+ ffi (1.17.4)
47
+ ffi (1.17.4-aarch64-linux-gnu)
48
+ ffi (1.17.4-arm64-darwin)
49
+ ffi (1.17.4-x86_64-darwin)
50
+ ffi (1.17.4-x86_64-linux-gnu)
51
+ formatador (1.2.3)
52
+ reline
53
+ gem-release (2.2.4)
48
54
  git (1.19.1)
49
55
  addressable (~> 2.8)
50
56
  rchardet (~> 1.8)
51
- guard (2.18.1)
57
+ guard (2.20.1)
52
58
  formatador (>= 0.2.4)
53
59
  listen (>= 2.7, < 4.0)
60
+ logger (~> 1.6)
54
61
  lumberjack (>= 1.0.12, < 2.0)
55
62
  nenv (~> 0.1)
56
63
  notiffany (~> 0.0)
@@ -64,50 +71,50 @@ GEM
64
71
  rspec (>= 2.99.0, < 4.0)
65
72
  hamster (3.0.0)
66
73
  concurrent-ruby (~> 1.0)
67
- i18n (1.14.5)
74
+ i18n (1.15.2)
68
75
  concurrent-ruby (~> 1.0)
69
- immutable-struct (2.4.1)
70
- json (2.7.2)
71
- language_server-protocol (3.17.0.3)
76
+ immutable-struct (2.5.0)
77
+ io-console (0.8.2)
78
+ json (2.21.1)
79
+ language_server-protocol (3.17.0.6)
72
80
  lino (4.1.0)
73
81
  childprocess (~> 5.0.0)
74
82
  hamster (~> 3.0)
75
83
  open4 (~> 1.3)
76
- listen (3.9.0)
84
+ lint_roller (1.1.0)
85
+ listen (3.10.0)
86
+ logger
77
87
  rb-fsevent (~> 0.10, >= 0.10.3)
78
88
  rb-inotify (~> 0.9, >= 0.9.10)
79
- logger (1.6.0)
80
- lumberjack (1.2.10)
89
+ logger (1.7.0)
90
+ lumberjack (1.4.2)
81
91
  method_source (1.1.0)
82
- minitest (5.24.1)
83
- mutex_m (0.2.0)
92
+ minitest (6.0.6)
93
+ drb (~> 2.0)
94
+ prism (~> 1.5)
84
95
  nenv (0.3.0)
85
- net-http (0.4.1)
86
- uri
96
+ net-http (0.9.1)
97
+ uri (>= 0.11.1)
87
98
  notiffany (0.1.3)
88
99
  nenv (~> 0.1)
89
100
  shellany (~> 0.0)
90
- octokit (8.1.0)
91
- base64
101
+ octokit (10.0.0)
92
102
  faraday (>= 1, < 3)
93
103
  sawyer (~> 0.9)
94
104
  open4 (1.3.4)
95
- parallel (1.25.1)
96
- parser (3.3.4.0)
105
+ parallel (2.1.0)
106
+ parser (3.3.11.1)
97
107
  ast (~> 2.4.1)
98
108
  racc
99
- pry (0.14.2)
109
+ prism (1.9.0)
110
+ pry (0.16.0)
100
111
  coderay (~> 1.1)
101
112
  method_source (~> 1.0)
102
- public_suffix (6.0.1)
103
- racc (1.8.0)
113
+ reline (>= 0.6.0)
114
+ public_suffix (7.0.5)
115
+ racc (1.8.1)
104
116
  rainbow (3.1.1)
105
- rake (13.2.1)
106
- rake_circle_ci (0.13.0)
107
- colored2 (~> 3.1)
108
- excon (~> 0.72)
109
- rake_factory (~> 0.33)
110
- sshkey (~> 2.0)
117
+ rake (13.4.2)
111
118
  rake_factory (0.33.0)
112
119
  activesupport (>= 4)
113
120
  rake (~> 13.0)
@@ -115,91 +122,102 @@ GEM
115
122
  colored2 (~> 3.1)
116
123
  git (~> 1.13, >= 1.13.2)
117
124
  rake_factory (~> 0.33)
118
- rake_git_crypt (0.2.0)
125
+ rake_git_crypt (0.4.0)
119
126
  colored2 (~> 3.1)
127
+ lino (~> 4.1)
120
128
  rake_factory (~> 0.33)
121
129
  ruby_git_crypt (~> 0.1)
122
130
  ruby_gpg2 (~> 0.12)
123
- rake_github (0.15.0)
131
+ rake_github (0.17.0)
124
132
  colored2 (~> 3.1)
125
- octokit (>= 4.16, < 9.0)
133
+ octokit (>= 7.0, < 11.0)
126
134
  rake_factory (~> 0.33)
135
+ rbnacl (~> 7.1)
127
136
  sshkey (~> 2.0)
128
137
  rake_gpg (0.20.0)
129
138
  rake_factory (~> 0.33)
130
139
  ruby_gpg2 (~> 0.12)
131
- rake_ssh (0.12.0)
132
- colored2 (~> 3.1)
140
+ rake_slack (0.3.0)
141
+ excon (>= 0.72, < 2.0)
133
142
  rake_factory (~> 0.33)
134
- sshkey (~> 2.0)
135
143
  rb-fsevent (0.11.2)
136
144
  rb-inotify (0.11.1)
137
145
  ffi (~> 1.0)
138
- rchardet (1.8.0)
139
- regexp_parser (2.9.2)
140
- rexml (3.3.2)
141
- strscan
142
- rspec (3.13.0)
146
+ rbnacl (7.1.2)
147
+ ffi (~> 1)
148
+ rchardet (1.10.2)
149
+ regexp_parser (2.12.0)
150
+ reline (0.6.3)
151
+ io-console (~> 0.5)
152
+ rspec (3.13.2)
143
153
  rspec-core (~> 3.13.0)
144
154
  rspec-expectations (~> 3.13.0)
145
155
  rspec-mocks (~> 3.13.0)
146
- rspec-core (3.13.0)
156
+ rspec-core (3.13.6)
147
157
  rspec-support (~> 3.13.0)
148
- rspec-expectations (3.13.1)
158
+ rspec-expectations (3.13.5)
149
159
  diff-lcs (>= 1.2.0, < 2.0)
150
160
  rspec-support (~> 3.13.0)
151
- rspec-mocks (3.13.1)
161
+ rspec-mocks (3.13.8)
152
162
  diff-lcs (>= 1.2.0, < 2.0)
153
163
  rspec-support (~> 3.13.0)
154
- rspec-support (3.13.1)
155
- rubocop (1.65.0)
164
+ rspec-support (3.13.7)
165
+ rubocop (1.88.2)
156
166
  json (~> 2.3)
157
- language_server-protocol (>= 3.17.0)
158
- parallel (~> 1.10)
167
+ language_server-protocol (~> 3.17.0.2)
168
+ lint_roller (~> 1.1.0)
169
+ parallel (>= 1.10)
159
170
  parser (>= 3.3.0.2)
160
171
  rainbow (>= 2.2.2, < 4.0)
161
- regexp_parser (>= 2.4, < 3.0)
162
- rexml (>= 3.2.5, < 4.0)
163
- rubocop-ast (>= 1.31.1, < 2.0)
172
+ regexp_parser (>= 2.9.3, < 3.0)
173
+ rubocop-ast (>= 1.49.0, < 2.0)
164
174
  ruby-progressbar (~> 1.7)
165
- unicode-display_width (>= 2.4.0, < 3.0)
166
- rubocop-ast (1.31.3)
167
- parser (>= 3.3.1.0)
168
- rubocop-rake (0.6.0)
169
- rubocop (~> 1.0)
170
- rubocop-rspec (3.0.3)
171
- rubocop (~> 1.61)
175
+ unicode-display_width (>= 2.4.0, < 4.0)
176
+ rubocop-ast (1.50.0)
177
+ parser (>= 3.3.7.2)
178
+ prism (~> 1.7)
179
+ rubocop-rake (0.7.1)
180
+ lint_roller (~> 1.1)
181
+ rubocop (>= 1.72.1)
182
+ rubocop-rspec (3.10.2)
183
+ lint_roller (~> 1.1)
184
+ regexp_parser (>= 2.0)
185
+ rubocop (~> 1.86, >= 1.86.2)
172
186
  ruby-progressbar (1.13.0)
173
187
  ruby_git_crypt (0.1.0)
174
188
  immutable-struct (~> 2.4)
175
189
  lino (>= 4.1)
176
190
  ruby_gpg2 (0.12.0)
177
191
  lino (>= 4.1)
178
- sawyer (0.9.2)
192
+ sawyer (0.9.3)
179
193
  addressable (>= 2.3.5)
180
194
  faraday (>= 0.17.3, < 3)
195
+ securerandom (0.4.1)
181
196
  shellany (0.0.1)
182
197
  simplecov (0.22.0)
183
198
  docile (~> 1.1)
184
199
  simplecov-html (~> 0.11)
185
200
  simplecov_json_formatter (~> 0.1)
186
- simplecov-html (0.12.3)
201
+ simplecov-html (0.13.2)
187
202
  simplecov_json_formatter (0.1.4)
188
203
  sshkey (2.0.0)
189
- strscan (3.1.0)
190
204
  terminal-notifier-guard (1.7.0)
191
- thor (1.3.1)
205
+ thor (1.5.0)
192
206
  tzinfo (2.0.6)
193
207
  concurrent-ruby (~> 1.0)
194
- unicode-display_width (2.5.0)
195
- uri (0.13.0)
196
- yard (0.9.36)
208
+ unicode-display_width (3.2.0)
209
+ unicode-emoji (~> 4.1)
210
+ unicode-emoji (4.2.0)
211
+ uri (1.1.1)
212
+ yard (0.9.44)
197
213
 
198
214
  PLATFORMS
199
215
  aarch64-linux
200
216
  arm64-darwin-21
201
217
  arm64-darwin-22
202
218
  arm64-darwin-23
219
+ arm64-darwin-25
220
+ ruby
203
221
  x86_64-darwin-19
204
222
  x86_64-darwin-20
205
223
  x86_64-darwin-21
@@ -213,12 +231,11 @@ DEPENDENCIES
213
231
  guard
214
232
  guard-rspec
215
233
  rake
216
- rake_circle_ci
217
234
  rake_git
218
235
  rake_git_crypt
219
236
  rake_github
220
237
  rake_gpg
221
- rake_ssh
238
+ rake_slack
222
239
  rspec
223
240
  rubocop
224
241
  rubocop-rake
@@ -228,4 +245,4 @@ DEPENDENCIES
228
245
  yard
229
246
 
230
247
  BUNDLED WITH
231
- 2.3.26
248
+ 4.0.16
data/README.md CHANGED
@@ -63,16 +63,16 @@ To check for code linting / formatting issues without fixing:
63
63
  You can also run `bin/console` for an interactive prompt that will allow you to
64
64
  experiment.
65
65
 
66
- ### Managing CircleCI keys
66
+ ### Managing CI keys
67
67
 
68
- To encrypt a GPG key for use by CircleCI:
68
+ To encrypt a GPG key for use by CI:
69
69
 
70
70
  ```shell
71
71
  openssl aes-256-cbc \
72
72
  -e \
73
73
  -md sha1 \
74
74
  -in ./config/secrets/ci/gpg.private \
75
- -out ./.circleci/gpg.private.enc \
75
+ -out ./.github/gpg.private.enc \
76
76
  -k "<passphrase>"
77
77
  ```
78
78
 
@@ -82,7 +82,7 @@ To check decryption is working correctly:
82
82
  openssl aes-256-cbc \
83
83
  -d \
84
84
  -md sha1 \
85
- -in ./.circleci/gpg.private.enc \
85
+ -in ./.github/gpg.private.enc \
86
86
  -k "<passphrase>"
87
87
  ```
88
88
 
data/Rakefile CHANGED
@@ -1,15 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rake_circle_ci'
4
3
  require 'rake_git'
5
4
  require 'rake_git_crypt'
6
5
  require 'rake_github'
7
6
  require 'rake_gpg'
8
- require 'rake_ssh'
7
+ require 'rake_slack'
9
8
  require 'rspec/core/rake_task'
10
9
  require 'rubocop/rake_task'
11
10
  require 'securerandom'
12
- require 'yaml'
13
11
  require 'yard'
14
12
 
15
13
  task default: %i[
@@ -60,13 +58,6 @@ namespace :encryption do
60
58
  end
61
59
 
62
60
  namespace :keys do
63
- namespace :deploy do
64
- RakeSSH.define_key_tasks(
65
- path: 'config/secrets/ci/',
66
- comment: 'maintainers@infrablocks.io'
67
- )
68
- end
69
-
70
61
  namespace :gpg do
71
62
  RakeGPG.define_generate_key_task(
72
63
  output_directory: 'config/secrets/ci',
@@ -92,7 +83,6 @@ namespace :secrets do
92
83
  desc 'Generate all generatable secrets.'
93
84
  task generate: %w[
94
85
  encryption:passphrase:generate
95
- keys:deploy:generate
96
86
  keys:gpg:generate
97
87
  ]
98
88
 
@@ -121,6 +111,11 @@ namespace :library do
121
111
 
122
112
  desc 'Attempt to automatically fix issues with the library'
123
113
  task fix: [:'rubocop:autocorrect_all']
114
+
115
+ desc 'Build the library'
116
+ task :build do
117
+ sh 'gem build enruby.gemspec'
118
+ end
124
119
  end
125
120
 
126
121
  namespace :documentation do
@@ -135,7 +130,7 @@ namespace :documentation do
135
130
 
136
131
  sh('git', 'commit',
137
132
  '-a',
138
- '-m', "Generate latest documentation#{skip_ci ? ' [ci skip]' : ''}")
133
+ '-m', "Generate latest documentation#{' [ci skip]' if skip_ci}")
139
134
  end
140
135
 
141
136
  desc 'Update documentation'
@@ -146,51 +141,95 @@ namespace :test do
146
141
  RSpec::Core::RakeTask.new(:unit)
147
142
  end
148
143
 
149
- RakeCircleCI.define_project_tasks(
150
- namespace: :circle_ci,
151
- project_slug: 'github/infrablocks/enruby'
152
- ) do |t|
153
- circle_ci_config =
154
- YAML.load_file('config/secrets/circle_ci/config.yaml')
155
-
156
- t.api_token = circle_ci_config['circle_ci_api_token']
157
- t.environment_variables = {
158
- ENCRYPTION_PASSPHRASE:
159
- File.read('config/secrets/ci/encryption.passphrase')
160
- .chomp
161
- }
162
- t.checkout_keys = []
163
- t.ssh_keys = [
164
- {
165
- hostname: 'github.com',
166
- private_key: File.read('config/secrets/ci/ssh.private')
167
- }
168
- ]
144
+ def gh_auth_token
145
+ `gh auth token`
146
+ rescue Errno::ENOENT
147
+ ''
148
+ end
149
+
150
+ def resolve_github_token
151
+ # Operator's ambient auth. Resolve once and fail fast: a missing,
152
+ # unauthenticated, or absent gh yields an empty string, which would
153
+ # otherwise surface later as an opaque Octokit 401. An empty or
154
+ # whitespace-only GITHUB_TOKEN is treated as absent so an authenticated
155
+ # operator falls through to `gh auth token` rather than hitting the raise.
156
+ token = ENV['GITHUB_TOKEN'].to_s.strip
157
+ token = gh_auth_token.strip if token.empty?
158
+ if token.empty?
159
+ raise 'No GitHub token available: set GITHUB_TOKEN or run `gh auth login`'
160
+ end
161
+
162
+ token
163
+ end
164
+
165
+ def read_encryption_passphrase
166
+ # Guard against a locked clone: without it, File.read returns git-crypt
167
+ # ciphertext and github:secrets:ensure silently uploads garbage that only
168
+ # surfaces much later as an opaque GPG unlock failure in the release job.
169
+ path = 'config/secrets/ci/encryption.passphrase'
170
+ unless File.exist?(path)
171
+ raise "Passphrase file not found: #{path} — expected an unlocked clone"
172
+ end
173
+
174
+ passphrase = File.binread(path)
175
+ if passphrase.start_with?("\x00GITCRYPT")
176
+ raise 'encryption.passphrase is git-crypt ciphertext — unlock the clone'
177
+ end
178
+
179
+ passphrase.chomp
169
180
  end
170
181
 
171
182
  RakeGithub.define_repository_tasks(
172
183
  namespace: :github,
173
184
  repository: 'infrablocks/enruby'
174
185
  ) do |t|
175
- github_config =
176
- YAML.load_file('config/secrets/github/config.yaml')
177
-
178
- t.access_token = github_config['github_personal_access_token']
179
- t.deploy_keys = [
180
- {
181
- title: 'CircleCI',
182
- public_key: File.read('config/secrets/ci/ssh.public')
183
- }
186
+ t.access_token = resolve_github_token
187
+
188
+ # Actions store only: dependabot runs never reach the passphrase — the
189
+ # only pr.yaml job that unlocks git-crypt (prerelease) is guarded to
190
+ # same-repo human PRs.
191
+ t.secrets = [
192
+ { name: 'ENCRYPTION_PASSPHRASE', value: read_encryption_passphrase }
184
193
  ]
194
+ t.environments = [
195
+ { name: 'release',
196
+ reviewers: [{ team: 'maintainers' }] }
197
+ ]
198
+ end
199
+
200
+ namespace :slack do
201
+ RakeSlack.define_notification_tasks do |t|
202
+ t.bot_token = ENV.fetch('SLACK_BOT_TOKEN', nil)
203
+ t.routing_rules = [
204
+ { when: { type: 'on_hold' },
205
+ channel: 'C038EDCRSQJ', format: :on_hold }, # release
206
+ { when: { actor: 'dependabot[bot]', outcome: 'success' },
207
+ channel: 'C03N711HVDG', format: :success }, # builds-dependabot
208
+ { when: { actor: 'dependabot[bot]' },
209
+ channel: 'C03N711HVDG', format: :failure }, # builds-dependabot
210
+ { when: { outcome: 'success' },
211
+ channel: 'C023XUE76GH', format: :success }, # builds
212
+ # Failures go to builds, not team-dev (org default), to keep noise
213
+ # out of a popular channel while this pipeline beds in.
214
+ { when: {},
215
+ channel: 'C023XUE76GH', format: :failure } # builds
216
+ ]
217
+ end
218
+ end
219
+
220
+ namespace :repository do
221
+ desc 'Set the git author for CI'
222
+ task :set_ci_author do
223
+ sh 'git config --global user.name "InfraBlocks CI"'
224
+ sh 'git config --global user.email "ci@infrablocks.io"'
225
+ end
185
226
  end
186
227
 
187
228
  namespace :pipeline do
188
- desc 'Prepare CircleCI Pipeline'
229
+ desc 'Prepare GitHub Actions pipeline'
189
230
  task prepare: %i[
190
- circle_ci:env_vars:ensure
191
- circle_ci:checkout_keys:ensure
192
- circle_ci:ssh_keys:ensure
193
- github:deploy_keys:ensure
231
+ github:secrets:ensure
232
+ github:environments:ensure
194
233
  ]
195
234
  end
196
235
 
@@ -201,6 +240,38 @@ namespace :version do
201
240
  end
202
241
  end
203
242
 
243
+ namespace :prerelease do
244
+ desc 'Build and push a namespaced pre-release to RubyGems ' \
245
+ '(PR CI only; no bump, no tag, no commit, no push)'
246
+ task :publish, %i[pr_number run_number run_attempt] do |_, args|
247
+ %i[pr_number run_number run_attempt].each do |name|
248
+ raise "Missing task argument: #{name}" if args[name].to_s.empty?
249
+ end
250
+
251
+ version_file = 'lib/enruby/version.rb'
252
+ version_pattern = /(VERSION\s*=\s*')([^']+)(')/
253
+ source = File.read(version_file)
254
+ base = source[version_pattern, 2]
255
+ raise "Could not read VERSION from #{version_file}" unless base
256
+
257
+ version = "#{base}.pr#{args.pr_number}" \
258
+ ".#{args.run_number}.#{args.run_attempt}"
259
+ gem_file = "enruby-#{version}.gem"
260
+ begin
261
+ File.write(version_file,
262
+ source.sub(version_pattern, "\\1#{version}\\3"))
263
+ # Build + push directly: `gem release` aborts on the (deliberately)
264
+ # uncommitted version rewrite. PR CI must not tag, commit, or push
265
+ # (contrast the `release` task).
266
+ sh 'gem build enruby.gemspec'
267
+ sh "gem push #{gem_file}"
268
+ ensure
269
+ File.write(version_file, source)
270
+ rm_f gem_file
271
+ end
272
+ end
273
+ end
274
+
204
275
  desc 'Release gem'
205
276
  task :release do
206
277
  sh 'gem release --tag --push'
data/enruby.gemspec CHANGED
@@ -35,10 +35,10 @@ Gem::Specification.new do |spec|
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ['lib']
37
37
 
38
- spec.required_ruby_version = '>= 3.1'
38
+ spec.required_ruby_version = '>= 3.3'
39
39
 
40
40
  spec.add_dependency 'immutable-struct', '~> 2.4'
41
- spec.add_dependency 'lino', '>= 3', '< 5'
41
+ spec.add_dependency 'lino', '>= 4.1'
42
42
 
43
43
  spec.add_development_dependency 'bundler'
44
44
  spec.add_development_dependency 'faker'
@@ -46,12 +46,11 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'guard'
47
47
  spec.add_development_dependency 'guard-rspec'
48
48
  spec.add_development_dependency 'rake'
49
- spec.add_development_dependency 'rake_circle_ci'
50
49
  spec.add_development_dependency 'rake_git'
51
50
  spec.add_development_dependency 'rake_git_crypt'
52
51
  spec.add_development_dependency 'rake_github'
53
52
  spec.add_development_dependency 'rake_gpg'
54
- spec.add_development_dependency 'rake_ssh'
53
+ spec.add_development_dependency 'rake_slack'
55
54
  spec.add_development_dependency 'rspec'
56
55
  spec.add_development_dependency 'rubocop'
57
56
  spec.add_development_dependency 'rubocop-rake'
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lino'
4
+ require 'tempfile'
5
+
6
+ module Enruby
7
+ module Command
8
+ class Base
9
+ # rubocop:disable Metrics/AbcSize
10
+
11
+ def initialize(opts = {})
12
+ @binary = opts[:binary] || configuration.binary
13
+ @logger = opts[:logger] || configuration.logger
14
+ @options = opts[:options] || configuration.options
15
+ @stdin = opts[:stdin] || configuration.stdin
16
+ @stdout = opts[:stdout] || configuration.stdout
17
+ @stderr = opts[:stderr] || configuration.stderr
18
+ end
19
+
20
+ # rubocop:enable Metrics/AbcSize
21
+
22
+ # Executes the command instance.
23
+ #
24
+ # @param [Hash<String, Object>] parameters The parameters used to
25
+ # invoke the command. See subclass documentation for details of
26
+ # supported options.
27
+ # @param [Hash<String, Object>] invocation_options Additional options
28
+ # controlling the invocation of the command.
29
+ # @option invocation_options [Hash<String, String>] :environment A map
30
+ # of environment variables to expose at command invocation time.
31
+ def execute(parameters = {}, invocation_options = {})
32
+ parameters = resolve_parameters(parameters)
33
+ invocation_options = resolve_invocation_options(invocation_options)
34
+
35
+ do_before(parameters)
36
+ result = build_and_execute_command(parameters, invocation_options)
37
+ do_after(parameters)
38
+
39
+ prepare_result(result, parameters, invocation_options)
40
+ rescue Lino::Errors::ExecutionError
41
+ message = "Failed while running '#{command_name}'."
42
+ logger.error(message)
43
+ raise Errors::ExecutionError, message
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :binary, :logger, :stdin, :stdout, :stderr
49
+
50
+ def command_name
51
+ self.class.to_s.split('::')[-1].downcase
52
+ end
53
+
54
+ def do_before(_parameters); end
55
+
56
+ def do_after(_parameters); end
57
+
58
+ def build_command(parameters, invocation_options)
59
+ Lino::CommandLineBuilder
60
+ .for_command(@binary)
61
+ .with_environment_variables(invocation_options[:environment] || {})
62
+ .with_options_after_subcommands
63
+ .with_option_separator('=')
64
+ .with_appliables(@options.resolve(options, parameters))
65
+ .with_subcommands(subcommands)
66
+ .with_arguments(arguments(parameters).compact.flatten)
67
+ .build
68
+ end
69
+
70
+ def process_result(result, _parameters, _invocation_options)
71
+ result
72
+ end
73
+
74
+ def parameter_defaults(_parameters)
75
+ {}
76
+ end
77
+
78
+ def parameter_overrides(_parameters)
79
+ {}
80
+ end
81
+
82
+ def invocation_option_defaults(_invocation_options)
83
+ { capture: [], result: :processed }
84
+ end
85
+
86
+ def subcommands
87
+ []
88
+ end
89
+
90
+ def options
91
+ []
92
+ end
93
+
94
+ def arguments(_parameters)
95
+ []
96
+ end
97
+
98
+ def build_and_execute_command(parameters, invocation_options)
99
+ command = build_command(parameters, invocation_options)
100
+ stdout = resolve_stdout(invocation_options)
101
+ stderr = resolve_stderr(invocation_options)
102
+
103
+ logger.debug("Running '#{command}'.")
104
+ command.execute(stdin:, stdout:, stderr:)
105
+
106
+ process_streams(invocation_options, stdout, stderr)
107
+ end
108
+
109
+ def resolve_parameters(parameters)
110
+ parameter_defaults(parameters)
111
+ .merge(parameters)
112
+ .merge(parameter_overrides(parameters))
113
+ end
114
+
115
+ def resolve_invocation_options(invocation_options)
116
+ invocation_option_defaults(invocation_options)
117
+ .merge(invocation_options)
118
+ end
119
+
120
+ def resolve_stdout(invocation_options)
121
+ invocation_options[:capture].include?(:stdout) ? Tempfile.new : @stdout
122
+ end
123
+
124
+ def resolve_stderr(invocation_options)
125
+ invocation_options[:capture].include?(:stderr) ? Tempfile.new : @stderr
126
+ end
127
+
128
+ def process_streams(invocation_options, stdout, stderr)
129
+ cap = invocation_options[:capture]
130
+
131
+ return nil if cap == []
132
+
133
+ result = {}
134
+ result = add_contents_to_result(cap, result, :stdout, stdout, :output)
135
+ add_contents_to_result(cap, result, :stderr, stderr, :error)
136
+ end
137
+
138
+ def add_contents_to_result(capture, result, stream_name, stream, type)
139
+ return result unless capture.include?(stream_name)
140
+
141
+ stream.rewind
142
+ result.merge({ type => stream.read })
143
+ end
144
+
145
+ def prepare_result(result, parameters, invocation_options)
146
+ return result if invocation_options[:result] == :raw
147
+
148
+ process_result(result, parameters, invocation_options)
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'command/base'
4
+
5
+ module Enruby
6
+ module Command
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mixins'
4
+
5
+ module Enruby
6
+ module Configuration
7
+ class Base
8
+ include Mixins::Streams
9
+ include Mixins::Logging
10
+ include Mixins::Binary
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Enruby
6
+ module Configuration
7
+ module Mixins
8
+ module Binary
9
+ attr_accessor :binary
10
+
11
+ def initialize
12
+ super
13
+ @binary = default_binary
14
+ end
15
+
16
+ private
17
+
18
+ def default_binary
19
+ raise NotImplementedError
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Enruby
6
+ module Configuration
7
+ module Mixins
8
+ module Logging
9
+ attr_accessor :logger
10
+
11
+ def initialize
12
+ super
13
+ @logger = default_logger
14
+ end
15
+
16
+ def default_logger
17
+ logger = Logger.new($stdout)
18
+ logger.level = Logger::INFO
19
+ logger
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enruby
4
+ module Configuration
5
+ module Mixins
6
+ module Streams
7
+ attr_accessor :stdin, :stdout, :stderr
8
+
9
+ def initialize
10
+ super
11
+ @stdin = nil
12
+ @stdout = $stdout
13
+ @stderr = $stderr
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mixins/streams'
4
+ require_relative 'mixins/logging'
5
+ require_relative 'mixins/binary'
6
+
7
+ module Enruby
8
+ module Configuration
9
+ module Mixins
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configuration/base'
4
+
5
+ module Enruby
6
+ module Configuration
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Enruby
4
- VERSION = '0.1.0.pre.3'
4
+ VERSION = '0.1.0.pre.3.pr80.1.1'
5
5
  end
data/lib/enruby.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'enruby/version'
4
+ require_relative 'enruby/command'
5
+ require_relative 'enruby/configuration'
4
6
 
5
7
  module Enruby
6
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.3
4
+ version: 0.1.0.pre.3.pr80.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - InfraBlocks Maintainers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-26 00:00:00.000000000 Z
11
+ date: 2026-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: immutable-struct
@@ -30,20 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '3'
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: '5'
33
+ version: '4.1'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - ">="
42
39
  - !ruby/object:Gem::Version
43
- version: '3'
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: '5'
40
+ version: '4.1'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: bundler
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,20 +122,6 @@ dependencies:
128
122
  - - ">="
129
123
  - !ruby/object:Gem::Version
130
124
  version: '0'
131
- - !ruby/object:Gem::Dependency
132
- name: rake_circle_ci
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - ">="
136
- - !ruby/object:Gem::Version
137
- version: '0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - ">="
143
- - !ruby/object:Gem::Version
144
- version: '0'
145
125
  - !ruby/object:Gem::Dependency
146
126
  name: rake_git
147
127
  requirement: !ruby/object:Gem::Requirement
@@ -199,7 +179,7 @@ dependencies:
199
179
  - !ruby/object:Gem::Version
200
180
  version: '0'
201
181
  - !ruby/object:Gem::Dependency
202
- name: rake_ssh
182
+ name: rake_slack
203
183
  requirement: !ruby/object:Gem::Requirement
204
184
  requirements:
205
185
  - - ">="
@@ -327,13 +307,21 @@ files:
327
307
  - bin/setup
328
308
  - enruby.gemspec
329
309
  - lib/enruby.rb
310
+ - lib/enruby/command.rb
311
+ - lib/enruby/command/base.rb
312
+ - lib/enruby/configuration.rb
313
+ - lib/enruby/configuration/base.rb
314
+ - lib/enruby/configuration/mixins.rb
315
+ - lib/enruby/configuration/mixins/binary.rb
316
+ - lib/enruby/configuration/mixins/logging.rb
317
+ - lib/enruby/configuration/mixins/streams.rb
330
318
  - lib/enruby/version.rb
331
319
  homepage: https://github.com/infrablocks/enruby
332
320
  licenses:
333
321
  - MIT
334
322
  metadata:
335
323
  rubygems_mfa_required: 'false'
336
- post_install_message:
324
+ post_install_message:
337
325
  rdoc_options: []
338
326
  require_paths:
339
327
  - lib
@@ -341,15 +329,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
341
329
  requirements:
342
330
  - - ">="
343
331
  - !ruby/object:Gem::Version
344
- version: '3.1'
332
+ version: '3.3'
345
333
  required_rubygems_version: !ruby/object:Gem::Requirement
346
334
  requirements:
347
- - - ">"
335
+ - - ">="
348
336
  - !ruby/object:Gem::Version
349
- version: 1.3.1
337
+ version: '0'
350
338
  requirements: []
351
- rubygems_version: 3.3.26
352
- signing_key:
339
+ rubygems_version: 3.5.22
340
+ signing_key:
353
341
  specification_version: 4
354
342
  summary: A framework for creating Ruby command line tool wrappers.
355
343
  test_files: []