hiiro 0.1.366 → 0.1.367

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.
@@ -1,6 +1,6 @@
1
1
  class Hiiro
2
2
  class TaskScope
3
- class Error < StandardError; end
3
+ class Error < Hiiro::Error; end
4
4
 
5
5
  attr_reader :reference
6
6
 
@@ -45,48 +45,7 @@ class Hiiro
45
45
  private
46
46
 
47
47
  def current_task
48
- tasks = TaskRecord.all_as_list
49
- if ENV['HERDR_WORKSPACE_ID'] || ENV['HERDR_PANE_ID'] || ENV['HERDR_ENV'] == '1'
50
- herdr = @herdr.call
51
- unless herdr.server_running?
52
- raise Error, 'Herdr is not running; start Herdr for workspace/tab/pane commands, or supply a task name for task data'
53
- end
54
- pane = herdr.get_pane(ENV['HERDR_PANE_ID']) if ENV['HERDR_PANE_ID']
55
- if ENV['HERDR_PANE_ID'] && !pane
56
- raise Error, 'Cannot resolve the current Herdr pane; supply a task name'
57
- end
58
- workspace_id = ENV['HERDR_WORKSPACE_ID'] || pane&.workspace_id
59
- if pane && workspace_id != pane.workspace_id
60
- raise Error, 'Conflicting Herdr pane/workspace context; supply a task name'
61
- end
62
- workspace = workspace_id ? herdr.get_workspace(workspace_id) : herdr.current_workspace
63
- raise Error, 'Cannot resolve the current Herdr workspace; supply a task name' unless workspace
64
-
65
- matches = tasks.select { |task| (task.session || task.name).tr('.', '_') == workspace.name }
66
- raise Error, "Ambiguous workspace task: #{matches.map(&:name).join(', ')}" if matches.length > 1
67
- return matches.first if matches.one?
68
- end
69
-
70
- cwd = File.realpath(Dir.pwd)
71
- matches = tasks.select do |task|
72
- directory = task.primary_directory || (task.tree && (task.tree.start_with?('/') ? task.tree : File.join(Hiiro::WORK_DIR, task.tree)))
73
- paths = [task.home, directory, *task.resources.where(kind: 'directory').select_map(:target)].compact
74
- paths.any? { |path| inside?(cwd, path) }
75
- end
76
- raise Error, "Ambiguous directory task: #{matches.map(&:name).join(', ')}" if matches.length > 1
77
- return matches.first if matches.one?
78
-
79
- saved = PinRecord.find_key('t', 'current_task')
80
- raise Error, 'No current task; supply a task name or run t TASK current' unless saved
81
-
82
- TaskRecord[saved.value] || raise(Error, 'Saved task no longer exists; run t TASK current')
83
- end
84
-
85
- def inside?(path, directory)
86
- return false unless Dir.exist?(directory)
87
-
88
- root = File.realpath(directory)
89
- path == root || path.start_with?(root == File::SEPARATOR ? root : root + File::SEPARATOR)
48
+ CurrentTask.new(herdr: @herdr, pin: true).resolve!
90
49
  end
91
50
  end
92
51
  end
@@ -2,7 +2,7 @@ require 'shellwords'
2
2
 
3
3
  class Hiiro
4
4
  class TaskSessions
5
- class Error < StandardError; end
5
+ class Error < Hiiro::Error; end
6
6
 
7
7
  def initialize(client, workspace:, directory:)
8
8
  @client = client
data/lib/hiiro/tasks.rb CHANGED
@@ -175,6 +175,28 @@ class Hiiro
175
175
  task_name = scope == :subtask ? "#{current_parent_task.name}/#{name}" : name
176
176
  subtree_name = scope == :subtask ? "#{current_parent_task.name}/#{name}" : "#{name}/main"
177
177
 
178
+ target_path = create_tree(subtree_name, sparse_groups: sparse_groups)
179
+ return unless target_path
180
+
181
+ session_name = task_name
182
+ task = Task.new(name: task_name, tree: subtree_name, session: session_name)
183
+ config.save_task(task)
184
+
185
+ base_dir = target_path
186
+ if app_name
187
+ app = environment.find_app(app_name)
188
+ base_dir = app.resolve(target_path) if app
189
+ end
190
+
191
+ Dir.chdir(base_dir)
192
+ hiiro.start_herdr_workspace(session_name, start_directory: Dir.pwd)
193
+
194
+ puts "Started task '#{task_name}' in worktree '#{subtree_name}'"
195
+ end
196
+
197
+ # Create (or reuse an unassigned) worktree under WORK_DIR and return its path,
198
+ # or nil on failure. Shared by `h task start` and `t TASK tree new`.
199
+ def create_tree(subtree_name, sparse_groups: [])
178
200
  target_path = File.join(Hiiro::WORK_DIR, subtree_name)
179
201
 
180
202
  git = Hiiro::Git.new(nil, Hiiro::REPO_PATH)
