drupid 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a929de2a2d0b7af58b9721bfbbcca432d7a4c89
4
+ data.tar.gz: b34541cadc20ec1c9ec0fc56ae739c9350ccd67b
5
+ SHA512:
6
+ metadata.gz: 4f4b0a07712d7a4d42f812696392c09b4420b873f36efddbf9862bc85bd8455ffeacc5e205daa3f80fc03686faa624d83302d230ae11b47dd332f8acef5977ff
7
+ data.tar.gz: 4a9445e9f04fb27f411e4ab4b990dfc735a7b3035a0a5e745816387d114e195da9da896800a29b97c0ecf44de3476df246c6677313adb0e230814fbf45f140f7
data/bin/drupid CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- # Copyright (c) 2012 Lifepillar
4
+ # Copyright (c) 2012-2013 Lifepillar
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to deal
@@ -39,14 +39,15 @@ module Drupid
39
39
  :nodeps => false,
40
40
  :nolibs => false,
41
41
  :out => nil,
42
- :site => nil
42
+ :site => nil,
43
+ :updatedb => false
43
44
  }
44
45
  @updater = nil
45
46
  end
46
47
 
47
48
  def preflight_dependencies
48
49
  odie 'Drupid requires Ruby 1.8.7 or later' if RUBY_VERSION < '1.8.7'
49
- ['diff','curl','git','drush','mktemp','patch','rsync'].each do |cmd|
50
+ ['diff','curl','git','mktemp','patch','rsync'].each do |cmd|
50
51
  if `which #{cmd} 2>/dev/null`.chomp.empty?
51
52
  odie "Drupid requires '#{cmd}', but '#{cmd}' was not found in your PATH."
52
53
  end
@@ -61,7 +62,7 @@ module Drupid
61
62
  o.banner = "Drupid synchronizes a Drush makefile" +
62
63
  " with a Drupal platform, and more!\n" +
63
64
  "Usage:\n" +
64
- "drupid -s <MAKEFILE> -p <DIRECTORY> [-cdDflnSv]\n" +
65
+ "drupid -s <MAKEFILE> -p <DIRECTORY> [-cdDflnSuv]\n" +
65
66
  "drupid --clear-cache [-nv]\n" +
66
67
  "drupid --edit [<URL>] [-v] [-o <FILE>]\n" +
67
68
  "drupid --graph -p <DIRECTORY> [-Sv]\n" +
@@ -81,7 +82,7 @@ module Drupid
81
82
  o.on('-D', '--debug', 'Enable debugging.') { $DEBUG = true; $VERBOSE = true }
82
83
  o.on('-e', '--edit [URL]', 'Create patches interactively.',
83
84
  'With no URL, edit the current directory.') { |u| @options[:command] = :edit; @options[:edit] = u }
84
- o.on('-f', '--force', 'Force completion, even if there are errors.') { |b| @options[:force] = b }
85
+ o.on('-f', '--force', 'Force completion, even if there are warnings or errors.') { |b| @options[:force] = b }
85
86
  o.on('-g', '--graph', 'Generate a dependency graph and exit.') { @options[:command] = :graph }
