drupid 1.0.1 → 1.1.0

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.
@@ -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