hiiro 0.1.342 → 0.1.343

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: 1496be512bebac30ab2a5fc84922bf0eefb05b3ff1632b04a6488142c805b388
4
- data.tar.gz: 215d5c29421e45abd0b8c5fe2984e372d776e5510cab0d71cd178e1c390081fe
3
+ metadata.gz: e0b4a52f12f6b8206e79bc9c467c11523d8b6c09592e83ee88617133112ee60a
4
+ data.tar.gz: 3190f9942e4f705fb7b4de299ed992d0b0123e5d57c5e375a3476f0b018b4867
5
5
  SHA512:
6
- metadata.gz: 3a25d21e45c9bdea4c7ca56a850f6f00b71fb62990a03eb545f0bc379a6881504bf213079ef25f50df99f9a624ae2571f1d3522089f3a837439b363ab8bbbc61
7
- data.tar.gz: a17b9aeccf2740727d1f4f306a4ad446b74cc7cf996f062bb6d8f37eef74660e84162ea9a3edf1542004412e86d2d2b547d81cc1b66493860afe6e018da1c6ad
6
+ metadata.gz: a6ce0e2c104da7509260220b5fc02162dde679457bc56012b704b17cb02ede55e51cd0e47f06b626ac40fd129b8f84991c0043e19523513e7012e11b4d8942b8
7
+ data.tar.gz: c1b053c3f8cac1f4af5433a64e217dfdc79c93dcf017eab287efbfeb1f2e90ea696012bb37da1a599aab43c069e309b6488c3cab530cdefbd7cfc0cf6c69dde7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.343] - 2026-04-12
4
+
5
+ ### Added
6
+ - Task subcommands now fall back to `~/proj/*` directories when no task matches
7
+ - `h task path hiiro` → resolves to `~/proj/hiiro` if no task named "hiiro" exists
8
+ - Works for: `cd`, `path`, `sh`, `branch`, `tree`, `session`, and any subcommand using `-t` flag
9
+ - `FallbackTarget` class duck-types as `Task` for seamless integration
10
+ - Ambiguous project matches print a warning to stderr
11
+
12
+ ### Fixed
13
+ - `Hiiro::Git::Pr.is_link?` is now a class method (was instance method)
14
+
3
15
  ## [0.1.342] - 2026-04-08
4
16
 
5
17
  ### Added
data/lib/hiiro/git/pr.rb CHANGED
@@ -20,7 +20,7 @@ class Hiiro
20
20
  []
21
21
  end
22
22
 
23
- def is_link?(link)
23
+ def self.is_link?(link)
24
24
  temp_link = link.to_s
25
25
  return false unless temp_link.match?('github.com') && temp_link.match?(/pull\/[0-9]+/)
26
26
 
data/lib/hiiro/tasks.rb CHANGED
@@ -63,6 +63,37 @@ class Hiiro
63
63
  Hiiro::Matcher.new(tasks, key).by_prefix(name).first&.item
64
64
  end
65
65
 
66
+ # Resolve a name to a Task or FallbackTarget (~/proj/* directory).
67
+ # Falls back to ~/proj/* prefix match when no task matches.
68
+ def resolve_name(name)
69
+ return nil if name.nil?
70
+
71
+ task = task_by_name(name)
72
+ return task if task
73
+
74
+ proj_dirs = Dir.glob(File.expand_path('~/proj/*/'))
75
+ dir_names = proj_dirs.map { |d| File.basename(d) }
76
+ result = Hiiro::Matcher.by_prefix(dir_names, name)
77
+ if result.one?
78
+ dir_name = result.first.item
79
+ return FallbackTarget.from_project(dir_name, File.expand_path("~/proj/#{dir_name}"))
80
+ elsif result.ambiguous?
81
+ STDERR.puts "Ambiguous project match for '#{name}': #{result.matches.map(&:item).join(', ')}"
82
+ end
83
+
84
+ nil
85
+ end
86
+
87
+ # Resolve the filesystem path for a Task or FallbackTarget.
88
+ def resolve_path(target)
89
+ return nil unless target
90
+
91
+ return target.path if target.is_a?(FallbackTarget)
92
+
93
+ tree = environment.find_tree(target.tree_name)
94
+ tree ? tree.path : File.join(Hiiro::WORK_DIR, target.tree_name)
95
+ end
96
+
66
97
  def task_by_tree(tree_name)
67
98
  environment.task_matcher.resolve(tree_name, :tree_name).resolved&.item
