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,174 @@
|
|
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
|
+
require "time"
|
20
|
+
# manage pig scripts
|
21
|
+
#
|
22
|
+
class Mortar::Command::Jobs < Mortar::Command::Base
|
23
|
+
|
24
|
+
include Mortar::Snapshot
|
25
|
+
|
26
|
+
# jobs
|
27
|
+
#
|
28
|
+
# Show recent and running jobs.
|
29
|
+
#
|
30
|
+
# -l, --limit LIMITJOBS # Limit the number of jobs returned (defaults to 10)
|
31
|
+
# -s, --skip SKIPJOBS # Skip a certain amount of jobs (defaults to 0)
|
32
|
+
#
|
33
|
+
# Examples:
|
34
|
+
#
|
35
|
+
# $ mortar jobs
|
36
|
+
#
|
37
|
+
# TBD
|
38
|
+
#
|
39
|
+
def index
|
40
|
+
options[:limit] ||= '10'
|
41
|
+
options[:skip] ||= '0'
|
42
|
+
jobs = api.get_jobs(options[:skip], options[:limit]).body['jobs']
|
43
|
+
jobs.each do |job|
|
44
|
+
if job['start_timestamp']
|
45
|
+
job['start_timestamp'] = Time.parse(job['start_timestamp']).strftime('%A, %B %e, %Y, %l:%M %p')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
headers = [ 'job_id', 'script' , 'status' , 'start_date' , 'elapsed_time' , 'cluster_size' , 'cluster_id']
|
49
|
+
columns = [ 'job_id', 'display_name', 'status_description', 'start_timestamp', 'duration', 'cluster_size', 'cluster_id']
|
50
|
+
display_table(jobs, columns, headers)
|
51
|
+
end
|
52
|
+
|
53
|
+
# jobs:run PIGSCRIPT
|
54
|
+
#
|
55
|
+
# Run a job on a Mortar Hadoop cluster.
|
56
|
+
#
|
57
|
+
# -c, --clusterid CLUSTERID # Run job on an existing cluster with ID of CLUSTERID (optional)
|
58
|
+
# -s, --clustersize NUMNODES # Run job on a new cluster, with NUMNODES nodes (optional; must be >= 2 if provided)
|
59
|
+
# -1, --singlejobcluster # Stop the cluster after job completes. (Default: false—-cluster can be used for other jobs, and will shut down after 1 hour of inactivity)
|
60
|
+
# -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
|
61
|
+
# -f, --param-file PARAMFILE # Load pig parameter values from a file.
|
62
|
+
#
|
63
|
+
#Examples:
|
64
|
+
#
|
65
|
+
# $ mortar jobs:run
|
66
|
+
#
|
67
|
+
# TBD
|
68
|
+
#
|
69
|
+
def run
|
70
|
+
# arguemnts
|
71
|
+
pigscript_name = shift_argument
|
72
|
+
unless pigscript_name
|
73
|
+
error("Usage: mortar jobs:run PIGSCRIPT\nMust specify PIGSCRIPT.")
|
74
|
+
end
|
75
|
+
validate_arguments!
|
76
|
+
|
77
|
+
unless options[:clusterid] || options[:clustersize]
|
78
|
+
error("Please provide either the --clustersize option to run job on a new cluster, or --clusterid to run on an existing one.")
|
79
|
+
end
|
80
|
+
|
81
|
+
if options[:clusterid]
|
82
|
+
[:clustersize, :singlejobcluster].each do |opt|
|
83
|
+
unless options[opt].nil?
|
84
|
+
error("Option #{opt.to_s} cannot be set when running a job on an existing cluster (with --clusterid option)")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
validate_git_based_project!
|
92
|
+
pigscript = validate_pigscript!(pigscript_name)
|
93
|
+
git_ref = create_and_push_snapshot_branch(git, project)
|
94
|
+
|
95
|
+
# post job to API
|
96
|
+
response = action("Requesting job execution") do
|
97
|
+
if options[:clustersize]
|
98
|
+
cluster_size = options[:clustersize].to_i
|
99
|
+
keepalive = ! options[:singlejobcluster]
|
100
|
+
api.post_job_new_cluster(project.name, pigscript.name, git_ref, cluster_size,
|
101
|
+
:parameters => pig_parameters,
|
102
|
+
:keepalive => keepalive).body
|
103
|
+
else
|
104
|
+
cluster_id = options[:clusterid]
|
105
|
+
api.post_job_existing_cluster(project.name, pigscript.name, git_ref, cluster_id,
|
106
|
+
:parameters => pig_parameters).body
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
display("job_id: #{response['job_id']}")
|
111
|
+
display
|
112
|
+
display("Job status can be viewed on the web at:\n\n #{response['web_job_url']}")
|
113
|
+
display
|
114
|
+
display("Or by running:\n\n mortar jobs:status #{response['job_id']}")
|
115
|
+
display
|
116
|
+
end
|
117
|
+
|
118
|
+
alias_command "run", "jobs:run"
|
119
|
+
|
120
|
+
|
121
|
+
# jobs:status JOB_ID
|
122
|
+
#
|
123
|
+
# Check the status of a job.
|
124
|
+
#
|
125
|
+
#Examples:
|
126
|
+
#
|
127
|
+
# $ mortar jobs:status 84f3c86f20034ed4bf5e359120a47f5a
|
128
|
+
#
|
129
|
+
# TBD
|
130
|
+
def status
|
131
|
+
job_id = shift_argument
|
132
|
+
unless job_id
|
133
|
+
error("Usage: mortar jobs:status JOB_ID\nMust specify JOB_ID.")
|
134
|
+
end
|
135
|
+
|
136
|
+
job_status = api.get_job(job_id).body
|
137
|
+
|
138
|
+
job_display_entries = {
|
139
|
+
"status" => job_status["status_description"],
|
140
|
+
"progress" => "#{job_status["progress"]}%",
|
141
|
+
"cluster_id" => job_status["cluster_id"],
|
142
|
+
"job submitted at" => job_status["start_timestamp"],
|
143
|
+
"job began running at" => job_status["running_timestamp"],
|
144
|
+
"job finished at" => job_status["stop_timestamp"],
|
145
|
+
"job running for" => job_status["duration"],
|
146
|
+
"job run with parameters" => job_status["parameters"],
|
147
|
+
"error" => job_status["error"]
|
148
|
+
}
|
149
|
+
|
150
|
+
unless job_status["error"].nil? || job_status["error"]["message"].nil?
|
151
|
+
error_context = get_error_message_context(job_status["error"]["message"])
|
152
|
+
unless error_context == ""
|
153
|
+
job_status["error"]["help"] = error_context
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
if job_status["num_hadoop_jobs"] && job_status["num_hadoop_jobs_succeeded"]
|
158
|
+
job_display_entries["hadoop jobs complete"] =
|
159
|
+
'%0.2f / %0.2f' % [job_status["num_hadoop_jobs_succeeded"], job_status["num_hadoop_jobs"]]
|
160
|
+
end
|
161
|
+
|
162
|
+
if job_status["outputs"] && job_status["outputs"].length > 0
|
163
|
+
job_display_entries["outputs"] = Hash[job_status["outputs"].select{|o| o["alias"]}.collect do |output|
|
164
|
+
output_hash = {}
|
165
|
+
output_hash["location"] = output["location"] if output["location"]
|
166
|
+
output_hash["records"] = output["records"] if output["records"]
|
167
|
+
[output['alias'], output_hash]
|
168
|
+
end]
|
169
|
+
end
|
170
|
+
|
171
|
+
styled_header("#{job_status["project_name"]}: #{job_status["pigscript_name"]} (job_id: #{job_status["job_id"]})")
|
172
|
+
styled_hash(job_display_entries)
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,45 @@
|
|
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
|
+
|
19
|
+
# manage pig scripts
|
20
|
+
#
|
21
|
+
class Mortar::Command::PigScripts < Mortar::Command::Base
|
22
|
+
|
23
|
+
# pigscripts
|
24
|
+
#
|
25
|
+
# display the available set of pigscripts
|
26
|
+
#
|
27
|
+
#Examples:
|
28
|
+
#
|
29
|
+
# $ mortar pigscripts
|
30
|
+
#
|
31
|
+
# hourly_top_searchers
|
32
|
+
# user_engagement
|
33
|
+
#
|
34
|
+
def index
|
35
|
+
# validation
|
36
|
+
validate_arguments!
|
37
|
+
if project.pigscripts.any?
|
38
|
+
styled_header("pigscripts")
|
39
|
+
styled_array(project.pigscripts.keys)
|
40
|
+
else
|
41
|
+
display("You have no pigscripts.")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,128 @@
|
|
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
|
+
|
19
|
+
## manage projects
|
20
|
+
#
|
21
|
+
class Mortar::Command::Projects < Mortar::Command::Base
|
22
|
+
|
23
|
+
# projects
|
24
|
+
#
|
25
|
+
# Display the available set of projects
|
26
|
+
#
|
27
|
+
#Examples:
|
28
|
+
#
|
29
|
+
# $ mortar projects
|
30
|
+
#
|
31
|
+
#=== projects
|
32
|
+
#demo
|
33
|
+
#rollup
|
34
|
+
#
|
35
|
+
def index
|
36
|
+
validate_arguments!
|
37
|
+
projects = api.get_projects().body["projects"]
|
38
|
+
if projects.any?
|
39
|
+
styled_header("projects")
|
40
|
+
styled_array(projects.collect{ |x| x["name"] })
|
41
|
+
else
|
42
|
+
display("You have no projects.")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# projects:create PROJECT
|
47
|
+
#
|
48
|
+
# create a mortar project for the current directory with the name PROJECT
|
49
|
+
#
|
50
|
+
#Example:
|
51
|
+
#
|
52
|
+
# $ mortar projects:create my_new_project
|
53
|
+
#
|
54
|
+
def create
|
55
|
+
name = shift_argument
|
56
|
+
unless name
|
57
|
+
error("Usage: mortar projects:create PROJECT\nMust specify PROJECT.")
|
58
|
+
end
|
59
|
+
validate_arguments!
|
60
|
+
|
61
|
+
unless git.has_dot_git?
|
62
|
+
error("Can only create a mortar project for an existing git project. Please run:\n\ngit init\ngit add .\ngit commit -a -m \"first commit\"\n\nto initialize your project in git.")
|
63
|
+
end
|
64
|
+
|
65
|
+
unless git.remotes(git_organization).empty?
|
66
|
+
begin
|
67
|
+
error("Currently in project: #{project.name}. You can not create a new project inside of an existing mortar project.")
|
68
|
+
rescue Mortar::Command::CommandFailed => cf
|
69
|
+
error("Currently in an existing Mortar project. You can not create a new project inside of an existing mortar project.")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
project_id = nil
|
74
|
+
action("Creating project", {:success => "started"}) do
|
75
|
+
project_id = api.post_project(name).body["project_id"]
|
76
|
+
end
|
77
|
+
|
78
|
+
last_project_result = nil
|
79
|
+
while last_project_result.nil? || (! Mortar::API::Projects::STATUSES_COMPLETE.include?(last_project_result["status"]))
|
80
|
+
sleep polling_interval
|
81
|
+
current_project_result = api.get_project(project_id).body
|
82
|
+
if last_project_result.nil? || (last_project_result["status"] != current_project_result["status"])
|
83
|
+
display(" ... #{current_project_result['status']}")
|
84
|
+
end
|
85
|
+
|
86
|
+
last_project_result = current_project_result
|
87
|
+
end
|
88
|
+
|
89
|
+
case last_project_result['status']
|
90
|
+
when Mortar::API::Projects::STATUS_FAILED
|
91
|
+
error("Project creation failed.\nError message: #{last_project_result['error_message']}")
|
92
|
+
when Mortar::API::Projects::STATUS_ACTIVE
|
93
|
+
git.remote_add("mortar", last_project_result['git_url'])
|
94
|
+
else
|
95
|
+
raise RuntimeError, "Unknown project status: #{last_project_result['status']} for project_id: #{project_id}"
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# projects:clone PROJECT
|
102
|
+
#
|
103
|
+
# clone the mortar project PROJECT into the current directory.
|
104
|
+
#
|
105
|
+
#Example:
|
106
|
+
#
|
107
|
+
# $ mortar projects:clone my_new_project
|
108
|
+
#
|
109
|
+
def clone
|
110
|
+
name = shift_argument
|
111
|
+
unless name
|
112
|
+
error("Usage: mortar projects:clone PROJECT\nMust specify PROJECT.")
|
113
|
+
end
|
114
|
+
validate_arguments!
|
115
|
+
projects = api.get_projects().body["projects"]
|
116
|
+
project = projects.find{|p| p['name'] == name}
|
117
|
+
unless project
|
118
|
+
error("No project named: #{name} exists. Your valid projects are:\n#{projects.collect{ |x| x["name"]}.join("\n")}")
|
119
|
+
end
|
120
|
+
|
121
|
+
project_dir = File.join(Dir.pwd, project['name'])
|
122
|
+
unless !File.exists?(project_dir)
|
123
|
+
error("Can't clone project: #{project['name']} since directory with that name already exists.")
|
124
|
+
end
|
125
|
+
|
126
|
+
git.clone(project['git_url'], project['name'])
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,94 @@
|
|
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::Validate < Mortar::Command::Base
|
23
|
+
|
24
|
+
include Mortar::Snapshot
|
25
|
+
|
26
|
+
# validate [PIGSCRIPT]
|
27
|
+
#
|
28
|
+
# Validate a pig script. Checks script for problems with:
|
29
|
+
# * Pig syntax
|
30
|
+
# * Python syntax
|
31
|
+
# * S3 data access
|
32
|
+
#
|
33
|
+
# -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
|
34
|
+
# -f, --param-file PARAMFILE # Load pig parameter values from a file.
|
35
|
+
#
|
36
|
+
# Examples:
|
37
|
+
#
|
38
|
+
# $ mortar validate
|
39
|
+
#
|
40
|
+
# TBD
|
41
|
+
#
|
42
|
+
def index
|
43
|
+
pigscript_name = shift_argument
|
44
|
+
unless pigscript_name
|
45
|
+
error("Usage: mortar validate PIGSCRIPT\nMust specify PIGSCRIPT.")
|
46
|
+
end
|
47
|
+
validate_arguments!
|
48
|
+
validate_git_based_project!
|
49
|
+
pigscript = validate_pigscript!(pigscript_name)
|
50
|
+
git_ref = create_and_push_snapshot_branch(git, project)
|
51
|
+
|
52
|
+
validate_id = nil
|
53
|
+
action("Starting validate") do
|
54
|
+
validate_id = api.post_validate(project.name, pigscript.name, git_ref, :parameters => pig_parameters).body["validate_id"]
|
55
|
+
end
|
56
|
+
|
57
|
+
validate_result = nil
|
58
|
+
display
|
59
|
+
ticking(polling_interval) do |ticks|
|
60
|
+
validate_result = api.get_validate(validate_id).body
|
61
|
+
is_finished =
|
62
|
+
Mortar::API::Validate::STATUSES_COMPLETE.include?(validate_result["status_code"])
|
63
|
+
|
64
|
+
redisplay("Status: %s %s" % [
|
65
|
+
validate_result['status_description'] + (is_finished ? "" : "..."),
|
66
|
+
is_finished ? " " : spinner(ticks)],
|
67
|
+
is_finished) # only display newline on last message
|
68
|
+
if is_finished
|
69
|
+
display
|
70
|
+
break
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
case validate_result['status_code']
|
75
|
+
when Mortar::API::Validate::STATUS_FAILURE
|
76
|
+
error_message = "Validate failed with #{validate_result['error_type'] || 'error'}"
|
77
|
+
if line_number = validate_result["line_number"]
|
78
|
+
error_message += " at Line #{line_number}"
|
79
|
+
if column_number = validate_result["column_number"]
|
80
|
+
error_message += ", Column #{column_number}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
error_context = get_error_message_context(validate_result['error_message'])
|
84
|
+
error_message += ":\n\n#{validate_result['error_message']}\n\n#{error_context}"
|
85
|
+
error(error_message)
|
86
|
+
when Mortar::API::Validate::STATUS_KILLED
|
87
|
+
error("Validate killed by user.")
|
88
|
+
when Mortar::API::Validate::STATUS_SUCCESS
|
89
|
+
display("Your script is valid.")
|
90
|
+
else
|
91
|
+
raise RuntimeError, "Unknown validate status: #{validate_result['status']} for validate_id: #{validate_id}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,42 @@
|
|
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
|
+
require "mortar/version"
|
22
|
+
|
23
|
+
# display version
|
24
|
+
#
|
25
|
+
class Mortar::Command::Version < Mortar::Command::Base
|
26
|
+
|
27
|
+
# version
|
28
|
+
#
|
29
|
+
# show mortar client version
|
30
|
+
#
|
31
|
+
#Example:
|
32
|
+
#
|
33
|
+
# $ mortar version
|
34
|
+
# mortar/1.2.3 (x86_64-darwin11.4.2) ruby/1.9.3
|
35
|
+
#
|
36
|
+
def index
|
37
|
+
validate_arguments!
|
38
|
+
|
39
|
+
display(Mortar::USER_AGENT)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|