mortar 0.7.5 → 0.7.6

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.
@@ -87,7 +87,7 @@ module Mortar
87
87
  raise GitError, "No commits found in repository. You must do an initial commit to initialize the repository."
88
88
  end
89
89
 
90
- safe_copy do
90
+ safe_copy(mortar_snapshot_pathlist) do
91
91
  did_stash_changes = stash_working_dir("Stash for push to master")
92
92
  git('push mortar master')
93
93
  end
@@ -95,14 +95,14 @@ module Mortar
95
95
  end
96
96
 
97
97
  #
98
- # Create a safe copy of the git directory
98
+ # Create a safe temporary directory with a given list of filesystem paths (files or dirs) copied into it
99
99
  #
100
100
 
101
- def safe_copy(&block)
101
+ def safe_copy(pathlist, &block)
102
102
  # Copy code into a temp directory so we don't confuse editors while snapshotting
103
103
  curdir = Dir.pwd
104
104
  tmpdir = Dir.mktmpdir
105
- FileUtils.cp_r(Dir.glob('*', File::FNM_DOTMATCH) - ['.', '..'], tmpdir)
105
+ FileUtils.cp_r(pathlist, tmpdir)
106
106
  Dir.chdir(tmpdir)
107
107
 
108
108
  if block
@@ -113,51 +113,77 @@ module Mortar
113
113
  return tmpdir
114
114
  end
115
115
  end
116
+
117
+ #
118
+ # Only snapshot filesystem paths that are in a whitelist
119
+ #
120
+
121
+ def mortar_snapshot_pathlist()
122
+ ensure_mortar_project_manifest_exists()
123
+
124
+ snapshot_pathlist = File.read('.mortar-project-manifest').split("\n")
125
+ snapshot_pathlist << ".git"
126
+
127
+ snapshot_pathlist.each do |path|
128
+ unless File.exists? path
129
+ Helpers.error(".mortar-project-manifest includes file/dir \"#{path}\" that is not in the mortar project directory.")
130
+ end
131
+ end
132
+
133
+ snapshot_pathlist
134
+ end
135
+
136
+ #
137
+ # Create a snapshot whitelist file if it doesn't already exist
138
+ #
139
+ def ensure_mortar_project_manifest_exists()
140
+ unless File.exists? '.mortar-project-manifest'
141
+ create_mortar_project_manifest('.')
142
+ end
143
+ end
144
+
145
+ #
146
+ # Create a project manifest file
147
+ #
148
+ def create_mortar_project_manifest(path)
149
+ File.open("#{path}/.mortar-project-manifest", 'w') do |manifest|
150
+ if File.directory? "#{path}/controlscripts"
151
+ manifest.puts "controlscripts"
152
+ end
153
+ if File.directory? "#{path}/fixtures"
154
+ manifest.puts "fixtures"
155
+ end
156
+ manifest.puts "pigscripts"
157
+ manifest.puts "macros"
158
+ manifest.puts "udfs"
159
+ end
160
+ end
116
161
 
117
162
  #
118
163
  # snapshot
119
164
  #
120
165
 
121
166
  def create_snapshot_branch
122
-
123
167
  # TODO: handle Ctrl-C in the middle
124
- # TODO: can we do the equivalent of stash without changing the working directory
125
168
  unless has_commits?
126
169
  raise GitError, "No commits found in repository. You must do an initial commit to initialize the repository."
127
170
  end
128
171
 
129
172
  # Copy code into a temp directory so we don't confuse editors while snapshotting
130
173
  curdir = Dir.pwd
131
- tmpdir = safe_copy
174
+ tmpdir = safe_copy(mortar_snapshot_pathlist)
132
175
 
133
176
  starting_branch = current_branch
134
177
  snapshot_branch = "mortar-snapshot-#{Mortar::UUID.create_random.to_s}"
135
- did_stash_changes = stash_working_dir(snapshot_branch)
136
- begin
137
- # checkout a new branch
138
- git("checkout -b #{snapshot_branch}")
139
-
140
- if did_stash_changes
141
- # apply the topmost stash that we just created
142
- git("stash apply stash@{0}")
143
- end
144
-
145
- add_untracked_files()
146
178
 
147
- # commit the changes if there are any
148
- if ! is_clean_working_directory?
149
- git("commit -a -m \"mortar development snapshot commit\"")
150
- end
151
-
152
- ensure
153
-
154
- # return to the starting branch
155
- git("checkout #{starting_branch}")
179
+ # checkout a new branch
180
+ git("checkout -b #{snapshot_branch}")
181
+
182
+ add_untracked_files()
156
183
 
157
- # rebuild the original state of the working set
158
- if did_stash_changes
159
- git("stash pop stash@{0}")
160
- end
184
+ # commit the changes if there are any
185
+ if ! is_clean_working_directory?
186
+ git("commit -a -m \"mortar development snapshot commit\"")
161
187
  end
162
188
 
163
189
  Dir.chdir(curdir)
@@ -176,11 +202,15 @@ module Mortar
176
202
 
