hiiro 0.1.150 → 0.1.152
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/lib/hiiro/service_manager.rb +159 -21
- 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: ca8a2bc3e8f629e23986cd1f75bdcca6fc2cd0aaabf85fbde2ae00e721077178
|
|
4
|
+
data.tar.gz: 1bfc80f8f3f0844bbc943c23f48258577f7d3b7cea66dd48319893e7f3289aa7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05dfbdf2fdef32ec3471b8f26efefc26f07b171b0886c6f9beb55ea7008218165cc126f762cd1ef5e391511815b42eb479aa0dcdff9cc5831b885a8c4ea15b52
|
|
7
|
+
data.tar.gz: b9645c6341b3cf753d209b7fcac576264788156a646042a5601d4e4f1269478fd87ab8d93024448ad2ce8eb410d01cd7cd410c26d20f0ebd71007967f6f6a028
|
|
@@ -109,13 +109,50 @@ class Hiiro
|
|
|
109
109
|
return false
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
+
session = tmux_info[:session] || current_tmux_session
|
|
113
|
+
unless session
|
|
114
|
+
puts "tmux is required to start a service group"
|
|
115
|
+
return false
|
|
116
|
+
end
|
|
117
|
+
|
|
112
118
|
puts "Starting group '#{group[:name]}'..."
|
|
113
|
-
|
|
119
|
+
|
|
120
|
+
# Create one window for the group, split panes for each service
|
|
121
|
+
first_member = members.first
|
|
122
|
+
first_name = first_member['name'] || first_member[:name]
|
|
123
|
+
first_svc = find_service(first_name)
|
|
124
|
+
first_base_dir = first_svc&.[](:base_dir) || Dir.pwd
|
|
125
|
+
|
|
126
|
+
# Create a new window for the group
|
|
127
|
+
window_target = create_tmux_window(session, group[:name], first_base_dir)
|
|
128
|
+
first_pane_id = capture_pane_id(window_target)
|
|
129
|
+
|
|
130
|
+
members.each_with_index do |member, idx|
|
|
114
131
|
member_name = member['name'] || member[:name]
|
|
115
132
|
use_overrides = member['use'] || member[:use] || {}
|
|
116
133
|
|
|
117
134
|
prepare_env(member_name, variation_overrides: use_overrides)
|
|
118
|
-
|
|
135
|
+
|
|
136
|
+
svc = find_service(member_name)
|
|
137
|
+
next unless svc
|
|
138
|
+
|
|
139
|
+
base_dir = svc[:base_dir] || Dir.pwd
|
|
140
|
+
|
|
141
|
+
if idx == 0
|
|
142
|
+
# First service uses the initial pane
|
|
143
|
+
pane_id = first_pane_id
|
|
144
|
+
else
|
|
145
|
+
# Subsequent services get split panes
|
|
146
|
+
pane_id = split_tmux_pane(window_target, base_dir)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
member_tmux_info = tmux_info.merge(
|
|
150
|
+
session: session,
|
|
151
|
+
window: window_target,
|
|
152
|
+
pane: pane_id,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
start(member_name, tmux_info: member_tmux_info, task_info: task_info, skip_env: true, skip_window_creation: true)
|
|
119
156
|
end
|
|
120
157
|
true
|
|
121
158
|
end
|
|
@@ -129,7 +166,45 @@ class Hiiro
|
|
|
129
166
|
load_state
|
|
130
167
|
end
|
|
131
168
|
|
|
132
|
-
def
|
|
169
|
+
def reset(name)
|
|
170
|
+
svc = find_service(name)
|
|
171
|
+
unless svc
|
|
172
|
+
puts "Service '#{name}' not found"
|
|
173
|
+
return false
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
svc_name = svc[:name]
|
|
177
|
+
state = load_state
|
|
178
|
+
unless state.key?(svc_name)
|
|
179
|
+
puts "Service '#{svc_name}' is not in running state"
|
|
180
|
+
return false
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
state.delete(svc_name)
|
|
184
|
+
save_state(state)
|
|
185
|
+
puts "Reset service '#{svc_name}' (cleared from running state)"
|
|
186
|
+
true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def clean
|
|
190
|
+
state = load_state
|
|
191
|
+
return puts("No running services to clean") if state.empty?
|
|
192
|
+
|
|
193
|
+
stale = state.select { |_, info| stale_pane?(info['tmux_pane']) }
|
|
194
|
+
if stale.empty?
|
|
195
|
+
puts "All running services have live panes"
|
|
196
|
+
return false
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
stale.each do |svc_name, _|
|
|
200
|
+
state.delete(svc_name)
|
|
201
|
+
puts "Cleaned stale service '#{svc_name}'"
|
|
202
|
+
end
|
|
203
|
+
save_state(state)
|
|
204
|
+
true
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def start(name, tmux_info: {}, task_info: {}, variation_overrides: {}, skip_env: false, skip_window_creation: false)
|
|
133
208
|
svc = find_service(name)
|
|
134
209
|
unless svc
|
|
135
210
|
puts "Service '#{name}' not found"
|
|
@@ -168,29 +243,38 @@ class Hiiro
|
|
|
168
243
|
return false
|
|
169
244
|
end
|
|
170
245
|
|
|
246
|
+
start_cmds = Array(start_cmd)
|
|
171
247
|
base_dir = svc[:base_dir]
|
|
172
|
-
|
|
248
|
+
session = tmux_info[:session] || current_tmux_session
|
|
249
|
+
|
|
250
|
+
# Write start commands to an executable tempfile
|
|
251
|
+
script = write_start_script(svc_name, start_cmds, base_dir)
|
|
252
|
+
|
|
253
|
+
if session && !skip_window_creation
|
|
254
|
+
# Create a new tmux window for this service
|
|
255
|
+
window_target = create_tmux_window(session, svc_name, base_dir || Dir.pwd)
|
|
256
|
+
pane_id = capture_pane_id(window_target)
|
|
257
|
+
elsif session && skip_window_creation
|
|
258
|
+
# Pane already created by start_group
|
|
259
|
+
pane_id = tmux_info[:pane]
|
|
260
|
+
window_target = tmux_info[:window]
|
|
261
|
+
else
|
|
262
|
+
pane_id = nil
|
|
263
|
+
window_target = nil
|
|
264
|
+
end
|
|
173
265
|
|
|
174
266
|
if pane_id
|
|
175
|
-
|
|
176
|
-
system('tmux', 'send-keys', '-t', pane_id, "cd #{base_dir} && #{start_cmd}", 'Enter')
|
|
177
|
-
else
|
|
178
|
-
system('tmux', 'send-keys', '-t', pane_id, start_cmd, 'Enter')
|
|
179
|
-
end
|
|
267
|
+
system('tmux', 'send-keys', '-t', pane_id, script, 'Enter')
|
|
180
268
|
else
|
|
181
|
-
|
|
182
|
-
system("cd #{base_dir} && #{start_cmd} &")
|
|
183
|
-
else
|
|
184
|
-
system("#{start_cmd} &")
|
|
185
|
-
end
|
|
269
|
+
system("#{script} &")
|
|
186
270
|
end
|
|
187
271
|
|
|
188
272
|
# Record state
|
|
189
273
|
state = load_state
|
|
190
274
|
state[svc_name] = {
|
|
191
275
|
'pid' => nil,
|
|
192
|
-
'tmux_session' => tmux_info[:session],
|
|
193
|
-
'tmux_window' => tmux_info[:window],
|
|
276
|
+
'tmux_session' => session || tmux_info[:session],
|
|
277
|
+
'tmux_window' => window_target || tmux_info[:window],
|
|
194
278
|
'tmux_pane' => pane_id,
|
|
195
279
|
'task' => task_info[:task_name],
|
|
196
280
|
'tree' => task_info[:tree],
|
|
@@ -220,7 +304,7 @@ class Hiiro
|
|
|
220
304
|
info = running_services[svc_name]
|
|
221
305
|
pane_id = info['tmux_pane']
|
|
222
306
|
|
|
223
|
-
if svc[:stop]
|
|
307
|
+
if svc[:stop] && !svc[:stop].to_s.strip.empty?
|
|
224
308
|
stop_cmd = svc[:stop]
|
|
225
309
|
if info['pid']
|
|
226
310
|
stop_cmd = stop_cmd.gsub('$PID', info['pid'].to_s)
|
|
@@ -260,11 +344,16 @@ class Hiiro
|
|
|
260
344
|
info = running_services[svc_name]
|
|
261
345
|
pane_id = info['tmux_pane']
|
|
262
346
|
session = info['tmux_session']
|
|
347
|
+
window = info['tmux_window']
|
|
263
348
|
|
|
264
349
|
if session
|
|
265
350
|
system('tmux', 'switch-client', '-t', session)
|
|
266
351
|
end
|
|
267
352
|
|
|
353
|
+
if window
|
|
354
|
+
system('tmux', 'select-window', '-t', window)
|
|
355
|
+
end
|
|
356
|
+
|
|
268
357
|
if pane_id
|
|
269
358
|
system('tmux', 'select-pane', '-t', pane_id)
|
|
270
359
|
end
|
|
@@ -398,8 +487,6 @@ class Hiiro
|
|
|
398
487
|
|
|
399
488
|
tmux_info = {
|
|
400
489
|
session: ENV['TMUX'] ? `tmux display-message -p '#S'`.chomp : nil,
|
|
401
|
-
window: ENV['TMUX'] ? `tmux display-message -p '#I'`.chomp : nil,
|
|
402
|
-
pane: ENV['TMUX_PANE'],
|
|
403
490
|
}
|
|
404
491
|
|
|
405
492
|
task_info = {}
|
|
@@ -433,6 +520,19 @@ class Hiiro
|
|
|
433
520
|
sm.stop(svc_name)
|
|
434
521
|
end
|
|
435
522
|
|
|
523
|
+
h.add_subcmd(:reset) do |svc_name=nil|
|
|
524
|
+
unless svc_name
|
|
525
|
+
puts "Usage: service reset <name>"
|
|
526
|
+
next
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
sm.reset(svc_name)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
h.add_subcmd(:clean) do
|
|
533
|
+
sm.clean
|
|
534
|
+
end
|
|
535
|
+
|
|
436
536
|
h.add_subcmd(:attach) do |svc_name=nil|
|
|
437
537
|
unless svc_name
|
|
438
538
|
puts "Usage: service attach <name>"
|
|
@@ -499,8 +599,7 @@ class Hiiro
|
|
|
499
599
|
'host' => 'localhost',
|
|
500
600
|
'port' => '',
|
|
501
601
|
'init' => [],
|
|
502
|
-
'start' => '',
|
|
503
|
-
'stop' => '',
|
|
602
|
+
'start' => [''],
|
|
504
603
|
'cleanup' => [],
|
|
505
604
|
}
|
|
506
605
|
|
|
@@ -606,6 +705,45 @@ class Hiiro
|
|
|
606
705
|
|
|
607
706
|
private
|
|
608
707
|
|
|
708
|
+
def stale_pane?(pane_id)
|
|
709
|
+
return true unless pane_id
|
|
710
|
+
!system('tmux', 'has-session', '-t', pane_id, [:out, :err] => '/dev/null')
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
def write_start_script(svc_name, cmds, base_dir)
|
|
714
|
+
dir = File.join(STATE_DIR, 'scripts')
|
|
715
|
+
FileUtils.mkdir_p(dir)
|
|
716
|
+
path = File.join(dir, "#{svc_name}.sh")
|
|
717
|
+
|
|
718
|
+
lines = ["#!/usr/bin/env bash", "set -e"]
|
|
719
|
+
lines << "cd #{base_dir}" if base_dir
|
|
720
|
+
lines.concat(cmds)
|
|
721
|
+
|
|
722
|
+
File.write(path, lines.join("\n") + "\n")
|
|
723
|
+
File.chmod(0755, path)
|
|
724
|
+
path
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
def current_tmux_session
|
|
728
|
+
return nil unless ENV['TMUX']
|
|
729
|
+
`tmux display-message -p '#S'`.chomp
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
def create_tmux_window(session, name, start_dir)
|
|
733
|
+
system('tmux', 'new-window', '-d', '-t', session, '-n', name, '-c', start_dir)
|
|
734
|
+
"#{session}:#{name}"
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def capture_pane_id(window_target)
|
|
738
|
+
`tmux list-panes -t #{window_target} -F '\#{pane_id}'`.chomp.split("\n").last
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
def split_tmux_pane(window_target, start_dir)
|
|
742
|
+
system('tmux', 'split-window', '-d', '-t', window_target, '-c', start_dir)
|
|
743
|
+
system('tmux', 'select-layout', '-t', window_target, 'even-vertical')
|
|
744
|
+
`tmux list-panes -t #{window_target} -F '\#{pane_id}'`.chomp.split("\n").last
|
|
745
|
+
end
|
|
746
|
+
|
|
609
747
|
def load_config
|
|
610
748
|
return {} unless File.exist?(config_file)
|
|
611
749
|
YAML.safe_load_file(config_file, permitted_classes: [Symbol]) || {}
|
data/lib/hiiro/version.rb
CHANGED