wisco 0.3.8 → 0.4.0
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/wisco/commands/exec.rb +100 -13
- data/lib/wisco/commands/list.rb +69 -1
- data/lib/wisco/version.rb +1 -1
- data/lib/wisco.rb +9 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d0223c07b265d6b699acec69facb0abc3cded752a3b99791454507bf8623490
|
|
4
|
+
data.tar.gz: 82b76acb11a65728840067d60bb809f0fb4f88421b0efeac922b967915cef2dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91cae2af261537aa28ab79a66f817fc4095f06c7d2f7cc16281e181872e4d5101b09386cc31793b1d8da09dbf03040946d2b162c41d3705062c4a7b77a5bd7a9
|
|
7
|
+
data.tar.gz: 8355aa7b644b559c082d656ca19134b3af9c3a2803f1e31ba7e27b4a31d11af9ea1788a558f259e69d7c4d0af88b5e6f27abf19d223b312c1aa1c273cda93d9b
|
data/lib/wisco/commands/exec.rb
CHANGED
|
@@ -6,6 +6,7 @@ require_relative '../config'
|
|
|
6
6
|
require_relative '../connector'
|
|
7
7
|
require_relative '../path_utils'
|
|
8
8
|
require_relative '../exec_script'
|
|
9
|
+
require_relative 'fixtures'
|
|
9
10
|
|
|
10
11
|
module Wisco
|
|
11
12
|
module Commands
|
|
@@ -14,7 +15,8 @@ module Wisco
|
|
|
14
15
|
|
|
15
16
|
def run(path_arg, target_dir, input: nil, pagination: true, verbose: false, debug: false,
|
|
16
17
|
extended: true, closure: nil, config_fields: nil, continue: nil,
|
|
17
|
-
extended_input_schema: nil, extended_output_schema: nil
|
|
18
|
+
extended_input_schema: nil, extended_output_schema: nil,
|
|
19
|
+
summary: true, summary_lines: 20)
|
|
18
20
|
target_dir = File.expand_path(target_dir)
|
|
19
21
|
config_path = Wisco.config_path(target_dir)
|
|
20
22
|
|
|
@@ -51,12 +53,12 @@ module Wisco
|
|
|
51
53
|
fixture_dir_output = fixtures_dir.sub(connector_path, '.')
|
|
52
54
|
|
|
53
55
|
unless File.directory?(fixtures_dir)
|
|
54
|
-
|
|
55
|
-
Wisco::
|
|
56
|
-
next
|
|
56
|
+
puts " Auto-setup: running fixtures for #{section}.#{key}"
|
|
57
|
+
Wisco::Commands::Fixtures.run("#{section}.#{key}", target_dir, debug: debug)
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
input_files = resolve_input_files(input, fixtures_dir, debug: debug)
|
|
61
|
+
batch = pairs.length > 1 || input_files.length > 1
|
|
60
62
|
|
|
61
63
|
if input_files.empty?
|
|
62
64
|
if %w[pick_lists methods].include?(section)
|
|
@@ -65,9 +67,14 @@ module Wisco
|
|
|
65
67
|
pagination: pagination, verbose: verbose, extended: extended,
|
|
66
68
|
closure: closure, config_fields: config_fields, continue: continue,
|
|
67
69
|
extended_input_schema: extended_input_schema,
|
|
68
|
-
extended_output_schema: extended_output_schema, debug: debug
|
|
70
|
+
extended_output_schema: extended_output_schema, debug: debug,
|
|
71
|
+
summary: summary, summary_lines: summary_lines, batch: batch)
|
|
69
72
|
else
|
|
70
73
|
Wisco::TerminalOutput.emit_warning(" Warning: No ready input files found in #{fixture_dir_output}")
|
|
74
|
+
input_template = File.join(fixtures_dir, 'execute_input.json')
|
|
75
|
+
if File.exist?(input_template)
|
|
76
|
+
Wisco::TerminalOutput.emit_info(" Fill in #{File.join(fixture_dir_output, 'execute_input.json')} and re-run.")
|
|
77
|
+
end
|
|
71
78
|
end
|
|
72
79
|
next
|
|
73
80
|
end
|
|
@@ -79,13 +86,15 @@ module Wisco
|
|
|
79
86
|
pagination: pagination, verbose: verbose,
|
|
80
87
|
extended: extended, closure: closure, config_fields: config_fields,
|
|
81
88
|
continue: continue, extended_input_schema: extended_input_schema,
|
|
82
|
-
extended_output_schema: extended_output_schema, debug: debug
|
|
89
|
+
extended_output_schema: extended_output_schema, debug: debug,
|
|
90
|
+
summary: summary, summary_lines: summary_lines, batch: batch)
|
|
83
91
|
else
|
|
84
92
|
execute_one(section, key, input_file, fixtures_dir,
|
|
85
93
|
connector_full_path, connection, pagination: pagination, verbose: verbose,
|
|
86
94
|
extended: extended, closure: closure, config_fields: config_fields,
|
|
87
95
|
continue: continue, extended_input_schema: extended_input_schema,
|
|
88
|
-
extended_output_schema: extended_output_schema, debug: debug
|
|
96
|
+
extended_output_schema: extended_output_schema, debug: debug,
|
|
97
|
+
summary: summary, summary_lines: summary_lines, batch: batch)
|
|
89
98
|
end
|
|
90
99
|
end
|
|
91
100
|
end
|
|
@@ -184,7 +193,8 @@ module Wisco
|
|
|
184
193
|
def execute_one(section, key, input_file, fixtures_dir, connector_full_path, connection,
|
|
185
194
|
pagination: true, verbose: false, debug: false,
|
|
186
195
|
extended: true, closure: nil, config_fields: nil, continue: nil,
|
|
187
|
-
extended_input_schema: nil, extended_output_schema: nil
|
|
196
|
+
extended_input_schema: nil, extended_output_schema: nil,
|
|
197
|
+
summary: true, summary_lines: 20, batch: false)
|
|
188
198
|
stem = input_file ? File.basename(input_file, '.*') : 'execute'
|
|
189
199
|
output_file = File.join(fixtures_dir, "output_#{stem}.json")
|
|
190
200
|
error_file = File.join(fixtures_dir, "error_#{stem}.txt")
|
|
@@ -265,12 +275,14 @@ module Wisco
|
|
|
265
275
|
end
|
|
266
276
|
|
|
267
277
|
FileUtils.rm_f(error_file)
|
|
268
|
-
|
|
269
278
|
return unless File.exist?(output_file)
|
|
270
279
|
|
|
271
|
-
|
|
280
|
+
parsed = JSON.parse(File.read(output_file))
|
|
281
|
+
pretty = JSON.pretty_generate(parsed)
|
|
272
282
|
File.write(output_file, pretty + "\n")
|
|
273
283
|
puts " Written: #{output_file}"
|
|
284
|
+
display_output_summary(parsed, pretty, section: section, summary: summary,
|
|
285
|
+
summary_lines: summary_lines, batch: batch)
|
|
274
286
|
end
|
|
275
287
|
|
|
276
288
|
# Handles `execute_*.rb` scripts: evaluates the script to produce dynamic
|
|
@@ -282,7 +294,8 @@ module Wisco
|
|
|
282
294
|
connector_full_path, connection, config,
|
|
283
295
|
pagination: true, verbose: false, debug: false,
|
|
284
296
|
extended: true, closure: nil, config_fields: nil, continue: nil,
|
|
285
|
-
extended_input_schema: nil, extended_output_schema: nil
|
|
297
|
+
extended_input_schema: nil, extended_output_schema: nil,
|
|
298
|
+
summary: true, summary_lines: 20, batch: false)
|
|
286
299
|
subdir = File.join(fixtures_dir, File.basename(script_path, '.rb'))
|
|
287
300
|
FileUtils.mkdir_p(subdir)
|
|
288
301
|
input_file = File.join(subdir, 'input.json')
|
|
@@ -377,14 +390,88 @@ module Wisco
|
|
|
377
390
|
end
|
|
378
391
|
|
|
379
392
|
FileUtils.rm_f(error_file)
|
|
380
|
-
|
|
381
393
|
return unless File.exist?(output_file)
|
|
382
394
|
|
|
383
|
-
|
|
395
|
+
parsed = JSON.parse(File.read(output_file))
|
|
396
|
+
pretty = JSON.pretty_generate(parsed)
|
|
384
397
|
File.write(output_file, pretty + "\n")
|
|
385
398
|
puts " Written: #{output_file}"
|
|
399
|
+
display_output_summary(parsed, pretty, section: section, summary: summary,
|
|
400
|
+
summary_lines: summary_lines, batch: batch)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# ── Output summary ─────────────────────────────────────────────────────
|
|
404
|
+
|
|
405
|
+
def display_output_summary(parsed, pretty, section:, summary:, summary_lines:, batch:)
|
|
406
|
+
return unless summary
|
|
407
|
+
|
|
408
|
+
if section == 'pick_lists'
|
|
409
|
+
if batch
|
|
410
|
+
count = parsed.is_a?(Array) ? parsed.length : '?'
|
|
411
|
+
puts " Items: #{count}"
|
|
412
|
+
else
|
|
413
|
+
display_pick_list_table(parsed)
|
|
414
|
+
end
|
|
415
|
+
return
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
puts pretty if !batch && pretty.lines.length <= (summary_lines || 20)
|
|
419
|
+
puts " #{format_summary(parsed)}"
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def display_pick_list_table(data)
|
|
423
|
+
unless data.is_a?(Array) && !data.empty?
|
|
424
|
+
puts ' (empty)'
|
|
425
|
+
return
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
rows = data.select { |item| item.is_a?(Array) && item.length >= 2 }
|
|
429
|
+
|
|
430
|
+
if rows.empty?
|
|
431
|
+
puts " Items: #{data.length} (unexpected format)"
|
|
432
|
+
return
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
max_col = 60
|
|
436
|
+
labels = rows.map { |item| truncate_str(item[0].to_s, max_col) }
|
|
437
|
+
values = rows.map { |item| truncate_str(item[1].to_s, max_col) }
|
|
438
|
+
|
|
439
|
+
col1_w = [labels.map(&:length).max, 'Label'.length].max
|
|
440
|
+
col2_w = [values.map(&:length).max, 'Value'.length].max
|
|
441
|
+
num_w = rows.length.to_s.length
|
|
442
|
+
|
|
443
|
+
puts " Items: #{rows.length}"
|
|
444
|
+
puts " | #{'#'.ljust(num_w)} | #{'Label'.ljust(col1_w)} | #{'Value'.ljust(col2_w)} |"
|
|
445
|
+
puts " |#{'-' * (num_w + 2)}|#{'-' * (col1_w + 2)}|#{'-' * (col2_w + 2)}|"
|
|
446
|
+
rows.each_with_index do |_, i|
|
|
447
|
+
puts " | #{(i + 1).to_s.ljust(num_w)} | #{labels[i].ljust(col1_w)} | #{values[i].ljust(col2_w)} |"
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def format_summary(parsed)
|
|
452
|
+
case parsed
|
|
453
|
+
when Array
|
|
454
|
+
return 'Array: 0 items' if parsed.empty?
|
|
455
|
+
first_str = parsed.first.inspect
|
|
456
|
+
first_str = "#{first_str[0, 97]}…" if first_str.length > 100
|
|
457
|
+
"Array: #{parsed.length} #{parsed.length == 1 ? 'item' : 'items'} — first: #{first_str}"
|
|
458
|
+
when Hash
|
|
459
|
+
return 'Hash: 0 keys' if parsed.empty?
|
|
460
|
+
keys = parsed.keys.first(20)
|
|
461
|
+
suffix = parsed.keys.length > 20 ? " (+#{parsed.keys.length - 20} more)" : ''
|
|
462
|
+
"Hash: #{parsed.keys.length} keys — #{keys.join(', ')}#{suffix}"
|
|
463
|
+
when NilClass
|
|
464
|
+
'(nil)'
|
|
465
|
+
else
|
|
466
|
+
"Value: #{parsed.inspect}"
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def truncate_str(str, max)
|
|
471
|
+
str.length > max ? "#{str[0, max - 1]}…" : str
|
|
386
472
|
end
|
|
387
473
|
|
|
474
|
+
# ── SDK array-args normalisation ───────────────────────────────────────
|
|
388
475
|
# The Workato SDK's InvokePath#invoke_method applies Array.wrap(args.last).flatten(1)
|
|
389
476
|
# when the last parameter is *args, which incorrectly unwraps array-valued positional
|
|
390
477
|
# arguments one level too many. These helpers compensate by pre-wrapping Array elements
|
data/lib/wisco/commands/list.rb
CHANGED
|
@@ -12,9 +12,14 @@ module Wisco
|
|
|
12
12
|
|
|
13
13
|
module_function
|
|
14
14
|
|
|
15
|
-
def run(subcommand, target, sort: nil)
|
|
15
|
+
def run(subcommand, target, sort: nil, format: nil)
|
|
16
16
|
validate_sort!(sort)
|
|
17
17
|
|
|
18
|
+
if format
|
|
19
|
+
run_formatted(target, format: format)
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
|
|
18
23
|
case subcommand
|
|
19
24
|
when nil then run_tree(target)
|
|
20
25
|
when 'actions' then run_actions(target, sort: sort)
|
|
@@ -93,6 +98,69 @@ module Wisco
|
|
|
93
98
|
run_triggers(target_dir, sort: sort)
|
|
94
99
|
end
|
|
95
100
|
|
|
101
|
+
# ---------------------------------------------------------------------------
|
|
102
|
+
# Machine-readable output
|
|
103
|
+
# ---------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
def run_formatted(target_dir, format:)
|
|
106
|
+
require 'yaml' if format.downcase == 'yaml'
|
|
107
|
+
connector = Wisco::Connector.load_connector_from_config(target_dir)
|
|
108
|
+
data = build_connector_hash(connector)
|
|
109
|
+
if format.downcase == 'yaml'
|
|
110
|
+
puts data.to_yaml
|
|
111
|
+
else
|
|
112
|
+
puts JSON.pretty_generate(data)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def build_connector_hash(connector)
|
|
117
|
+
{
|
|
118
|
+
'title' => connector[:title].to_s,
|
|
119
|
+
'connection' => build_connection(connector[:connection]),
|
|
120
|
+
'actions' => build_section(connector[:actions]),
|
|
121
|
+
'triggers' => build_section(connector[:triggers]),
|
|
122
|
+
'methods' => (connector[:methods] || {}).keys.map(&:to_s).sort,
|
|
123
|
+
'pick_lists' => (connector[:pick_lists] || {}).keys.map(&:to_s).sort
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def build_connection(conn)
|
|
128
|
+
return { 'fields' => [] } unless conn.is_a?(Hash)
|
|
129
|
+
|
|
130
|
+
fields = conn[:fields] || []
|
|
131
|
+
{ 'fields' => fields.map { |f| safe_serialize(f) }.compact }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def build_section(section)
|
|
135
|
+
return {} unless section.is_a?(Hash)
|
|
136
|
+
|
|
137
|
+
section.keys.sort_by(&:to_s).each_with_object({}) do |key, h|
|
|
138
|
+
item = section[key]
|
|
139
|
+
h[key.to_s] = {
|
|
140
|
+
'title' => title_for(key, item),
|
|
141
|
+
'subtitle' => subtitle_for(item).to_s
|
|
142
|
+
}
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Recursively converts a connector value to a JSON-safe structure.
|
|
147
|
+
# Proc/lambda values are dropped (returned as nil so callers can compact).
|
|
148
|
+
def safe_serialize(value)
|
|
149
|
+
case value
|
|
150
|
+
when Hash
|
|
151
|
+
value.each_with_object({}) do |(k, v), h|
|
|
152
|
+
next if v.is_a?(Proc)
|
|
153
|
+
|
|
154
|
+
serialized = safe_serialize(v)
|
|
155
|
+
h[k.to_s] = serialized
|
|
156
|
+
end
|
|
157
|
+
when Array then value.map { |v| safe_serialize(v) }
|
|
158
|
+
when Proc then nil
|
|
159
|
+
when Symbol then value.to_s
|
|
160
|
+
else value
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
96
164
|
# ---------------------------------------------------------------------------
|
|
97
165
|
# List utilities
|
|
98
166
|
# ---------------------------------------------------------------------------
|
data/lib/wisco/version.rb
CHANGED
data/lib/wisco.rb
CHANGED
|
@@ -68,13 +68,14 @@ module Wisco
|
|
|
68
68
|
all Show tree + actions + triggers
|
|
69
69
|
PATH defaults to the current directory.
|
|
70
70
|
DESC
|
|
71
|
-
option :sort,
|
|
71
|
+
option :sort, type: :string, desc: 'Sort actions/triggers by key or title', enum: %w[key title]
|
|
72
|
+
option :format, type: :string, desc: 'Machine-readable output format (use with "all")', enum: %w[json yaml]
|
|
72
73
|
def list(subcommand = nil, path = nil)
|
|
73
74
|
if subcommand&.match?(%r{^[./~\\]|^[A-Za-z]:[/\\]})
|
|
74
75
|
path = subcommand
|
|
75
76
|
subcommand = nil
|
|
76
77
|
end
|
|
77
|
-
Wisco::Commands::List.run(subcommand, path || Dir.pwd, sort: options[:sort])
|
|
78
|
+
Wisco::Commands::List.run(subcommand, path || Dir.pwd, sort: options[:sort], format: options[:format])
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
desc 'exec PATH [TARGET_DIR]', 'Execute connector methods against fixture data'
|
|
@@ -98,7 +99,9 @@ module Wisco
|
|
|
98
99
|
option :continue, type: :string, desc: 'Continue JSON file (multistep actions)'
|
|
99
100
|
option :'extended-input-schema', type: :string, desc: 'Extended input schema JSON (overrides --extended auto-detection)'
|
|
100
101
|
option :'extended-output-schema', type: :string, desc: 'Extended output schema JSON (overrides --extended auto-detection)'
|
|
101
|
-
option :debug,
|
|
102
|
+
option :debug, type: :boolean, default: false, desc: 'Print ExecCommand call details'
|
|
103
|
+
option :summary, type: :boolean, default: true, desc: 'Show output summary after execution (use --no-summary to disable)'
|
|
104
|
+
option :'summary-lines', type: :numeric, default: 20, desc: 'Max output lines to display in full before switching to summary-only'
|
|
102
105
|
def exec(path_arg, target_dir = nil)
|
|
103
106
|
Wisco::Commands::Exec.run(
|
|
104
107
|
path_arg,
|
|
@@ -112,7 +115,9 @@ module Wisco
|
|
|
112
115
|
continue: options[:continue],
|
|
113
116
|
extended_input_schema: options[:extended_input_schema],
|
|
114
117
|
extended_output_schema: options[:extended_output_schema],
|
|
115
|
-
debug: options[:debug]
|
|
118
|
+
debug: options[:debug],
|
|
119
|
+
summary: options[:summary],
|
|
120
|
+
summary_lines: options[:'summary-lines']
|
|
116
121
|
)
|
|
117
122
|
end
|
|
118
123
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wisco
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mbillington
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|