177
203
  git_ref = Helpers.action("Sending code snapshot to Mortar") do
178
204
  # push the code
179
- push(project.remote, snapshot_branch)
205
+ begin
206
+ push(project.remote, snapshot_branch)
207
+ rescue
208
+ retry if retry_snapshot_push?
209
+ Helpers.error("Could not connect to github remote. Tried #{@snapshot_push_attempts.to_s} times.")
210
+ end
180
211
 
181
- # grab the commit hash and clean out the branch from the local branches
212
+ # grab the commit hash
182
213
  ref = git_ref(snapshot_branch)
183
- branch_delete(snapshot_branch)
184
214
  ref
185
215
  end
186
216
 
@@ -189,6 +219,19 @@ module Mortar
189
219
  return git_ref
190
220
  end
191
221
 
222
+ def retry_snapshot_push?
223
+ @last_snapshot_retry_sleep_time ||= 0
224
+ @snapshot_retry_sleep_time ||= 1
225
+
226
+ sleep(@snapshot_retry_sleep_time)
227
+ @last_snapshot_retry_sleep_time, @snapshot_retry_sleep_time =
228
+ @snapshot_retry_sleep_time, @last_snapshot_retry_sleep_time + @snapshot_retry_sleep_time
229
+
230
+ @snapshot_push_attempts ||= 0
231
+ @snapshot_push_attempts += 1
232
+ @snapshot_push_attempts < 10
233
+ end
234
+
192
235
  #
193
236
  # add
194
237
  #
@@ -92,16 +92,30 @@ EOF
92
92
  jy = Mortar::Local::Jython.new()
93
93
  jy.install_or_update()
94
94
 
95
- ensure_local_install_dir_in_gitignore
95
+ ensure_local_install_dirs_in_gitignore
96
96
  end
97
97
 
98
- def ensure_local_install_dir_in_gitignore()
98
+ def ensure_local_install_dirs_in_gitignore()
99
99
  if File.exists? local_project_gitignore
100
- open(local_project_gitignore, 'r+') do |gitignore|
101
- unless gitignore.read().include? local_install_directory_name
102
- gitignore.seek(0, IO::SEEK_END)
100
+ File.open(local_project_gitignore, 'r+') do |gitignore|
101
+ contents = gitignore.read()
102
+ gitignore.seek(0, IO::SEEK_END)
103
+
104
+ unless contents[-1] == "\n"
105
+ gitignore.puts "" # write a newline
106
+ end
107
+
108
+ unless contents.include? local_install_directory_name
103
109
  gitignore.puts local_install_directory_name
104
110
  end
111
+
112
+ unless contents.include? "logs"
113
+ gitignore.puts "logs"
114
+ end
115
+
116
+ unless contents.include? "illustrate-output"
117
+ gitignore.puts "illustrate-output"
118
+ end
105
119
  end
106
120
  end
107
121
  end
@@ -42,8 +42,12 @@ module Mortar
42
42
  File.join(project_root, local_install_directory_name)
43
43
  end
44
44
 
45
- def local_pig_logfile
46
- project_root + "/local-pig.log"
45
+ def local_log_dir
46
+ project_root + "/logs"
47
+ end
48
+
49
+ def local_udf_log_dir
50
+ local_log_dir + "/udf"
47
51
  end
48
52
 
49
53
  def local_project_gitignore
@@ -235,7 +235,7 @@ class Mortar::Local::Pig
235
235
  # get it to do something interesting, such as '-f some-file.pig'
236
236
  def run_pig_command(cmd, parameters = nil, jython_output = true)
237
237
  unset_hadoop_env_vars
238
- delete_local_log_file
238
+ reset_local_logs
239
239
  # Generate the script for running the command, then
240
240
  # write it to a temp script which will be exectued
241
241
  script_text = script_for_command(cmd, parameters)
@@ -255,10 +255,12 @@ class Mortar::Local::Pig
255
255
  ENV['HADOOP_CONF_DIR'] = ''
256
256
  end
257
257
 
258
- def delete_local_log_file
259
- if File.exists? local_pig_logfile
260
- FileUtils.rm local_pig_logfile
258
+ def reset_local_logs
259
+ if Dir.exists? local_log_dir
260
+ FileUtils.rm_rf local_log_dir
261
261
  end
262
+ Dir.mkdir local_log_dir
263
+ Dir.mkdir local_udf_log_dir
262
264
  end
263
265
 
264
266
  # Generates a bash script which sets up the necessary environment and
@@ -298,7 +300,8 @@ class Mortar::Local::Pig
298
300
  opts['fs.s3.awsAccessKeyId'] = ENV['AWS_ACCESS_KEY']
299
301
  opts['fs.s3.awsSecretAccessKey'] = ENV['AWS_SECRET_KEY']
300
302
  opts['pig.events.logformat'] = PIG_LOG_FORMAT
301
- opts['pig.logfile'] = local_pig_logfile
303
+ opts['pig.logfile'] = local_log_dir + "/local-pig.log"
304
+ opts['pig.udf.scripting.log.dir'] = local_udf_log_dir
302
305
  opts['python.verbose'] = 'error'