68
99
  end
@@ -499,8 +530,8 @@ class Hiiro
499
530
 
500
531
  def value_for_task(task_name = nil, &block)
501
532
  if task_name
502
- task = task_by_name(task_name)
503
- return block.call(task) if task
533
+ target = resolve_name(task_name)
534
+ return block.call(target) if target
504
535
  end
505
536
 
506
537
  task_list = scope == :subtask ? tasks.sort_by(&:short_name) : environment.all_tasks.sort_by(&:name)
@@ -769,9 +800,9 @@ class Hiiro
769
800
  task = sel.is_a?(Hiiro::Task) ? sel : nil
770
801
  [task, positional]
771
802
  elsif opts.task
772
- [tm.task_by_name(opts.task), positional]
803
+ [tm.resolve_name(opts.task), positional]
773
804
  elsif positional.any?
774
- found = tm.task_by_name(positional.first)
805
+ found = tm.resolve_name(positional.first)
775
806
  found ? [found, positional[1..]] : [tm.current_task, positional]
776
807
  else
777
808
  [tm.current_task, positional]
@@ -1001,8 +1032,7 @@ class Hiiro
1001
1032
  puts "No task found"
1002
1033
  next
1003
1034
  end
1004
- tree = tm.environment.find_tree(task.tree_name)
1005
- tree_path = tree ? tree.path : File.join(Hiiro::WORK_DIR, task.tree_name)
1035
+ tree_path = tm.resolve_path(task)
1006
1036
  app_name = positional[0]
1007
1037
  if app_name.nil?
1008
1038
  tm.send_cd(tree_path)
@@ -1023,8 +1053,7 @@ class Hiiro
1023
1053
  STDERR.puts "No task found"
1024
1054
  next
1025
1055
  end
1026
- tree = tm.environment.find_tree(task.tree_name)
1027
- tree_path = tree ? tree.path : File.join(Hiiro::WORK_DIR, task.tree_name)
1056
+ tree_path = tm.resolve_path(task)
1028
1057
 
1029
1058
  app_name = positional[0]
1030
1059
  globs = positional[1..]
@@ -1099,8 +1128,7 @@ class Hiiro
1099
1128
  puts "Not in a task session (use -t or -f to specify)"
1100
1129
  next
1101
1130
  end
1102
- tree = tm.environment.find_tree(task.tree_name)
1103
- path = tree ? tree.path : File.join(Hiiro::WORK_DIR, task.tree_name)
1131
+ path = tm.resolve_path(task)
1104
1132
 
1105
1133
  if opts.session
1106
1134
  session_name = opts.session
@@ -1446,6 +1474,53 @@ class Hiiro
1446
1474
  end
1447
1475
  end
1448
1476
 
1477
+ class FallbackTarget
1478
+ attr_reader :name, :type
1479
+
1480
+ def self.from_project(name, path)
1481
+ new(name: name, path: path, type: :project)
1482
+ end
1483
+
1484
+ def initialize(name:, path:, type:)
1485
+ @name = name
1486
+ @_path = path
1487
+ @type = type
1488
+ end
1489
+
1490
+ def session_name = name
1491
+ def tree_name = nil
1492
+ def color_index = nil
1493
+ def subtask? = false
1494
+ def top_level? = true
1495
+ def short_name = name
1496
+ def parent_name = nil
1497
+ def tree = nil
1498
+
1499
+ def path
1500
+ @_path
1501
+ end
1502
+
1503
+ def branch
1504
+ return nil unless @_path
1505
+ out = IO.popen(['git', '-C', @_path, 'rev-parse', '--abbrev-ref', 'HEAD'], err: File::NULL, &:read)
1506
+ out&.strip&.then { |b| b.empty? ? nil : b }
1507
+ end
1508
+
1509
+ def display_data(scope: :task, environment:)
1510
+ br = branch
1511
+ {
1512
+ name: name,
1513
+ tree: '(project)',
1514
+ branch: br ? "[#{br}]" : '(none)',
1515
+ session: "(#{name})"
1516
+ }
1517
+ end
1518
+
1519
+ def to_s
1520
+ name
1521
+ end
1522
+ end
1523
+
1449
1524
  class App
1450
1525
  attr_reader :name, :relative_path
1451
1526
 
data/lib/hiiro/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Hiiro
2
- VERSION = "0.1.342"
2
+ VERSION = "0.1.343"
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.342
4
+ version: 0.1.343
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Toyota