hiiro 0.1.155 → 0.1.157
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/examples/services.sleepers.yml +41 -0
- data/examples/services.yml +7 -5
- data/lib/hiiro/service_manager.rb +72 -33
- data/lib/hiiro/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a1dfe8868ee27e926e81edb4d93f9dd75bab129a493985a00505a267088e32c
|
|
4
|
+
data.tar.gz: c5f7a4fb1aea909d05ebb8e00a737bc28bf7524a19e4f52f7af518aba508d5f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9dc4b695cbb678fa4ec76e940baba3356c67f6eeb551bcef4dd7f42de63c247fe42b9b98403a08ff7b0af406de0ce109d7bdbac9eda37dee71938b432566f114
|
|
7
|
+
data.tar.gz: f16b50413fd3c6e01b206bc385f08157fa504466470ad1dbb84dd9513c0253961f2c5a81f928fff0334241d40ac7fb1d64dd1a3e3e62da835e0ca4ea5b952cc8
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
s1:
|
|
3
|
+
base_dir: lib
|
|
4
|
+
host: localhost
|
|
5
|
+
port: '1111'
|
|
6
|
+
init:
|
|
7
|
+
- 'echo pwd: $PWD'
|
|
8
|
+
- pwd
|
|
9
|
+
- echo
|
|
10
|
+
- echo sleeper 1
|
|
11
|
+
start:
|
|
12
|
+
- sleep 1d
|
|
13
|
+
cleanup:
|
|
14
|
+
- ls -lA
|
|
15
|
+
env_files:
|
|
16
|
+
- env_file: ".env"
|
|
17
|
+
base_env: ''
|
|
18
|
+
env_vars:
|
|
19
|
+
hello: world
|
|
20
|
+
s2:
|
|
21
|
+
base_dir: lib
|
|
22
|
+
host: localhost
|
|
23
|
+
port: '2222'
|
|
24
|
+
init:
|
|
25
|
+
- 'echo pwd: $PWD'
|
|
26
|
+
- pwd
|
|
27
|
+
- echo
|
|
28
|
+
- echo sleeper 2
|
|
29
|
+
start:
|
|
30
|
+
- sleep 2d
|
|
31
|
+
cleanup:
|
|
32
|
+
- ls -lA
|
|
33
|
+
env_files:
|
|
34
|
+
- env_file: ".env"
|
|
35
|
+
base_env: ''
|
|
36
|
+
env_vars:
|
|
37
|
+
bye: world
|
|
38
|
+
ss:
|
|
39
|
+
services:
|
|
40
|
+
- name: s1
|
|
41
|
+
- name: s2
|
data/examples/services.yml
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Example services.yml
|
|
2
2
|
# Place at ~/.config/hiiro/services.yml
|
|
3
3
|
#
|
|
4
|
+
# base_dir is always relative to the repo root (where init/start commands run)
|
|
5
|
+
#
|
|
4
6
|
# Base env templates referenced by base_env live in:
|
|
5
7
|
# ~/.config/hiiro/env_templates/
|
|
6
8
|
|
|
@@ -22,7 +24,7 @@ redis:
|
|
|
22
24
|
# Rails API - multiple init steps, single env file with variations
|
|
23
25
|
# =============================================================================
|
|
24
26
|
api-rails:
|
|
25
|
-
base_dir:
|
|
27
|
+
base_dir: apps/api
|
|
26
28
|
host: localhost
|
|
27
29
|
port: 3000
|
|
28
30
|
init:
|
|
@@ -67,7 +69,7 @@ api-rails:
|
|
|
67
69
|
# GraphQL service - multiple env files
|
|
68
70
|
# =============================================================================
|
|
69
71
|
graphql:
|
|
70
|
-
base_dir:
|
|
72
|
+
base_dir: services/graphql
|
|
71
73
|
host: localhost
|
|
72
74
|
port: 4000
|
|
73
75
|
init:
|
|
@@ -118,7 +120,7 @@ graphql:
|
|
|
118
120
|
# Frontend - depends on graphql URL
|
|
119
121
|
# =============================================================================
|
|
120
122
|
frontend:
|
|
121
|
-
base_dir:
|
|
123
|
+
base_dir: apps/frontend
|
|
122
124
|
host: localhost
|
|
123
125
|
port: 8080
|
|
124
126
|
start:
|
|
@@ -149,7 +151,7 @@ frontend:
|
|
|
149
151
|
# Worker with custom stop command
|
|
150
152
|
# =============================================================================
|
|
151
153
|
sidekiq:
|
|
152
|
-
base_dir:
|
|
154
|
+
base_dir: apps/api
|
|
153
155
|
host: localhost
|
|
154
156
|
port: ""
|
|
155
157
|
start:
|
|
@@ -172,7 +174,7 @@ sidekiq:
|
|
|
172
174
|
# Multi-command start - seed data then launch
|
|
173
175
|
# =============================================================================
|
|
174
176
|
demo-server:
|
|
175
|
-
base_dir:
|
|
177
|
+
base_dir: apps/demo
|
|
176
178
|
host: localhost
|
|
177
179
|
port: 5000
|
|
178
180
|
init:
|
|
@@ -50,8 +50,7 @@ class Hiiro
|
|
|
50
50
|
svc = find_service(svc_name)
|
|
51
51
|
return unless svc
|
|
52
52
|
|
|
53
|
-
base_dir = svc[:base_dir]
|
|
54
|
-
return unless base_dir
|
|
53
|
+
base_dir = resolve_base_dir(svc[:base_dir])
|
|
55
54
|
|
|
56
55
|
env_file_configs = build_env_file_configs(svc)
|
|
57
56
|
return if env_file_configs.empty?
|
|
@@ -86,7 +85,7 @@ class Hiiro
|
|
|
86
85
|
first_member = members.first
|
|
87
86
|
first_name = first_member['name'] || first_member[:name]
|
|
88
87
|
first_svc = find_service(first_name)
|
|
89
|
-
first_base_dir = first_svc&.[](:base_dir)
|
|
88
|
+
first_base_dir = resolve_base_dir(first_svc&.[](:base_dir))
|
|
90
89
|
|
|
91
90
|
# Create a new window for the group
|
|
92
91
|
window_target = create_tmux_window(session, group[:name], first_base_dir)
|
|
@@ -99,7 +98,7 @@ class Hiiro
|
|
|
99
98
|
svc = find_service(member_name)
|
|
100
99
|
next unless svc
|
|
101
100
|
|
|
102
|
-
base_dir = svc[:base_dir]
|
|
101
|
+
base_dir = resolve_base_dir(svc[:base_dir])
|
|
103
102
|
|
|
104
103
|
if idx == 0
|
|
105
104
|
# First service uses the initial pane
|
|
@@ -182,40 +181,29 @@ class Hiiro
|
|
|
182
181
|
return false
|
|
183
182
|
end
|
|
184
183
|
|
|
185
|
-
# Run init commands
|
|
186
|
-
if svc[:init]
|
|
187
|
-
svc[:init].each do |cmd|
|
|
188
|
-
base_dir = svc[:base_dir]
|
|
189
|
-
if base_dir
|
|
190
|
-
system("cd #{base_dir} && #{cmd}")
|
|
191
|
-
else
|
|
192
|
-
system(cmd)
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
end
|
|
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
|
-
|
|
202
|
-
# Start the service
|
|
203
184
|
start_cmd = svc[:start]
|
|
204
185
|
unless start_cmd
|
|
205
186
|
puts "No start command configured for '#{svc_name}'"
|
|
206
187
|
return false
|
|
207
188
|
end
|
|
208
189
|
|
|
190
|
+
# Build separate init/env/start scripts + a launcher that runs them in order
|
|
191
|
+
init_cmds = Array(svc[:init] || [])
|
|
209
192
|
start_cmds = Array(start_cmd)
|
|
210
|
-
|
|
193
|
+
script = write_launcher_script(
|
|
194
|
+
svc_name,
|
|
195
|
+
init_cmds: init_cmds,
|
|
196
|
+
start_cmds: start_cmds,
|
|
197
|
+
env_prep: !skip_env,
|
|
198
|
+
variation_overrides: variation_overrides,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
base_dir = resolve_base_dir(svc[:base_dir])
|
|
211
202
|
session = tmux_info[:session] || current_tmux_session
|
|
212
203
|
|
|
213
|
-
# Write start commands to an executable tempfile
|
|
214
|
-
script = write_start_script(svc_name, start_cmds)
|
|
215
|
-
|
|
216
204
|
if session && !skip_window_creation
|
|
217
205
|
# Create a new tmux window for this service
|
|
218
|
-
window_target = create_tmux_window(session, svc_name, base_dir
|
|
206
|
+
window_target = create_tmux_window(session, svc_name, base_dir)
|
|
219
207
|
pane_id = capture_pane_id(window_target)
|
|
220
208
|
elsif session && skip_window_creation
|
|
221
209
|
# Pane already created by start_group
|
|
@@ -228,10 +216,8 @@ class Hiiro
|
|
|
228
216
|
|
|
229
217
|
if pane_id
|
|
230
218
|
system('tmux', 'send-keys', '-t', pane_id, script, 'Enter')
|
|
231
|
-
elsif base_dir
|
|
232
|
-
system("cd #{base_dir} && #{script} &")
|
|
233
219
|
else
|
|
234
|
-
system("#{script} &")
|
|
220
|
+
system("cd #{base_dir} && #{script} &")
|
|
235
221
|
end
|
|
236
222
|
|
|
237
223
|
# Record state
|
|
@@ -761,19 +747,63 @@ class Hiiro
|
|
|
761
747
|
!system('tmux', 'has-session', '-t', pane_id, [:out, :err] => '/dev/null')
|
|
762
748
|
end
|
|
763
749
|
|
|
764
|
-
def
|
|
750
|
+
def scripts_dir
|
|
765
751
|
dir = File.join(STATE_DIR, 'scripts')
|
|
766
752
|
FileUtils.mkdir_p(dir)
|
|
767
|
-
|
|
753
|
+
dir
|
|
754
|
+
end
|
|
768
755
|
|
|
756
|
+
def write_shell_script(path, cmds)
|
|
769
757
|
lines = ["#!/usr/bin/env bash", "set -e"]
|
|
770
758
|
lines.concat(cmds)
|
|
771
|
-
|
|
772
759
|
File.write(path, lines.join("\n") + "\n")
|
|
773
760
|
File.chmod(0755, path)
|
|
774
761
|
path
|
|
775
762
|
end
|
|
776
763
|
|
|
764
|
+
def write_env_prep_script(svc_name, variation_overrides)
|
|
765
|
+
path = File.join(scripts_dir, "#{svc_name}-env.rb")
|
|
766
|
+
overrides_literal = variation_overrides.map { |k, v| "#{k.inspect} => #{v.inspect}" }.join(", ")
|
|
767
|
+
|
|
768
|
+
code = <<~RUBY
|
|
769
|
+
#!/usr/bin/env ruby
|
|
770
|
+
require 'hiiro'
|
|
771
|
+
sm = Hiiro::ServiceManager.new
|
|
772
|
+
sm.prepare_env(#{svc_name.inspect}, variation_overrides: { #{overrides_literal} })
|
|
773
|
+
RUBY
|
|
774
|
+
|
|
775
|
+
File.write(path, code)
|
|
776
|
+
File.chmod(0755, path)
|
|
777
|
+
path
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
def write_launcher_script(svc_name, init_cmds:, start_cmds:, env_prep: true, variation_overrides: {})
|
|
781
|
+
dir = scripts_dir
|
|
782
|
+
|
|
783
|
+
# Write init script (may be empty)
|
|
784
|
+
init_path = File.join(dir, "#{svc_name}-init.sh")
|
|
785
|
+
write_shell_script(init_path, init_cmds)
|
|
786
|
+
|
|
787
|
+
# Write start script
|
|
788
|
+
start_path = File.join(dir, "#{svc_name}-start.sh")
|
|
789
|
+
write_shell_script(start_path, start_cmds)
|
|
790
|
+
|
|
791
|
+
# Write env prep script
|
|
792
|
+
env_path = nil
|
|
793
|
+
if env_prep
|
|
794
|
+
env_path = write_env_prep_script(svc_name, variation_overrides)
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
# Write launcher that orchestrates: init -> env -> start
|
|
798
|
+
launcher_path = File.join(dir, "#{svc_name}.sh")
|
|
799
|
+
steps = []
|
|
800
|
+
steps << init_path unless init_cmds.empty?
|
|
801
|
+
steps << env_path if env_path
|
|
802
|
+
steps << "exec #{start_path}"
|
|
803
|
+
|
|
804
|
+
write_shell_script(launcher_path, steps)
|
|
805
|
+
end
|
|
806
|
+
|
|
777
807
|
def current_tmux_session
|
|
778
808
|
return nil unless ENV['TMUX']
|
|
779
809
|
`tmux display-message -p '#S'`.chomp
|
|
@@ -817,5 +847,14 @@ class Hiiro
|
|
|
817
847
|
def symbolize_keys(hash)
|
|
818
848
|
hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
|
819
849
|
end
|
|
850
|
+
|
|
851
|
+
def resolve_base_dir(base_dir)
|
|
852
|
+
return Dir.pwd if base_dir.nil? || base_dir.to_s.empty?
|
|
853
|
+
|
|
854
|
+
git_root = `git rev-parse --show-toplevel 2>/dev/null`.chomp
|
|
855
|
+
root = git_root.empty? ? Dir.pwd : git_root
|
|
856
|
+
|
|
857
|
+
File.join(root, base_dir)
|
|
858
|
+
end
|
|
820
859
|
end
|
|
821
860
|
end
|
data/lib/hiiro/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hiiro
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.157
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Toyota
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pry
|
|
@@ -113,6 +113,7 @@ files:
|
|
|
113
113
|
- docs/h-session.md
|
|
114
114
|
- docs/h-window.md
|
|
115
115
|
- editboth
|
|
116
|
+
- examples/services.sleepers.yml
|
|
116
117
|
- examples/services.yml
|
|
117
118
|
- exe/h
|
|
118
119
|
- exe/hiiro
|