Module: Drupid::Utils

Defined Under Namespace

Classes: ErrorDuringExecution, NotAnArchiveError, Tty

Instance Method Summary collapse

Instance Method Details

#blah(notice) ⇒ Object

Prints a notice if in verbose mode.



120
121
122
123
# File 'lib/drupid/utils.rb', line 120

def blah notice
  return unless $VERBOSE
  puts "#{Tty.green}==>#{Tty.reset} #{notice}"
end

#bzr(*args) ⇒ Object



191
192
193
194
195
196
# File 'lib/drupid/utils.rb', line 191

def bzr *args
  bzr = Pathname.new(which 'bzr')
  raise "bzr not found" unless bzr.exist?
  raise "bzr is not executable" unless bzr.executable?
  runBabyRun bzr, args, :redirect_stderr_to_stdout => true    
end

#compare_paths(src, tgt, additional_rsync_options = []) ⇒ Object

Compares the content of two directories using rsync. Changes in timestamps only are ignored. Returns a possibly empty list of differences.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/drupid/utils.rb', line 249

def compare_paths src, tgt, additional_rsync_options = []
  p1 = Pathname.new(src).realpath.to_s + '/'
  p2 = Pathname.new(tgt).realpath.to_s + '/'
  args = Array.new
  args << '-rlD'
  args << '--dry-run'
  args << '--delete'
  args << '--itemize-changes'
  args += additional_rsync_options
  args << p1
  args << p2
  output = runBabyRun 'rsync', args, :verbose => false
  changes = Array.new
  output.each_line do |l|
    next if l =~ /[fdLDS]\.\.[tT]\.\.\.\./ # Skip changes in timestamps only
    changes << l.strip
  end
  return changes
end

#curl(*args) ⇒ Object



154
155
156
157
158
159
160
161
# File 'lib/drupid/utils.rb', line 154

def curl *args
  curl = Pathname.new(which 'curl')
  args = ['-qf#LA', USER_AGENT, *args]
  args << "--insecure" #if MacOS.version < 10.6
  args << "--silent" unless $VERBOSE

  runBabyRun curl, args
end

#cvs(*args) ⇒ Object



177
178
179
180
181
182
# File 'lib/drupid/utils.rb', line 177

def cvs *args
  cvs = Pathname.new(which 'cvs')
  raise "cvs not found" unless cvs.exist?
  raise "cvs is not executable" unless cvs.executable?
  runBabyRun cvs, args, :redirect_stderr_to_stdout => true
end

#debug(title, *info) ⇒ Object

Prints debug information.



109
110
111
112
113
114
115
116
117
# File 'lib/drupid/utils.rb', line 109

def debug title, *info
  return unless $DEBUG
  puts "#{Tty.purple}[DEBUG]#{Tty.white} #{title}#{Tty.reset}"
  info.each do |chunk|
    chunk.each_line do |l|
      puts "#{Tty.purple}[DEBUG]#{Tty.reset} #{l.chomp!}"
    end
  end
end

#dont_debugObject

Temporarily forces $DEBUG = false in the given block.

This is used to suppress some harmless but annoying exception messages from some methods, e.g., FileUtils.mkpath.



301
302
303
304
305
306
307
308
309
# File 'lib/drupid/utils.rb', line 301

def dont_debug
  saved_debug = $DEBUG
  $DEBUG = false
  begin
    yield
  ensure
    $DEBUG = saved_debug
  end
end

#git(*args) ⇒ Object



163
164
165
166
167
168
# File 'lib/drupid/utils.rb', line 163

def git *args
  git = Pathname.new(which 'git')
  raise "git not found" unless git.exist?
  raise "git is not executable" unless git.executable?
  runBabyRun git, args, :redirect_stderr_to_stdout => true
end

#hg(*args) ⇒ Object



184
185
186
187
188
189
# File 'lib/drupid/utils.rb', line 184

def hg *args
  hg = Pathname.new(which 'hg')
  raise "hg not found" unless hg.exist?
  raise "hg is not executable" unless hg.executable?
  runBabyRun hg, args, :redirect_stderr_to_stdout => true   
end

#ignore_interruptsObject



274
275
276
277
278
279
# File 'lib/drupid/utils.rb', line 274

def ignore_interrupts
  std_trap = trap("INT") {}
  yield
ensure
  trap("INT", std_trap)
end

#interactive_shellObject



281
282
283
284
285
286
287
# File 'lib/drupid/utils.rb', line 281

def interactive_shell
  fork {exec ENV['SHELL'] }
  Process.wait
  unless $?.success?
    owarn "Non-zero exit status: #{$?}"
  end
end

#odie(error) ⇒ Object

Prints an error message and exits.



103
104
105
106
# File 'lib/drupid/utils.rb', line 103

def odie error
  ofail error
  exit 1
end

