mortar 0.2.0 → 0.2.1
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/lib/mortar/command.rb +10 -0
- data/lib/mortar/command/clusters.rb +6 -1
- data/lib/mortar/command/describe.rb +1 -3
- data/lib/mortar/command/jobs.rb +74 -34
- data/lib/mortar/command/projects.rb +35 -0
- data/lib/mortar/command/validate.rb +2 -4
- data/lib/mortar/templates/pigscript/pigscript.pig +1 -1
- data/lib/mortar/templates/project/gitignore +1 -0
- data/lib/mortar/templates/project/pigscripts/pigscript.pig +1 -1
- data/lib/mortar/version.rb +1 -1
- data/spec/mortar/command/clusters_spec.rb +1 -2
- data/spec/mortar/command/describe_spec.rb +2 -2
- data/spec/mortar/command/jobs_spec.rb +86 -9
- data/spec/mortar/command/projects_spec.rb +56 -0
- data/spec/mortar/command/validate_spec.rb +2 -2
- metadata +3 -3
data/lib/mortar/command.rb
CHANGED
@@ -128,6 +128,7 @@ module Mortar
|
|
128
128
|
def self.prepare_run(cmd, args=[])
|
129
129
|
command = parse(cmd)
|
130
130
|
|
131
|
+
|
131
132
|
if args.include?('-h') || args.include?('--help')
|
132
133
|
args.unshift(cmd) unless cmd =~ /^-.*/
|
133
134
|
cmd = 'help'
|
@@ -138,6 +139,15 @@ module Mortar
|
|
138
139
|
if %w( -v --version ).include?(cmd)
|
139
140
|
cmd = 'version'
|
140
141
|
command = parse(cmd)
|
142
|
+
# Check if the command tried matches a command file. If it does, the command exists, but doesn't have an index action
|
143
|
+
# Otherwise it would have been picked up by the original parse command.
|
144
|
+
elsif Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].find { |file| file.include?(cmd) }
|
145
|
+
display "#{cmd} command requires arguments"
|
146
|
+
display
|
147
|
+
# Display the command's help message
|
148
|
+
args.unshift(cmd) unless cmd =~ /^-.*/
|
149
|
+
cmd = 'help'
|
150
|
+
command = parse('help')
|
141
151
|
else
|
142
152
|
error([
|
143
153
|
"`#{cmd}` is not a mortar command.",
|
@@ -36,8 +36,13 @@ class Mortar::Command::Clusters < Mortar::Command::Base
|
|
36
36
|
validate_arguments!
|
37
37
|
|
38
38
|
clusters = api.get_clusters().body['clusters']
|
39
|
-
|
39
|
+
if not clusters.empty?
|
40
|
+
display_table(clusters,
|
40
41
|
%w( cluster_id size status_description cluster_type_description start_timestamp duration),
|
41
42
|
['cluster_id', 'Size (# of Nodes)', 'Status', 'Type', 'Start Timestamp', 'Elapsed Time'])
|
43
|
+
else
|
44
|
+
display("There are no running or recent clusters")
|
45
|
+
end
|
46
|
+
|
42
47
|
end
|
43
48
|
end
|
@@ -66,9 +66,7 @@ class Mortar::Command::Describe < Mortar::Command::Base
|
|
66
66
|
is_finished =
|
67
67
|
Mortar::API::Describe::STATUSES_COMPLETE.include?(describe_result["status_code"])
|
68
68
|
|
69
|
-
redisplay("
|
70
|
-
describe_result['status_description'] + (is_finished ? "" : "..."),
|
71
|
-
is_finished ? " " : spinner(ticks)],
|
69
|
+
redisplay("[#{spinner(ticks)}] Calculating schema for #{alias_name} and ancestors...",
|
72
70
|
is_finished) # only display newline on last message
|
73
71
|
if is_finished
|
74
72
|
display
|
data/lib/mortar/command/jobs.rb
CHANGED
@@ -124,7 +124,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
124
124
|
display
|
125
125
|
display("Job status can be viewed on the web at:\n\n #{response['web_job_url']}")
|
126
126
|
display
|
127
|
-
display("Or by running:\n\n mortar jobs:status #{response['job_id']}")
|
127
|
+
display("Or by running:\n\n mortar jobs:status #{response['job_id']} --poll")
|
128
128
|
display
|
129
129
|
end
|
130
130
|
|
@@ -135,6 +135,9 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
135
135
|
#
|
136
136
|
# Check the status of a job.
|
137
137
|
#
|
138
|
+
# -p, --poll # Poll the status of a job
|
139
|
+
#
|
140
|
+
#
|
138
141
|
#Examples:
|
139
142
|
#
|
140
143
|
# $ mortar jobs:status 2000cbbba40a860a6f000000
|
@@ -149,43 +152,80 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
149
152
|
error("Usage: mortar jobs:status JOB_ID\nMust specify JOB_ID.")
|
150
153
|
end
|
151
154
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
155
|
+
# Inner function to display the hash table when the job is complte
|
156
|
+
def display_job_status(job_status)
|
157
|
+
job_display_entries = {
|
158
|
+
"status" => job_status["status_description"],
|
159
|
+
"progress" => "#{job_status["progress"]}%",
|
160
|
+
"cluster_id" => job_status["cluster_id"],
|
161
|
+
"job submitted at" => job_status["start_timestamp"],
|
162
|
+
"job began running at" => job_status["running_timestamp"],
|
163
|
+
"job finished at" => job_status["stop_timestamp"],
|
164
|
+
"job running for" => job_status["duration"],
|
165
|
+
"job run with parameters" => job_status["parameters"],
|
166
|
+
}
|
167
|
+
|
168
|
+
|
169
|
+
unless job_status["error"].nil? || job_status["error"]["message"].nil?
|
170
|
+
error_context = get_error_message_context(job_status["error"]["message"])
|
171
|
+
unless error_context == ""
|
172
|
+
job_status["error"]["help"] = error_context
|
173
|
+
end
|
174
|
+
job_status["error"].each_pair do |key, value|
|
175
|
+
job_display_entries["error - #{key}"] = value
|
176
|
+
end
|
170
177
|
end
|
178
|
+
|
179
|
+
if job_status["num_hadoop_jobs"] && job_status["num_hadoop_jobs_succeeded"]
|
180
|
+
job_display_entries["hadoop jobs complete"] =
|
181
|
+
'%0.2f / %0.2f' % [job_status["num_hadoop_jobs_succeeded"], job_status["num_hadoop_jobs"]]
|
182
|
+
end
|
183
|
+
|
184
|
+
if job_status["outputs"] && job_status["outputs"].length > 0
|
185
|
+
job_display_entries["outputs"] = Hash[job_status["outputs"].select{|o| o["alias"]}.collect do |output|
|
186
|
+
output_hash = {}
|
187
|
+
output_hash["location"] = output["location"] if output["location"]
|
188
|
+
output_hash["records"] = output["records"] if output["records"]
|
189
|
+
[output['alias'], output_hash]
|
190
|
+
end]
|
191
|
+
end
|
192
|
+
|
193
|
+
styled_header("#{job_status["project_name"]}: #{job_status["pigscript_name"]} (job_id: #{job_status["job_id"]})")
|
194
|
+
styled_hash(job_display_entries)
|
171
195
|
end
|
172
196
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
197
|
+
# If polling the status
|
198
|
+
if options[:poll]
|
199
|
+
ticking(polling_interval) do |ticks|
|
200
|
+
job_status = api.get_job(job_id).body
|
201
|
+
# If the job is complete exit and display the table normally
|
202
|
+
if Mortar::API::Jobs::STATUSES_COMPLETE.include?(job_status["status_code"] )
|
203
|
+
redisplay("")
|
204
|
+
display_job_status(job_status)
|
205
|
+
break
|
206
|
+
end
|
207
|
+
|
208
|
+
# If the job is running show the progress bar
|
209
|
+
if job_status["status_code"] == Mortar::API::Jobs::STATUS_RUNNING
|
210
|
+
progressbar = "=" + ("=" * (job_status["progress"].to_i / 5)) + ">"
|
211
|
+
|
212
|
+
if job_status["num_hadoop_jobs"] && job_status["num_hadoop_jobs_succeeded"]
|
213
|
+
hadoop_jobs_ratio_complete =
|
214
|
+
'%0.2f / %0.2f' % [job_status["num_hadoop_jobs_succeeded"], job_status["num_hadoop_jobs"]]
|
215
|
+
end
|
216
|
+
|
217
|
+
printf("\r[#{spinner(ticks)}] Status: [%-22s] %s%% Complete (%s MapReduce jobs finished)", progressbar, job_status["progress"], hadoop_jobs_ratio_complete)
|
218
|
+
|
219
|
+
# If the job is not complete, but not in the running state, just display its status
|
220
|
+
else
|
221
|
+
redisplay("[#{spinner(ticks)}] Status: #{job_status['status_description']}")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
# If not polling, get the job status and display the results
|
225
|
+
else
|
226
|
+
job_status = api.get_job(job_id).body
|
227
|
+
display_job_status(job_status)
|
185
228
|
end
|
186
|
-
|
187
|
-
styled_header("#{job_status["project_name"]}: #{job_status["pigscript_name"]} (job_id: #{job_status["job_id"]})")
|
188
|
-
styled_hash(job_display_entries)
|
189
229
|
end
|
190
230
|
|
191
231
|
# jobs:stop JOB_ID
|
@@ -105,6 +105,41 @@ class Mortar::Command::Projects < Mortar::Command::Base
|
|
105
105
|
end
|
106
106
|
|
107
107
|
end
|
108
|
+
|
109
|
+
# projects:set_remote PROJECT
|
110
|
+
#
|
111
|
+
# Adds the Mortar remote to the local git project. This is necessary for successfully executing many of the Mortar commands.
|
112
|
+
#
|
113
|
+
#Example:
|
114
|
+
#
|
115
|
+
# $ mortar projects:set_remote my_project
|
116
|
+
#
|
117
|
+
def set_remote
|
118
|
+
project_name = shift_argument
|
119
|
+
|
120
|
+
unless project_name
|
121
|
+
error("Usage: mortar projects:set_remote PROJECT\nMust specify PROJECT.")
|
122
|
+
end
|
123
|
+
|
124
|
+
unless git.has_dot_git?
|
125
|
+
error("Can only set the remote 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.")
|
126
|
+
end
|
127
|
+
|
128
|
+
if git.remotes(git_organization).include?("mortar")
|
129
|
+
display("The remote has already been set for project: #{project_name}")
|
130
|
+
return
|
131
|
+
end
|
132
|
+
|
133
|
+
projects = api.get_projects().body["projects"]
|
134
|
+
project = projects.find { |p| p['name'] == project_name}
|
135
|
+
unless project
|
136
|
+
error("No project named: #{project_name} exists. You can create this project using:\n\n mortar projects:create")
|
137
|
+
end
|
138
|
+
|
139
|
+
git.remote_add("mortar", project['git_url'])
|
140
|
+
display("Successfully added the mortar remote to the #{project_name} project")
|
141
|
+
|
142
|
+
end
|
108
143
|
|
109
144
|
# projects:clone PROJECT
|
110
145
|
#
|
@@ -66,10 +66,8 @@ class Mortar::Command::Validate < Mortar::Command::Base
|
|
66
66
|
validate_result = api.get_validate(validate_id).body
|
67
67
|
is_finished =
|
68
68
|
Mortar::API::Validate::STATUSES_COMPLETE.include?(validate_result["status_code"])
|
69
|
-
|
70
|
-
redisplay("
|
71
|
-
validate_result['status_description'] + (is_finished ? "" : "..."),
|
72
|
-
is_finished ? " " : spinner(ticks)],
|
69
|
+
|
70
|
+
redisplay("[#{spinner(ticks)}] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access",
|
73
71
|
is_finished) # only display newline on last message
|
74
72
|
if is_finished
|
75
73
|
display
|
@@ -12,7 +12,7 @@
|
|
12
12
|
* User-Defined Functions (UDFs)
|
13
13
|
*/
|
14
14
|
|
15
|
-
REGISTER '../udfs/python/<%= script_name %>.py'
|
15
|
+
REGISTER '../udfs/python/<%= script_name %>.py' USING streaming_python AS <%= script_name %>;
|
16
16
|
<% end %>
|
17
17
|
|
18
18
|
-- This is an example of loading up input data
|
@@ -10,7 +10,7 @@
|
|
10
10
|
/**
|
11
11
|
* User-Defined Functions (UDFs)
|
12
12
|
*/
|
13
|
-
REGISTER '../udfs/python/<%= project_name %>.py'
|
13
|
+
REGISTER '../udfs/python/<%= project_name %>.py' USING streaming_python AS <%= project_name %>;
|
14
14
|
|
15
15
|
-- This is an example of loading up input data
|
16
16
|
my_input_data = LOAD '$INPUT_PATH'
|
data/lib/mortar/version.rb
CHANGED
@@ -52,8 +52,7 @@ STDOUT
|
|
52
52
|
mock(Mortar::Auth.api).get_clusters().returns(Excon::Response.new(:body => {"clusters" => []}))
|
53
53
|
stderr, stdout = execute("clusters", nil, nil)
|
54
54
|
stdout.should == <<-STDOUT
|
55
|
-
|
56
|
-
---------- ----------------- ------ ---- --------------- ------------
|
55
|
+
There are no running or recent clusters
|
57
56
|
STDOUT
|
58
57
|
end
|
59
58
|
end
|
@@ -86,7 +86,7 @@ Taking code snapshot... done
|
|
86
86
|
Sending code snapshot to Mortar... done
|
87
87
|
Starting describe... done
|
88
88
|
|
89
|
-
\r\e[
|
89
|
+
\r\e[0K[/] Calculating schema for my_alias and ancestors...\r\e[0K[-] Calculating schema for my_alias and ancestors...\r\e[0K[\\] Calculating schema for my_alias and ancestors...\r\e[0K[|] Calculating schema for my_alias and ancestors...
|
90
90
|
|
91
91
|
Results available at https://api.mortardata.com/describe/c571a8c7f76a4fd4a67c103d753e2dd5
|
92
92
|
Opening web browser to show results... done
|
@@ -119,7 +119,7 @@ Taking code snapshot... done
|
|
119
119
|
Sending code snapshot to Mortar... done
|
120
120
|
Starting describe... done
|
121
121
|
|
122
|
-
\r\e[
|
122
|
+
\r\e[0K[/] Calculating schema for my_alias and ancestors...\r\e[0K[-] Calculating schema for my_alias and ancestors...
|
123
123
|
|
124
124
|
STDOUT
|
125
125
|
stderr.should == <<-STDERR
|
@@ -56,7 +56,7 @@ Job status can be viewed on the web at:
|
|
56
56
|
|
57
57
|
Or by running:
|
58
58
|
|
59
|
-
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
|
59
|
+
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 --poll
|
60
60
|
|
61
61
|
STDOUT
|
62
62
|
end
|
@@ -87,7 +87,7 @@ Job status can be viewed on the web at:
|
|
87
87
|
|
88
88
|
Or by running:
|
89
89
|
|
90
|
-
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
|
90
|
+
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 --poll
|
91
91
|
|
92
92
|
STDOUT
|
93
93
|
end
|
@@ -116,7 +116,7 @@ Job status can be viewed on the web at:
|
|
116
116
|
|
117
117
|
Or by running:
|
118
118
|
|
119
|
-
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5
|
119
|
+
mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 --poll
|
120
120
|
|
121
121
|
STDOUT
|
122
122
|
end
|
@@ -339,11 +339,10 @@ STDOUT
|
|
339
339
|
stdout.should == <<-STDOUT
|
340
340
|
=== myproject: my_script (job_id: c571a8c7f76a4fd4a67c103d753e2dd5)
|
341
341
|
cluster_id: e2790e7e8c7d48e39157238d58191346
|
342
|
-
error:
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
type: RuntimeError
|
342
|
+
error - column_number: 34
|
343
|
+
error - line_number: 43
|
344
|
+
error - message: An error occurred and here's some more info
|
345
|
+
error - type: RuntimeError
|
347
346
|
hadoop jobs complete: 0.00 / 4.00
|
348
347
|
job began running at: 2012-02-28T03:41:52.613000+00:00
|
349
348
|
job finished at: 2012-02-28T03:45:52.613000+00:00
|
@@ -354,6 +353,85 @@ job running for: 6 mins
|
|
354
353
|
job submitted at: 2012-02-28T03:35:42.831000+00:00
|
355
354
|
progress: 55%
|
356
355
|
status: Execution error
|
356
|
+
STDOUT
|
357
|
+
end
|
358
|
+
end
|
359
|
+
it "gets status for a running job using polling" do
|
360
|
+
with_git_initialized_project do |p|
|
361
|
+
job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
|
362
|
+
pigscript_name = "my_script"
|
363
|
+
project_name = "myproject"
|
364
|
+
status_code = Mortar::API::Jobs::STATUS_RUNNING
|
365
|
+
progress = 0
|
366
|
+
cluster_id = "e2790e7e8c7d48e39157238d58191346"
|
367
|
+
start_timestamp = "2012-02-28T03:35:42.831000+00:00"
|
368
|
+
stop_timestamp = "2012-02-28T03:44:52.613000+00:00"
|
369
|
+
running_timestamp = "2012-02-28T03:41:52.613000+00:00"
|
370
|
+
parameters = {"my_param_1" => "value1", "MY_PARAM_2" => "3"}
|
371
|
+
|
372
|
+
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
373
|
+
"pigscript_name" => pigscript_name,
|
374
|
+
"project_name" => project_name,
|
375
|
+
"status_code" => status_code,
|
376
|
+
"status_description" => "Execution error",
|
377
|
+
"progress" => progress,
|
378
|
+
"cluster_id" => cluster_id,
|
379
|
+
"start_timestamp" => start_timestamp,
|
380
|
+
"running_timestamp" => running_timestamp,
|
381
|
+
"duration" => "6 mins",
|
382
|
+
"num_hadoop_jobs" => 4,
|
383
|
+
"num_hadoop_jobs_succeeded" => 0,
|
384
|
+
"parameters" => parameters
|
385
|
+
}))
|
386
|
+
|
387
|
+
status_code = Mortar::API::Jobs::STATUS_SUCCESS
|
388
|
+
progress = 100
|
389
|
+
outputs = [{'name'=> 'hottest_songs_of_the_decade',
|
390
|
+
'records' => 10,
|
391
|
+
'alias' => 'output_data',
|
392
|
+
'location' => 's3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data'},
|
393
|
+
{'name'=> 'hottest_songs_of_the_decade',
|
394
|
+
'records' => 100,
|
395
|
+
'alias' => 'output_data_2',
|
396
|
+
'location' => 's3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data_2'}]
|
397
|
+
|
398
|
+
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
399
|
+
"pigscript_name" => pigscript_name,
|
400
|
+
"project_name" => project_name,
|
401
|
+
"status_code" => status_code,
|
402
|
+
"status_description" => "Success",
|
403
|
+
"progress" => progress,
|
404
|
+
"cluster_id" => cluster_id,
|
405
|
+
"start_timestamp" => start_timestamp,
|
406
|
+
"running_timestamp" => running_timestamp,
|
407
|
+
"stop_timestamp" => stop_timestamp,
|
408
|
+
"duration" => "6 mins",
|
409
|
+
"num_hadoop_jobs" => 4,
|
410
|
+
"num_hadoop_jobs_succeeded" => 4,
|
411
|
+
"parameters" => parameters,
|
412
|
+
"outputs" => outputs
|
413
|
+
}))
|
414
|
+
stderr, stdout = execute("jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 -p", p, @git)
|
415
|
+
stdout.should == <<-STDOUT
|
416
|
+
\r[/] Status: [=> ] 0% Complete (0.00 / 4.00 MapReduce jobs finished)\r\e[0K=== myproject: my_script (job_id: c571a8c7f76a4fd4a67c103d753e2dd5)
|
417
|
+
cluster_id: e2790e7e8c7d48e39157238d58191346
|
418
|
+
hadoop jobs complete: 4.00 / 4.00
|
419
|
+
job began running at: 2012-02-28T03:41:52.613000+00:00
|
420
|
+
job finished at: 2012-02-28T03:44:52.613000+00:00
|
421
|
+
job run with parameters:
|
422
|
+
MY_PARAM_2: 3
|
423
|
+
my_param_1: value1
|
424
|
+
job running for: 6 mins
|
425
|
+
job submitted at: 2012-02-28T03:35:42.831000+00:00
|
426
|
+
outputs:
|
427
|
+
output_data:
|
428
|
+
location: s3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data
|
429
|
+
records: 10
|
430
|
+
output_data_2:
|
431
|
+
location: s3n://my-bucket/my-folder/hottest_songs_of_the_decade/output_data_2
|
432
|
+
records: 100
|
433
|
+
progress: 100%
|
434
|
+
status: Success
|
357
435
|
STDOUT
|
358
436
|
end
|
359
437
|
end
|
@@ -380,7 +458,6 @@ STDOUT
|
|
380
458
|
|
381
459
|
|
382
460
|
end
|
383
|
-
|
384
461
|
end
|
385
462
|
end
|
386
463
|
end
|
@@ -129,6 +129,62 @@ STDOUT
|
|
129
129
|
end
|
130
130
|
|
131
131
|
end
|
132
|
+
|
133
|
+
context("set_remote") do
|
134
|
+
|
135
|
+
it "sets the remote of a project" do
|
136
|
+
with_git_initialized_project do |p|
|
137
|
+
project_name = p.name
|
138
|
+
project_git_url = "git@github.com:mortarcode-dev/#{project_name}"
|
139
|
+
`git remote rm mortar`
|
140
|
+
mock(Mortar::Auth.api).get_projects().returns(Excon::Response.new(:body => {"projects" => [ { "name" => project_name, "status" => Mortar::API::Projects::STATUS_ACTIVE, "git_url" => project_git_url } ] })).ordered
|
141
|
+
|
142
|
+
mock(@git).remote_add("mortar", project_git_url)
|
143
|
+
|
144
|
+
stderr, stdout = execute("projects:set_remote #{project_name}", p, @git)
|
145
|
+
stdout.should == <<-STDOUT
|
146
|
+
Successfully added the mortar remote to the myproject project
|
147
|
+
STDOUT
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it "remote already added" do
|
152
|
+
with_git_initialized_project do |p|
|
153
|
+
project_name = p.name
|
154
|
+
|
155
|
+
stderr, stdout = execute("projects:set_remote #{project_name}", p, @git)
|
156
|
+
stdout.should == <<-STDERR
|
157
|
+
The remote has already been set for project: myproject
|
158
|
+
STDERR
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
it "No project given" do
|
163
|
+
with_git_initialized_project do |p|
|
164
|
+
stderr, stdout = execute("projects:set_remote", p, @git)
|
165
|
+
stderr.should == <<-STDERR
|
166
|
+
! Usage: mortar projects:set_remote PROJECT
|
167
|
+
! Must specify PROJECT.
|
168
|
+
STDERR
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it "No project with that name" do
|
173
|
+
with_git_initialized_project do |p|
|
174
|
+
project_name = p.name
|
175
|
+
project_git_url = "git@github.com:mortarcode-dev/#{project_name}"
|
176
|
+
mock(Mortar::Auth.api).get_projects().returns(Excon::Response.new(:body => {"projects" => [ { "name" => "derp", "status" => Mortar::API::Projects::STATUS_ACTIVE, "git_url" => project_git_url } ] })).ordered
|
177
|
+
`git remote rm mortar`
|
178
|
+
|
179
|
+
stderr, stdout = execute("projects:set_remote #{project_name}", p, @git)
|
180
|
+
stderr.should == <<-STDERR
|
181
|
+
! No project named: myproject exists. You can create this project using:
|
182
|
+
!
|
183
|
+
! mortar projects:create
|
184
|
+
STDERR
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
132
188
|
|
133
189
|
|
134
190
|
context("clone") do
|
@@ -71,7 +71,7 @@ Taking code snapshot... done
|
|
71
71
|
Sending code snapshot to Mortar... done
|
72
72
|
Starting validate... done
|
73
73
|
|
74
|
-
\r\e[
|
74
|
+
\r\e[0K[/] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access\r\e[0K[-] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access\r\e[0K[\\] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access\r\e[0K[|] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access
|
75
75
|
|
76
76
|
Your script is valid.
|
77
77
|
STDOUT
|
@@ -103,7 +103,7 @@ Taking code snapshot... done
|
|
103
103
|
Sending code snapshot to Mortar... done
|
104
104
|
Starting validate... done
|
105
105
|
|
106
|
-
\r\e[
|
106
|
+
\r\e[0K[/] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access\r\e[0K[-] Checking your script for problems with: Pig syntax, Python syntax, and S3 data access
|
107
107
|
|
108
108
|
STDOUT
|
109
109
|
stderr.should == <<-STDERR
|
metadata
CHANGED