@@ -184,33 +206,19 @@ class Hiiro
184
206
  FileUtils.mkdir_p(File.dirname(target_path))
185
207
  unless git.move_worktree(available.path, target_path, repo_path: Hiiro::REPO_PATH)
186
208
  puts "ERROR: Failed to rename worktree"
187
- return
209
+ return nil
188
210
  end
189
211
  else
190
212
  puts "Creating new worktree '#{subtree_name}'..."
191
213
  FileUtils.mkdir_p(File.dirname(target_path))
192
214
  unless git.add_worktree_detached(target_path, repo_path: Hiiro::REPO_PATH)
193
215
  puts "ERROR: Failed to create worktree"
194
- return
216
+ return nil
195
217
  end
196
218
  end
197
219
 
198
220
  apply_sparse_checkout(target_path, sparse_groups) if sparse_groups.any?
199
-
200
- session_name = task_name
201
- task = Task.new(name: task_name, tree: subtree_name, session: session_name)
202
- config.save_task(task)
203
-
204
- base_dir = target_path
205
- if app_name
206
- app = environment.find_app(app_name)
207
- base_dir = app.resolve(target_path) if app
208
- end
209
-
210
- Dir.chdir(base_dir)
211
- hiiro.start_herdr_workspace(session_name, start_directory: Dir.pwd)
212
-
213
- puts "Started task '#{task_name}' in worktree '#{subtree_name}'"
221
+ target_path
214
222
  end
215
223
 
216
224
  def switch_to_task(task, app_name: nil, force: false)
@@ -1463,10 +1471,11 @@ class Hiiro
1463
1471
  end
1464
1472
 
1465
1473
  def name
1466
- @name ||= if path.start_with?(Hiiro::WORK_DIR + '/')
1467
- path.sub(Hiiro::WORK_DIR + '/', '')
1468
- else
1469
- File.basename(path)
1474
+ @name ||= begin
1475
+ roots = [Hiiro::WORK_DIR]
1476
+ roots << File.realpath(Hiiro::WORK_DIR) if Dir.exist?(Hiiro::WORK_DIR)
1477
+ root = roots.uniq.find { |dir| path.start_with?(dir + '/') }
1478
+ root ? path.delete_prefix(root + '/') : File.basename(path)
1470
1479
  end
1471
1480
  end
1472
1481
 
@@ -1683,13 +1692,17 @@ class Hiiro
1683
1692
  end
1684
1693
 
1685
1694
  def task
1695
+ return @task if defined?(@task)
1696
+
1697
+ s = session
1698
+ t = tree
1699
+ @task = all_tasks.find { |task|
1700
+ (s && task.session_name == s.name) ||
1701
+ (t && (task.tree_name == t.name || task.tree_name == t.path))
1702
+ }
1686
1703
  @task ||= begin
1687
- s = session
1688
- t = tree
1689
- all_tasks.find { |task|
1690
- (s && task.session_name == s.name) ||
1691
- (t && (task.tree_name == t.name || task.tree_name == t.path))
1692
- }
1704
+ record = CurrentTask.new(herdr: -> { Hiiro::Herdr.client }, cwd: path, pin: false).resolve
1705
+ record && all_tasks.find { |task| task.name == record.name }
1693
1706
  end
1694
1707
  end
1695
1708
 
data/lib/hiiro/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  class Hiiro
2
- VERSION = "0.1.366"
2
+ VERSION = "0.1.367"
3
3
  SUPPORTED_RUBY_VERSION = ">= 3.2.0"
4
4
  end
data/lib/hiiro.rb CHANGED
@@ -6,6 +6,7 @@ require "ostruct"
6
6
  require 'awesome_print'
7
7
 
8
8
  require_relative "hiiro/version"
9
+ require_relative "hiiro/error"
9
10
  require_relative "hiiro/config"
10
11
  require_relative "hiiro/effects"
11
12
  require_relative "hiiro/db"
@@ -46,6 +47,10 @@ require_relative "hiiro/pane_home"
46
47
  require_relative "hiiro/pin_record"
47
48
  require_relative "hiiro/reminder"
48
49
  require_relative 'hiiro/registry'
50
+ require_relative 'hiiro/current_task'
51
+ require_relative 'hiiro/task_scope'
52
+ require_relative 'hiiro/task_sessions'
53
+ require_relative 'hiiro/task_cli'
49
54
  require_relative 'hiiro/tui'
50
55
 
51
56
  class String
@@ -65,7 +70,7 @@ class Hiiro
65
70
  WORK_DIR = File.join(Dir.home, 'work')
66
71
  REPO_PATH = File.join(WORK_DIR, '.git')
67
72
 
68
- def self.init(*oargs, plugins: [], logging: false, tasks: false, task_scope: nil, **values, &block)
73
+ def self.init(*oargs, plugins: [], logging: false, tasks: false, task_scope: nil, builtin_commands: true, **values, &block)
69
74
  load_env
