mortar 0.1.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.
- data/README.md +36 -0
- data/bin/mortar +13 -0
- data/lib/mortar.rb +23 -0
- data/lib/mortar/auth.rb +312 -0
- data/lib/mortar/cli.rb +54 -0
- data/lib/mortar/command.rb +267 -0
- data/lib/mortar/command/auth.rb +96 -0
- data/lib/mortar/command/base.rb +319 -0
- data/lib/mortar/command/clusters.rb +41 -0
- data/lib/mortar/command/describe.rb +97 -0
- data/lib/mortar/command/generate.rb +121 -0
- data/lib/mortar/command/help.rb +166 -0
- data/lib/mortar/command/illustrate.rb +97 -0
- data/lib/mortar/command/jobs.rb +174 -0
- data/lib/mortar/command/pigscripts.rb +45 -0
- data/lib/mortar/command/projects.rb +128 -0
- data/lib/mortar/command/validate.rb +94 -0
- data/lib/mortar/command/version.rb +42 -0
- data/lib/mortar/errors.rb +24 -0
- data/lib/mortar/generators/generator_base.rb +107 -0
- data/lib/mortar/generators/macro_generator.rb +37 -0
- data/lib/mortar/generators/pigscript_generator.rb +40 -0
- data/lib/mortar/generators/project_generator.rb +67 -0
- data/lib/mortar/generators/udf_generator.rb +28 -0
- data/lib/mortar/git.rb +233 -0
- data/lib/mortar/helpers.rb +488 -0
- data/lib/mortar/project.rb +156 -0
- data/lib/mortar/snapshot.rb +39 -0
- data/lib/mortar/templates/macro/macro.pig +14 -0
- data/lib/mortar/templates/pigscript/pigscript.pig +38 -0
- data/lib/mortar/templates/pigscript/python_udf.py +13 -0
- data/lib/mortar/templates/project/Gemfile +3 -0
- data/lib/mortar/templates/project/README.md +8 -0
- data/lib/mortar/templates/project/gitignore +4 -0
- data/lib/mortar/templates/project/macros/gitkeep +0 -0
- data/lib/mortar/templates/project/pigscripts/pigscript.pig +35 -0
- data/lib/mortar/templates/project/udfs/python/python_udf.py +13 -0
- data/lib/mortar/templates/udf/python_udf.py +13 -0
- data/lib/mortar/version.rb +20 -0
- data/lib/vendor/mortar/okjson.rb +598 -0
- data/lib/vendor/mortar/uuid.rb +312 -0
- data/spec/mortar/auth_spec.rb +156 -0
- data/spec/mortar/command/auth_spec.rb +46 -0
- data/spec/mortar/command/base_spec.rb +82 -0
- data/spec/mortar/command/clusters_spec.rb +61 -0
- data/spec/mortar/command/describe_spec.rb +135 -0
- data/spec/mortar/command/generate_spec.rb +139 -0
- data/spec/mortar/command/illustrate_spec.rb +140 -0
- data/spec/mortar/command/jobs_spec.rb +364 -0
- data/spec/mortar/command/pigscripts_spec.rb +70 -0
- data/spec/mortar/command/projects_spec.rb +165 -0
- data/spec/mortar/command/validate_spec.rb +119 -0
- data/spec/mortar/command_spec.rb +122 -0
- data/spec/mortar/git_spec.rb +278 -0
- data/spec/mortar/helpers_spec.rb +82 -0
- data/spec/mortar/project_spec.rb +76 -0
- data/spec/mortar/snapshot_spec.rb +46 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +278 -0
- data/spec/support/display_message_matcher.rb +68 -0
- metadata +259 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Mortar Data Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "mortar/command/base"
|
18
|
+
require "mortar/snapshot"
|
19
|
+
|
20
|
+
# manage pig scripts
|
21
|
+
#
|
22
|
+
class Mortar::Command::Describe < Mortar::Command::Base
|
23
|
+
|
24
|
+
include Mortar::Snapshot
|
25
|
+
|
26
|
+
# describe [PIGSCRIPT] [ALIAS]
|
27
|
+
#
|
28
|
+
# Describe the schema of an alias and all of its ancestors.
|
29
|
+
#
|
30
|
+
# -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
|
31
|
+
# -f, --param-file PARAMFILE # Load pig parameter values from a file.
|
32
|
+
#
|
33
|
+
# Examples:
|
34
|
+
#
|
35
|
+
# $ mortar describe
|
36
|
+
#
|
37
|
+
# TBD
|
38
|
+
#
|
39
|
+
def index
|
40
|
+
pigscript_name = shift_argument
|
41
|
+
alias_name = shift_argument
|
42
|
+
unless pigscript_name && alias_name
|
43
|
+
error("Usage: mortar describe PIGSCRIPT ALIAS\nMust specify PIGSCRIPT and ALIAS.")
|
44
|
+
end
|
45
|
+
validate_arguments!
|
46
|
+
validate_git_based_project!
|
47
|
+
pigscript = validate_pigscript!(pigscript_name)
|
48
|
+
git_ref = create_and_push_snapshot_branch(git, project)
|
49
|
+
|
50
|
+
describe_id = nil
|
51
|
+
action("Starting describe") do
|
52
|
+
describe_id = api.post_describe(project.name, pigscript.name, alias_name, git_ref, :parameters => pig_parameters).body["describe_id"]
|
53
|
+
end
|
54
|
+
|
55
|
+
describe_result = nil
|
56
|
+
display
|
57
|
+
ticking(polling_interval) do |ticks|
|
58
|
+
describe_result = api.get_describe(describe_id, :exclude_result => true).body
|
59
|
+
is_finished =
|
60
|
+
Mortar::API::Describe::STATUSES_COMPLETE.include?(describe_result["status_code"])
|
61
|
+
|
62
|
+
redisplay("Status: %s %s" % [
|
63
|
+
describe_result['status_description'] + (is_finished ? "" : "..."),
|
64
|
+
is_finished ? " " : spinner(ticks)],
|
65
|
+
is_finished) # only display newline on last message
|
66
|
+
if is_finished
|
67
|
+
display
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
case describe_result['status_code']
|
73
|
+
when Mortar::API::Describe::STATUS_FAILURE
|
74
|
+
error_message = "Describe failed with #{describe_result['error_type'] || 'error'}"
|
75
|
+
if line_number = describe_result["line_number"]
|
76
|
+
error_message += " at Line #{line_number}"
|
77
|
+
if column_number = describe_result["column_number"]
|
78
|
+
error_message += ", Column #{column_number}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
error_context = get_error_message_context(describe_result['error_message'])
|
82
|
+
error_message += ":\n\n#{describe_result['error_message']}\n\n#{error_context}"
|
83
|
+
error(error_message)
|
84
|
+
when Mortar::API::Describe::STATUS_KILLED
|
85
|
+
error("Describe killed by user.")
|
86
|
+
when Mortar::API::Describe::STATUS_SUCCESS
|
87
|
+
web_result_url = describe_result['web_result_url']
|
88
|
+
display("Results available at #{web_result_url}")
|
89
|
+
action("Opening web browser to show results") do
|
90
|
+
require "launchy"
|
91
|
+
Launchy.open(web_result_url).join
|
92
|
+
end
|
93
|
+
else
|
94
|
+
raise RuntimeError, "Unknown describe status: #{describe_result['status']} for describe_id: #{describe_id}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Mortar Data Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "mortar/generators/project_generator"
|
18
|
+
require "mortar/generators/udf_generator"
|
19
|
+
require "mortar/generators/pigscript_generator"
|
20
|
+
require "mortar/generators/macro_generator"
|
21
|
+
require "mortar/command/base"
|
22
|
+
|
23
|
+
# generate new projects and scaffolding
|
24
|
+
#
|
25
|
+
class Mortar::Command::Generate < Mortar::Command::Base
|
26
|
+
|
27
|
+
# generate:project
|
28
|
+
#
|
29
|
+
# generate new project
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# Examples:
|
33
|
+
#
|
34
|
+
# $ mortar generate:project
|
35
|
+
#
|
36
|
+
# TBD
|
37
|
+
#
|
38
|
+
def _project
|
39
|
+
project_name = shift_argument
|
40
|
+
unless project_name
|
41
|
+
error("Usage: mortar new PROJECTNAME\nMust specify PROJECTNAME.")
|
42
|
+
end
|
43
|
+
pigscript_name = project_name
|
44
|
+
app_generator = Mortar::Generators::ProjectGenerator.new
|
45
|
+
app_generator.generate_project(project_name, options)
|
46
|
+
end
|
47
|
+
alias_command "new", "generate:_project"
|
48
|
+
alias_command "generate:project", "generate:_project"
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
# generate:python_udf
|
53
|
+
#
|
54
|
+
# generate new python user defined function
|
55
|
+
#
|
56
|
+
#
|
57
|
+
# Examples:
|
58
|
+
#
|
59
|
+
# $ mortar generate:python_udf UDFNAME
|
60
|
+
#
|
61
|
+
# TBD
|
62
|
+
#
|
63
|
+
def python_udf
|
64
|
+
udf_name = shift_argument
|
65
|
+
unless udf_name
|
66
|
+
error("Usage: mortar generate:python_udf UDFNAME\nMust specify UDFNAME.")
|
67
|
+
end
|
68
|
+
udf_generator = Mortar::Generators::UDFGenerator.new
|
69
|
+
udf_generator.generate_python_udf(udf_name, project, options)
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# generate:pigscript
|
74
|
+
#
|
75
|
+
# generate new pig script
|
76
|
+
#
|
77
|
+
# --skip-udf # Create the pig script without a partnered python udf
|
78
|
+
#
|
79
|
+
# Examples:
|
80
|
+
#
|
81
|
+
# $ mortar generate:pigscript SCRIPTNAME
|
82
|
+
#
|
83
|
+
# TBD
|
84
|
+
#
|
85
|
+
def pigscript
|
86
|
+
script_name = shift_argument
|
87
|
+
unless script_name
|
88
|
+
error("Usage: mortar generate:pigscript SCRIPTNAME\nMust specify SCRIPTNAME.")
|
89
|
+
end
|
90
|
+
options[:skip_udf] ||= false
|
91
|
+
|
92
|
+
script_generator = Mortar::Generators::PigscriptGenerator.new
|
93
|
+
script_generator.generate_pigscript(script_name, project, options)
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
# generate:macro
|
98
|
+
#
|
99
|
+
# generate new macro
|
100
|
+
#
|
101
|
+
#
|
102
|
+
# Examples:
|
103
|
+
#
|
104
|
+
# $ mortar generate:macro MACRONAME
|
105
|
+
#
|
106
|
+
# TBD
|
107
|
+
#
|
108
|
+
def macro
|
109
|
+
macro_name = shift_argument
|
110
|
+
unless macro_name
|
111
|
+
error("Usage: mortar generate:macro MACRONAME\nMust specify MACRONAME.")
|
112
|
+
end
|
113
|
+
|
114
|
+
macro_generator = Mortar::Generators::MacroGenerator.new
|
115
|
+
macro_generator.generate_macro(macro_name, project, options)
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Mortar Data Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
# Portions of this code from heroku (https://github.com/heroku/heroku/) Copyright Heroku 2008 - 2012,
|
17
|
+
# used under an MIT license (https://github.com/heroku/heroku/blob/master/LICENSE).
|
18
|
+
#
|
19
|
+
|
20
|
+
require "mortar/command/base"
|
21
|
+
|
22
|
+
# list commands and display help
|
23
|
+
#
|
24
|
+
class Mortar::Command::Help < Mortar::Command::Base
|
25
|
+
|
26
|
+
PRIMARY_NAMESPACES = []
|
27
|
+
|
28
|
+
# help [COMMAND]
|
29
|
+
#
|
30
|
+
# list available commands or display help for a specific command
|
31
|
+
#
|
32
|
+
#Examples:
|
33
|
+
#
|
34
|
+
# $ mortar help
|
35
|
+
# Usage: mortar COMMAND [command-specific-options]
|
36
|
+
#
|
37
|
+
# Primary help topics, type "mortar help TOPIC" for more details:
|
38
|
+
#
|
39
|
+
# ...
|
40
|
+
#
|
41
|
+
# Additional topics:
|
42
|
+
#
|
43
|
+
# ...
|
44
|
+
#
|
45
|
+
def index
|
46
|
+
if command = args.shift
|
47
|
+
help_for_command(command)
|
48
|
+
else
|
49
|
+
help_for_root
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_command "-h", "help"
|
54
|
+
alias_command "--help", "help"
|
55
|
+
|
56
|
+
def self.usage_for_command(command)
|
57
|
+
command = new.send(:commands)[command]
|
58
|
+
"Usage: mortar #{command[:banner]}" if command
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def commands_for_namespace(name)
|
64
|
+
Mortar::Command.commands.values.select do |command|
|
65
|
+
command[:namespace] == name && command[:command] != name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def namespaces
|
70
|
+
namespaces = Mortar::Command.namespaces
|
71
|
+
namespaces.delete("app")
|
72
|
+
namespaces
|
73
|
+
end
|
74
|
+
|
75
|
+
def commands
|
76
|
+
Mortar::Command.commands
|
77
|
+
end
|
78
|
+
|
79
|
+
def legacy_help_for_namespace(namespace)
|
80
|
+
instance = Mortar::Command::Help.groups.map do |group|
|
81
|
+
[ group.title, group.select { |c| c.first =~ /^#{namespace}/ }.length ]
|
82
|
+
end.sort_by { |l| l.last }.last
|
83
|
+
return nil unless instance
|
84
|
+
return nil if instance.last.zero?
|
85
|
+
instance.first
|
86
|
+
end
|
87
|
+
|
88
|
+
def legacy_help_for_command(command)
|
89
|
+
Mortar::Command::Help.groups.each do |group|
|
90
|
+
group.each do |cmd, description|
|
91
|
+
return description if cmd.split(" ").first == command
|
92
|
+
end
|
93
|
+
end
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def primary_namespaces
|
98
|
+
PRIMARY_NAMESPACES.map { |name| namespaces[name] }.compact
|
99
|
+
end
|
100
|
+
|
101
|
+
def additional_namespaces
|
102
|
+
(namespaces.values - primary_namespaces)
|
103
|
+
end
|
104
|
+
|
105
|
+
def summary_for_namespaces(namespaces)
|
106
|
+
size = longest(namespaces.map { |n| n[:name] })
|
107
|
+
namespaces.sort_by {|namespace| namespace[:name]}.each do |namespace|
|
108
|
+
name = namespace[:name]
|
109
|
+
namespace[:description] ||= legacy_help_for_namespace(name)
|
110
|
+
puts " %-#{size}s # %s" % [ name, namespace[:description] ]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def help_for_root
|
115
|
+
puts "Usage: mortar COMMAND [command-specific-options]"
|
116
|
+
puts
|
117
|
+
puts "Primary help topics, type \"mortar help TOPIC\" for more details:"
|
118
|
+
puts
|
119
|
+
summary_for_namespaces(primary_namespaces)
|
120
|
+
puts
|
121
|
+
puts "Additional topics:"
|
122
|
+
puts
|
123
|
+
summary_for_namespaces(additional_namespaces)
|
124
|
+
puts
|
125
|
+
end
|
126
|
+
|
127
|
+
def help_for_namespace(name)
|
128
|
+
namespace_commands = commands_for_namespace(name)
|
129
|
+
|
130
|
+
unless namespace_commands.empty?
|
131
|
+
size = longest(namespace_commands.map { |c| c[:banner] })
|
132
|
+
namespace_commands.sort_by { |c| c[:banner].to_s }.each do |command|
|
133
|
+
next if command[:help] =~ /DEPRECATED/
|
134
|
+
command[:summary] ||= legacy_help_for_command(command[:command])
|
135
|
+
puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def help_for_command(name)
|
141
|
+
if command_alias = Mortar::Command.command_aliases[name]
|
142
|
+
display("Alias: #{name} redirects to #{command_alias}")
|
143
|
+
name = command_alias
|
144
|
+
end
|
145
|
+
if command = commands[name]
|
146
|
+
puts "Usage: mortar #{command[:banner]}"
|
147
|
+
|
148
|
+
if command[:help].strip.length > 0
|
149
|
+
puts command[:help].split("\n")[1..-1].join("\n")
|
150
|
+
else
|
151
|
+
puts
|
152
|
+
puts " " + legacy_help_for_command(name).to_s
|
153
|
+
end
|
154
|
+
puts
|
155
|
+
end
|
156
|
+
|
157
|
+
if commands_for_namespace(name).size > 0
|
158
|
+
puts "Additional commands, type \"mortar help COMMAND\" for more details:"
|
159
|
+
puts
|
160
|
+
help_for_namespace(name)
|
161
|
+
puts
|
162
|
+
elsif command.nil?
|
163
|
+
error "#{name} is not a mortar command. See `mortar help`."
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Mortar Data Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "mortar/command/base"
|
18
|
+
require "mortar/snapshot"
|
19
|
+
|
20
|
+
# manage pig scripts
|
21
|
+
#
|
22
|
+
class Mortar::Command::Illustrate < Mortar::Command::Base
|
23
|
+
|
24
|
+
include Mortar::Snapshot
|
25
|
+
|
26
|
+
# illustrate [PIGSCRIPT] [ALIAS]
|
27
|
+
#
|
28
|
+
# Illustrate the effects and output of a pigscript.
|
29
|
+
#
|
30
|
+
# -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
|
31
|
+
# -f, --param-file PARAMFILE # Load pig parameter values from a file.
|
32
|
+
#
|
33
|
+
# Examples:
|
34
|
+
#
|
35
|
+
# $ mortar illustrate
|
36
|
+
#
|
37
|
+
# TBD
|
38
|
+
#
|
39
|
+
def index
|
40
|
+
pigscript_name = shift_argument
|
41
|
+
alias_name = shift_argument
|
42
|
+
unless pigscript_name && alias_name
|
43
|
+
error("Usage: mortar illustrate PIGSCRIPT ALIAS\nMust specify PIGSCRIPT and ALIAS.")
|
44
|
+
end
|
45
|
+
validate_arguments!
|
46
|
+
validate_git_based_project!
|
47
|
+
pigscript = validate_pigscript!(pigscript_name)
|
48
|
+
git_ref = create_and_push_snapshot_branch(git, project)
|
49
|
+
|
50
|
+
illustrate_id = nil
|
51
|
+
action("Starting illustrate") do
|
52
|
+
illustrate_id = api.post_illustrate(project.name, pigscript.name, alias_name, git_ref, :parameters => pig_parameters).body["illustrate_id"]
|
53
|
+
end
|
54
|
+
|
55
|
+
illustrate_result = nil
|
56
|
+
display
|
57
|
+
ticking(polling_interval) do |ticks|
|
58
|
+
illustrate_result = api.get_illustrate(illustrate_id, :exclude_result => true).body
|
59
|
+
is_finished =
|
60
|
+
Mortar::API::Illustrate::STATUSES_COMPLETE.include?(illustrate_result["status_code"])
|
61
|
+
|
62
|
+
redisplay("Status: %s %s" % [
|
63
|
+
illustrate_result['status_description'] + (is_finished ? "" : "..."),
|
64
|
+
is_finished ? " " : spinner(ticks)],
|
65
|
+
is_finished) # only display newline on last message
|
66
|
+
if is_finished
|
67
|
+
display
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
case illustrate_result['status_code']
|
73
|
+
when Mortar::API::Illustrate::STATUS_FAILURE
|
74
|
+
error_message = "Illustrate failed with #{illustrate_result['error_type'] || 'error'}"
|
75
|
+
if line_number = illustrate_result["line_number"]
|
76
|
+
error_message += " at Line #{line_number}"
|
77
|
+
if column_number = illustrate_result["column_number"]
|
78
|
+
error_message += ", Column #{column_number}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
error_context = get_error_message_context(illustrate_result['error_message'])
|
82
|
+
error_message += ":\n\n#{illustrate_result['error_message']}\n\n#{error_context}"
|
83
|
+
error(error_message)
|
84
|
+
when Mortar::API::Illustrate::STATUS_KILLED
|
85
|
+
error("Illustrate killed by user.")
|
86
|
+
when Mortar::API::Illustrate::STATUS_SUCCESS
|
87
|
+
web_result_url = illustrate_result['web_result_url']
|
88
|
+
display("Results available at #{web_result_url}")
|
89
|
+
action("Opening web browser to show results") do
|
90
|
+
require "launchy"
|
91
|
+
Launchy.open(web_result_url).join
|
92
|
+
end
|
93
|
+
else
|
94
|
+
raise RuntimeError, "Unknown illustrate status: #{illustrate_result['status_code']} for illustrate_id: #{illustrate_id}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|