lux-hammer 0.2.5 → 0.2.6

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/.version +1 -1
  3. data/README.md +6 -5
  4. data/lib/lux-hammer.rb +32 -16
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb668fabef5892decb2ee58add685f52dad7fe742ae0cd8597ba62da576c3d13
4
- data.tar.gz: f74beef4ccb0af5aaa546c7c4a2dec29bc08fffdb929edfa5f3dcdf261627b69
3
+ metadata.gz: 173d405adff150c31284b295fbcc13b56d73a70d6752509f4954f5a89d5f4df7
4
+ data.tar.gz: 1439b6d6e44bec16a5571ffaec390d98ea945360862fb4514f55fedf89a575df
5
5
  SHA512:
6
- metadata.gz: 9fddfa7b7f657cb1baa30793e46fe331cd3f65704ac31ce582bcfc851b154a15eb72e5610e0a0b8af29ed99a763823f7c7bbdd1ef7ad33f40b95fcd803a6216f
7
- data.tar.gz: 6b176bb61def54c305a28f0c9b9419074ed16c14c1b8412ccc084cd2ed5f1a0bfa93d947aac9fcce704cde00c2307bb897e0255e200f1bf1bb077f2795f40330
6
+ metadata.gz: 537c36703b561535f96fc6dd5454a2f6e01df6cac7059b8115b9c6ed176875edab529fbe0d530695d4bbc233fadb67964f2485baa8497de324e4a76b33de353b
7
+ data.tar.gz: 3abb187bb1fe58b03571fdbad1aac1e5a22a2023aeda4b8289ac0508813a85916bbc50a6b07b1988d9d888d3aff50b09658d77b5427704c1061a2c475c9bf151
data/.version CHANGED
@@ -1 +1 @@
1
- 0.2.5
1
+ 0.2.6
data/README.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # hammer
2
2
 