86
87
  o.on('-h', '--help', 'Print help and exit.') {
87
88
  puts o
@@ -97,6 +98,7 @@ module Drupid
97
98
  end
98
99
  o.on('-S', '--site NAME', 'Process the given site.',
99
100
  '(For multi-site platforms.)') { |s| @options[:site] = s }
101
+ o.on('-u', '--updatedb', "Update Drupal's database after a successful sync.") { @options[:updatedb] = true }
100
102
  o.on('-v', '--verbose', 'Be verbose.') { $VERBOSE = true }
101
103
  o.on('-V', '--version', 'Print version and exit.') { puts DRUPID_USER_AGENT; exit 0 }
102
104
  o.parse!
@@ -132,7 +134,7 @@ module Drupid
132
134
  rescue => ex
133
135
  odie "Could not analyze platform: #{ex}"
134
136
  end
135
- @updater = Drupid::Updater.new(mf, pl, @options[:site])
137
+ @updater = Drupid::Updater.new(mf, pl, @options)
136
138
  blah 'Syncing (this may take a while)...'
137
139
  ohai 'Preflighting changes...'
138
140
  @updater.sync(
@@ -166,6 +168,21 @@ module Drupid
166
168
  '.lock' != @updater.makefile.path.extname
167
169
  @updater.makefile.save(@updater.makefile.path.sub_ext('.make.lock'))
168
170
  end
171
+ if (not failed) and @options[:updatedb]
172
+ if which('drush').nil?
173
+ owarn 'Not updating the database because Drush cannot be found.'
174
+ elsif @updater.updatedb
175
+ ohai "Success!"
176
+ else
177
+ ofail "Database update failed."
178
+ failed = true
179
+ end
180
+ end
181
+ if failed
182
+ exit 1
183
+ else
184
+ exit 0
185
+ end
169
186
  end
170
187
 
171
188
  def clear_cache
@@ -256,6 +273,7 @@ module Drupid
256
273
  rescue Interrupt
257
274
  puts
258
275
  drupid.ohai "Drupid interrupted"
276
+ exit 1
259
277
  rescue => ex
260
278
  puts
261
279
  drupid.debug 'Backtrace:', ex.backtrace.join("\n")
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright (c) 2012 Lifepillar
3
+ # Copyright (c) 2012-2013 Lifepillar
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -38,7 +38,7 @@ module Kernel
38
38
  end unless Kernel.respond_to? :silence_warnings
39
39
 
40
40
  module Drupid
41
- DRUPID_VERSION = '1.0.1'
41
+ DRUPID_VERSION = '1.1.0'
42
42
  DRUPID_USER_AGENT = "Drupid #{DRUPID_VERSION} (Ruby #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}; #{RUBY_PLATFORM})"
43
43
  end
44
44
 
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright (c) 2012 Lifepillar
3
+ # Copyright (c) 2012-2013 Lifepillar
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -120,9 +120,12 @@ module Drupid
120
120
  @local_path = cached_location
121
121
  debug "#{extended_name} is cached"
122
122
  else
123
- raise "No download URL specified for #{extended_name}" unless download_url
123
+ raise "No download URL specified for #{extended_name}" if download_url.nil?
124
124
  blah "Fetching #{extended_name}"
125
- downloader = Drupid.makeDownloader download_url.to_s, cached_location.dirname.to_s, cached_location.basename.to_s, download_specs
125
+ downloader = Drupid.makeDownloader self.download_url.to_s,
126
+ self.cached_location.dirname.to_s,
127
+ self.cached_location.basename.to_s,
128
+ self.download_specs
126
129
  downloader.fetch
127
130
  downloader.stage
128
131
  @local_path = downloader.staged_path
@@ -134,8 +137,8 @@ module Drupid
134
137
  def patch
135
138
  fetch unless exist?
136
139
  return unless has_patches?
137
- patched_location.rmtree if patched_location.exist? # Ensure no previous patched copy exists
138
- @local_path.ditto patched_location
140
+ dont_debug { patched_location.rmtree if patched_location.exist? } # Make sure that no previous patched copy exists
141
+ dont_debug { @local_path.ditto patched_location }
139
142
  @local_path = patched_location
140
143
  # Download patches
141
144
  patched_location.dirname.cd do
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright (c) 2012 Lifepillar
3
+ # Copyright (c) 2012-2013 Lifepillar
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -90,7 +90,7 @@ module Drupid
90
90
  when %r[^https?://svn\.] then Subversion
91
91
  when %r[\.git$] then Git
92
92
  when %r[\/] then Curl
93
- else Drush
93
+ else Curl
94
94
  end
95
95
  end
96
96
 
@@ -153,10 +153,9 @@ module Drupid
153
153
 
154
154
  # Retrieves a file from this object's URL.
155
155
  def fetch
156
- @tarball_path.rmtree if @tarball_path.exist?
156
+ dont_debug { @tarball_path.rmtree if @tarball_path.exist? }
157
157
  begin
158
- debug "Pathname.mkpath may raise harmless exceptions"
159
- @dest.mkpath unless @dest.exist?
158
+ dont_debug { @dest.mkpath }
160
159
  _fetch
161
160
  rescue Exception => e
162
161
  ignore_interrupts { @tarball_path.unlink if @tarball_path.exist? }
@@ -173,8 +172,8 @@ module Drupid
173
172
  # Invokes #fetch to retrieve the file if needed.
174
173
  def stage wd = @dest
175
174
  fetch unless @tarball_path.exist?
176
- debug "Pathname.mkpath may raise harmless exceptions"
177
- wd.mkpath unless wd.exist?
175
+ dont_debug { wd.mkpath }
176
+ debug "Staging into #{wd}"
178
177
  target = wd + @tarball_path.basename
179
178
  type = @tarball_path.compression_type
180
179
  if type
@@ -185,27 +184,31 @@ module Drupid
185
184
  if 1 == content.size and content.first.directory?
186
185
  src = content.first
187
186
  target = wd + src.basename
188
- FileUtils.mv src.to_s, wd.to_s, :force => true, :verbose => $DEBUG
187
+ debug "Moving #{src} into #{wd}"
188
+ dont_debug { FileUtils.mv src.to_s, wd.to_s, :force => true }
189
189
  else # the archive did not have a root folder or it expanded to a file instead of a folder
190
190
  # We cannot move the temporary directory we are in, so we copy its content
191
191
  src = Pathname.pwd
192
192
  target = wd + src.basename
193
- target.rmtree if target.exist? # Overwrite
194
- target.mkpath
193
+ dont_debug { target.rmtree if target.exist? } # Overwrite
194
+ dont_debug { target.mkpath }
195
195
  src.ditto target
196
196
  end
197
197
  debug "Temporary staging target: #{target}"
198
198
  end
199
199
  elsif wd != @dest
200
- FileUtils.mv @tarball_path.to_s, wd.to_s, :force => true, :verbose => $DEBUG
201
- end
200
+ debug "Moving #{@tarball_path} into #{wd}"
201
+ dont_debug { FileUtils.mv @tarball_path.to_s, wd.to_s, :force => true }
202
+ end
202
203
  if @name and @name != target.basename.to_s
203
204
  new_path = target.dirname + @name
204
- new_path.rmtree if new_path.exist? # Overwrite
205
+ dont_debug { new_path.rmtree if new_path.exist? }
206
+ debug "Renaming from #{target} to #{new_path}"
205
207
  File.rename target.to_s, new_path.to_s
206
208
  target = target.dirname+@name
207
209
  end
208
210
  @staged_path = target
211
+ debug "Staging completed"
209
212
  end
210
213
 
211
214
  private
@@ -226,25 +229,6 @@ module Drupid
226
229
 
227
230
  end # Curl
228
231
 
229
-
230
- class Drush < Curl
231
- def initialize url, dest, name, download_specs = {}
232
- super
233
- @tarball_path = @dest + @name
234
- end
235
-
236
- def _fetch
237
- output = Drupid::Drush.pm_download url, :destination => dest
238
- p = Drupid::Drush.download_path(output)
239
- if p
240
- @tarball_path = Pathname.new(p).realpath
241
- else
242
- raise "Download failed for project #{name} (using Drush):\n#{output}"
243
- end
244
- end
245
- end # Drush
246
-
247
-
248
232
  # Detect and download from Apache Mirror
249
233
  class CurlApacheMirror < Curl
250
234
  def _fetch
@@ -331,8 +315,8 @@ module Drupid
331
315
  # Invokes #fetch to retrieve the file if needed.
332
316
  def stage wd = @dest
333
317
  fetch unless @clone.exist?
334
- debug "Pathname.mkpath may raise harmless exceptions"
335
- wd.mkpath unless wd.exist?
318
+ dont_debug { wd.mkpath }
319
+ debug "Staging into #{wd}"
336
320
  target = wd + @clone.basename
337
321
  Dir.chdir @clone do
338
322
  if @specs.has_key?('branch')
@@ -388,8 +372,8 @@ module Drupid
388
372
 
389
373
  def stage wd = @dest
390
374
  fetch unless @co.exist?
391
- debug "Pathname.mkpath may raise harmless exceptions"
392
- wd.mkpath unless wd.exist?
375
+ dont_debug { wd.mkpath }
376
+ debug "Staging into #{wd}"
393
377
  target = wd + @co.basename
394
378
  svn 'export', '--force', @co, target
395
379
  end
@@ -449,16 +433,16 @@ module Drupid
449
433
 
450
434
  def stage wd = @dest
451
435
  fetch unless @co.exist?
452
- debug "Pathname.mkpath may raise harmless exceptions"
453
- wd.mkpath unless wd.exist?
436
+ dont_debug { wd.mkpath }
437
+ debug "Staging into #{wd}"
454
438
  target = wd + @co.basename
455
- FileUtils.cp_r Dir[(@co+"{.}").to_s], target
439
+ dont_debug { FileUtils.cp_r Dir[(@co+"{.}").to_s], target }
456
440
 
457
441
  require 'find'
458
442
  Find.find(Dir.pwd) do |path|
459
443
  if FileTest.directory?(path) && File.basename(path) == "CVS"
460
444
  Find.prune
461
- FileUtil.rm_r path, :force => true
445
+ dont_debug { FileUtils.rm_r path, :force => true }
462
446
  end
463
447
  end
464
448
  end
@@ -496,8 +480,8 @@ module Drupid
496
480
 
497
481
  def stage wd = @dest
498
482
  fetch unless @co.exist?
499
- debug "Pathname.mkpath may raise harmless exceptions"
500
- wd.mkpath unless wd.exist?
483
+ dont_debug { wd.mkpath }
484
+ debug "Staging into #{wd}"
501
485
  dst = wd + @co.basename
502
486
  Dir.chdir @clone do
503
487
  #if @spec and @ref
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright (c) 2012 Lifepillar
3
+ # Copyright (c) 2012-2013 Lifepillar
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -19,125 +19,23 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
+ require 'yaml'
22
23
 
23
24
  module Drupid
24
25
 
25
26
  # A wrapper around drush.
26
- module Drush extend Drupid::Utils
27
-
28
- DRUSH = `which drush`.strip
29
-
30
- def self.drush *args
31
- runBabyRun DRUSH, args
32
- end
33
-
34
- # Executes 'drush core-status' at the given path and
35
- # returns the output of the command.
36
- def self.status path, options = {}
37
- output = nil
38
- FileUtils.cd(path) do
39
- output = drush 'core-status', '--pipe'
40
- end
41
- output
42
- end
43
-
44
- # Executes 'drush pm-releases --all' for the given project and
45
- # returns the output of the command.
46
- def self.pm_releases project_name, options = {}
47
- drush 'pm-releases', '--all', project_name
48
- end
49
-
50
- # Parses the output of 'drush pm-releases' and returns
51
- # the version of the latest recommended release, or nil
52
- # if no such release exists.
53
- def self.recommended_release pm_releases_output
54
- pm_releases_output.each_line do |l|
55
- return $~[1] if (l.match(/^\s*([^\s]+).*Recommended/))
56
- end
57
- nil
58
- end
59
-
60
- # Parses the output of 'drush pm-releases' and returns
61
- # the version of the latest supported release, or nil
62
- # if no such release exists.
63
- def self.supported_release pm_releases_output
64
- pm_releases_output.each_line do |l|
65
- return $~[1] if (l.match(/^\s*([^\s]+).*Supported/))
66
- end
67
- nil
68
- end
69
-
70
- # Executes 'drush pm-download <project_name>' and
71
- # returns the output of the command.
72
- # If :working_dir is set to an existing directory, move into that directory before
73
- # executing the command.
74
- #
75
- # Options: source, destination, working_dir
76
- def self.pm_download project_name, options = {}
77
- args = ['pm-download', '-y']
78
- args << "--source=#{options[:source]}" if options[:source]
79
- args << "--destination\=#{options[:destination]}" if options[:destination]
80
- args << "--variant=profile-only"
81
- args << "--verbose" if $VERBOSE
82
- args << project_name
83
- if options[:working_dir] and File.directory?(options[:working_dir])
84
- wd = options[:working_dir]
85
- else
86
- wd = FileUtils.pwd
87
- end
88
- output = nil
89
- FileUtils.cd(wd) do
90
- output = runBabyRun DRUSH, args, :redirect_stderr_to_stdout => true
91
- end
92
- output
93
- end
94
-
95
- # Parses the output of 'drush pm-download' and returns
96
- # the path to the downloaded project, or nil
97
- # if the path cannot be determined.
98
- def self.download_path pm_download_output
99
- pm_download_output.match(/^\s*Project.+downloaded to *(.\[.+[\n\r])?\s*(.+)\./)
100
- return File.expand_path($~[2]) if $~
101
- return nil
102
- end
103
-
104
- # Parses the output of 'drush pm-download' and returns
105
- # the version of the downloaded project, or nil
106
- # if the version cannot be determined.
107
- def self.downloaded_version pm_download_output
108
- pm_download_output.match(/^\s*Project.+\((.+)\) +downloaded +to/)
109
- return $~[1] if $~
110
- return nil
111
- end
112
-
113
- # Executes 'drush pm-info' at the given path and with an
114
- # optional list of projects.
115
- # Returns the output of the command.
116
- def self.pm_info path, projects = [], options = {}
117
- output = nil
118
- args = Array.new
119
- args << 'pm-info'
120
- args << projects.join(' ') unless nil != projects and projects.empty?
121
- FileUtils.cd(path) do
122
- output = runBabyRun DRUSH, args, :redirect_stderr_to_stdout => true
123
- end
124
- output
125
- end
126
-
127
- # Returns the version of Drupal (e.g., '7.12')
128
- # if the given path contains Drupal;
129
- # returns nil otherwise.
130
- def self.drupal_version path, options = {}
131
- st = self.status(path, options)
132
- return nil unless st.match(/drupal_version=(\d+\.\d+)/)
133
- return $~[1]
134
- end
27
+ module Drush
135
28
 
136
29
  # Returns true if a Drupal's site is bootstrapped at the given path;
137
30
  # returns false otherwise.
138
31
  def self.bootstrapped?(path, options = {})
139
- st = self.status(path, options)
140
- st.match(/drupal_bootstrap=Successful/) ? true : false
32
+ output = ''
33
+ FileUtils.cd(path) do
34
+ output = %x|drush core-status --format=yaml|
35
+ end
36
+ st = YAML.load(output)
37
+ return false unless st
38
+ return (st['bootstrap'] =~ /Successful/) ? true : false
141
39
  end
142
40
 
143
41
  # Returns true if the project at the given path is an enabled theme
@@ -150,34 +48,28 @@ module Drupid
150
48
  #
151
49
  # Options: verbose
152
50
  def self.installed?(site_path, project_name, project_path, options = {})
153
- st = ''
154
- begin
155
- st = self.pm_info(site_path, [project_name], options)
156
- rescue # site not fully bootstrapped
157
- return false
51
+ output = nil
52
+ FileUtils.cd(site_path) do
53
+ # Redirect stderr to stdout because we do not want to output
54
+ # Drush's error messages when Drupid is run in verbose mode.
55
+ output = %x|drush pm-info --format=yaml #{project_name} 2>&1|
56
+ return false unless $?.success? # site not fully bootstrapped
158
57
  end
159
- return false unless st.match(/Path +: +#{project_path}/)
160
- return false unless st.match(/Type +: +([^\s]+)/)
161
- type = $~[1]
162
- return false unless st.match(/Status +: +(.+)$/)
163
- project_status = $~[1]
164
- ('module' == type and project_status !~ /not installed/) or
165
- ('theme' == type and project_status =~ /^enabled/)
58
+ st = YAML.load(output)
59
+ return false unless st.has_key?(project_name)
60
+ type = st[project_name]['type']
61
+ status = st[project_name]['status']
62
+ ('module' == type and status !~ /not installed/) or
63
+ ('theme' == type and status =~ /^enabled/)
166
64
  end
167
65
 
168
- # Executes 'drush make' and returns the output of the command.
66
+ # Runs drush updatedb at the specified path.
169
67
  #
170
- # Options: contrib_path, nocore, dry, verbose
171
- def self.make(makefile, target, options = {})
172
- args = Array.new
173
- args << 'make'
174
- args << '-y'
175
- args << '--no-core' if options[:nocore]
176
- args << "--contrib-destination=#{options[:contrib_path]}" if options[:contrib_path]
177
- args << "--no-patch-txt"
178
- args << makefile
179
- args << target
180
- drush(*args)
68
+ # Raises a Drupid:ErrorDuringExecution exception if an error occurs.
69
+ def self.updatedb site_path
70
+ FileUtils.cd(site_path) do
71
+ return system 'drush updatedb -y'
72
+ end
181
73
  end
182
74
 
183
75
  end # module Drush