303
306
  opts['jython.output'] = true
304
307
  opts['python.home'] = jython_directory
@@ -3,5 +3,6 @@ Gemfile.lock
3
3
  *.class
4
4
  *.log
5
5
  tmp
6
- log
7
6
  .mortar-local
7
+ logs
8
+ illustrate-output
@@ -16,5 +16,5 @@
16
16
 
17
17
  module Mortar
18
18
  # see http://semver.org/
19
- VERSION = "0.7.5"
19
+ VERSION = "0.7.6"
20
20
  end
@@ -145,7 +145,7 @@ STDERR
145
145
  mock(j).install_or_update.returns(true)
146
146
  end
147
147
  any_instance_of(Mortar::Local::Controller) do |j|
148
- mock(j).ensure_local_install_dir_in_gitignore.returns(true)
148
+ mock(j).ensure_local_install_dirs_in_gitignore.returns(true)
149
149
  end
150
150
  stderr, stdout = execute("local:configure")
151
151
  stderr.should == ""
@@ -16,8 +16,10 @@
16
16
 
17
17
  require "spec_helper"
18
18
  require "mortar/git"
19
+ require "mortar/helpers"
19
20
 
20
21
  module Mortar
22
+
21
23
  describe Git do
22
24
 
23
25
  before do
@@ -280,6 +282,24 @@ STASH
280
282
  end
281
283
  end
282
284
 
285
+ it "retries pushing the snapshot branch if there is a socket error" do
286
+ with_git_initialized_project do |p|
287
+ # RR seems to only count a method as being called if it completes
288
+ # So we expect "never", even though it's actually tried N times (tested below)
289
+ mock(@git).push.never { raise Exception.new }
290
+ mock(@git).sleep.times(10).with_any_args
291
+
292
+ original_stdin, original_stderr, original_stdout = $stdin, $stderr, $stdout
293
+ $stdin, $stderr, $stdout = StringIO.new, StringIO.new, StringIO.new
294
+
295
+ begin
296
+ @git.create_and_push_snapshot_branch(p)
297
+ rescue SystemExit
298
+ ensure
299
+ $stdin, $stderr, $stdout = original_stdin, original_stderr, original_stdout
300
+ end
301
+ end
302
+ end
283
303
  end
284
304
 
285
305
  =begin
@@ -30,6 +30,7 @@ Excon.defaults[:mock] = true
30
30
  require "mortar-api-ruby"
31
31
 
32
32
  require "mortar/cli"
33
+ require "mortar/git"
33
34
  require "rspec"
34
35
  require "rr"
35
36
  require "fakefs/safe"
@@ -163,6 +164,9 @@ def with_blank_project(&block)
163
164
  FileUtils.mkdir_p(File.join(project_path, "controlscripts"))
164
165
  FileUtils.mkdir_p(File.join(project_path, "pigscripts"))
165
166
  FileUtils.mkdir_p(File.join(project_path, "macros"))
167
+ FileUtils.mkdir_p(File.join(project_path, "udfs"))
168
+ FileUtils.mkdir_p(File.join(project_path, "udfs/python"))
169
+ FileUtils.mkdir_p(File.join(project_path, "udfs/jython"))
166
170
 
167
171
  Dir.chdir(project_path)
168
172
 
@@ -188,9 +192,11 @@ end
188
192
  def with_git_initialized_project(&block)
189
193
  # wrap block in a proc that does a commit
190
194
  commit_proc = Proc.new do |project|
191
- write_file(File.join(project.root_path, "README.txt"), "Some README text")
195
+ git = Mortar::Git::Git.new
196
+ git.create_mortar_project_manifest(project.root_path)
197
+
192
198
  remote = "mortar"
193
- `git add README.txt`
199
+ `git add .mortar-project-manifest`
194
200
  `git commit -a -m "First commit"`
195
201
  `git remote add #{remote} git@github.com:mortarcode-dev/4dbbd83cae8d5bf8a4000000_#{project.name}.git`
196
202
  project.remote = remote
@@ -269,10 +275,15 @@ def create_and_validate_git_snapshot(git)
269
275
  # ensure the snapshot branch exists
270
276
  git.git("branch").include?(snapshot_branch).should be_true
271
277
 
278
+ snapshotted_paths = Dir.glob("**/*")
279
+ snapshotted_paths.should include("controlscripts")
280
+ snapshotted_paths.should include("pigscripts")
281
+ snapshotted_paths.should include("macros")
282
+ snapshotted_paths.should include("udfs/python")
283
+ snapshotted_paths.should include("udfs/jython")
284
+
272
285
  Dir.chdir(curdir)
273
286
  FileUtils.remove_entry_secure(snapshot_dir)
274
-
275
- git.branches.should == initial_git_branches
276
287
  end
277
288
 
278
289
  require "mortar/helpers"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mortar
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 5
10
- version: 0.7.5
9
+ - 6
10
+ version: 0.7.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mortar Data
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-04-18 00:00:00 Z
18
+ date: 2013-04-23 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: mortar-api-ruby