Module: Space::Architect::CLI
- Defined in:
- lib/space_architect/cli.rb,
lib/space_architect/cli/src.rb,
lib/space_architect/cli/space.rb,
lib/space_architect/cli/research.rb,
lib/space_architect/cli/architect.rb
Defined Under Namespace
Constant Summary collapse
- Outcome =
Delegate the outcome seam to Space::Core::CLI so both architect commands (which call CLI.record_outcome lexically) and the moved Helpers (which call CLI.record_outcome with Space::Core::CLI as lexical root) share one slot.
Space::Core::CLI::Outcome
- Helpers =
Space::Core::CLI::Helpers
- BaseCommand =
Space::Core::CLI::BaseCommand
- TOP_LEVEL_HELP =
[[], ["--help"], ["-h"], ["help"]].freeze
- VERSION_REQUEST =
[["version"], ["--version"]].freeze
Class Method Summary collapse
- .call(argv, out = $stdout, err = $stderr) ⇒ Object
-
.dispatch_space(rest, out = $stdout, err = $stderr) ⇒ Object
Exit-code bridge to the Space::Core CLI engine.
-
.dispatch_src(rest, out = $stdout, err = $stderr) ⇒ Object
Exit-code bridge to the Space::Src CLI engine.
- .last_outcome ⇒ Object
-
.normalize_args(argv) ⇒ Object
Move –color/–colors options to the end of the argument list so dry-cli’s command routing is not confused by options before the subcommand name.
- .record_outcome(o) ⇒ Object
- .run(argv, out = $stdout, err = $stderr) ⇒ Object
Class Method Details
.call(argv, out = $stdout, err = $stderr) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/space_architect/cli.rb', line 26 def self.call(argv, out = $stdout, err = $stderr) Thread.current[:space_core_cli_outcome] = nil Space::Core::CLI.help_pastel = Pastel.new(enabled: Space::Core::CLI.help_colors?(argv, out, err)) if TOP_LEVEL_HELP.include?(argv) out.puts Dry::CLI::Usage.call(Registry.get([])) return 0 end if VERSION_REQUEST.include?(argv) out.puts Space::Core::VERSION return 0 end if argv.first == "src" return dispatch_src(argv[1..], out, err) end normalized = normalize_args(argv) if normalized.first == "space" return dispatch_space(normalized[1..], out, err) end Dry::CLI.new(Registry).call(arguments: normalized, out: out, err: err) last_outcome&.exit_code || 0 end |
.dispatch_space(rest, out = $stdout, err = $stderr) ⇒ Object
Exit-code bridge to the Space::Core CLI engine. ‘architect space <args>` (and `exe/space <args>` via Space::Core::CLI directly) hands the raw remainder to Space::Core’s own dry-cli registry and translates Space::Core’s recorded Outcome into the host exit code. Space::Core has its own Registry, Outcome, and :space_core_cli_outcome thread-local; this is the seam between the two registries (NOT a re-registration).
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/space_architect/cli/space.rb', line 13 def self.dispatch_space(rest, out = $stdout, err = $stderr) if ::Space::Core::CLI::TOP_LEVEL_HELP.include?(rest) out.puts Dry::CLI::Usage.call(::Space::Core::CLI::Registry.get([])) return 0 end if ::Space::Core::CLI::VERSION_REQUEST.include?(rest) out.puts ::Space::Core::VERSION return 0 end Thread.current[:space_core_cli_outcome] = nil Dry::CLI.new(::Space::Core::CLI::Registry).call(arguments: rest, out: out, err: err) ::Space::Core::CLI.last_outcome&.exit_code || 0 end |
.dispatch_src(rest, out = $stdout, err = $stderr) ⇒ Object
Exit-code bridge to the Space::Src CLI engine. ‘architect src <args>` hands the raw remainder to Space::Src’s own dry-cli registry and translates Space::Src’s recorded Outcome into the host exit code. Space::Src has its own Registry, Outcome, and :space_src_cli_* thread-locals; this is the seam between the two registries (NOT a re-registration). Space::Src’s top-level help/version interceptors call Kernel.exit, so we reproduce that interception here against the injected IO instead of delegating to them. dry-cli’s internal exit on a bare group / unknown command propagates as SystemExit — same as the host’s own bare groups (e.g. ‘space repo`) — and is intentionally NOT rescued (accepted behavior change).
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/space_architect/cli/src.rb', line 17 def self.dispatch_src(rest, out = $stdout, err = $stderr) if ::Space::Src::CLI::TOP_LEVEL_HELP.include?(rest) out.puts Dry::CLI::Usage.call(::Space::Src::CLI::Registry.get([])) return 0 end if ::Space::Src::CLI::VERSION_REQUEST.include?(rest) out.puts ::Space::Src::VERSION return 0 end if ::Space::Src::CLI.(rest) paths = ::Space::Src::CLI.make_paths config = ::Space::Src::Config::Store.load(paths.config_file).success return ::Space::Src::Nav.dispatch(rest[0], out, err, config.base_dir) end Thread.current[:space_src_cli_outcome] = nil Dry::CLI.new(::Space::Src::CLI::Registry).call(arguments: rest, out: out, err: err) ::Space::Src::CLI.last_outcome&.exit_code || 0 end |
.last_outcome ⇒ Object
17 |
# File 'lib/space_architect/cli.rb', line 17 def self.last_outcome = Space::Core::CLI.last_outcome |
.normalize_args(argv) ⇒ Object
Move –color/–colors options to the end of the argument list so dry-cli’s command routing is not confused by options before the subcommand name.
Two passes:
1. Leading: extract two-token form (--color VALUE) and =-form from the
front while args still look like options.
2. Non-leading: extract =-form (--color=VALUE / --colors=VALUE) from any
position before the -- separator. The bare two-token form is ambiguous
with a subcommand name in non-leading position and is left in place.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/space_architect/cli.rb', line 63 def self.normalize_args(argv) args = argv.dup extracted = [] # Pass 1: leading two-token and =-form (existing behavior, unchanged) while (arg = args.first) && arg != "--" && arg.start_with?("-") if %w[--color --colors].include?(arg) extracted << args.shift extracted << args.shift if args.first && !args.first.start_with?("-") elsif arg.start_with?("--color=", "--colors=") extracted << args.shift else break end end # Pass 2: =-form from any non-leading position, stop at -- sep = args.index("--") head = sep ? args[0, sep] : args tail = sep ? args[sep..] : [] mid_color, head = head.partition { |a| a.start_with?("--color=", "--colors=") } extracted += mid_color args = head + tail extracted.empty? ? args : args + extracted end |
.record_outcome(o) ⇒ Object
16 |
# File 'lib/space_architect/cli.rb', line 16 def self.record_outcome(o) = Space::Core::CLI.record_outcome(o) |
.run(argv, out = $stdout, err = $stderr) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/space_architect/cli.rb', line 90 def self.run(argv, out = $stdout, err = $stderr) Kernel.exit(call(argv, out, err)) rescue Interrupt err.puts "interrupted" Kernel.exit(130) end |