hiiro 0.1.24 → 0.1.25
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/bin/g-pr +327 -0
- data/bin/h-branch +18 -0
- data/bin/h-dot +35 -0
- data/bin/h-dotfiles +42 -0
- data/bin/h-home +62 -0
- data/bin/h-html +380 -0
- data/bin/h-link +243 -125
- data/bin/h-mic +93 -0
- data/bin/h-note +119 -0
- data/bin/h-plugin +1 -1
- data/bin/h-pr +72 -2
- data/bin/h-pr-monitor +3 -0
- data/bin/h-pr-watch +3 -0
- data/bin/h-project +173 -0
- data/bin/h-runtask +79 -0
- data/bin/h-serve +6 -0
- data/bin/h-session +21 -1
- data/bin/h-sha +10 -0
- data/bin/h-subtask +2 -1
- data/bin/h-task +69 -6
- data/bin/h-video +2 -1
- data/bin/h-vim +63 -0
- data/lib/hiiro/history.rb +1 -3
- data/lib/hiiro/version.rb +1 -1
- data/script/sync +107 -0
- metadata +17 -2
data/bin/h-note
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "hiiro"
|
|
4
|
+
require "open3"
|
|
5
|
+
require "pathname"
|
|
6
|
+
require "tmpdir"
|
|
7
|
+
|
|
8
|
+
hiiro = Hiiro.init(*ARGV)
|
|
9
|
+
|
|
10
|
+
# Helper class for directory operations
|
|
11
|
+
class Directory
|
|
12
|
+
# Temporarily change to a directory, run block, then change back
|
|
13
|
+
def self.temp_cd(dir, &block)
|
|
14
|
+
original_dir = Dir.pwd
|
|
15
|
+
Dir.chdir(dir)
|
|
16
|
+
yield
|
|
17
|
+
ensure
|
|
18
|
+
Dir.chdir(original_dir)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Print directory tree with indentation
|
|
22
|
+
def self.dir_tree(dir, prefix = "", base_dir = nil)
|
|
23
|
+
base_dir ||= dir
|
|
24
|
+
entries = Dir.entries(dir).reject { |e| e.start_with?('.') }.sort
|
|
25
|
+
|
|
26
|
+
entries.each do |entry|
|
|
27
|
+
path = File.join(dir, entry)
|
|
28
|
+
relative_path = Pathname.new(path).relative_path_from(base_dir)
|
|
29
|
+
|
|
30
|
+
if File.directory?(path)
|
|
31
|
+
puts "#{prefix}#{entry}/"
|
|
32
|
+
dir_tree(path, prefix + " ", base_dir)
|
|
33
|
+
else
|
|
34
|
+
puts "#{prefix}#{relative_path}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
notes_dir = ENV['NOTES_DIR'] || File.join(Dir.home, 'notes')
|
|
41
|
+
|
|
42
|
+
hiiro.add_subcmd(:edit) { |*args|
|
|
43
|
+
system(ENV['EDITOR'] || 'nvim', __FILE__)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
hiiro.add_subcmd(:new) { |*args|
|
|
47
|
+
unless Dir.exist?(notes_dir)
|
|
48
|
+
Dir.mkdir(notes_dir)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Directory.temp_cd(notes_dir) {
|
|
52
|
+
system(ENV['EDITOR'] || 'vim', '-O', *args)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
hiiro.add_subcmd(:categories) { |*args|
|
|
57
|
+
unless Dir.exist?(notes_dir)
|
|
58
|
+
Dir.mkdir(notes_dir)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Directory.temp_cd(notes_dir) {
|
|
62
|
+
Directory.dir_tree(notes_dir)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
hiiro.add_subcmd(:tagged_files) { |*args|
|
|
67
|
+
unless Dir.exist?(notes_dir)
|
|
68
|
+
Dir.mkdir(notes_dir)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
Directory.temp_cd(notes_dir) {
|
|
72
|
+
args.each do |tag|
|
|
73
|
+
tag = tag.sub(/^#+/, '')
|
|
74
|
+
tag_pattern = format('#%s\\b', tag)
|
|
75
|
+
cmd = format('rg -S %s %s', tag_pattern.inspect, notes_dir)
|
|
76
|
+
out, err, status = Open3.capture3(cmd)
|
|
77
|
+
|
|
78
|
+
if status.success?
|
|
79
|
+
puts format('#%s', tag)
|
|
80
|
+
puts format('#%s', tag).gsub(/./, ?-)
|
|
81
|
+
out.lines.each do |line|
|
|
82
|
+
file = line.sub(/:.*/, '')
|
|
83
|
+
puts Pathname.new(file).relative_path_from(notes_dir)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
puts
|
|
88
|
+
end
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
hiiro.add_subcmd(:ls) { |*args|
|
|
93
|
+
unless Dir.exist?(notes_dir)
|
|
94
|
+
Dir.mkdir(notes_dir)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
Directory.temp_cd(notes_dir) {
|
|
98
|
+
Dir.glob('**/*').each(&method(:puts))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
hiiro.add_subcmd(:tags) { |*args|
|
|
103
|
+
unless Dir.exist?(notes_dir)
|
|
104
|
+
Dir.mkdir(notes_dir)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
Directory.temp_cd(notes_dir) {
|
|
108
|
+
tag_pattern = '#[^#[:space:]]+'
|
|
109
|
+
cmd = format('rg -SI %s %s', tag_pattern.inspect, notes_dir)
|
|
110
|
+
out, err, status = Open3.capture3(cmd)
|
|
111
|
+
|
|
112
|
+
if status.success?
|
|
113
|
+
puts out.scan(Regexp.new(tag_pattern)).sort.uniq
|
|
114
|
+
end
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
hiiro.run
|
|
119
|
+
|
data/bin/h-plugin
CHANGED
data/bin/h-pr
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
require "hiiro"
|
|
4
|
+
require "time"
|
|
4
5
|
require "fileutils"
|
|
5
6
|
require "yaml"
|
|
6
7
|
require "json"
|
|
7
8
|
|
|
8
9
|
Hiiro.load_env
|
|
9
|
-
hiiro = Hiiro.init(*ARGV, plugins: [Task])
|
|
10
|
+
hiiro = Hiiro.init(*ARGV, plugins: [Task, Tmux, Pins])
|
|
10
11
|
|
|
11
12
|
class PRManager
|
|
12
13
|
attr_reader :hiiro
|
|
@@ -243,8 +244,77 @@ class PRManager
|
|
|
243
244
|
end
|
|
244
245
|
end
|
|
245
246
|
|
|
247
|
+
WATCH_BLOCK = lambda { |original_pr_number=nil, *args|
|
|
248
|
+
watch = hiiro.get_value(:watch)
|
|
249
|
+
fail_fast = hiiro.get_value(:fail_fast)
|
|
250
|
+
|
|
251
|
+
pr_valid = false
|
|
252
|
+
pr_number = nil
|
|
253
|
+
if !original_pr_number.nil? && pin_value = hiiro.pins.get(original_pr_number)
|
|
254
|
+
pr_valid = true
|
|
255
|
+
pr_number = pin_value
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
pr_args = [pr_valid ? pr_number : original_pr_number].compact
|
|
259
|
+
args = [*pr_args, *args]
|
|
260
|
+
|
|
261
|
+
base_cmd = %w[gh pr checks]
|
|
262
|
+
base_cmd << '--watch' if watch
|
|
263
|
+
base_cmd << '--fail-fast' if fail_fast
|
|
264
|
+
|
|
265
|
+
command = [
|
|
266
|
+
*base_cmd,
|
|
267
|
+
*args,
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
puts command: command, base_cmd: base_cmd, args: args;
|
|
271
|
+
|
|
272
|
+
result = system(*command)
|
|
273
|
+
|
|
274
|
+
pr_info = JSON.parse(`gh pr view #{pr_args.first} --json url,number,title`)
|
|
275
|
+
pr_url = pr_info['url']
|
|
276
|
+
pr_number = pr_info['number']
|
|
277
|
+
pr_title = pr_info['title']
|
|
278
|
+
|
|
279
|
+
if result
|
|
280
|
+
system('say', 'pr good')
|
|
281
|
+
system('terminal-notifier', '-title', 'PR Good', '-message', "##{pr_number}: #{pr_title}", '-open', pr_url)
|
|
282
|
+
else
|
|
283
|
+
system('say', 'pr bad')
|
|
284
|
+
system('terminal-notifier', '-title', 'PR Bad', '-message', "##{pr_number}: #{pr_title}", '-open', pr_url)
|
|
285
|
+
end
|
|
286
|
+
}
|
|
287
|
+
|
|
246
288
|
manager = PRManager.new(hiiro)
|
|
247
289
|
|
|
290
|
+
hiiro.add_subcmd(:check, &WATCH_BLOCK)
|
|
291
|
+
hiiro.add_subcmd(:watch, watch: true, &WATCH_BLOCK)
|
|
292
|
+
hiiro.add_subcmd(:fwatch, watch: true, fail_fast: true, &WATCH_BLOCK)
|
|
293
|
+
|
|
294
|
+
hiiro.add_subcmd(:number) { |*args|
|
|
295
|
+
stdout = `gh pr view`
|
|
296
|
+
|
|
297
|
+
number = stdout[/number:\s*(\d+)/, 1]
|
|
298
|
+
|
|
299
|
+
if number
|
|
300
|
+
print number
|
|
301
|
+
else
|
|
302
|
+
puts stdout
|
|
303
|
+
end
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
hiiro.add_subcmd(:link) { |*args|
|
|
307
|
+
stdout = `gh pr view`
|
|
308
|
+
|
|
309
|
+
number = stdout[/number:\s*(\d+)/, 1]
|
|
310
|
+
|
|
311
|
+
if number
|
|
312
|
+
print ['https://github.com/instacart/carrot/pull/', number].join
|
|
313
|
+
else
|
|
314
|
+
puts stdout
|
|
315
|
+
end
|
|
316
|
+
}
|
|
317
|
+
|
|
248
318
|
hiiro.add_subcmd(:edit) { system(ENV['EDITOR'] || 'nvim', __FILE__) }
|
|
249
319
|
hiiro.add_subcmd(:save) { |pr_number=nil| manager.save(pr_number) }
|
|
250
320
|
hiiro.add_subcmd(:history) { |*args| manager.history(args) }
|
|
@@ -252,6 +322,6 @@ hiiro.add_subcmd(:current) { manager.current }
|
|
|
252
322
|
hiiro.add_subcmd(:open) { |pr_number=nil| manager.open(pr_number) }
|
|
253
323
|
hiiro.add_subcmd(:view) { |pr_number=nil| manager.view(pr_number) }
|
|
254
324
|
|
|
255
|
-
hiiro.add_default { manager.help }
|
|
325
|
+
# hiiro.add_default { manager.help }
|
|
256
326
|
|
|
257
327
|
hiiro.run
|
data/bin/h-pr-monitor
ADDED
data/bin/h-pr-watch
ADDED
data/bin/h-project
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "hiiro"
|
|
4
|
+
|
|
5
|
+
o = Hiiro.init(*ARGV)
|
|
6
|
+
|
|
7
|
+
# Helper to start or attach to a tmux session
|
|
8
|
+
def start_tmux_session(session_name)
|
|
9
|
+
session_name = session_name.to_s
|
|
10
|
+
|
|
11
|
+
unless system('tmux', 'has-session', '-t', session_name)
|
|
12
|
+
system('tmux', 'new', '-d', '-A', '-s', session_name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if ENV['TMUX']
|
|
16
|
+
system('tmux', 'switchc', '-t', session_name)
|
|
17
|
+
elsif ENV['NVIM']
|
|
18
|
+
puts "Can't attach to tmux inside a vim terminal"
|
|
19
|
+
else
|
|
20
|
+
system('tmux', 'new', '-A', '-s', session_name)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Get project directories from ~/proj/
|
|
25
|
+
def project_dirs
|
|
26
|
+
Dir.glob(File.join(Dir.home, 'proj', '*/')).map { |path|
|
|
27
|
+
[File.basename(path), path]
|
|
28
|
+
}.to_h
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Get projects from config file
|
|
32
|
+
def projects_from_config
|
|
33
|
+
projects_file = File.join(Dir.home, '.config/hiiro', 'projects.yml')
|
|
34
|
+
|
|
35
|
+
return {} unless File.exist?(projects_file)
|
|
36
|
+
|
|
37
|
+
require 'yaml'
|
|
38
|
+
YAML.safe_load_file(projects_file)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# === OPEN PROJECT (default) ===
|
|
42
|
+
|
|
43
|
+
o.add_subcmd(:open) { |project_name|
|
|
44
|
+
re = /#{project_name}/i
|
|
45
|
+
|
|
46
|
+
conf_matches = (projects_from_config || {}).select { |k, v| k.match?(re) }
|
|
47
|
+
dir_matches = (project_dirs || {}).select { |proj, path| proj.match?(re) }
|
|
48
|
+
|
|
49
|
+
matches = dir_matches.merge(conf_matches)
|
|
50
|
+
if matches.count > 1
|
|
51
|
+
matches = matches.select { |name, path| name == project_name }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
case matches.count
|
|
55
|
+
when 0
|
|
56
|
+
name = 'proj'
|
|
57
|
+
path = File.join(Dir.home, 'proj')
|
|
58
|
+
|
|
59
|
+
unless Dir.exist?(path)
|
|
60
|
+
puts "Error: #{path.inspect} does not exist"
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
puts "changing dir: #{path}"
|
|
65
|
+
Dir.chdir(path)
|
|
66
|
+
|
|
67
|
+
start_tmux_session(name)
|
|
68
|
+
when 1
|
|
69
|
+
name, path = matches.first
|
|
70
|
+
|
|
71
|
+
puts "changing dir: #{path}"
|
|
72
|
+
Dir.chdir(path)
|
|
73
|
+
|
|
74
|
+
start_tmux_session(name)
|
|
75
|
+
when (2..)
|
|
76
|
+
puts "ERROR: Multiple matches found"
|
|
77
|
+
puts
|
|
78
|
+
puts "Matches:"
|
|
79
|
+
matches.each { |name, path|
|
|
80
|
+
puts format(" %s: %s", name, path)
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# === LIST PROJECTS ===
|
|
86
|
+
|
|
87
|
+
o.add_subcmd(:list) { |*args|
|
|
88
|
+
dirs = project_dirs
|
|
89
|
+
conf = projects_from_config
|
|
90
|
+
|
|
91
|
+
all_projects = dirs.merge(conf)
|
|
92
|
+
|
|
93
|
+
puts "Projects:"
|
|
94
|
+
puts
|
|
95
|
+
all_projects.keys.sort.each do |name|
|
|
96
|
+
path = all_projects[name]
|
|
97
|
+
source = conf.key?(name) ? '[config]' : '[dir]'
|
|
98
|
+
puts format(" %-12s %-8s %s", name, source, path)
|
|
99
|
+
end
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
o.add_subcmd(:ls) { |*args|
|
|
103
|
+
o.run_subcmd(:list, *args)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# === SHOW CONFIG FILE ===
|
|
107
|
+
|
|
108
|
+
o.add_subcmd(:config) { |*args|
|
|
109
|
+
projects_file = File.join(Dir.home, '.config/hiiro', 'projects.yml')
|
|
110
|
+
|
|
111
|
+
if File.exist?(projects_file)
|
|
112
|
+
puts File.read(projects_file)
|
|
113
|
+
else
|
|
114
|
+
puts "No config file found at: #{projects_file}"
|
|
115
|
+
puts
|
|
116
|
+
puts "Create it with YAML format:"
|
|
117
|
+
puts " project_name: /path/to/project"
|
|
118
|
+
end
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# === EDIT CONFIG FILE ===
|
|
122
|
+
|
|
123
|
+
o.add_subcmd(:edit) { |*args|
|
|
124
|
+
projects_file = File.join(Dir.home, '.config/hiiro', 'projects.yml')
|
|
125
|
+
editor = ENV['EDITOR'] || 'vim'
|
|
126
|
+
|
|
127
|
+
# Create config dir if needed
|
|
128
|
+
config_dir = File.dirname(projects_file)
|
|
129
|
+
Dir.mkdir(config_dir) unless Dir.exist?(config_dir)
|
|
130
|
+
|
|
131
|
+
# Create empty file if it doesn't exist
|
|
132
|
+
unless File.exist?(projects_file)
|
|
133
|
+
File.write(projects_file, "# Project aliases\n# project_name: /path/to/project\n")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
exec(editor, projects_file)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# === HELP ===
|
|
140
|
+
|
|
141
|
+
o.add_subcmd(:help) { |*args|
|
|
142
|
+
puts <<~HELP
|
|
143
|
+
h-project - Project directory and tmux session manager
|
|
144
|
+
|
|
145
|
+
USAGE:
|
|
146
|
+
h-project <project_name> Open project (fuzzy match) and start tmux session
|
|
147
|
+
h-project open <project_name> Same as above
|
|
148
|
+
h-project list List all known projects
|
|
149
|
+
h-project ls Alias for list
|
|
150
|
+
h-project config Show config file contents
|
|
151
|
+
h-project edit Edit config file
|
|
152
|
+
|
|
153
|
+
SOURCES:
|
|
154
|
+
Projects are discovered from two sources:
|
|
155
|
+
1. Directories in ~/proj/
|
|
156
|
+
2. Entries in ~/.config/hiiro/projects.yml
|
|
157
|
+
|
|
158
|
+
CONFIG FORMAT (projects.yml):
|
|
159
|
+
project_name: /path/to/project
|
|
160
|
+
another: /some/other/path
|
|
161
|
+
|
|
162
|
+
MATCHING:
|
|
163
|
+
Project names are matched using regex (case insensitive).
|
|
164
|
+
If multiple matches are found, an exact match is preferred.
|
|
165
|
+
If still ambiguous, all matches are displayed.
|
|
166
|
+
HELP
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if o.runnable?
|
|
170
|
+
o.run
|
|
171
|
+
else
|
|
172
|
+
o.run_subcmd(:help)
|
|
173
|
+
end
|
data/bin/h-runtask
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
stamp="$(date +"%Y%m%d%H%M%S")"
|
|
4
|
+
logfile="tmp/run-task.$stamp"
|
|
5
|
+
task_logfile="tmp/run-task.status.$stamp"
|
|
6
|
+
# task_name="generate-sso-config.retailers-domain.customers-backend.customers"
|
|
7
|
+
task_name="generate-sso-config.partners-domain.customers-backend.customers"
|
|
8
|
+
full_sha="$(git log -1 | head -1 | sed 's/commit //;s/[[:space:]].*//')"
|
|
9
|
+
sha="$(echo -n "$full_sha" | sed 's/\(.......\).*/\1/')"
|
|
10
|
+
trusted=${2:-false}
|
|
11
|
+
method_choice=${1:-id}
|
|
12
|
+
|
|
13
|
+
if test $method_choice = "id"
|
|
14
|
+
then
|
|
15
|
+
trusted=false
|
|
16
|
+
SSO_CONFIG="{\"retailer_name\":\"Joshtestidtoken\",\"method_choice\":\"id_token\",\"client_id\":\"updated client id\",\"popup\":true,\"trusted\":${trusted},\"scope\":\"default\",\"activation_status\":\"active\",\"store_config_id\":1459,\"code_challenge_method\":\"S256\",\"user_info_mapping\":{\"provider_uid\":\"sub\",\"first_name\":\"user_first_name\",\"last_name\":\"user_last_name\",\"email\":\"email\",\"phone\":\"default\",\"membership_number\":\"rewards_number\"},\"token_endpoint\":\"http://example.com/token\",\"authorization_endpoint\":\"http://example.com/authorization\",\"logout_endpoint\":\"http://example.com/logout\"}"
|
|
17
|
+
else
|
|
18
|
+
SSO_CONFIG="{\"retailer_name\":\"Joshuitest\",\"method_choice\":\"userinfo endpoint\",\"client_id\":\"updated client id\",\"popup\":true,\"trusted\":${trusted},\"scope\":\"default\",\"activation_status\":\"active\",\"store_config_id\":1459,\"code_challenge_method\":\"S256\",\"user_info_mapping\":{\"provider_uid\":\"sub\",\"first_name\":\"user_first_name\",\"last_name\":\"user_last_name\",\"email\":\"email\",\"phone\":\"default\",\"membership_number\":\"rewards_number\"},\"token_endpoint\":\"http://example.com/token\",\"authorization_endpoint\":\"http://example.com/authorization\",\"logout_endpoint\":\"http://example.com/logout\",\"user_info_endpoint\":\"http://example.com/user_info\"}"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "stamp: $stamp"
|
|
22
|
+
echo "logfile: $logfile"
|
|
23
|
+
echo "task_name: $task_name"
|
|
24
|
+
echo "full_sha: $full_sha"
|
|
25
|
+
echo "sha: $sha"
|
|
26
|
+
echo "trusted: $trusted"
|
|
27
|
+
echo "method_choice: $method_choice"
|
|
28
|
+
echo "SSO_CONFIG: $SSO_CONFIG"
|
|
29
|
+
echo
|
|
30
|
+
echo "$SSO_CONFIG" | jq
|
|
31
|
+
|
|
32
|
+
mkdir -pv tmp
|
|
33
|
+
|
|
34
|
+
if test -f tmp/run-task
|
|
35
|
+
then
|
|
36
|
+
mv -v tmp/run-task "$logfile"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if ! test -f $logfile
|
|
40
|
+
then
|
|
41
|
+
isc task -e production run $task_name $full_sha --command 'bundle exec rake partners_domain:sso_config:generate' --conf "SSO_CONFIG=${SSO_CONFIG}" | tee $logfile
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
uuid="$(egrep -o '\b[0-9a-f-]{36}\b' $logfile | head -1)"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
echo
|
|
48
|
+
echo "UUID: $uuid"
|
|
49
|
+
echo
|
|
50
|
+
|
|
51
|
+
while true
|
|
52
|
+
do
|
|
53
|
+
sleep 5
|
|
54
|
+
clear
|
|
55
|
+
isc -e production task runs "$task_name" "$uuid" | tee $task_logfile
|
|
56
|
+
echo
|
|
57
|
+
egrep 'Status: (pending|in-progress)' $task_logfile || break
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
log_url="$(egrep -o 'Datadog Logs:.*' $task_logfile | sed 's/Datadog Logs: //')"
|
|
61
|
+
|
|
62
|
+
if [[ ! -z $log_url ]]
|
|
63
|
+
then
|
|
64
|
+
open "$log_url"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if egrep 'Status: failed' $task_logfile
|
|
68
|
+
then
|
|
69
|
+
say "task failed"
|
|
70
|
+
else
|
|
71
|
+
if egrep 'Status: succe' $task_logfile
|
|
72
|
+
then
|
|
73
|
+
say "task successful"
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo
|
|
78
|
+
rm -v $logfile $task_logfile
|
|
79
|
+
|
data/bin/h-serve
ADDED
data/bin/h-session
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require 'hiiro'
|
|
4
|
+
require 'pry'
|
|
5
|
+
require 'rspec'
|
|
6
|
+
|
|
7
|
+
# $> h session
|
|
8
|
+
#
|
|
9
|
+
# Subcommand required!
|
|
10
|
+
#
|
|
11
|
+
# Possible subcommands:
|
|
12
|
+
# pin (subcommand) /Users/unixsuperhero/.config/hiiro/plugins/pins.rb:12
|
|
13
|
+
# edit (subcommand) /Users/unixsuperhero/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/hiiro-0.1.8/lib/hiiro.rb:14
|
|
14
|
+
# ses (subcommand) /Users/unixsuperhero/bin/h-session:99
|
|
15
|
+
# ls (subcommand) /Users/unixsuperhero/bin/h-session:111
|
|
16
|
+
# new (subcommand) /Users/unixsuperhero/bin/h-session:115
|
|
17
|
+
# kill (subcommand) /Users/unixsuperhero/bin/h-session:119
|
|
18
|
+
# attach (subcommand) /Users/unixsuperhero/bin/h-session:123
|
|
19
|
+
# rename (subcommand) /Users/unixsuperhero/bin/h-session:127
|
|
20
|
+
# switch (subcommand) /Users/unixsuperhero/bin/h-session:131
|
|
21
|
+
# detach (subcommand) /Users/unixsuperhero/bin/h-session:135
|
|
22
|
+
# has (subcommand) /Users/unixsuperhero/bin/h-session:139
|
|
23
|
+
# info (subcommand) /Users/unixsuperhero/bin/h-session:143
|
|
4
24
|
|
|
5
25
|
o = Hiiro.init(*ARGV, plugins: [Pins])
|
|
6
26
|
|
data/bin/h-sha
ADDED
data/bin/h-subtask
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
require "hiiro"
|
|
6
6
|
require "fileutils"
|
|
7
7
|
require "yaml"
|
|
8
|
+
require "time"
|
|
8
9
|
|
|
9
10
|
Hiiro.load_env
|
|
10
11
|
hiiro = Hiiro.init(*ARGV, plugins: [Tmux, Task])
|
|
@@ -16,6 +17,6 @@ hiiro.add_subcmd(:ls) { tasks.list_subtasks }
|
|
|
16
17
|
hiiro.add_subcmd(:new) { |subtask_name| tasks.new_subtask(subtask_name) }
|
|
17
18
|
hiiro.add_subcmd(:switch) { |subtask_name| tasks.switch_subtask(subtask_name) }
|
|
18
19
|
|
|
19
|
-
hiiro.add_default { tasks.subtask_help }
|
|
20
|
+
# hiiro.add_default { tasks.subtask_help }
|
|
20
21
|
|
|
21
22
|
hiiro.run
|
data/bin/h-task
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "hiiro"
|
|
4
4
|
require "fileutils"
|
|
5
5
|
require "yaml"
|
|
6
|
+
require "pathname"
|
|
6
7
|
|
|
7
8
|
Hiiro.load_env
|
|
8
9
|
hiiro = Hiiro.init(*ARGV, plugins: [Tmux])
|
|
@@ -20,7 +21,7 @@ class TaskManager
|
|
|
20
21
|
puts "Subcommands:"
|
|
21
22
|
puts " list, ls List all worktrees and their active tasks"
|
|
22
23
|
puts " start TASK [APP] Start a task (reuses available worktree or creates new)"
|
|
23
|
-
puts " switch TASK
|
|
24
|
+
puts " switch [TASK] Switch to an existing task (interactive if no task given)"
|
|
24
25
|
puts " app APP_NAME Open a tmux window for an app in current worktree"
|
|
25
26
|
puts " apps List configured apps from apps.yml"
|
|
26
27
|
puts " save Save current tmux session info for this task"
|
|
@@ -42,17 +43,37 @@ class TaskManager
|
|
|
42
43
|
|
|
43
44
|
current = current_task
|
|
44
45
|
active, available = trees.partition { |tree_name| task_for_tree(tree_name) }
|
|
46
|
+
sessions = tmux_sessions
|
|
45
47
|
|
|
46
48
|
active.each do |tree_name|
|
|
47
49
|
task = task_for_tree(tree_name)
|
|
48
50
|
marker = (current && current[:tree] == tree_name) ? "*" : " "
|
|
49
|
-
|
|
51
|
+
|
|
52
|
+
# Check if there's a tmux session for this task
|
|
53
|
+
session_name = session_name_for(task)
|
|
54
|
+
has_session = sessions.include?(session_name)
|
|
55
|
+
session_marker = has_session ? "+" : " "
|
|
56
|
+
session_info = has_session ? " (#{session_name})" : ""
|
|
57
|
+
|
|
58
|
+
puts format("%s%s %-20s => %s%s", marker, session_marker, tree_name, task, session_info)
|
|
50
59
|
end
|
|
51
60
|
|
|
52
61
|
puts if active.any? && available.any?
|
|
53
62
|
|
|
54
63
|
available.each do |tree_name|
|
|
55
|
-
puts format("
|
|
64
|
+
puts format(" %-20s (available)", tree_name)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# List tmux sessions without associated tasks
|
|
68
|
+
associated_sessions = active.map { |tree_name| session_name_for(task_for_tree(tree_name)) }
|
|
69
|
+
unassociated_sessions = sessions - associated_sessions
|
|
70
|
+
|
|
71
|
+
if unassociated_sessions.any?
|
|
72
|
+
puts
|
|
73
|
+
puts "Tmux sessions without tasks:"
|
|
74
|
+
unassociated_sessions.each do |session|
|
|
75
|
+
puts format(" %s", session)
|
|
76
|
+
end
|
|
56
77
|
end
|
|
57
78
|
end
|
|
58
79
|
|
|
@@ -136,7 +157,13 @@ class TaskManager
|
|
|
136
157
|
end
|
|
137
158
|
|
|
138
159
|
# Start working on a task
|
|
139
|
-
def switch_task(task_name)
|
|
160
|
+
def switch_task(task_name = nil)
|
|
161
|
+
# If no task name provided, use interactive selection
|
|
162
|
+
if task_name.nil? || task_name.empty?
|
|
163
|
+
task_name = select_task_interactive
|
|
164
|
+
return false unless task_name
|
|
165
|
+
end
|
|
166
|
+
|
|
140
167
|
tree, task = assignments.find { |tree, task| task.start_with?(task_name) } || []
|
|
141
168
|
|
|
142
169
|
unless task
|
|
@@ -150,6 +177,34 @@ class TaskManager
|
|
|
150
177
|
true
|
|
151
178
|
end
|
|
152
179
|
|
|
180
|
+
# Interactive task selection using sk
|
|
181
|
+
def select_task_interactive
|
|
182
|
+
active_tasks = trees.select { |tree_name| task_for_tree(tree_name) }
|
|
183
|
+
|
|
184
|
+
if active_tasks.empty?
|
|
185
|
+
puts "No active tasks found."
|
|
186
|
+
return nil
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Build selection lines
|
|
190
|
+
lines = active_tasks.map do |tree_name|
|
|
191
|
+
task = task_for_tree(tree_name)
|
|
192
|
+
"#{tree_name.ljust(20)} => #{task}"
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
require 'open3'
|
|
196
|
+
selected, status = Open3.capture2('sk', stdin_data: lines.join("\n"))
|
|
197
|
+
|
|
198
|
+
if status.success? && !selected.strip.empty?
|
|
199
|
+
# Parse the selected line to extract the task name
|
|
200
|
+
if selected =~ /=>\s*(\S+)/
|
|
201
|
+
return $1
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
nil
|
|
206
|
+
end
|
|
207
|
+
|
|
153
208
|
# Open an app window within the current tree
|
|
154
209
|
def open_app(app_name)
|
|
155
210
|
current = current_task
|
|
@@ -337,7 +392,8 @@ class TaskManager
|
|
|
337
392
|
puts printable_apps.keys.sort.map{|k| format("%#{longest_app_name}s => %s", k, printable_apps[k]) }
|
|
338
393
|
exit 1
|
|
339
394
|
when 1
|
|
340
|
-
|
|
395
|
+
pwd_to_root = Pathname.new(tree_root).relative_path_from(Pathname.pwd)
|
|
396
|
+
print File.join(pwd_to_root, apps_config[matching_apps.first])
|
|
341
397
|
exit 0
|
|
342
398
|
else
|
|
343
399
|
puts "Multiple matches found:"
|
|
@@ -623,6 +679,13 @@ class TaskManager
|
|
|
623
679
|
{ 'index' => idx, 'name' => name, 'path' => path }
|
|
624
680
|
}
|
|
625
681
|
end
|
|
682
|
+
|
|
683
|
+
# Get all tmux sessions
|
|
684
|
+
def tmux_sessions
|
|
685
|
+
output = `tmux list-sessions -F '\#{session_name}' 2>/dev/null`
|
|
686
|
+
return [] unless $?.success?
|
|
687
|
+
output.lines.map(&:strip)
|
|
688
|
+
end
|
|
626
689
|
end
|
|
627
690
|
|
|
628
691
|
# Create task manager instance
|
|
@@ -633,7 +696,7 @@ hiiro.add_subcmd(:edit) { system(ENV['EDITOR'] || 'nvim', __FILE__) }
|
|
|
633
696
|
hiiro.add_subcmd(:list) { tasks.list_trees }
|
|
634
697
|
hiiro.add_subcmd(:ls) { tasks.list_trees }
|
|
635
698
|
hiiro.add_subcmd(:start) { |task_name, app=nil| tasks.start_task(task_name, app: app) }
|
|
636
|
-
hiiro.add_subcmd(:switch) { |task_name| tasks.switch_task(task_name) }
|
|
699
|
+
hiiro.add_subcmd(:switch) { |task_name=nil| tasks.switch_task(task_name) }
|
|
637
700
|
hiiro.add_subcmd(:app) { |app_name| tasks.open_app(app_name) }
|
|
638
701
|
hiiro.add_subcmd(:path) { |app_name=nil, task=nil| tasks.app_path(app_name, task: task) }
|
|
639
702
|
hiiro.add_subcmd(:cd) { |*args| tasks.cd_app(*args) }
|