hiiro 0.1.153 → 0.1.154
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/README.md +115 -0
- data/lib/hiiro/service_manager.rb +90 -66
- data/lib/hiiro/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a2fdf896084fbec37ad190f81188a0e470aaf30c491acb77df209e3b6d3da6cf
|
|
4
|
+
data.tar.gz: 3310a848c676685907bec54adba6b2eb76be56a811cf73f1dd56fb4a3953ddd7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 85fe854d98a6ffa72e9df07b3816bd8a0e20ca044667afabefd8cd5918264804b8d92f85c464301aaf3275be71ba410399ab27499473ffb3b4b163e872040bff
|
|
7
|
+
data.tar.gz: 0ea45cfd61f388f051c50eca1fc6a7f1f46039cd56f6129dc03b12e5a93ad952298225d18ea0cb078aabea04f78fcf4e27ae6662d54abeb45bdaa9ffd0dba590
|
data/README.md
CHANGED
|
@@ -241,3 +241,118 @@ bundle exec rake test
|
|
|
241
241
|
## License
|
|
242
242
|
|
|
243
243
|
MIT
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# COMPLEX SERVICES
|
|
247
|
+
|
|
248
|
+
```sh
|
|
249
|
+
|
|
250
|
+
❯ in this setup...can you configure a couple complex services that use variations, etc. i need examples of how to configure it. and then can you show me how to run it for different variations
|
|
251
|
+
|
|
252
|
+
⏺ Here's an example ~/.config/hiiro/services.yml:
|
|
253
|
+
|
|
254
|
+
# Individual services
|
|
255
|
+
api-rails:
|
|
256
|
+
base_dir: ~/work/api
|
|
257
|
+
host: localhost
|
|
258
|
+
port: 3000
|
|
259
|
+
init:
|
|
260
|
+
- bundle install
|
|
261
|
+
start:
|
|
262
|
+
- bin/rails s -p 3000
|
|
263
|
+
cleanup: []
|
|
264
|
+
env_file: .env.development
|
|
265
|
+
base_env: api-rails.env
|
|
266
|
+
env_vars:
|
|
267
|
+
DATABASE_URL:
|
|
268
|
+
variations:
|
|
269
|
+
local: postgres://localhost:5432/api_dev
|
|
270
|
+
docker: postgres://db:5432/api_dev
|
|
271
|
+
REDIS_URL:
|
|
272
|
+
variations:
|
|
273
|
+
local: redis://localhost:6379
|
|
274
|
+
docker: redis://redis:6379
|
|
275
|
+
|
|
276
|
+
graphql:
|
|
277
|
+
base_dir: ~/work/graphql
|
|
278
|
+
host: localhost
|
|
279
|
+
port: 4000
|
|
280
|
+
init:
|
|
281
|
+
- npm install
|
|
282
|
+
start:
|
|
283
|
+
- npm run dev
|
|
284
|
+
env_file: .env.local
|
|
285
|
+
base_env: graphql.env
|
|
286
|
+
env_vars:
|
|
287
|
+
API_URL:
|
|
288
|
+
variations:
|
|
289
|
+
local: http://localhost:3000
|
|
290
|
+
staging: https://api.staging.example.com
|
|
291
|
+
AUTH_PROVIDER:
|
|
292
|
+
variations:
|
|
293
|
+
local: http://localhost:8080/auth
|
|
294
|
+
staging: https://auth.staging.example.com
|
|
295
|
+
|
|
296
|
+
frontend:
|
|
297
|
+
base_dir: ~/work/frontend
|
|
298
|
+
host: localhost
|
|
299
|
+
port: 8080
|
|
300
|
+
start:
|
|
301
|
+
- npm run dev
|
|
302
|
+
env_file: .env.local
|
|
303
|
+
base_env: frontend.env
|
|
304
|
+
env_vars:
|
|
305
|
+
GRAPHQL_URL:
|
|
306
|
+
variations:
|
|
307
|
+
local: http://localhost:4000/graphql
|
|
308
|
+
staging: https://graphql.staging.example.com/graphql
|
|
309
|
+
|
|
310
|
+
# Service groups
|
|
311
|
+
full-stack:
|
|
312
|
+
services:
|
|
313
|
+
- name: api-rails
|
|
314
|
+
use:
|
|
315
|
+
DATABASE_URL: local
|
|
316
|
+
REDIS_URL: local
|
|
317
|
+
- name: graphql
|
|
318
|
+
use:
|
|
319
|
+
API_URL: local
|
|
320
|
+
AUTH_PROVIDER: local
|
|
321
|
+
- name: frontend
|
|
322
|
+
use:
|
|
323
|
+
GRAPHQL_URL: local
|
|
324
|
+
|
|
325
|
+
staging-fe:
|
|
326
|
+
services:
|
|
327
|
+
- name: graphql
|
|
328
|
+
use:
|
|
329
|
+
API_URL: staging
|
|
330
|
+
AUTH_PROVIDER: staging
|
|
331
|
+
- name: frontend
|
|
332
|
+
use:
|
|
333
|
+
GRAPHQL_URL: local
|
|
334
|
+
|
|
335
|
+
Usage:
|
|
336
|
+
|
|
337
|
+
# Start a single service (defaults to "local" variations)
|
|
338
|
+
h service start api-rails
|
|
339
|
+
|
|
340
|
+
# Start with specific variations
|
|
341
|
+
h service start api-rails --use DATABASE_URL=docker --use REDIS_URL=docker
|
|
342
|
+
|
|
343
|
+
# Start the full local stack (one window, 3 split panes)
|
|
344
|
+
h service start full-stack
|
|
345
|
+
|
|
346
|
+
# Start frontend pointing at staging backends
|
|
347
|
+
h service start staging-fe
|
|
348
|
+
|
|
349
|
+
# No args — fuzzy select from all services + groups
|
|
350
|
+
h service start
|
|
351
|
+
|
|
352
|
+
The key ideas:
|
|
353
|
+
- local is the default variation — if you don't pass --use, each env var gets its local value
|
|
354
|
+
- Groups let you pre-bake variation combos — full-stack vs staging-fe are just different use: presets for the same services
|
|
355
|
+
- Base env templates live in ~/.config/hiiro/env_templates/ (e.g., api-rails.env) — they get copied to base_dir/env_file first, then variations are injected on top
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
```
|
|
@@ -50,50 +50,15 @@ class Hiiro
|
|
|
50
50
|
svc = find_service(svc_name)
|
|
51
51
|
return unless svc
|
|
52
52
|
|
|
53
|
-
env_vars = svc[:env_vars]
|
|
54
|
-
return unless env_vars || svc[:base_env]
|
|
55
|
-
|
|
56
53
|
base_dir = svc[:base_dir]
|
|
57
|
-
|
|
58
|
-
base_env = svc[:base_env]
|
|
59
|
-
|
|
60
|
-
# Copy base env template if configured
|
|
61
|
-
if base_env && env_file && base_dir
|
|
62
|
-
src = File.join(ENV_TEMPLATES_DIR, base_env)
|
|
63
|
-
dest = File.join(base_dir, env_file)
|
|
64
|
-
if File.exist?(src)
|
|
65
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
66
|
-
FileUtils.cp(src, dest)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Inject variation values into env file
|
|
71
|
-
return unless env_vars && env_file && base_dir
|
|
72
|
-
|
|
73
|
-
dest = File.join(base_dir, env_file)
|
|
74
|
-
lines = File.exist?(dest) ? File.readlines(dest) : []
|
|
54
|
+
return unless base_dir
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
env_file_configs = build_env_file_configs(svc)
|
|
57
|
+
return if env_file_configs.empty?
|
|
78
58
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
next unless value
|
|
82
|
-
|
|
83
|
-
# Replace existing line or append
|
|
84
|
-
replaced = false
|
|
85
|
-
lines.map! do |line|
|
|
86
|
-
if line.match?(/\A#{Regexp.escape(var_name)}=/)
|
|
87
|
-
replaced = true
|
|
88
|
-
"#{var_name}=#{value}\n"
|
|
89
|
-
else
|
|
90
|
-
line
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
lines << "#{var_name}=#{value}\n" unless replaced
|
|
59
|
+
env_file_configs.each do |efc|
|
|
60
|
+
prepare_single_env(base_dir, efc, variation_overrides)
|
|
94
61
|
end
|
|
95
|
-
|
|
96
|
-
File.write(dest, lines.join)
|
|
97
62
|
end
|
|
98
63
|
|
|
99
64
|
def start_group(name, tmux_info: {}, task_info: {})
|
|
@@ -131,8 +96,6 @@ class Hiiro
|
|
|
131
96
|
member_name = member['name'] || member[:name]
|
|
132
97
|
use_overrides = member['use'] || member[:use] || {}
|
|
133
98
|
|
|
134
|
-
prepare_env(member_name, variation_overrides: use_overrides)
|
|
135
|
-
|
|
136
99
|
svc = find_service(member_name)
|
|
137
100
|
next unless svc
|
|
138
101
|
|
|
@@ -152,7 +115,7 @@ class Hiiro
|
|
|
152
115
|
pane: pane_id,
|
|
153
116
|
)
|
|
154
117
|
|
|
155
|
-
start(member_name, tmux_info: member_tmux_info, task_info: task_info,
|
|
118
|
+
start(member_name, tmux_info: member_tmux_info, task_info: task_info, variation_overrides: use_overrides, skip_window_creation: true)
|
|
156
119
|
end
|
|
157
120
|
true
|
|
158
121
|
end
|
|
@@ -219,11 +182,6 @@ class Hiiro
|
|
|
219
182
|
return false
|
|
220
183
|
end
|
|
221
184
|
|
|
222
|
-
# Prepare env file unless already handled by start_group
|
|
223
|
-
unless skip_env
|
|
224
|
-
prepare_env(svc_name, variation_overrides: variation_overrides)
|
|
225
|
-
end
|
|
226
|
-
|
|
227
185
|
# Run init commands
|
|
228
186
|
if svc[:init]
|
|
229
187
|
svc[:init].each do |cmd|
|
|
@@ -236,6 +194,11 @@ class Hiiro
|
|
|
236
194
|
end
|
|
237
195
|
end
|
|
238
196
|
|
|
197
|
+
# Prepare env files after init (e.g., init may install deps that generate .env templates)
|
|
198
|
+
unless skip_env
|
|
199
|
+
prepare_env(svc_name, variation_overrides: variation_overrides)
|
|
200
|
+
end
|
|
201
|
+
|
|
239
202
|
# Start the service
|
|
240
203
|
start_cmd = svc[:start]
|
|
241
204
|
unless start_cmd
|
|
@@ -628,6 +591,9 @@ class Hiiro
|
|
|
628
591
|
'init' => [],
|
|
629
592
|
'start' => [''],
|
|
630
593
|
'cleanup' => [],
|
|
594
|
+
'env_files' => [
|
|
595
|
+
{ 'env_file' => '.env', 'base_env' => '', 'env_vars' => {} },
|
|
596
|
+
],
|
|
631
597
|
}
|
|
632
598
|
|
|
633
599
|
require 'tempfile'
|
|
@@ -702,29 +668,30 @@ class Hiiro
|
|
|
702
668
|
next
|
|
703
669
|
end
|
|
704
670
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
puts "No
|
|
671
|
+
configs = sm.send(:build_env_file_configs, svc)
|
|
672
|
+
if configs.empty?
|
|
673
|
+
puts "No env files configured for '#{svc[:name]}'"
|
|
708
674
|
next
|
|
709
675
|
end
|
|
710
676
|
|
|
711
|
-
puts "Env
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
677
|
+
puts "Env files for '#{svc[:name]}':"
|
|
678
|
+
configs.each do |efc|
|
|
679
|
+
puts
|
|
680
|
+
puts " #{efc[:env_file] || '(no dest)'}"
|
|
681
|
+
puts " template: #{efc[:base_env]}" if efc[:base_env]
|
|
715
682
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
puts " #{variation}: #{value}"
|
|
719
|
-
end
|
|
720
|
-
end
|
|
683
|
+
env_vars = efc[:env_vars]
|
|
684
|
+
next unless env_vars
|
|
721
685
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
686
|
+
env_vars.each do |var_name, var_config|
|
|
687
|
+
variations = var_config.is_a?(Hash) && (var_config['variations'] || var_config[:variations])
|
|
688
|
+
next unless variations
|
|
689
|
+
|
|
690
|
+
puts " #{var_name}:"
|
|
691
|
+
variations.each do |variation, value|
|
|
692
|
+
puts " #{variation}: #{value}"
|
|
693
|
+
end
|
|
694
|
+
end
|
|
728
695
|
end
|
|
729
696
|
end
|
|
730
697
|
end
|
|
@@ -732,6 +699,63 @@ class Hiiro
|
|
|
732
699
|
|
|
733
700
|
private
|
|
734
701
|
|
|
702
|
+
# Normalize env file config into an array of hashes,
|
|
703
|
+
# supporting both old single-env format and new env_files array
|
|
704
|
+
def build_env_file_configs(svc)
|
|
705
|
+
if svc[:env_files]
|
|
706
|
+
Array(svc[:env_files]).map { |ef| symbolize_keys(ef.is_a?(Hash) ? ef : {}) }
|
|
707
|
+
elsif svc[:env_file] || svc[:base_env] || svc[:env_vars]
|
|
708
|
+
[{ env_file: svc[:env_file], base_env: svc[:base_env], env_vars: svc[:env_vars] }]
|
|
709
|
+
else
|
|
710
|
+
[]
|
|
711
|
+
end
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
def prepare_single_env(base_dir, efc, variation_overrides)
|
|
715
|
+
env_file = efc[:env_file]
|
|
716
|
+
base_env = efc[:base_env]
|
|
717
|
+
env_vars = efc[:env_vars]
|
|
718
|
+
|
|
719
|
+
# Copy base env template if configured
|
|
720
|
+
if base_env && env_file
|
|
721
|
+
src = File.join(ENV_TEMPLATES_DIR, base_env)
|
|
722
|
+
dest = File.join(base_dir, env_file)
|
|
723
|
+
if File.exist?(src)
|
|
724
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
725
|
+
FileUtils.cp(src, dest)
|
|
726
|
+
end
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
# Inject variation values into env file
|
|
730
|
+
return unless env_vars && env_file
|
|
731
|
+
|
|
732
|
+
dest = File.join(base_dir, env_file)
|
|
733
|
+
lines = File.exist?(dest) ? File.readlines(dest) : []
|
|
734
|
+
|
|
735
|
+
env_vars.each do |var_name, var_config|
|
|
736
|
+
var_config = symbolize_keys(var_config) if var_config.is_a?(Hash)
|
|
737
|
+
variations = var_config.is_a?(Hash) && (var_config[:variations] || var_config['variations'])
|
|
738
|
+
next unless variations
|
|
739
|
+
|
|
740
|
+
variation = (variation_overrides[var_name] || variation_overrides[var_name.to_sym] || 'local').to_s
|
|
741
|
+
value = variations[variation]
|
|
742
|
+
next unless value
|
|
743
|
+
|
|
744
|
+
replaced = false
|
|
745
|
+
lines.map! do |line|
|
|
746
|
+
if line.match?(/\A#{Regexp.escape(var_name.to_s)}=/)
|
|
747
|
+
replaced = true
|
|
748
|
+
"#{var_name}=#{value}\n"
|
|
749
|
+
else
|
|
750
|
+
line
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
lines << "#{var_name}=#{value}\n" unless replaced
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
File.write(dest, lines.join)
|
|
757
|
+
end
|
|
758
|
+
|
|
735
759
|
def stale_pane?(pane_id)
|
|
736
760
|
return true unless pane_id
|
|
737
761
|
!system('tmux', 'has-session', '-t', pane_id, [:out, :err] => '/dev/null')
|
data/lib/hiiro/version.rb
CHANGED