mortar 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|