#ofail(error, *info) ⇒ Object

Prints an error message.



97
98
99
100
# File 'lib/drupid/utils.rb', line 97

def ofail error, *info
  puts "#{Tty.red}Fail#{Tty.reset}: #{error}"
  puts info unless info.empty?
end

#ohai(title, *sput) ⇒ Object

Prints a message.



86
87
88
89
# File 'lib/drupid/utils.rb', line 86

def ohai title, *sput
  puts "#{Tty.green}==>#{Tty.white} #{title}#{Tty.reset}"
  puts sput unless sput.empty?
end

#owarn(warning) ⇒ Object

Print a warning message.



92
93
94
# File 'lib/drupid/utils.rb', line 92

def owarn warning
  puts "#{Tty.red}Warn#{Tty.reset}: #{warning}"
end

#runBabyRun(command, arguments = [], options = {}) ⇒ Object

Executes a command. Returns the output of the command. Raises a Drupid::ErrorDuringExecution error if the command does not exit successfully.

command

A String or Pathname object

arguments

An optional Array of arguments

options

An optional Hash of options

Options: out, err, redirect_stderr_to_stdout, dry



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/drupid/utils.rb', line 134

def runBabyRun command, arguments = [], options = {}
  opts = { :dry => false }.merge!(options)
  cmd = String.new(command.to_s)
  raise "Not an array" unless arguments.is_a?(Array)
  args = arguments.map { |arg| arg.to_s }
  cmd << ' '     + args.shelljoin
  cmd << ' >'    + Shellwords.shellescape(opts[:out]) if opts[:out]
  cmd << ' 2>'   + Shellwords.shellescape(opts[:err]) if opts[:err]
  cmd << ' 2>&1' if opts[:redirect_stderr_to_stdout]
  debug "Pwd: #{Dir.pwd}"
  debug cmd
  return cmd if opts[:dry]
  output = %x|#{cmd}| # Run baby run!
  unless $?.success?
    debug 'Command failed', output
    raise ErrorDuringExecution, output
  end
  return output
end

#svn(*args) ⇒ Object



170
171
172
173
174
175
# File 'lib/drupid/utils.rb', line 170

def svn *args
  svn = Pathname.new(which 'svn')
  raise "svn not found" unless svn.exist?
  raise "svn is not executable" unless svn.executable?
  runBabyRun svn, args, :redirect_stderr_to_stdout => true
end

#tempdirObject

Creates a temporary directory then yield. When the block returns, recursively delete the temporary directory.



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/drupid/utils.rb', line 225

def tempdir
  # I used /tmp rather than `mktemp -td` because that generates a directory
  # name with exotic characters like + in it, and these break badly written
  # scripts that don't escape strings before trying to regexp them :(

  # If the user has FileVault enabled, then we can't mv symlinks from the
  # /tmp volume to the other volume. So we let the user override the tmp
  # prefix if they need to.
  tmp_prefix = '/tmp'
  tmp = Pathname.new `mktemp -d #{tmp_prefix}/temp_item-XXXXXX`.strip
  raise "Couldn't create temporary directory" if not tmp.directory? or $? != 0
  begin
    wd = Dir.pwd
    FileUtils.chdir tmp
    yield
  ensure
    FileUtils.chdir wd
    dont_debug { tmp.rmtree }
  end
end

#uncompress(archive, options = {}) ⇒ Object

Uncompresses an archive in the current directory.

archive

A Pathname object representing the full path to the archive.

The the :type options is used, the archive is interpreted as the given type (:zip, :gzip, :bzip2, :compress, :tar, :xz, :rar), otherwise the type is guessed based on the file content.

Options: type



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/drupid/utils.rb', line 205

def uncompress archive, options = {}
  type = options[:type] ? options[:type] : archive.compression_type
  case type
  when :zip
    runBabyRun 'unzip', ['-qq', archive]
  when :gzip, :bzip2, :compress, :tar
    # Assume these are also tarred
    # TODO check if it's really a tar archive
    runBabyRun 'tar', ['xf', archive]
  when :xz
    runBabyRun "xz -dc \"#{archive}\" | tar xf -"
  when :rar
    runBabyRun 'unrar', ['x', '-inul', archive]
  else
    raise NotAnArchiveError
  end
end

#which(cmd) ⇒ Object



269
270
271
272
# File 'lib/drupid/utils.rb', line 269

def which cmd
  path = `which #{cmd} 2>/dev/null`.chomp
  path.empty? ? nil : Pathname.new(path)
end

#writeFile(path, content) ⇒ Object

Creates the specified file with the given content. The file is overwritten if it exists.



291
292
293
294
295
# File 'lib/drupid/utils.rb', line 291

def writeFile path, content
  p = Pathname.new(path)
  blah "Writing #{p}"
  p.open("w") { |f| f.write(content) }
end