3
- The bastard Frankenstein child of Rake, Thor, and Joshua. Sewn
4
- together from three good ideas, with the rest of each parent left on
3
+ The bastard Frankenstein child of Rake](https://github.com/ruby/rake),
4
+ [Thor](https://github.com/rails/thor), and [Joshua](https://github.com/dux/joshua).
5
+ Sewn together from three good ideas, with the rest of each parent left on
5
6
  the cutting room floor.
6
7
 
7
8
  Drop a `Hammerfile`, run `hammer`, ship. AI LLM-s love `hammer`.
8
9
 
9
10
  ```ruby
10
- namespace :db do # Rake-style colon paths
11
- task :migrate do # Joshua-style task block
11
+ namespace :db do # Rake-style colon paths
12
+ task :migrate do # Joshua-style task block
12
13
  desc 'Run pending migrations'
13
- opt :pretend, type: :boolean, alias: :p # Thor-style typed opts
14
+ opt :pretend, type: :boolean, alias: :p # Thor-style typed opts
14
15
  proc do |o|
15
16
  say.green "migrating pretend=#{o[:pretend].inspect}"
16
17
  end
data/lib/lux-hammer.rb CHANGED
@@ -467,6 +467,7 @@ class Hammer
467
467
  Shell.say ''
468
468
  print_command_list(self)
469
469
  end
470
+ print_global_flags
470
471
  print_footer
471
472
  end
472
473
 
@@ -478,6 +479,7 @@ class Hammer
478
479
  Shell.say ''
479
480
  print_command_list(ns, prefix)
480
481
  end
482
+ print_global_flags
481
483
  print_footer
482
484
  end
483
485
 
@@ -490,6 +492,16 @@ class Hammer
490
492
 
491
493
  HOMEPAGE ||= 'https://github.com/dux/hammer'.freeze
492
494
 
495
+ # Global flags only exist when invoked via the `hammer` binary
496
+ # (see `Hammer.cli`), not for user-built CLIs that call `start`
497
+ # on their own subclass.
498
+ def print_global_flags
499
+ return unless root.instance_variable_get(:@hammer_binary)
500
+ Shell.say ''
501
+ Shell.say 'Global:', :yellow
502
+ Shell.say ' --ai # Print AGENTS.md (AI-friendly Hammerfile authoring docs)'
503
+ end
504
+
493
505
  def print_footer
494
506
  Shell.say ''
495
507
  Shell.say "powered by hammer - #{HOMEPAGE}", :gray
@@ -505,13 +517,13 @@ class Hammer
505
517
 
506
518
  # group by "section" = everything between the view prefix and the
507
519
  # leaf name. Bare leaves go in :root.
508
- groups = rows.group_by { |full, _| section_for(full, prefix) }
509
- width = rows.map { |full, c| label_for(full, c).length }.max
520
+ groups = rows.group_by { |full, _| section_for(full, prefix, klass) }
521
+ width = rows.map { |full, _| full.length }.max
510
522
  first = true
511
523
 
512
524
  if (rooted = groups.delete(:root))
513
525
  Shell.say 'Commands:', :yellow
514
- emit_rows(rooted.sort_by { |full, _| full }, width)
526
+ emit_rows(rooted.sort_by { |full, _| [full.count(':'), full] }, width)
515
527
  first = false
516
528
  end
517
529
 
@@ -519,14 +531,14 @@ class Hammer
519
531
  Shell.say unless first
520
532
  first = false
521
533
  Shell.say "#{section}:", :yellow
522
- emit_rows(items.sort_by { |full, _| full }, width)
534
+ emit_rows(items.sort_by { |full, _| [full.count(':'), full] }, width)
523
535
  end
524
536
  end
525
537
 
526
538
  def emit_rows(rows, width)
527
539
  rows.each do |full, c|
528
- label = label_for(full, c)
529
- Shell.say " #{program_name} #{label.ljust(width)} # #{c.brief}"
540
+ brief = c.alts.empty? ? c.brief : "#{c.brief} (alt: #{c.alts.join(', ')})"
541
+ Shell.say " #{program_name} #{full.ljust(width)} # #{brief}"
530
542
  end
531
543
  end
532
544
 
@@ -534,17 +546,18 @@ class Hammer
534
546
  # for 'db:users:list' viewed from 'db'; :root if the command sits at
535
547
  # the view's top level. Only the first segment under the view groups,
536
548
  # so deeper paths fold into their top-level section.
537
- def section_for(full, prefix)
538
- segs = full.split(':')[0..-2]
539
- if prefix && !prefix.empty?
540
- segs = segs[prefix.split(':').size..] || []
549
+ #
550
+ # Exception: a bare command that shares its name with a sibling
551
+ # namespace (e.g. `mount` alongside a `mount:` namespace) groups
552
+ # under that namespace's section, not :root.
553
+ def section_for(full, prefix, klass = nil)
554
+ segs = full.split(':')
555
+ segs = segs[prefix.split(':').size..] || [] if prefix && !prefix.empty?
556
+ if segs.size == 1 && klass && klass.namespaces.key?(segs.first)
557
+ return segs.first
541
558
  end
542
- segs.empty? ? :root : segs.first
543
- end
544
-
545
- # "db:migrate" or "db:migrate (alt: m)"
546
- def label_for(full, cmd)
547
- cmd.alts.empty? ? full : "#{full} (alt: #{cmd.alts.join(', ')})"
559
+ parent = segs[0..-2]
560
+ parent.empty? ? :root : parent.first
548
561
  end
549
562
 
550
563
  # " URL [ENV] [OPTIONS]" - shows the positional-fill names for
@@ -676,6 +689,9 @@ class Hammer
676
689
  end
677
690
 
678
691
  klass = Class.new(Hammer)
692
+ # Mark this class as the `hammer` binary's root so help output can
693
+ # surface binary-only globals like `--ai`.
694
+ klass.instance_variable_set(:@hammer_binary, true)
679
695
  # Resolve before chdir so paths like `bin/foo` stay relative to the
680
696
  # cwd the user actually invoked from. `program_name` memoizes.
681
697
  klass.program_name
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lux-hammer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dino Reic