ukiryu 0.3.0 → 0.3.1
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/lib/ukiryu/version.rb +1 -1
- data/spec/support/tool_helper.rb +49 -0
- data/spec/ukiryu/cli_stdin_spec.rb +33 -30
- data/spec/ukiryu/tools/imagemagick_spec.rb +13 -3
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b172d6156b86340038461644b956c478709d55f34ee393d6e8768aeb424266f7
|
|
4
|
+
data.tar.gz: 85b530c9f1b1aadc4b43bddc0d6ada89f6ccb3ba225d92dbb703f070cb3b7275
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ac908e5fe60994361b0a7d2a8fc975d52f3969d0a516696749fe8de7b870147a7f5410344e4bcb92c2b5008cfdcbffca9894bfa1199c486f405ff05e8d1e6d1
|
|
7
|
+
data.tar.gz: 75c41074359f2ef89d505c77370f2e97826d0fa57afac1f59f5e0867b96788dde9dfb58db19d050b5d4677615ea084b18137a6e7ba72cd11fbdbd385a6564b5c
|
data/lib/ukiryu/version.rb
CHANGED
data/spec/support/tool_helper.rb
CHANGED
|
@@ -27,7 +27,56 @@ module ToolHelper
|
|
|
27
27
|
tool.version if tool.available?
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# True when the local ImageMagick can ENCODE PNG. Some runner builds
|
|
31
|
+
# (tool-setup/static installs) ship decode-only delegate sets: identify
|
|
32
|
+
# works but every PNG write fails with "no encode delegate for this
|
|
33
|
+
# image format `''". The fixture-copy specs decode fine; the
|
|
34
|
+
# resize/mogrify specs need the encoder.
|
|
35
|
+
def png_encode_available?
|
|
36
|
+
magick = %w[magick convert].find do |m|
|
|
37
|
+
system(m, "-version", out: File::NULL, err: File::NULL)
|
|
38
|
+
end
|
|
39
|
+
return false unless magick
|
|
40
|
+
|
|
41
|
+
require "tmpdir"
|
|
42
|
+
probe = File.join(Dir.tmpdir, "ukiryu_png_probe_#{Process.pid}.png")
|
|
43
|
+
File.delete(probe) if File.exist?(probe)
|
|
44
|
+
begin
|
|
45
|
+
ok = system(magick, "-size", "4x4", "xc:white", "png:#{probe}",
|
|
46
|
+
out: File::NULL, err: File::NULL)
|
|
47
|
+
ok && File.exist?(probe) && !File.zero?(probe)
|
|
48
|
+
ensure
|
|
49
|
+
File.delete(probe) if File.exist?(probe)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# True when mogrify can rewrite an image IN PLACE. ImageMagick
|
|
54
|
+
# 7.1.2-33 on macOS 26 regressed here: the same build encodes PNG
|
|
55
|
+
# (the probe above passes) yet in-place mogrify dies with
|
|
56
|
+
# "no encode delegate for this image format `'". Version-dependent,
|
|
57
|
+
# so the probe — not a version list — is the gate.
|
|
58
|
+
def mogrify_in_place_available?
|
|
59
|
+
magick = %w[magick convert].find do |m|
|
|
60
|
+
system(m, "-version", out: File::NULL, err: File::NULL)
|
|
61
|
+
end
|
|
62
|
+
return false unless magick
|
|
63
|
+
|
|
64
|
+
require "tmpdir"
|
|
65
|
+
require "fileutils"
|
|
66
|
+
dir = Dir.mktmpdir("ukiryu_mogrify_probe")
|
|
67
|
+
src = File.join(dir, "src.png")
|
|
68
|
+
ok = system(magick, "-size", "4x4", "xc:white", "png:#{src}",
|
|
69
|
+
out: File::NULL, err: File::NULL)
|
|
70
|
+
return false unless ok && File.exist?(src) && !File.zero?(src)
|
|
71
|
+
|
|
72
|
+
system(magick, "mogrify", "-resize", "2x2!", src,
|
|
73
|
+
out: File::NULL, err: File::NULL)
|
|
74
|
+
ensure
|
|
75
|
+
FileUtils.rm_rf(dir) if dir
|
|
76
|
+
end
|
|
77
|
+
|
|
30
78
|
# Create a temporary test image by copying a fixture image
|
|
79
|
+
|
|
31
80
|
# This avoids using ImageMagick's built-in formats which aren't available on all builds
|
|
32
81
|
# @param path [String] the path to create the image at
|
|
33
82
|
# @param size [String] the image size (e.g., "100x100", "200x150")
|
|
@@ -39,20 +39,23 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
39
39
|
Open3.capture3(env, 'bash', '-c', command)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
|
-
|
|
42
|
+
# Streams stay separate: engine-detection warnings legitimately land
|
|
43
|
+
# on stderr (e.g. leptris's "native acceleration unavailable" at
|
|
44
|
+
# require), and JSON assertions must parse the stream they mean.
|
|
45
|
+
[stdout, stderr, status]
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
def run_ukiryu_exec(args, stdin_data = nil)
|
|
46
49
|
cmd = "bundle exec ukiryu #{args}"
|
|
47
|
-
|
|
48
|
-
[
|
|
50
|
+
stdout, stderr, status = run_cli_command(cmd, stdin_data)
|
|
51
|
+
[stdout, stderr, status]
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
describe '--stdin flag' do
|
|
52
55
|
it 'reads from stdin pipe' do
|
|
53
56
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
54
57
|
|
|
55
|
-
output, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', '{"test": "value"}')
|
|
58
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', '{"test": "value"}')
|
|
56
59
|
|
|
57
60
|
# Parse JSON and extract stdout
|
|
58
61
|
parsed = JSON.parse(output)
|
|
@@ -64,7 +67,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
64
67
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
65
68
|
|
|
66
69
|
json_data = '{"lines": ["line1", "line2", "line3"]}'
|
|
67
|
-
output, status = run_ukiryu_exec('exec jq process --stdin filter=".lines" --format=json', json_data)
|
|
70
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin filter=".lines" --format=json', json_data)
|
|
68
71
|
|
|
69
72
|
parsed = JSON.parse(output)
|
|
70
73
|
stdout = parsed['output']['stdout']
|
|
@@ -80,7 +83,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
80
83
|
it 'reads from stdin pipe when stdin=- is specified' do
|
|
81
84
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
82
85
|
|
|
83
|
-
output, status = run_ukiryu_exec('exec jq process stdin=- filter=".foo" --format=json', '{"foo": "bar"}')
|
|
86
|
+
output, stderr, status = run_ukiryu_exec('exec jq process stdin=- filter=".foo" --format=json', '{"foo": "bar"}')
|
|
84
87
|
|
|
85
88
|
parsed = JSON.parse(output)
|
|
86
89
|
expect(parsed['output']['stdout'].strip).to eq('"bar"')
|
|
@@ -92,8 +95,8 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
92
95
|
|
|
93
96
|
stdin_data = '{"test": "data"}'
|
|
94
97
|
|
|
95
|
-
output1, status1 = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', stdin_data)
|
|
96
|
-
output2, status2 = run_ukiryu_exec('exec jq process stdin=- filter=".test" --format=json', stdin_data)
|
|
98
|
+
output1, stderr1, status1 = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', stdin_data)
|
|
99
|
+
output2, stderr2, status2 = run_ukiryu_exec('exec jq process stdin=- filter=".test" --format=json', stdin_data)
|
|
97
100
|
|
|
98
101
|
parsed1 = JSON.parse(output1)
|
|
99
102
|
parsed2 = JSON.parse(output2)
|
|
@@ -111,11 +114,11 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
111
114
|
file.close
|
|
112
115
|
|
|
113
116
|
# On Windows, we need to redirect stderr separately to avoid mixing with JSON output
|
|
114
|
-
output, status = if platform == :windows
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
output, stderr, status = if platform == :windows
|
|
118
|
+
run_cli_command("bundle exec ukiryu exec jq process stdin=@#{file.path} filter=\".file\" --format=json 2>$null")
|
|
119
|
+
else
|
|
120
|
+
run_cli_command("bundle exec ukiryu exec jq process stdin=@#{file.path} filter=\".file\" --format=json")
|
|
121
|
+
end
|
|
119
122
|
|
|
120
123
|
parsed = JSON.parse(output)
|
|
121
124
|
expect(parsed['output']['stdout'].strip).to eq('"content"')
|
|
@@ -124,9 +127,9 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
124
127
|
end
|
|
125
128
|
|
|
126
129
|
it 'shows error when file does not exist' do
|
|
127
|
-
output, status = run_cli_command('bundle exec ukiryu exec jq process stdin=@/nonexistent/file.json filter="." 2>&1')
|
|
130
|
+
output, stderr, status = run_cli_command('bundle exec ukiryu exec jq process stdin=@/nonexistent/file.json filter="." 2>&1')
|
|
128
131
|
|
|
129
|
-
expect(output).to include('File not found')
|
|
132
|
+
expect(output + stderr).to include('File not found')
|
|
130
133
|
expect(status.success?).to be false
|
|
131
134
|
end
|
|
132
135
|
end
|
|
@@ -140,7 +143,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
140
143
|
file.write('{"test": "value"}')
|
|
141
144
|
file.flush # Ensure data is written to disk
|
|
142
145
|
|
|
143
|
-
output, status = run_ukiryu_exec("exec jq process stdin=@#{file.path} filter=.test --format=json")
|
|
146
|
+
output, stderr, status = run_ukiryu_exec("exec jq process stdin=@#{file.path} filter=.test --format=json")
|
|
144
147
|
|
|
145
148
|
parsed = JSON.parse(output)
|
|
146
149
|
expect(parsed).not_to be_nil
|
|
@@ -156,10 +159,10 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
156
159
|
|
|
157
160
|
# Use NO_COLOR to avoid ANSI escape codes in output
|
|
158
161
|
# Use -D for dry-run (uppercase D, not lowercase d which is now --definition)
|
|
159
|
-
output, status = run_ukiryu_exec('exec jq process --stdin -D filter="."', '{"test": "value"}')
|
|
162
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin -D filter="."', '{"test": "value"}')
|
|
160
163
|
|
|
161
|
-
expect(output).to include('DRY RUN')
|
|
162
|
-
expect(output).to include('stdin:')
|
|
164
|
+
expect(output + stderr).to include('DRY RUN')
|
|
165
|
+
expect(output + stderr).to include('stdin:')
|
|
163
166
|
# Output has escaped backslashes in the inspection format
|
|
164
167
|
expect(output).to include('test')
|
|
165
168
|
expect(output).to include('value')
|
|
@@ -171,7 +174,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
171
174
|
|
|
172
175
|
long_data = 'x' * 200
|
|
173
176
|
# Use -D for dry-run (uppercase D, not lowercase d which is now --definition)
|
|
174
|
-
output, status = run_ukiryu_exec('exec jq process --stdin -D filter="."', long_data)
|
|
177
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin -D filter="."', long_data)
|
|
175
178
|
|
|
176
179
|
expect(output).to include('...')
|
|
177
180
|
# Preview should be truncated (check in the output, not just the matched string)
|
|
@@ -185,7 +188,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
185
188
|
it 'outputs JSON format with stdin' do
|
|
186
189
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
187
190
|
|
|
188
|
-
output, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', '{"test": "value"}')
|
|
191
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=json', '{"test": "value"}')
|
|
189
192
|
|
|
190
193
|
parsed = JSON.parse(output)
|
|
191
194
|
expect(parsed['output']['stdout']).to include('"value"')
|
|
@@ -195,7 +198,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
195
198
|
it 'outputs YAML format with stdin' do
|
|
196
199
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
197
200
|
|
|
198
|
-
output, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=yaml', '{"test": "value"}')
|
|
201
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin filter=".test" --format=yaml', '{"test": "value"}')
|
|
199
202
|
|
|
200
203
|
expect(output).to include('stdout:')
|
|
201
204
|
expect(output).to include('value')
|
|
@@ -213,7 +216,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
213
216
|
file.close
|
|
214
217
|
|
|
215
218
|
# Use cat instead of echo to avoid escaping issues
|
|
216
|
-
result, status = run_cli_command("cat #{file.path} | bundle exec ukiryu exec jq process --stdin filter='.items' --format=json | head -10")
|
|
219
|
+
result, stderr, status = run_cli_command("cat #{file.path} | bundle exec ukiryu exec jq process --stdin filter='.items' --format=json | head -10")
|
|
217
220
|
|
|
218
221
|
# The output should be valid JSON, and head should truncate it
|
|
219
222
|
expect(result).not_to be_empty
|
|
@@ -227,7 +230,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
227
230
|
|
|
228
231
|
# Simulate curl output using echo instead of actual network call
|
|
229
232
|
json_data = '{"slideshow": {"title": "Test Presentation"}}'
|
|
230
|
-
result, status = run_cli_command("echo '#{json_data}' | bundle exec ukiryu exec jq process --stdin filter='.slideshow.title' --format=json")
|
|
233
|
+
result, stderr, status = run_cli_command("echo '#{json_data}' | bundle exec ukiryu exec jq process --stdin filter='.slideshow.title' --format=json")
|
|
231
234
|
|
|
232
235
|
expect(result).not_to be_empty
|
|
233
236
|
expect(result).to include('Test Presentation')
|
|
@@ -239,7 +242,7 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
239
242
|
it 'outputs only the command stdout without wrapping' do
|
|
240
243
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
241
244
|
|
|
242
|
-
output, status = run_ukiryu_exec('exec jq process --stdin --raw filter=".test"', '{"test": "value"}')
|
|
245
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin --raw filter=".test"', '{"test": "value"}')
|
|
243
246
|
|
|
244
247
|
# Should output just "value" without YAML/JSON wrapping
|
|
245
248
|
expect(output.strip).to eq('"value"')
|
|
@@ -252,12 +255,12 @@ RSpec.describe 'Ukiryu::CliCommands::RunCommand stdin handling' do
|
|
|
252
255
|
skip 'Unix pipe tests require Unix shell' if platform == :windows
|
|
253
256
|
|
|
254
257
|
# Test with a command that produces stderr - use syntax error in jq
|
|
255
|
-
output, = run_ukiryu_exec('exec jq process --stdin --raw filter=".foo[bar"', '{}')
|
|
258
|
+
output, stderr, status = run_ukiryu_exec('exec jq process --stdin --raw filter=".foo[bar"', '{}')
|
|
256
259
|
|
|
257
|
-
# jq
|
|
258
|
-
expect(
|
|
259
|
-
expect(output).to include('error')
|
|
260
|
-
expect(output).to include('syntax error')
|
|
260
|
+
# jq's error passes through to the CLI's stderr
|
|
261
|
+
expect(stderr).not_to be_empty
|
|
262
|
+
expect(output + stderr).to include('error')
|
|
263
|
+
expect(output + stderr).to include('syntax error')
|
|
261
264
|
end
|
|
262
265
|
end
|
|
263
266
|
end
|
|
@@ -43,7 +43,10 @@ RSpec.describe 'ImageMagick Tool Profile' do
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
describe 'convert command' do
|
|
46
|
-
before(:each)
|
|
46
|
+
before(:each) do
|
|
47
|
+
skip_unless_tool_available(:imagemagick)
|
|
48
|
+
skip 'ImageMagick lacks a PNG encode delegate on this runner' unless png_encode_available?
|
|
49
|
+
end
|
|
47
50
|
|
|
48
51
|
it 'converts between formats' do
|
|
49
52
|
input = File.join(@temp_dir, 'input.png')
|
|
@@ -140,7 +143,10 @@ RSpec.describe 'ImageMagick Tool Profile' do
|
|
|
140
143
|
end
|
|
141
144
|
|
|
142
145
|
describe 'identify command' do
|
|
143
|
-
before(:each)
|
|
146
|
+
before(:each) do
|
|
147
|
+
skip_unless_tool_available(:imagemagick)
|
|
148
|
+
skip 'ImageMagick lacks a PNG encode delegate on this runner' unless png_encode_available?
|
|
149
|
+
end
|
|
144
150
|
|
|
145
151
|
it 'identifies image format and characteristics' do
|
|
146
152
|
input = File.join(@temp_dir, 'test.png')
|
|
@@ -168,7 +174,11 @@ RSpec.describe 'ImageMagick Tool Profile' do
|
|
|
168
174
|
end
|
|
169
175
|
|
|
170
176
|
describe 'mogrify command' do
|
|
171
|
-
before(:each)
|
|
177
|
+
before(:each) do
|
|
178
|
+
skip_unless_tool_available(:imagemagick)
|
|
179
|
+
skip 'ImageMagick lacks a PNG encode delegate on this runner' unless png_encode_available?
|
|
180
|
+
skip 'ImageMagick regressed in-place mogrify on this runner' unless mogrify_in_place_available?
|
|
181
|
+
end
|
|
172
182
|
|
|
173
183
|
it 'modifies images in place' do
|
|
174
184
|
input = File.join(@temp_dir, 'test.png')
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ukiryu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -29,28 +29,28 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 6.2.1
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 6.2.1
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: lutaml-model
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.8.
|
|
46
|
+
version: 0.8.114
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.8.
|
|
53
|
+
version: 0.8.114
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: lutaml-xsd
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -426,7 +426,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
426
426
|
- !ruby/object:Gem::Version
|
|
427
427
|
version: '0'
|
|
428
428
|
requirements: []
|
|
429
|
-
rubygems_version: 4.0.
|
|
429
|
+
rubygems_version: 4.0.23
|
|
430
430
|
specification_version: 4
|
|
431
431
|
summary: The "OpenAPI" for Command Line Interfaces
|
|
432
432
|
test_files:
|