70
75
  Hiiro::DB.setup!
71
76
 
@@ -98,24 +103,14 @@ class Hiiro
98
103
  new(h_bin, *h_args, logging: logging, tasks: tasks, task_scope: task_scope, **values).tap do |hiiro|
99
104
  hiiro.load_plugins(plugins)
100
105
 
101
- hiiro.add_subcommand(:pry) { |*args|
102
- binding.pry
103
- }
104
-
105
- hiiro.add_subcmd(:edit, **values) { |*args|
106
- hiiro.edit_files(hiiro.bin)
107
- }
108
-
109
- if hiiro.tasks_enabled?
110
- hiiro.add_subcmd(:task) do |*args|
111
- tm = TaskManager.new(hiiro, scope: :task)
112
- Tasks.build_hiiro(hiiro, tm).run
113
- end
106
+ if builtin_commands
107
+ hiiro.add_subcommand(:pry) { |*args|
108
+ binding.pry
109
+ }
114
110
 
115
- hiiro.add_subcmd(:subtask) do |*args|
116
- tm = TaskManager.new(hiiro, scope: :subtask)
117
- Tasks.build_hiiro(hiiro, tm).run
118
- end
111
+ hiiro.add_subcmd(:edit, **values) { |*args|
112
+ hiiro.edit_files(hiiro.bin)
113
+ }
119
114
  end
120
115
 
121
116
  if block
@@ -132,8 +127,8 @@ class Hiiro
132
127
  Options.setup(&block)
133
128
  end
134
129
 
135
- def self.run(*args, plugins: [], logging: false, tasks: false, task_scope: nil, **values, &block)
136
- hiiro = init(*args, plugins:, logging:, tasks:, task_scope:, **values, &block)
130
+ def self.run(*args, plugins: [], logging: false, tasks: false, task_scope: nil, builtin_commands: true, **values, &block)
131
+ hiiro = init(*args, plugins:, logging:, tasks:, task_scope:, builtin_commands:, **values, &block)
137
132
 
138
133
  hiiro.run
139
134
  end
@@ -227,6 +222,12 @@ class Hiiro
227
222
  Hiiro::Config.open(file, dir: dir)
228
223
  end
229
224
 
225
+ # Open a file, directory, or URL with the OS default handler.
226
+ def open_default(target)
227
+ executable = RUBY_PLATFORM.include?('darwin') ? 'open' : 'xdg-open'
228
+ system(executable, target)
229
+ end
230
+
230
231
  def herdr_client
231
232
  @herdr_client ||= Herdr.client!(self)
232
233
  end
@@ -276,6 +277,8 @@ class Hiiro
276
277
  handle_result(result)
277
278
 
278
279
  exit 1
280
+ rescue Hiiro::Error => e
281
+ abort "ERROR: #{e.message}"
279
282
  rescue => e
280
283
  puts "ERROR: #{e.message}"
281
284
  puts e.backtrace
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.366
4
+ version: 0.1.367
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Toyota
@@ -129,6 +129,8 @@ email:
129
129
  executables:
130
130
  - h
131
131
  - hiiro
132
+ - t
133
+ - tt
132
134
  extensions: []
133
135
  extra_rdoc_files: []
134
136
  files:
@@ -170,6 +172,7 @@ files:
170
172
  - bin/h-sha
171
173
  - bin/h-sparse
172
174
  - bin/h-tags
175
+ - bin/h-task
173
176
  - bin/h-time
174
177
  - bin/h-title
175
178
  - bin/h-todo
@@ -336,6 +339,8 @@ files:
336
339
  - examples/sparse_groups.yml
337
340
  - exe/h
338
341
  - exe/hiiro
342
+ - exe/t
343
+ - exe/tt
339
344
  - h-tmux-plugins.tmux
340
345
  - hiiro.gemspec
341
346
  - lib/hiiro.rb
@@ -349,8 +354,10 @@ files:
349
354
  - lib/hiiro/capture.rb
350
355
  - lib/hiiro/check_run.rb
351
356
  - lib/hiiro/config.rb
357
+ - lib/hiiro/current_task.rb
352
358
  - lib/hiiro/db.rb
353
359
  - lib/hiiro/effects.rb
360
+ - lib/hiiro/error.rb
354
361
  - lib/hiiro/fuzzyfind.rb
355
362
  - lib/hiiro/git.rb
356
363
  - lib/hiiro/git/branch.rb
@@ -383,6 +390,7 @@ files:
383
390
  - lib/hiiro/service_manager.rb
384
391
  - lib/hiiro/shell.rb
385
392
  - lib/hiiro/tags.rb
393
+ - lib/hiiro/task_cli.rb
386
394
  - lib/hiiro/task_record.rb
387
395
  - lib/hiiro/task_scope.rb
388
396
  - lib/hiiro/task_sessions.rb