Module: Browserctl::Commands::Flow

Extended by:
CliOutput
Defined in:
lib/browserctl/commands/flow.rb

Constant Summary collapse

USAGE =
"Usage: browserctl flow <run|list|describe> [args]"

Constants included from CliOutput

CliOutput::AUTH_REQUIRED_EXIT_CODE

Class Method Summary collapse

Methods included from CliOutput

exit_code_for, print_result, structured_error_line

Class Method Details

.format_params(flow) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/browserctl/commands/flow.rb', line 106

def self.format_params(flow)
  flow.param_defs.transform_values do |p|
    entry = { required: p.required, secret: p.secret, default: p.default }
    entry[:secret_ref] = p.secret_ref if p.secret_ref
    entry
  end
end

.load_params_file(path) ⇒ Object



92
93
94
95
96
# File 'lib/browserctl/commands/flow.rb', line 92

def self.load_params_file(path)
  Browserctl::Runner.load_params_file(path)
rescue StandardError => e
  abort "Error loading params file: #{e.message}"
end

.pair_args(args) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/browserctl/commands/flow.rb', line 98

def self.pair_args(args)
  out = {}
  args.each_slice(2) do |flag, val|
    out[flag.sub(/\A--/, "").to_sym] = val
  end
  out
end

.parse_run_args(args) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/browserctl/commands/flow.rb', line 75

def self.parse_run_args(args)
  page_name = take_option(args, "--page")
  params_path = take_option(args, "--params")
  file_params = params_path ? load_params_file(params_path) : {}
  cli_params = pair_args(args)
  [page_name, file_params.merge(cli_params)]
end

.resolve(name_or_path) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/browserctl/commands/flow.rb', line 62

def self.resolve(name_or_path)
  if File.exist?(name_or_path)
    before = Browserctl.flow_registry_snapshot.keys
    load File.expand_path(name_or_path)
    new_name = (Browserctl.flow_registry_snapshot.keys - before).first
    new_name ||= File.basename(name_or_path, ".rb")
    flow = Browserctl.lookup_flow(new_name)
  else
    flow = Browserctl::FlowRegistry.resolve(name_or_path)
  end
  flow or abort "flow '#{name_or_path}' not found"
end

.run(client, args) ⇒ Object



15
16
17
18
19
20
21
22
23
# File 'lib/browserctl/commands/flow.rb', line 15

def self.run(client, args)
  sub = args.shift or abort USAGE
  case sub
  when "run"      then run_flow(client, args)
  when "list"     then run_list
  when "describe" then run_describe(args)
  else abort "unknown flow subcommand '#{sub}'\n#{USAGE}"
  end
end

.run_describe(args) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/browserctl/commands/flow.rb', line 46

def self.run_describe(args)
  name = args.shift or abort "usage: browserctl flow describe <name>"
  flow = resolve(name)
  puts JSON.pretty_generate(
    name: flow.name,
    desc: flow.description,
    version: flow.version_string,
    requires_browserctl: flow.min_browserctl_version,
    params: format_params(flow),
    preconditions: flow.preconditions.map(&:label),
    steps: flow.steps.map(&:label),
    postconditions: flow.postconditions.map(&:label),
    produces_state: !flow.produces_state_block.nil?
  )
end

.run_flow(client, args) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/browserctl/commands/flow.rb', line 25

def self.run_flow(client, args)
  name = args.shift or
    abort "usage: browserctl flow run <name|file> [--page NAME] [--params FILE] [--key value ...]"

  flow = resolve(name)
  page_name, params = parse_run_args(args)
  page_proxy = page_name ? Browserctl::PageProxy.new(page_name, client) : nil

  result = flow.run(page: page_proxy, client: client, **params)
  puts JSON.generate(ok: true, flow: flow.name, result: serialisable(result))
rescue Browserctl::FlowError => e
  warn "Error: #{e.message}"
  puts JSON.generate(ok: false, code: e.code, error: e.message)
  exit 1
end

.run_listObject



41
42
43
44
# File 'lib/browserctl/commands/flow.rb', line 41

def self.run_list
  entries = Browserctl::FlowRegistry.list
  puts JSON.generate(flows: entries)
end

.serialisable(value) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/browserctl/commands/flow.rb', line 114

def self.serialisable(value)
  case value
  when nil, true, false, Numeric, String, Hash, Array then value
  when Symbol then value.to_s
  else value.respond_to?(:to_h) ? value.to_h : value.to_s
  end
end

.take_option(args, flag) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/browserctl/commands/flow.rb', line 83

def self.take_option(args, flag)
  idx = args.index(flag)
  return nil unless idx

  value = args.delete_at(idx + 1)
  args.delete_at(idx)
  value
end