ukiryu 0.1.1 → 0.1.3
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/.github/workflows/release.yml +58 -14
- data/.gitignore +3 -0
- data/.rubocop_todo.yml +170 -79
- data/Gemfile +1 -1
- data/README.adoc +1603 -576
- data/docs/.gitignore +1 -0
- data/docs/Gemfile +10 -0
- data/docs/INDEX.adoc +261 -0
- data/docs/_config.yml +180 -0
- data/docs/advanced/custom-tool-classes.adoc +581 -0
- data/docs/advanced/index.adoc +20 -0
- data/docs/features/configuration.adoc +657 -0
- data/docs/features/index.adoc +31 -0
- data/docs/features/platform-support.adoc +488 -0
- data/docs/getting-started/core-concepts.adoc +666 -0
- data/docs/getting-started/index.adoc +36 -0
- data/docs/getting-started/installation.adoc +216 -0
- data/docs/getting-started/quick-start.adoc +258 -0
- data/docs/guides/env-var-sets.adoc +388 -0
- data/docs/guides/index.adoc +20 -0
- data/docs/interfaces/cli.adoc +609 -0
- data/docs/interfaces/index.adoc +153 -0
- data/docs/interfaces/ruby-api.adoc +538 -0
- data/docs/lychee.toml +49 -0
- data/docs/reference/configuration-options.adoc +720 -0
- data/docs/reference/error-codes.adoc +634 -0
- data/docs/reference/index.adoc +20 -0
- data/docs/reference/ruby-api.adoc +1217 -0
- data/docs/understanding/index.adoc +20 -0
- data/lib/ukiryu/cli.rb +43 -58
- data/lib/ukiryu/cli_commands/base_command.rb +16 -27
- data/lib/ukiryu/cli_commands/cache_command.rb +100 -0
- data/lib/ukiryu/cli_commands/commands_command.rb +8 -8
- data/lib/ukiryu/cli_commands/commands_command.rb.fixed +1 -1
- data/lib/ukiryu/cli_commands/config_command.rb +49 -7
- data/lib/ukiryu/cli_commands/definitions_command.rb +254 -0
- data/lib/ukiryu/cli_commands/describe_command.rb +13 -7
- data/lib/ukiryu/cli_commands/describe_command.rb.fixed +1 -1
- data/lib/ukiryu/cli_commands/docs_command.rb +148 -0
- data/lib/ukiryu/cli_commands/exec_inline_command.rb.fixed +1 -1
- data/lib/ukiryu/cli_commands/extract_command.rb +2 -2
- data/lib/ukiryu/cli_commands/info_command.rb +7 -7
- data/lib/ukiryu/cli_commands/lint_command.rb +167 -0
- data/lib/ukiryu/cli_commands/list_command.rb +6 -6
- data/lib/ukiryu/cli_commands/opts_command.rb +2 -2
- data/lib/ukiryu/cli_commands/opts_command.rb.fixed +1 -1
- data/lib/ukiryu/cli_commands/register_command.rb +144 -0
- data/lib/ukiryu/cli_commands/resolve_command.rb +124 -0
- data/lib/ukiryu/cli_commands/run_command.rb +38 -14
- data/lib/ukiryu/cli_commands/run_file_command.rb +2 -2
- data/lib/ukiryu/cli_commands/system_command.rb +50 -32
- data/lib/ukiryu/cli_commands/validate_command.rb +452 -51
- data/lib/ukiryu/cli_commands/which_command.rb +5 -5
- data/lib/ukiryu/command_builder.rb +81 -23
- data/lib/ukiryu/config/env_provider.rb +3 -3
- data/lib/ukiryu/config/env_schema.rb +6 -6
- data/lib/ukiryu/config.rb +11 -11
- data/lib/ukiryu/definition/definition_cache.rb +238 -0
- data/lib/ukiryu/definition/definition_composer.rb +257 -0
- data/lib/ukiryu/definition/definition_linter.rb +460 -0
- data/lib/ukiryu/definition/definition_validator.rb +320 -0
- data/lib/ukiryu/definition/discovery.rb +239 -0
- data/lib/ukiryu/definition/documentation_generator.rb +429 -0
- data/lib/ukiryu/definition/lint_issue.rb +168 -0
- data/lib/ukiryu/definition/loader.rb +139 -0
- data/lib/ukiryu/definition/metadata.rb +159 -0
- data/lib/ukiryu/definition/source.rb +87 -0
- data/lib/ukiryu/definition/sources/file.rb +138 -0
- data/lib/ukiryu/definition/sources/string.rb +88 -0
- data/lib/ukiryu/definition/validation_result.rb +158 -0
- data/lib/ukiryu/definition/version_resolver.rb +194 -0
- data/lib/ukiryu/definition.rb +40 -0
- data/lib/ukiryu/errors.rb +6 -0
- data/lib/ukiryu/execution_context.rb +11 -11
- data/lib/ukiryu/executor.rb +6 -0
- data/lib/ukiryu/extractors/extractor.rb +6 -5
- data/lib/ukiryu/extractors/help_parser.rb +13 -19
- data/lib/ukiryu/logger.rb +3 -1
- data/lib/ukiryu/models/command_definition.rb +3 -3
- data/lib/ukiryu/models/command_info.rb +1 -1
- data/lib/ukiryu/models/components.rb +1 -3
- data/lib/ukiryu/models/env_var_definition.rb +11 -3
- data/lib/ukiryu/models/flag_definition.rb +15 -0
- data/lib/ukiryu/models/option_definition.rb +7 -7
- data/lib/ukiryu/models/platform_profile.rb +6 -3
- data/lib/ukiryu/models/routing.rb +1 -1
- data/lib/ukiryu/models/tool_definition.rb +2 -4
- data/lib/ukiryu/models/tool_metadata.rb +6 -6
- data/lib/ukiryu/models/validation_result.rb +1 -1
- data/lib/ukiryu/models/version_compatibility.rb +6 -3
- data/lib/ukiryu/models/version_detection.rb +10 -1
- data/lib/ukiryu/{registry.rb → register.rb} +54 -38
- data/lib/ukiryu/register_auto_manager.rb +268 -0
- data/lib/ukiryu/schema_validator.rb +31 -10
- data/lib/ukiryu/shell/base.rb +18 -0
- data/lib/ukiryu/shell/bash.rb +19 -1
- data/lib/ukiryu/shell/cmd.rb +11 -1
- data/lib/ukiryu/shell/powershell.rb +11 -1
- data/lib/ukiryu/shell.rb +1 -1
- data/lib/ukiryu/tool.rb +107 -95
- data/lib/ukiryu/tool_index.rb +22 -22
- data/lib/ukiryu/tools/base.rb +12 -25
- data/lib/ukiryu/tools/generator.rb +7 -7
- data/lib/ukiryu/tools.rb +3 -3
- data/lib/ukiryu/type.rb +20 -5
- data/lib/ukiryu/version.rb +1 -1
- data/lib/ukiryu/version_detector.rb +21 -2
- data/lib/ukiryu.rb +6 -3
- data/ukiryu-proposal.md +41 -41
- data/ukiryu.gemspec +1 -0
- metadata +64 -8
- data/.gitmodules +0 -3
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Understanding
|
|
4
|
+
nav_order: 5
|
|
5
|
+
has_children: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Understanding
|
|
9
|
+
|
|
10
|
+
Deep dive into Ukiryu's architecture, design decisions, and internal mechanisms.
|
|
11
|
+
|
|
12
|
+
// Overview
|
|
13
|
+
== Overview
|
|
14
|
+
|
|
15
|
+
This section covers the technical internals of Ukiryu:
|
|
16
|
+
|
|
17
|
+
* link:/understanding/architecture[Architecture] - System design and components
|
|
18
|
+
* link:/understanding/register[Register] - Profile loading and caching
|
|
19
|
+
* link:/understanding/shell-layer[Shell Layer] - Platform and shell adaptation
|
|
20
|
+
* link:/understanding/command-builder[Command Builder] - Argument construction
|
data/lib/ukiryu/cli.rb
CHANGED
|
@@ -15,6 +15,10 @@ require_relative 'cli_commands/version_command'
|
|
|
15
15
|
require_relative 'cli_commands/system_command'
|
|
16
16
|
require_relative 'cli_commands/validate_command'
|
|
17
17
|
require_relative 'cli_commands/extract_command'
|
|
18
|
+
require_relative 'cli_commands/definitions_command'
|
|
19
|
+
require_relative 'cli_commands/cache_command'
|
|
20
|
+
require_relative 'cli_commands/resolve_command'
|
|
21
|
+
require_relative 'cli_commands/register_command'
|
|
18
22
|
require_relative 'thor_ext'
|
|
19
23
|
require_relative 'version'
|
|
20
24
|
|
|
@@ -29,74 +33,77 @@ module Ukiryu
|
|
|
29
33
|
# Extend FriendlyCLI for better Thor behavior
|
|
30
34
|
extend FriendlyCLI
|
|
31
35
|
|
|
32
|
-
# Set default
|
|
36
|
+
# Set default register path if not configured
|
|
33
37
|
def self.exit_on_failure?
|
|
34
38
|
false
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
desc 'run-file REQUEST_FILE', 'Execute a Ukiryu Structured Execution Request from a YAML file'
|
|
38
|
-
method_option :
|
|
42
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
39
43
|
method_option :output, aliases: :o, desc: 'Output file for response (default: stdout)', type: :string
|
|
40
44
|
method_option :format, aliases: :f, desc: 'Response format (yaml, json, table, raw)', type: :string, default: 'yaml'
|
|
41
45
|
method_option :dry_run, aliases: :d, desc: 'Show execution request without executing', type: :boolean,
|
|
42
46
|
default: false
|
|
43
|
-
method_option :shell, desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)',
|
|
47
|
+
method_option :shell, desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)',
|
|
48
|
+
type: :string
|
|
44
49
|
def run_file(request_file)
|
|
45
50
|
CliCommands::RunFileCommand.new(options).run(request_file)
|
|
46
51
|
end
|
|
47
52
|
|
|
48
53
|
desc 'exec TOOL [COMMAND] [KEY=VALUE ...]', 'Execute a tool command inline'
|
|
49
|
-
method_option :
|
|
54
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
55
|
+
method_option :definition, aliases: :d, desc: 'Path to tool definition file', type: :string
|
|
50
56
|
method_option :format, aliases: :f, desc: 'Response format (yaml, json, table, raw)', type: :string, default: 'yaml'
|
|
51
57
|
method_option :output, aliases: :o, desc: 'Output file for response (default: stdout)', type: :string
|
|
52
|
-
method_option :dry_run, aliases: :
|
|
58
|
+
method_option :dry_run, aliases: :D, desc: 'Show execution request without executing', type: :boolean,
|
|
53
59
|
default: false
|
|
54
|
-
method_option :shell,
|
|
60
|
+
method_option :shell, aliases: :s,
|
|
61
|
+
desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)', type: :string
|
|
55
62
|
method_option :stdin, desc: 'Read input from stdin (pass to command)', type: :boolean, default: false
|
|
56
63
|
method_option :raw, desc: 'Output raw stdout/stderr (for pipe composition)', type: :boolean, default: false
|
|
57
64
|
def exec(tool_name, command_name = nil, *params)
|
|
58
65
|
CliCommands::RunCommand.new(options).run(tool_name, command_name, *params)
|
|
59
66
|
end
|
|
60
67
|
|
|
61
|
-
desc 'list', 'List all available tools in the
|
|
62
|
-
method_option :
|
|
68
|
+
desc 'list', 'List all available tools in the register'
|
|
69
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
63
70
|
def list
|
|
64
71
|
CliCommands::ListCommand.new(options).run
|
|
65
72
|
end
|
|
66
73
|
|
|
67
|
-
desc 'info [TOOL]', 'Show detailed information about a tool
|
|
68
|
-
method_option :
|
|
74
|
+
desc 'info [TOOL]', 'Show detailed information about a tool'
|
|
75
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
69
76
|
method_option :all, desc: 'Show all implementations for interfaces', type: :boolean, default: false
|
|
70
77
|
def info(tool_name = nil)
|
|
71
78
|
if tool_name.nil?
|
|
72
|
-
#
|
|
73
|
-
|
|
79
|
+
# No tool specified - show help
|
|
80
|
+
help
|
|
74
81
|
else
|
|
75
82
|
CliCommands::InfoCommand.new(options).run(tool_name)
|
|
76
83
|
end
|
|
77
84
|
end
|
|
78
85
|
|
|
79
86
|
desc 'commands TOOL', 'List all commands available for a tool'
|
|
80
|
-
method_option :
|
|
87
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
81
88
|
def commands(tool_name)
|
|
82
89
|
CliCommands::CommandsCommand.new(options).run(tool_name)
|
|
83
90
|
end
|
|
84
91
|
|
|
85
92
|
desc 'opts TOOL [COMMAND]', 'Show options for a tool or specific command'
|
|
86
|
-
method_option :
|
|
93
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
87
94
|
def opts(tool_name, command_name = nil)
|
|
88
95
|
CliCommands::OptsCommand.new(options).run(tool_name, command_name)
|
|
89
96
|
end
|
|
90
97
|
|
|
91
98
|
desc 'describe TOOL [COMMAND]', 'Show comprehensive documentation for a tool or specific command'
|
|
92
|
-
method_option :
|
|
99
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
93
100
|
method_option :format, aliases: :f, desc: 'Output format (text, yaml, json)', type: :string, default: 'text'
|
|
94
101
|
def describe(tool_name, command_name = nil)
|
|
95
102
|
CliCommands::DescribeCommand.new(options).run(tool_name, command_name)
|
|
96
103
|
end
|
|
97
104
|
|
|
98
105
|
desc 'system [SUBCOMMAND]', 'Show system information (shells, etc.)'
|
|
99
|
-
method_option :
|
|
106
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
100
107
|
def system(subcommand = nil)
|
|
101
108
|
CliCommands::SystemCommand.new(options).run(subcommand)
|
|
102
109
|
end
|
|
@@ -107,7 +114,7 @@ module Ukiryu
|
|
|
107
114
|
end
|
|
108
115
|
|
|
109
116
|
desc 'which IDENTIFIER', 'Show which tool implementation would be selected'
|
|
110
|
-
method_option :
|
|
117
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
111
118
|
method_option :platform, desc: 'Platform to check (macos, linux, windows)', type: :string
|
|
112
119
|
method_option :shell, desc: 'Shell to check (bash, zsh, fish, sh, powershell, cmd)', type: :string
|
|
113
120
|
def which(identifier)
|
|
@@ -115,16 +122,13 @@ module Ukiryu
|
|
|
115
122
|
end
|
|
116
123
|
|
|
117
124
|
desc 'config [ACTION] [KEY] [VALUE]', 'Manage configuration (list, get, set, unset)'
|
|
118
|
-
method_option :
|
|
125
|
+
method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
|
|
119
126
|
def config(action = 'list', key = nil, value = nil)
|
|
120
127
|
CliCommands::ConfigCommand.new(options).run(action, key, value)
|
|
121
128
|
end
|
|
122
129
|
|
|
123
|
-
desc 'validate [
|
|
124
|
-
|
|
125
|
-
def validate(tool_name = nil)
|
|
126
|
-
CliCommands::ValidateCommand.new(options).run(tool_name)
|
|
127
|
-
end
|
|
130
|
+
desc 'validate [COMMAND]', 'Validate tool definitions'
|
|
131
|
+
subcommand 'validate', CliCommands::ValidateCommand
|
|
128
132
|
|
|
129
133
|
desc 'extract TOOL', 'Extract tool definition from an installed CLI tool'
|
|
130
134
|
method_option :output, aliases: :o, desc: 'Output file for extracted definition', type: :string
|
|
@@ -134,41 +138,22 @@ module Ukiryu
|
|
|
134
138
|
CliCommands::ExtractCommand.new(options).run(tool_name)
|
|
135
139
|
end
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
Shell.available_shells.each do |shell|
|
|
154
|
-
puts " - #{shell}"
|
|
155
|
-
end
|
|
156
|
-
puts ''
|
|
157
|
-
puts 'Available Commands:'
|
|
158
|
-
puts ' list - List all available tools'
|
|
159
|
-
puts ' info TOOL - Show detailed information about a tool'
|
|
160
|
-
puts ' which IDENTIFIER - Show which tool implementation would be selected'
|
|
161
|
-
puts ' commands TOOL - List all commands available for a tool'
|
|
162
|
-
puts ' opts TOOL [COMMAND] - Show options for a tool or specific command'
|
|
163
|
-
puts ' describe TOOL [COMMAND] - Show comprehensive documentation'
|
|
164
|
-
puts ' config [ACTION] - Manage configuration (list, get, set, unset)'
|
|
165
|
-
puts ' system [shells] - Show system information (shells, etc.)'
|
|
166
|
-
puts ' exec ... - Execute a tool command inline'
|
|
167
|
-
puts ' run-file ... - Execute from a YAML file'
|
|
168
|
-
puts ' version - Show Ukiryu version'
|
|
169
|
-
puts ''
|
|
170
|
-
puts 'For more information on a specific command:'
|
|
171
|
-
puts ' ukiryu help COMMAND'
|
|
141
|
+
desc 'definitions [COMMAND]', 'Manage tool definitions'
|
|
142
|
+
subcommand 'definitions', CliCommands::DefinitionsCommand
|
|
143
|
+
|
|
144
|
+
desc 'cache [ACTION]', 'Manage definition cache'
|
|
145
|
+
subcommand 'cache', CliCommands::CacheCommand
|
|
146
|
+
|
|
147
|
+
desc 'resolve TOOL [VERSION]', 'Resolve which definition would be used for a tool'
|
|
148
|
+
def resolve(tool_name, version_constraint = nil)
|
|
149
|
+
CliCommands::ResolveCommand.new(options).run(tool_name, version_constraint)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
desc 'register [SUBCOMMAND]', 'Manage the tool register'
|
|
153
|
+
method_option :force, aliases: :f, desc: 'Force re-clone the register', type: :boolean, default: false
|
|
154
|
+
method_option :verbose, aliases: :v, desc: 'Show verbose output', type: :boolean, default: false
|
|
155
|
+
def register(subcommand = nil)
|
|
156
|
+
CliCommands::RegisterCommand.new(options).run(subcommand, options)
|
|
172
157
|
end
|
|
173
158
|
end
|
|
174
159
|
end
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../config'
|
|
4
|
+
require_relative '../register'
|
|
4
5
|
|
|
5
6
|
module Ukiryu
|
|
6
7
|
module CliCommands
|
|
7
8
|
# Base class for CLI commands
|
|
8
9
|
#
|
|
9
10
|
# Provides shared functionality for all CLI commands including
|
|
10
|
-
#
|
|
11
|
+
# register setup, output formatting, and error handling.
|
|
11
12
|
#
|
|
12
13
|
# @abstract Subclasses must implement the `run` method
|
|
13
14
|
class BaseCommand
|
|
@@ -31,14 +32,14 @@ module Ukiryu
|
|
|
31
32
|
raise NotImplementedError, "#{self.class} must implement #run"
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
# Setup the
|
|
35
|
+
# Setup the register path
|
|
35
36
|
#
|
|
36
|
-
# @param custom_path [String, nil] custom
|
|
37
|
-
def
|
|
38
|
-
|
|
39
|
-
return unless
|
|
37
|
+
# @param custom_path [String, nil] custom register path
|
|
38
|
+
def setup_register(custom_path = nil)
|
|
39
|
+
register_path = custom_path || config.register || default_register_path
|
|
40
|
+
return unless register_path && Dir.exist?(register_path)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
Register.default_register_path = register_path
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Apply CLI options to the Config instance
|
|
@@ -49,7 +50,7 @@ module Ukiryu
|
|
|
49
50
|
cli_mappings = {
|
|
50
51
|
format: 'yaml', # default format in Thor
|
|
51
52
|
output: nil,
|
|
52
|
-
|
|
53
|
+
register: nil,
|
|
53
54
|
timeout: nil,
|
|
54
55
|
shell: nil
|
|
55
56
|
}
|
|
@@ -80,26 +81,14 @@ module Ukiryu
|
|
|
80
81
|
config.set_cli_option(:dry_run, options[:dry_run])
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
# Get the default
|
|
84
|
+
# Get the default register path
|
|
84
85
|
#
|
|
85
|
-
# @return [String, nil] the default
|
|
86
|
-
def
|
|
87
|
-
#
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
gem_root = File.dirname(File.dirname(File.dirname(__FILE__)))
|
|
92
|
-
registry_path = File.join(gem_root, '..', 'register')
|
|
93
|
-
return File.expand_path(registry_path) if Dir.exist?(registry_path)
|
|
94
|
-
|
|
95
|
-
# 2. Try from current directory (development setup)
|
|
96
|
-
current = File.expand_path('../register', Dir.pwd)
|
|
97
|
-
return current if Dir.exist?(current)
|
|
98
|
-
|
|
99
|
-
# 3. Try from parent directory
|
|
100
|
-
parent = File.expand_path('../../register', Dir.pwd)
|
|
101
|
-
return parent if Dir.exist?(parent)
|
|
102
|
-
|
|
86
|
+
# @return [String, nil] the default register path from RegisterAutoManager
|
|
87
|
+
def default_register_path
|
|
88
|
+
# Use RegisterAutoManager to find or create the register
|
|
89
|
+
require_relative '../register_auto_manager'
|
|
90
|
+
RegisterAutoManager.register_path
|
|
91
|
+
rescue StandardError
|
|
103
92
|
nil
|
|
104
93
|
end
|
|
105
94
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
require_relative '../definition/definition_cache'
|
|
5
|
+
|
|
6
|
+
module Ukiryu
|
|
7
|
+
module CliCommands
|
|
8
|
+
# Manage definition cache
|
|
9
|
+
#
|
|
10
|
+
# The cache command allows users to view and manage the definition cache.
|
|
11
|
+
class CacheCommand < Thor
|
|
12
|
+
class_option :verbose, type: :boolean, default: false
|
|
13
|
+
class_option :dry_run, type: :boolean, default: false
|
|
14
|
+
|
|
15
|
+
desc 'info', 'Show cache information'
|
|
16
|
+
def info
|
|
17
|
+
show_cache_info
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc 'stats', 'Show detailed cache statistics'
|
|
21
|
+
def stats
|
|
22
|
+
show_cache_stats
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc 'clear', 'Clear all cached definitions'
|
|
26
|
+
def clear
|
|
27
|
+
clear_cache
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# Show cache information
|
|
33
|
+
def show_cache_info
|
|
34
|
+
cache = Ukiryu::Definition::DefinitionCache.instance
|
|
35
|
+
stats = cache.stats
|
|
36
|
+
|
|
37
|
+
say 'Definition Cache:', :cyan
|
|
38
|
+
say '', :clear
|
|
39
|
+
|
|
40
|
+
say "Status: #{stats[:size].positive? ? 'Active' : 'Empty'}", stats[:size].positive? ? :green : :dim
|
|
41
|
+
say "Entries: #{stats[:size]}", :white
|
|
42
|
+
say "TTL: #{stats[:ttl]} seconds", :white
|
|
43
|
+
say "Refresh Strategy: #{stats[:refresh_strategy]}", :white
|
|
44
|
+
|
|
45
|
+
return unless stats[:entries] && !stats[:entries].empty?
|
|
46
|
+
|
|
47
|
+
say '', :clear
|
|
48
|
+
say 'Cached Definitions:', :white
|
|
49
|
+
stats[:entries].each do |key|
|
|
50
|
+
say " - #{key}", :dim
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Clear the cache
|
|
55
|
+
def clear_cache
|
|
56
|
+
cache = Ukiryu::Definition::DefinitionCache.instance
|
|
57
|
+
|
|
58
|
+
if options[:dry_run]
|
|
59
|
+
say 'Dry run: Would clear cache', :cyan
|
|
60
|
+
count = cache.stats[:size]
|
|
61
|
+
say "Entries to be cleared: #{count}", :white
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
count = cache.clear
|
|
66
|
+
|
|
67
|
+
say "✓ Cache cleared (#{count} entries)", :green
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Show cache statistics
|
|
71
|
+
def show_cache_stats
|
|
72
|
+
cache = Ukiryu::Definition::DefinitionCache.instance
|
|
73
|
+
stats = cache.stats
|
|
74
|
+
|
|
75
|
+
say 'Cache Statistics:', :cyan
|
|
76
|
+
say '', :clear
|
|
77
|
+
|
|
78
|
+
say "Total Entries: #{stats[:size]}", :white
|
|
79
|
+
say "TTL: #{stats[:ttl]} seconds (#{(stats[:ttl] / 60).round(1)} minutes)", :white
|
|
80
|
+
say "Refresh Strategy: #{stats[:refresh_strategy]}", :white
|
|
81
|
+
say '', :clear
|
|
82
|
+
|
|
83
|
+
return unless stats[:entries] && !stats[:entries].empty?
|
|
84
|
+
|
|
85
|
+
say 'Cached Keys:', :white
|
|
86
|
+
stats[:entries].each do |key|
|
|
87
|
+
entry = cache.get(key)
|
|
88
|
+
if entry
|
|
89
|
+
age = Time.now - entry.loaded_at
|
|
90
|
+
stale = entry.stale? ? ' (stale)' : ''
|
|
91
|
+
say " - #{key}#{stale}", :white
|
|
92
|
+
say " Age: #{age.round}s", :dim
|
|
93
|
+
else
|
|
94
|
+
say " - #{key} (empty)", :dim
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -11,11 +11,11 @@ module Ukiryu
|
|
|
11
11
|
#
|
|
12
12
|
# @param tool_name [String] the tool name
|
|
13
13
|
def run(tool_name)
|
|
14
|
-
|
|
14
|
+
setup_register
|
|
15
15
|
|
|
16
16
|
# Use find_by for interface-based discovery (ping -> ping_bsd/ping_gnu)
|
|
17
17
|
tool = Tool.find_by(tool_name.to_sym)
|
|
18
|
-
error!("Tool not found: #{tool_name}\nAvailable tools: #{
|
|
18
|
+
error!("Tool not found: #{tool_name}\nAvailable tools: #{Register.tools.sort.join(', ')}") unless tool
|
|
19
19
|
|
|
20
20
|
tool_commands = tool.commands
|
|
21
21
|
error! "No commands defined for #{tool_name}" unless tool_commands
|
|
@@ -73,9 +73,9 @@ module Ukiryu
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Show cli_flag if this is a flag-based action
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
return unless cmd.flag_action?
|
|
77
|
+
|
|
78
|
+
say " Action flag: #{cmd.cli_flag}", :dim
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Display hierarchical commands with routing information
|
|
@@ -86,8 +86,8 @@ module Ukiryu
|
|
|
86
86
|
def display_hierarchical_commands(tool, grouped)
|
|
87
87
|
# Show routing table first
|
|
88
88
|
if tool.routing?
|
|
89
|
-
say
|
|
90
|
-
tool.routing.
|
|
89
|
+
say ' Routing table:', :dim
|
|
90
|
+
tool.routing.each_key do |key|
|
|
91
91
|
target = tool.routing.resolve(key)
|
|
92
92
|
say " #{key} => #{target}", :dim
|
|
93
93
|
end
|
|
@@ -96,7 +96,7 @@ module Ukiryu
|
|
|
96
96
|
|
|
97
97
|
# Show top-level commands (no belongs_to)
|
|
98
98
|
if grouped.key?(nil) && !grouped[nil].empty?
|
|
99
|
-
say
|
|
99
|
+
say ' Top-level commands:', :cyan
|
|
100
100
|
grouped[nil].each do |cmd|
|
|
101
101
|
display_command(cmd)
|
|
102
102
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'base_command'
|
|
4
4
|
require_relative '../config'
|
|
5
|
+
require_relative '../register_auto_manager'
|
|
5
6
|
require 'yaml'
|
|
6
7
|
require 'fileutils'
|
|
7
8
|
|
|
@@ -18,7 +19,7 @@ module Ukiryu
|
|
|
18
19
|
# @param key [String, nil] the config key
|
|
19
20
|
# @param value [String, nil] the config value
|
|
20
21
|
def run(action = 'list', key = nil, value = nil)
|
|
21
|
-
|
|
22
|
+
setup_register
|
|
22
23
|
|
|
23
24
|
case action
|
|
24
25
|
when 'list'
|
|
@@ -41,8 +42,11 @@ module Ukiryu
|
|
|
41
42
|
say 'Current configuration:', :cyan
|
|
42
43
|
say '', :clear
|
|
43
44
|
|
|
45
|
+
# Get actual register info for better display
|
|
46
|
+
register_display = format_register_display
|
|
47
|
+
|
|
44
48
|
config_data = {
|
|
45
|
-
'
|
|
49
|
+
'Register' => register_display,
|
|
46
50
|
'Timeout' => format_config_value(config.timeout, '(no timeout)'),
|
|
47
51
|
'Debug' => format_config_value(config.debug),
|
|
48
52
|
'Dry run' => format_config_value(config.dry_run),
|
|
@@ -51,7 +55,7 @@ module Ukiryu
|
|
|
51
55
|
'Format' => format_config_value(config.format),
|
|
52
56
|
'Output' => format_config_value(config.output, '(stdout)'),
|
|
53
57
|
'Search paths' => format_config_value(config.search_paths, '(not set)'),
|
|
54
|
-
'Use color' => format_config_value(config.use_color
|
|
58
|
+
'Use color' => format_config_value(config.use_color)
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
config_data.each do |k, v|
|
|
@@ -82,7 +86,7 @@ module Ukiryu
|
|
|
82
86
|
say '', :clear
|
|
83
87
|
say 'Environment variables:', :cyan
|
|
84
88
|
env_vars = {
|
|
85
|
-
'
|
|
89
|
+
'UKIRYU_REGISTER' => ENV['UKIRYU_REGISTER'],
|
|
86
90
|
'UKIRYU_TIMEOUT' => ENV['UKIRYU_TIMEOUT'],
|
|
87
91
|
'UKIRYU_DEBUG' => ENV['UKIRYU_DEBUG'],
|
|
88
92
|
'UKIRYU_DRY_RUN' => ENV['UKIRYU_DRY_RUN'],
|
|
@@ -111,7 +115,7 @@ module Ukiryu
|
|
|
111
115
|
normalized_key = normalize_key(key)
|
|
112
116
|
|
|
113
117
|
value = case normalized_key
|
|
114
|
-
when :
|
|
118
|
+
when :register then config.register
|
|
115
119
|
when :timeout then config.timeout
|
|
116
120
|
when :debug then config.debug
|
|
117
121
|
when :dry_run then config.dry_run
|
|
@@ -122,7 +126,7 @@ module Ukiryu
|
|
|
122
126
|
when :search_paths then config.search_paths
|
|
123
127
|
when :use_color then config.use_color
|
|
124
128
|
else
|
|
125
|
-
error! "Unknown config key: #{key}\nValid keys:
|
|
129
|
+
error! "Unknown config key: #{key}\nValid keys: register, timeout, debug, dry_run, metrics, shell, format, output, search_paths, use_color"
|
|
126
130
|
end
|
|
127
131
|
|
|
128
132
|
say "#{key}: #{format_config_value(value, '(not set)')}", :white
|
|
@@ -206,7 +210,7 @@ module Ukiryu
|
|
|
206
210
|
when :shell then config.shell = value
|
|
207
211
|
when :format then config.format = value
|
|
208
212
|
when :output then config.output = value
|
|
209
|
-
when :
|
|
213
|
+
when :register then config.register = value
|
|
210
214
|
when :search_paths then config.search_paths = value
|
|
211
215
|
when :use_color then config.use_color = value
|
|
212
216
|
end
|
|
@@ -221,6 +225,44 @@ module Ukiryu
|
|
|
221
225
|
value.nil? ? default : value
|
|
222
226
|
end
|
|
223
227
|
|
|
228
|
+
# Format register display showing actual register being used
|
|
229
|
+
#
|
|
230
|
+
# @return [String] formatted register display
|
|
231
|
+
def format_register_display
|
|
232
|
+
info = RegisterAutoManager.register_info
|
|
233
|
+
|
|
234
|
+
case info[:status]
|
|
235
|
+
when :ok
|
|
236
|
+
# Register exists and is valid
|
|
237
|
+
source_label = format_source_label(info[:source])
|
|
238
|
+
tools_count = info[:tools_count] ? " (#{info[:tools_count]} tools)" : ''
|
|
239
|
+
"#{info[:path]} [#{source_label}]#{tools_count}"
|
|
240
|
+
when :not_cloned, :not_found
|
|
241
|
+
# Register not cloned yet
|
|
242
|
+
'~/.ukiryu/register (not found - run: ukiryu register update)'
|
|
243
|
+
when :invalid
|
|
244
|
+
# Register exists but is invalid
|
|
245
|
+
"#{info[:path]} (invalid - run: ukiryu register update --force)"
|
|
246
|
+
else
|
|
247
|
+
'(unknown)'
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Format source label for display
|
|
252
|
+
#
|
|
253
|
+
# @param source [Symbol] the source symbol
|
|
254
|
+
# @return [String] formatted source label
|
|
255
|
+
def format_source_label(source)
|
|
256
|
+
case source
|
|
257
|
+
when :env
|
|
258
|
+
'env'
|
|
259
|
+
when :user
|
|
260
|
+
'user'
|
|
261
|
+
else
|
|
262
|
+
source.to_s
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
224
266
|
# Ensure config directory exists
|
|
225
267
|
def ensure_config_dir
|
|
226
268
|
FileUtils.mkdir_p(CONFIG_DIR) unless Dir.exist?(CONFIG_DIR)
|