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,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Interfaces
|
|
4
|
+
nav_order: 3
|
|
5
|
+
has_children: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Interfaces
|
|
9
|
+
|
|
10
|
+
Ukiryu provides multiple ways to interact with tools, each suited for different use cases.
|
|
11
|
+
|
|
12
|
+
// Overview
|
|
13
|
+
== Overview
|
|
14
|
+
|
|
15
|
+
Ukiryu supports three primary interfaces:
|
|
16
|
+
|
|
17
|
+
* link:/interfaces/ruby-api[Ruby API] - Programmatic interface for Ruby applications
|
|
18
|
+
* link:/interfaces/cli[Command Line Interface] - Interactive shell usage
|
|
19
|
+
* link:/interfaces/configuration[Configuration] - Environment variables and settings
|
|
20
|
+
|
|
21
|
+
Each interface supports the same core functionality with appropriate trade-offs:
|
|
22
|
+
|
|
23
|
+
[cols="1,1,2"]
|
|
24
|
+
|===
|
|
25
|
+
|Interface |Best For |Key Features
|
|
26
|
+
|
|
27
|
+
|Ruby API |Applications, libraries |Type-safe parameters, structured results, error handling
|
|
28
|
+
|
|
29
|
+
|CLI |Scripts, automation |Simple syntax, shell integration, human-readable output
|
|
30
|
+
|
|
31
|
+
|ENV Variables |CI/CD, deployment |Global configuration, override settings
|
|
32
|
+
|===
|
|
33
|
+
|
|
34
|
+
// Configuration Across Interfaces
|
|
35
|
+
== Configuration Across Interfaces
|
|
36
|
+
|
|
37
|
+
All interfaces support the same configuration options with consistent precedence:
|
|
38
|
+
|
|
39
|
+
[NOTE]
|
|
40
|
+
.Configuration Precedence (Highest to Lowest)
|
|
41
|
+
1. Environment variables (`UKIRYU_*`)
|
|
42
|
+
2. Command-line parameters (`key=value`)
|
|
43
|
+
3. Ruby API parameters (`{key: value}`)
|
|
44
|
+
4. Profile defaults (from YAML)
|
|
45
|
+
|
|
46
|
+
=== Example: Timeout Configuration
|
|
47
|
+
|
|
48
|
+
[source,ruby]
|
|
49
|
+
----
|
|
50
|
+
// Ruby API - lowest precedence
|
|
51
|
+
result = tool.execute(:export, params, timeout: 60)
|
|
52
|
+
----
|
|
53
|
+
|
|
54
|
+
[source,bash]
|
|
55
|
+
----
|
|
56
|
+
# CLI - medium precedence
|
|
57
|
+
ukiryu exec inkscape export timeout=120 inputs=drawing.svg
|
|
58
|
+
----
|
|
59
|
+
|
|
60
|
+
[source,bash]
|
|
61
|
+
----
|
|
62
|
+
# ENV - highest precedence
|
|
63
|
+
export UKIRYU_TIMEOUT=180
|
|
64
|
+
ukiryu exec inkscape export inputs=drawing.svg
|
|
65
|
+
----
|
|
66
|
+
|
|
67
|
+
Result: The command uses 180 second timeout (from ENV).
|
|
68
|
+
|
|
69
|
+
// Common Patterns
|
|
70
|
+
== Common Patterns
|
|
71
|
+
|
|
72
|
+
=== Error Handling
|
|
73
|
+
|
|
74
|
+
[source,ruby]
|
|
75
|
+
----
|
|
76
|
+
// Ruby API - structured exceptions
|
|
77
|
+
begin
|
|
78
|
+
result = tool.execute(:export, params)
|
|
79
|
+
rescue Ukiryu::ExecutionError => e
|
|
80
|
+
logger.error("Command failed: #{e.result.stderr}")
|
|
81
|
+
end
|
|
82
|
+
----
|
|
83
|
+
|
|
84
|
+
[source,bash]
|
|
85
|
+
----
|
|
86
|
+
# CLI - exit codes
|
|
87
|
+
ukiryu exec inkscape export inputs=drawing.svg
|
|
88
|
+
if [ $? -ne 0 ]; then
|
|
89
|
+
echo "Command failed"
|
|
90
|
+
fi
|
|
91
|
+
----
|
|
92
|
+
|
|
93
|
+
=== Result Inspection
|
|
94
|
+
|
|
95
|
+
[source,ruby]
|
|
96
|
+
----
|
|
97
|
+
// Ruby API - rich result object
|
|
98
|
+
result = tool.execute(:export, params)
|
|
99
|
+
puts "Success: #{result.success?}"
|
|
100
|
+
puts "Duration: #{result.metadata.duration_seconds}s"
|
|
101
|
+
puts "Command: #{result.command_info.full_command}"
|
|
102
|
+
puts "Stdout: #{result.output.stdout}"
|
|
103
|
+
----
|
|
104
|
+
|
|
105
|
+
=== Tool Discovery
|
|
106
|
+
|
|
107
|
+
[source,ruby]
|
|
108
|
+
----
|
|
109
|
+
// Ruby API
|
|
110
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
111
|
+
puts tool.available? # Is tool installed?
|
|
112
|
+
puts tool.version # Detected version
|
|
113
|
+
puts tool.executable # Full path to executable
|
|
114
|
+
----
|
|
115
|
+
|
|
116
|
+
[source,bash]
|
|
117
|
+
----
|
|
118
|
+
# CLI
|
|
119
|
+
ukiryu info inkscape # Detailed tool information
|
|
120
|
+
ukiryu list # All available tools
|
|
121
|
+
ukiryu describe inkscape # Command documentation
|
|
122
|
+
----
|
|
123
|
+
|
|
124
|
+
// Choosing the Right Interface
|
|
125
|
+
== Choosing the Right Interface
|
|
126
|
+
|
|
127
|
+
=== Use Ruby API When
|
|
128
|
+
|
|
129
|
+
* Building Ruby applications
|
|
130
|
+
* Need programmatic error handling
|
|
131
|
+
* Want type-safe parameters
|
|
132
|
+
* Processing results in code
|
|
133
|
+
|
|
134
|
+
=== Use CLI When
|
|
135
|
+
|
|
136
|
+
* Writing shell scripts
|
|
137
|
+
* Interactive tool usage
|
|
138
|
+
* Quick one-off commands
|
|
139
|
+
* Integrating with Unix pipelines
|
|
140
|
+
|
|
141
|
+
=== Use ENV Variables When
|
|
142
|
+
|
|
143
|
+
* Configuring CI/CD pipelines
|
|
144
|
+
* Setting global defaults
|
|
145
|
+
* Overriding tool behavior without code changes
|
|
146
|
+
* Debugging with verbose output
|
|
147
|
+
|
|
148
|
+
// See Also
|
|
149
|
+
== See Also
|
|
150
|
+
|
|
151
|
+
* link:/features/configuration[Configuration Options] - All configuration methods
|
|
152
|
+
* link:/reference/configuration-options[Configuration Reference] - Complete option list
|
|
153
|
+
* link:/guides/[Guides] - Task-specific tutorials
|
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Ruby API
|
|
4
|
+
parent: Interfaces
|
|
5
|
+
nav_order: 1
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
== Ruby API
|
|
9
|
+
|
|
10
|
+
The Ruby API provides a programmatic interface for executing tools with type-safe parameters and structured results.
|
|
11
|
+
|
|
12
|
+
// Purpose
|
|
13
|
+
== Purpose
|
|
14
|
+
|
|
15
|
+
This page documents the Ruby API for executing commands, handling results, and managing configuration.
|
|
16
|
+
|
|
17
|
+
// References
|
|
18
|
+
== References
|
|
19
|
+
|
|
20
|
+
* `Ukiryu::Tool` - Main tool interface
|
|
21
|
+
* `Ukiryu::Register` - Tool profile register
|
|
22
|
+
* `Ukiryu::Execution::Result` - Result object
|
|
23
|
+
* link:/reference/ruby-api[API Reference]
|
|
24
|
+
|
|
25
|
+
// Concepts
|
|
26
|
+
== Concepts
|
|
27
|
+
|
|
28
|
+
* **Tool instance**: Cached object representing a specific tool
|
|
29
|
+
* **Command execution**: Type-safe parameter passing with validation
|
|
30
|
+
* **Result object**: Structured output with metadata
|
|
31
|
+
* **Error handling**: Exception-based error reporting
|
|
32
|
+
* **Configuration precedence**: ENV > parameters > defaults
|
|
33
|
+
|
|
34
|
+
// Basic Usage
|
|
35
|
+
== Basic Usage
|
|
36
|
+
|
|
37
|
+
=== Getting a Tool
|
|
38
|
+
|
|
39
|
+
[source,ruby]
|
|
40
|
+
----
|
|
41
|
+
require 'ukiryu'
|
|
42
|
+
|
|
43
|
+
# Get tool by name
|
|
44
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
45
|
+
|
|
46
|
+
# Check availability
|
|
47
|
+
if tool.available?
|
|
48
|
+
puts "Inkscape is installed at: #{tool.executable}"
|
|
49
|
+
puts "Version: #{tool.version}"
|
|
50
|
+
else
|
|
51
|
+
puts "Inkscape is not installed"
|
|
52
|
+
end
|
|
53
|
+
----
|
|
54
|
+
|
|
55
|
+
=== Executing Commands
|
|
56
|
+
|
|
57
|
+
[source,ruby]
|
|
58
|
+
----
|
|
59
|
+
# Execute a command with parameters
|
|
60
|
+
result = tool.execute(:export, {
|
|
61
|
+
inputs: ['drawing.svg'],
|
|
62
|
+
output: 'drawing.png',
|
|
63
|
+
format: :png
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
# Check success
|
|
67
|
+
if result.success?
|
|
68
|
+
puts "Conversion successful!"
|
|
69
|
+
else
|
|
70
|
+
puts "Conversion failed!"
|
|
71
|
+
puts "Error: #{result.stderr}"
|
|
72
|
+
end
|
|
73
|
+
----
|
|
74
|
+
|
|
75
|
+
// Configuration Methods
|
|
76
|
+
== Configuration Methods
|
|
77
|
+
|
|
78
|
+
=== Method 1: Ruby API Parameters (Lowest Precedence)
|
|
79
|
+
|
|
80
|
+
Pass parameters directly to `execute`:
|
|
81
|
+
|
|
82
|
+
[source,ruby]
|
|
83
|
+
----
|
|
84
|
+
result = tool.execute(:export, {
|
|
85
|
+
inputs: ['drawing.svg'],
|
|
86
|
+
output: 'drawing.png',
|
|
87
|
+
format: :png,
|
|
88
|
+
dpi: 300,
|
|
89
|
+
width: 1024,
|
|
90
|
+
height: 768
|
|
91
|
+
}, timeout: 60) # Execution timeout in seconds
|
|
92
|
+
----
|
|
93
|
+
|
|
94
|
+
=== Method 2: Global Configuration (Medium Precedence)
|
|
95
|
+
|
|
96
|
+
Set default configuration for all operations:
|
|
97
|
+
|
|
98
|
+
[source,ruby]
|
|
99
|
+
----
|
|
100
|
+
# Set register path
|
|
101
|
+
Ukiryu::Register.default_register_path = '/path/to/register'
|
|
102
|
+
|
|
103
|
+
# Set default timeout
|
|
104
|
+
Ukiryu::Executor::DEFAULT_TIMEOUT = 120
|
|
105
|
+
----
|
|
106
|
+
|
|
107
|
+
=== Method 3: Environment Variables (Highest Precedence)
|
|
108
|
+
|
|
109
|
+
Set environment variables to override all other configuration:
|
|
110
|
+
|
|
111
|
+
[source,ruby]
|
|
112
|
+
----
|
|
113
|
+
# Set before loading Ukiryu
|
|
114
|
+
ENV['UKIRYU_REGISTER'] = '/path/to/register'
|
|
115
|
+
ENV['UKIRYU_TIMEOUT'] = '180'
|
|
116
|
+
ENV['UKIRYU_DEBUG'] = 'true'
|
|
117
|
+
|
|
118
|
+
require 'ukiryu'
|
|
119
|
+
|
|
120
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
121
|
+
result = tool.execute(:export, params)
|
|
122
|
+
# Uses 180 second timeout from ENV
|
|
123
|
+
----
|
|
124
|
+
|
|
125
|
+
=== Configuration Precedence Example
|
|
126
|
+
|
|
127
|
+
[source,ruby]
|
|
128
|
+
----
|
|
129
|
+
# Profile default: 90 seconds
|
|
130
|
+
# Ruby API parameter: 60 seconds
|
|
131
|
+
# ENV variable: 180 seconds (wins!)
|
|
132
|
+
|
|
133
|
+
ENV['UKIRYU_TIMEOUT'] = '180'
|
|
134
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
135
|
+
|
|
136
|
+
result = tool.execute(:export, {
|
|
137
|
+
inputs: ['drawing.svg'],
|
|
138
|
+
output: 'drawing.png'
|
|
139
|
+
}, timeout: 60)
|
|
140
|
+
|
|
141
|
+
# Result: Uses 180 second timeout from ENV
|
|
142
|
+
----
|
|
143
|
+
|
|
144
|
+
// Result Object
|
|
145
|
+
== Result Object
|
|
146
|
+
|
|
147
|
+
The `execute` method returns a structured result object:
|
|
148
|
+
|
|
149
|
+
[source,ruby]
|
|
150
|
+
----
|
|
151
|
+
result = tool.execute(:export, params)
|
|
152
|
+
|
|
153
|
+
# Command information
|
|
154
|
+
puts "Executable: #{result.command_info.executable}"
|
|
155
|
+
puts "Arguments: #{result.command_info.arguments}"
|
|
156
|
+
puts "Full command: #{result.command_info.full_command}"
|
|
157
|
+
puts "Shell: #{result.command_info.shell}"
|
|
158
|
+
|
|
159
|
+
# Output
|
|
160
|
+
puts "Exit status: #{result.output.exit_status}"
|
|
161
|
+
puts "Stdout: #{result.output.stdout}"
|
|
162
|
+
puts "Stderr: #{result.output.stderr}"
|
|
163
|
+
puts "Success: #{result.success?}"
|
|
164
|
+
|
|
165
|
+
# Metadata
|
|
166
|
+
puts "Duration: #{result.metadata.duration_seconds}s"
|
|
167
|
+
puts "Formatted: #{result.metadata.formatted_duration}"
|
|
168
|
+
puts "Started: #{result.metadata.started_at}"
|
|
169
|
+
puts "Finished: #{result.metadata.finished_at}"
|
|
170
|
+
----
|
|
171
|
+
|
|
172
|
+
=== Convenience Methods
|
|
173
|
+
|
|
174
|
+
[source,ruby]
|
|
175
|
+
----
|
|
176
|
+
result = tool.execute(:export, params)
|
|
177
|
+
|
|
178
|
+
# Check success
|
|
179
|
+
result.success? # => true if exit status == 0
|
|
180
|
+
result.failure? # => true if exit status != 0
|
|
181
|
+
|
|
182
|
+
# Access output
|
|
183
|
+
result.stdout # => Stdout (stripped)
|
|
184
|
+
result.stderr # => Stderr (stripped)
|
|
185
|
+
result.stdout_lines # => Array of lines
|
|
186
|
+
result.stderr_lines # => Array of lines
|
|
187
|
+
----
|
|
188
|
+
|
|
189
|
+
// Type System
|
|
190
|
+
== Type System
|
|
191
|
+
|
|
192
|
+
Ukiryu validates parameter types against the profile definition.
|
|
193
|
+
|
|
194
|
+
=== Supported Types
|
|
195
|
+
|
|
196
|
+
[source,ruby]
|
|
197
|
+
----
|
|
198
|
+
# file - File path with platform formatting
|
|
199
|
+
tool.execute(:export, {
|
|
200
|
+
inputs: ['drawing.svg'], # Array of file paths
|
|
201
|
+
output: 'output.png' # Single file path
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
# string - Text value
|
|
205
|
+
tool.execute(:convert, {
|
|
206
|
+
text: 'Hello World'
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
# integer - Whole number with range
|
|
210
|
+
tool.execute(:export, {
|
|
211
|
+
dpi: 300 # Within 1-10000 range
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
# float - Decimal number with range
|
|
215
|
+
tool.execute(:export, {
|
|
216
|
+
background_opacity: 0.5 # Within 0.0-1.0 range
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
# symbol - Enumerated value
|
|
220
|
+
tool.execute(:export, {
|
|
221
|
+
format: :png # Must be in values list
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
# boolean - True/false flag
|
|
225
|
+
tool.execute(:export, {
|
|
226
|
+
plain: true,
|
|
227
|
+
batch_process: true
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
# array - Multiple values
|
|
231
|
+
tool.execute(:export, {
|
|
232
|
+
export_ids: ['id1', 'id2', 'id3'] # Joined with separator
|
|
233
|
+
})
|
|
234
|
+
----
|
|
235
|
+
|
|
236
|
+
=== Type Validation Errors
|
|
237
|
+
|
|
238
|
+
[source,ruby]
|
|
239
|
+
----
|
|
240
|
+
# Invalid type raises error
|
|
241
|
+
begin
|
|
242
|
+
tool.execute(:export, {
|
|
243
|
+
format: :unsupported # Not in values list
|
|
244
|
+
})
|
|
245
|
+
rescue Ukiryu::TypeError => e
|
|
246
|
+
puts "Type error: #{e.message}"
|
|
247
|
+
# => "Invalid value :unsupported for format. Valid values: svg, png, pdf, ..."
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Out of range raises error
|
|
251
|
+
begin
|
|
252
|
+
tool.execute(:export, {
|
|
253
|
+
dpi: -5 # Outside range 1-10000
|
|
254
|
+
})
|
|
255
|
+
rescue Ukiryu::RangeError => e
|
|
256
|
+
puts "Range error: #{e.message}"
|
|
257
|
+
# => "Value -5 is outside valid range 1-10000 for dpi"
|
|
258
|
+
end
|
|
259
|
+
----
|
|
260
|
+
|
|
261
|
+
// Error Handling
|
|
262
|
+
== Error Handling
|
|
263
|
+
|
|
264
|
+
=== Exception Types
|
|
265
|
+
|
|
266
|
+
[source,ruby]
|
|
267
|
+
----
|
|
268
|
+
require 'ukiryu'
|
|
269
|
+
|
|
270
|
+
begin
|
|
271
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
272
|
+
result = tool.execute(:export, params)
|
|
273
|
+
|
|
274
|
+
rescue Ukiryu::ToolNotFoundError => e
|
|
275
|
+
# Tool not in register
|
|
276
|
+
puts "Tool not found!"
|
|
277
|
+
puts "Available tools: #{Ukiryu::Register.tools.join(', ')}"
|
|
278
|
+
|
|
279
|
+
rescue Ukiryu::ProfileNotFoundError => e
|
|
280
|
+
# No compatible profile for platform/shell
|
|
281
|
+
puts "No profile available for this platform/shell"
|
|
282
|
+
|
|
283
|
+
rescue Ukiryu::ExecutionError => e
|
|
284
|
+
# Command failed (non-zero exit)
|
|
285
|
+
puts "Command failed!"
|
|
286
|
+
puts "Exit code: #{e.result.exit_status}"
|
|
287
|
+
puts "Command: #{e.result.command}"
|
|
288
|
+
puts "Stderr: #{e.result.stderr}"
|
|
289
|
+
|
|
290
|
+
rescue Ukiryu::TimeoutError => e
|
|
291
|
+
# Command exceeded timeout
|
|
292
|
+
puts "Command timed out after #{e.timeout} seconds"
|
|
293
|
+
end
|
|
294
|
+
----
|
|
295
|
+
|
|
296
|
+
=== Handling Failures Gracefully
|
|
297
|
+
|
|
298
|
+
[source,ruby]
|
|
299
|
+
----
|
|
300
|
+
# Allow failure without exception
|
|
301
|
+
result = tool.execute(:export, params, allow_failure: true)
|
|
302
|
+
|
|
303
|
+
if result.failure?
|
|
304
|
+
# Handle failure gracefully
|
|
305
|
+
logger.warn("Export failed: #{result.stderr}")
|
|
306
|
+
# Continue processing...
|
|
307
|
+
end
|
|
308
|
+
----
|
|
309
|
+
|
|
310
|
+
=== Detailed Error Information
|
|
311
|
+
|
|
312
|
+
[source,ruby]
|
|
313
|
+
----
|
|
314
|
+
begin
|
|
315
|
+
result = tool.execute(:export, params)
|
|
316
|
+
rescue Ukiryu::ExecutionError => e
|
|
317
|
+
# Access full result information
|
|
318
|
+
result = e.result
|
|
319
|
+
|
|
320
|
+
puts "Executable: #{result.command_info.executable}"
|
|
321
|
+
puts "Command: #{result.command_info.full_command}"
|
|
322
|
+
puts "Exit status: #{result.exit_status}"
|
|
323
|
+
puts "Stdout: #{result.stdout}"
|
|
324
|
+
puts "Stderr: #{result.stderr}"
|
|
325
|
+
|
|
326
|
+
# Log error details
|
|
327
|
+
logger.error("Command failed", {
|
|
328
|
+
executable: result.command_info.executable,
|
|
329
|
+
command: result.command_info.full_command,
|
|
330
|
+
exit_status: result.exit_status,
|
|
331
|
+
stderr: result.stderr
|
|
332
|
+
})
|
|
333
|
+
end
|
|
334
|
+
----
|
|
335
|
+
|
|
336
|
+
// Advanced Usage
|
|
337
|
+
== Advanced Usage
|
|
338
|
+
|
|
339
|
+
=== Tool Caching
|
|
340
|
+
|
|
341
|
+
[source,ruby]
|
|
342
|
+
----
|
|
343
|
+
# Tool instances are cached by {name}-{platform}-{shell}-{version}
|
|
344
|
+
tool1 = Ukiryu::Tool.get(:inkscape)
|
|
345
|
+
tool2 = Ukiryu::Tool.get(:inkscape)
|
|
346
|
+
|
|
347
|
+
tool1.equal?(tool2) # => true (same cached instance)
|
|
348
|
+
|
|
349
|
+
# Clear cache and reload
|
|
350
|
+
Ukiryu::Tool.clear_cache
|
|
351
|
+
tool3 = Ukiryu::Tool.get(:inkscape, reload: true)
|
|
352
|
+
----
|
|
353
|
+
|
|
354
|
+
=== Version Selection
|
|
355
|
+
|
|
356
|
+
[source,ruby]
|
|
357
|
+
----
|
|
358
|
+
# Get specific version
|
|
359
|
+
tool = Ukiryu::Tool.get(:inkscape, version: '0.92')
|
|
360
|
+
|
|
361
|
+
# Auto-detect version
|
|
362
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
363
|
+
# Uses version detection from profile
|
|
364
|
+
# Matches highest compatible profile
|
|
365
|
+
|
|
366
|
+
# Get version info
|
|
367
|
+
puts "Profile version: #{tool.profile.version}"
|
|
368
|
+
puts "Detected version: #{tool.version}"
|
|
369
|
+
----
|
|
370
|
+
|
|
371
|
+
=== Platform/Shell Override
|
|
372
|
+
|
|
373
|
+
[source,ruby]
|
|
374
|
+
----
|
|
375
|
+
# Auto-detect platform and shell
|
|
376
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
377
|
+
|
|
378
|
+
# Force specific platform
|
|
379
|
+
tool = Ukiryu::Tool.get(:inkscape, platform: :linux)
|
|
380
|
+
|
|
381
|
+
# Force specific shell
|
|
382
|
+
tool = Ukiryu::Tool.get(:inkscape, shell: :zsh)
|
|
383
|
+
----
|
|
384
|
+
|
|
385
|
+
=== Working Directory
|
|
386
|
+
|
|
387
|
+
[source,ruby]
|
|
388
|
+
----
|
|
389
|
+
# Execute in specific directory
|
|
390
|
+
result = tool.execute(:export, params, cwd: '/path/to/directory')
|
|
391
|
+
----
|
|
392
|
+
|
|
393
|
+
=== Stdin Input
|
|
394
|
+
|
|
395
|
+
[source,ruby]
|
|
396
|
+
----
|
|
397
|
+
# Pass stdin data to command
|
|
398
|
+
result = tool.execute(:compress, {
|
|
399
|
+
inputs: ['-'] # Read from stdin
|
|
400
|
+
}, stdin: "Hello World\n")
|
|
401
|
+
|
|
402
|
+
# Or pass IO object
|
|
403
|
+
File.open('data.txt') do |file|
|
|
404
|
+
result = tool.execute(:compress, {
|
|
405
|
+
inputs: ['-']
|
|
406
|
+
}, stdin: file)
|
|
407
|
+
end
|
|
408
|
+
----
|
|
409
|
+
|
|
410
|
+
// Examples
|
|
411
|
+
== Examples
|
|
412
|
+
|
|
413
|
+
=== Image Conversion with ImageMagick
|
|
414
|
+
|
|
415
|
+
[source,ruby]
|
|
416
|
+
----
|
|
417
|
+
require 'ukiryu'
|
|
418
|
+
|
|
419
|
+
tool = Ukiryu::Tool.get(:imagemagick)
|
|
420
|
+
|
|
421
|
+
# Convert to different format
|
|
422
|
+
result = tool.execute(:convert, {
|
|
423
|
+
inputs: ['photo.jpg'],
|
|
424
|
+
output: 'photo.png'
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
# With options
|
|
428
|
+
result = tool.execute(:convert, {
|
|
429
|
+
inputs: ['photo.jpg'],
|
|
430
|
+
output: 'photo.png',
|
|
431
|
+
resize: '50%',
|
|
432
|
+
quality: 85,
|
|
433
|
+
strip: true # Remove metadata
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
if result.success?
|
|
437
|
+
puts "Conversion successful!"
|
|
438
|
+
puts "Output size: #{File.size('photo.png')} bytes"
|
|
439
|
+
end
|
|
440
|
+
----
|
|
441
|
+
|
|
442
|
+
=== PDF Processing with Ghostscript
|
|
443
|
+
|
|
444
|
+
[source,ruby]
|
|
445
|
+
----
|
|
446
|
+
require 'ukiryu'
|
|
447
|
+
|
|
448
|
+
tool = Ukiryu::Tool.get(:ghostscript)
|
|
449
|
+
|
|
450
|
+
# Compress PDF
|
|
451
|
+
result = tool.execute(:convert, {
|
|
452
|
+
inputs: ['document.pdf'],
|
|
453
|
+
device: :pdfwrite,
|
|
454
|
+
output: 'document-compressed.pdf',
|
|
455
|
+
safer: true,
|
|
456
|
+
quiet: true
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
# Extract pages as images
|
|
460
|
+
result = tool.execute(:convert, {
|
|
461
|
+
inputs: ['presentation.pdf'],
|
|
462
|
+
device: :png16m,
|
|
463
|
+
output: 'slide-%03d.png',
|
|
464
|
+
quiet: true
|
|
465
|
+
})
|
|
466
|
+
----
|
|
467
|
+
|
|
468
|
+
=== Batch Processing
|
|
469
|
+
|
|
470
|
+
[source,ruby]
|
|
471
|
+
----
|
|
472
|
+
require 'ukiryu'
|
|
473
|
+
|
|
474
|
+
tool = Ukiryu::Tool.get(:inkscape)
|
|
475
|
+
|
|
476
|
+
# Process multiple files
|
|
477
|
+
files = Dir['*.svg']
|
|
478
|
+
files.each do |input_file|
|
|
479
|
+
output_file = input_file.sub('.svg', '.png')
|
|
480
|
+
|
|
481
|
+
result = tool.execute(:export, {
|
|
482
|
+
inputs: [input_file],
|
|
483
|
+
output: output_file,
|
|
484
|
+
format: :png,
|
|
485
|
+
dpi: 300
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
if result.failure?
|
|
489
|
+
puts "Failed to convert #{input_file}: #{result.stderr}"
|
|
490
|
+
else
|
|
491
|
+
puts "Converted #{input_file} -> #{output_file}"
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
----
|
|
495
|
+
|
|
496
|
+
=== Custom Error Handling
|
|
497
|
+
|
|
498
|
+
[source,ruby]
|
|
499
|
+
----
|
|
500
|
+
require 'ukiryu'
|
|
501
|
+
|
|
502
|
+
class ConversionService
|
|
503
|
+
def initialize(tool_name)
|
|
504
|
+
@tool = Ukiryu::Tool.get(tool_name)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def convert(input, output, options = {})
|
|
508
|
+
result = @tool.execute(:export, {
|
|
509
|
+
inputs: [input],
|
|
510
|
+
output: output
|
|
511
|
+
}.merge(options))
|
|
512
|
+
|
|
513
|
+
unless result.success?
|
|
514
|
+
raise ConversionError, "Failed to convert #{input} to #{output}: #{result.stderr}"
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
result
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
class ConversionError < StandardError; end
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
# Usage
|
|
524
|
+
service = ConversionService.new(:inkscape)
|
|
525
|
+
begin
|
|
526
|
+
service.convert('drawing.svg', 'drawing.png', format: :png)
|
|
527
|
+
rescue ConversionService::ConversionError => e
|
|
528
|
+
puts e.message
|
|
529
|
+
end
|
|
530
|
+
----
|
|
531
|
+
|
|
532
|
+
// See Also
|
|
533
|
+
== See Also
|
|
534
|
+
|
|
535
|
+
* link:/interfaces/cli[Command Line Interface] - Shell-based tool usage
|
|
536
|
+
* link:/features/configuration[Configuration Options] - All configuration methods
|
|
537
|
+
* link:/guides/[Guides] - Task-specific tutorials
|
|
538
|
+
* link:/reference/ruby-api[API Reference] - Complete API documentation
|