/
task_helper.rb
78 lines (67 loc) · 1.82 KB
/
task_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
require 'json'
class TaskHelper
attr_reader :debug_statements
class Error < RuntimeError
attr_reader :kind, :details, :issue_code
def initialize(msg, kind, details = nil)
super(msg)
@kind = kind
@issue_code = issue_code
@details = details || {}
end
def to_h
{ 'kind' => kind,
'msg' => message,
'details' => details }
end
end
def debug(statement)
@debug_statements ||= []
@debug_statements << statement
end
def task(params = {})
msg = 'The task author must implement the `task` method in the task'
raise TaskHelper::Error.new(msg, 'tasklib/not-implemented')
end
# Accepts a Data object and returns a copy with all hash keys
# symbolized.
def self.walk_keys(data)
case data
when Hash
data.each_with_object({}) do |(k, v), acc|
v = walk_keys(v)
acc[k.to_sym] = v
end
when Array
data.map { |v| walk_keys(v) }
else
data
end
end
def self.run
input = $stdin.read
params = walk_keys(JSON.parse(input))
# This method accepts a hash of parameters to run the task, then executes
# the task. Unhandled errors are caught and turned into an error result.
# @param [Hash] params A hash of params for the task
# @return [Hash] The result of the task
task = new
result = task.task(**params)
if result.instance_of?(Hash)
$stdout.print JSON.generate(result)
else
$stdout.print result.to_s
end
rescue TaskHelper::Error => e
$stdout.print({ _error: e.to_h }.to_json)
exit 1
rescue StandardError => e
details = {
'backtrace' => e.backtrace,
'debug' => task.debug_statements
}.compact
error = TaskHelper::Error.new(e.message, e.class.to_s, details)
$stdout.print({ _error: error.to_h }.to_json)
exit 1
end
end