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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b270bade909acb9e7805983022b54951c14048c9964f758a011448400cc8e492
4
- data.tar.gz: 5045f0d977f5113886e6c35d8288a5eb9ca697a24f529a097ff9f61ceda70e62
3
+ metadata.gz: a2fdf896084fbec37ad190f81188a0e470aaf30c491acb77df209e3b6d3da6cf
4
+ data.tar.gz: 3310a848c676685907bec54adba6b2eb76be56a811cf73f1dd56fb4a3953ddd7
5
5
  SHA512:
6
- metadata.gz: 9ea8d52d648ab2cf4d79d7a35a1877a53e7bff26fab0ece31d0d4b3b46172b04aeadef115395bd154f60bfc418acdfd8b0b7bdca20cb6affc499751ba8bb8687
7
- data.tar.gz: 2ff7f43419014b05dab1e12c15200eb612c81966bc9611b47b88f6127aad8ceafd423514a70f1f876600d590be41646ca675fc15e8d78a8c70a43e2c92498112
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
- env_file = svc[:env_file]
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
- env_vars.each do |var_name, var_config|
77
- next unless var_config.is_a?(Hash) && var_config['variations']
56
+ env_file_configs = build_env_file_configs(svc)
57
+ return if env_file_configs.empty?
78
58
 
79
- variation = (variation_overrides[var_name] || variation_overrides[var_name.to_sym] || 'local').to_s
80
- value = var_config['variations'][variation]
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, skip_env: true, skip_window_creation: true)
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
- env_vars = svc[:env_vars]
706
- unless env_vars
707
- puts "No env_vars configured for '#{svc[:name]}'"
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 vars for '#{svc[:name]}':"
712
- puts
713
- env_vars.each do |var_name, var_config|
714
- next unless var_config.is_a?(Hash) && var_config['variations']
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
- puts " #{var_name}:"
717
- var_config['variations'].each do |variation, value|
718
- puts " #{variation}: #{value}"
719
- end
720
- end
683
+ env_vars = efc[:env_vars]
684
+ next unless env_vars
721
685
 
722
- if svc[:base_env]
723
- puts
724
- puts "Base env template: #{svc[:base_env]}"
725
- end
726
- if svc[:env_file]
727
- puts "Env file: #{svc[:env_file]}"
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
@@ -1,3 +1,3 @@
1
1
  class Hiiro
2
- VERSION = "0.1.153"
2
+ VERSION = "0.1.154"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiiro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.153
4
+ version: 0.1.154
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Toyota