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.
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2012 Lifepillar
1
+ # -*- coding: ascii -*-
2
+
3
+ # Copyright (c) 2012-2013 Lifepillar
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -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
@@ -45,7 +45,8 @@ module Drupid
45
45
  end
46
46
 
47
47
  def fetch
48
- cached_location.rmtree if cached_location.exist?
48
+ debug "Cached location: #{cached_location}"
49
+ dont_debug { cached_location.rmtree if cached_location.exist? }
49
50
  super
50
51
  end
51
52
  end # Library
@@ -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
@@ -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
@@ -39,6 +39,7 @@ module Drupid
39
39
  # Downloads the patch into the current directory.
40
40
  def fetch
41
41
  dst = Pathname.pwd+File.basename(@url.to_s)
42
+ blah "Fetching patch..."
42
43
  begin
43
44
  curl @url.to_s, '-o', dst
44
45
  rescue
@@ -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
@@ -30,10 +30,10 @@ module Drupid
30
30
  # or nil if this platform does not contain Drupal core.
31
31
  attr :drupal_project
32
32
  # The path for contrib modules and themes (e.g., 'sites/all'),
33
- # relative to #path.
33
+ # relative to #local_path.
34
34
  attr_accessor :contrib_path
35
35
  # The path to the sites directory (default: 'sites'), relative
36
- # relative to #path.
36
+ # relative to #local_path.
37
37
  attr :sites_dir
38
38
 
39
39
  # Creates a new platform object for the Drupal installation at the
@@ -50,7 +50,7 @@ module Drupid
50
50
  # Returns the version of Drupal core in this platform, or
51
51
  # nil if the version cannot be determined.
52
52
  def version
53
- if @drupal_project and @drupal_project.has_version?
53
+ if (@drupal_project and @drupal_project.has_version?) or load_drupal_version
54
54
  return @drupal_project.version
55
55
  end
56
56
  return nil
@@ -134,13 +134,9 @@ module Drupid
134
134
 
135
135
  # Retrieves information about Drupal core in this platform.
136
136
  def analyze_drupal_core
137
+ debug 'Analyzing Drupal Core...'
137
138
  @drupal_project = nil
138
- vers = Drupid::Drush.drupal_version(local_path)
139
- if vers
140
- core = vers.match(/(\d+)\./)[1].to_i
141
- @drupal_project = Drupid::Project.new('drupal', core, vers)
142
- @drupal_project.local_path = self.local_path
143
- end
139
+ load_drupal_version
144
140
  end
145
141
 
146
142
  # Extracts information about the projects in this platform.
@@ -230,5 +226,29 @@ module Drupid
230
226
  graph.write_to_graphic_file('svg')
231
227
  end
232
228
 
229
+ private
230
+
231
+ def load_drupal_version
232
+ # Drupal 7 stores VERSION in bootstrap.inc. Drupal 8 moved that to /core/includes.
233
+ bootstrap_files = ['core/includes/bootstrap.inc', 'includes/bootstrap.inc', 'modules/system/system.module']
234
+ bootstrap_files.each do |bf|
235
+ f = self.local_path+bf
236
+ next unless f.exist?
237
+ f.open('r').each_line do |l|
238
+ if l =~ /define.*'VERSION'.*'(.+)'/
239
+ v = $1
240
+ debug "Drupal version detected: #{v}"
241
+ core = v.match(/^(\d+)\./)[1].to_i
242
+ @drupal_project = Drupid::Project.new('drupal', core, v)
243
+ @drupal_project.local_path = self.local_path
244
+ debug "Drupal platform has version: #{@drupal_project.version} (core: #{@drupal_project.version.core})"
245
+ return true
246
+ end
247
+ end
248
+ end
249
+ debug "Unable to detect version of Drupal at #{self.local_path}"
250
+ return false
251
+ end
252
+
233
253
  end # Platform
234
254
  end # Drupid
@@ -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
@@ -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,6 +19,8 @@
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 'nokogiri'
23
+ require 'open-uri'
22
24
 
23
25
  module Drupid
24
26
 
@@ -272,6 +274,7 @@ module Drupid
272
274
  @version = vers ? Version.from_s(@core.to_s + '-' + vers) : nil
273
275
  @proj_type = ('drupal' == @name) ? 'drupal' : nil
274
276
  @info_file = nil
277
+ @release_xml = nil
275
278
  end
276
279
 
277
280
  # Returns true if a version is specified for this project, false otherwise.
@@ -289,6 +292,7 @@ module Drupid
289
292
  # The argument must be a String object or a Drupid::Version object.
290
293
  # For the syntax of the String argument, see Drupid::Version.
291
294
  def version=(new_version)
295
+ return @version = nil if new_version.nil?
292
296
  if new_version.is_a?(Version)
293
297
  temp_version = new_version
294
298
  elsif new_version.is_a?(String)
@@ -297,24 +301,65 @@ module Drupid
297
301
  else
298
302
  raise NotDrupalVersionError
299
303
  end
300
- raise NotDrupalVersionError, "Incompatible version for project #{extended_name}: #{temp_version.long}" if temp_version.core != core
304
+ raise NotDrupalVersionError, "Incompatible version for project #{self.extended_name}: #{temp_version.long}" if temp_version.core != self.core
301
305
  @version = temp_version
302
306
  end
303
307
 
304
- # Updates the version of this project to the latest recommended release;
305
- # if no recommended release is available, tries to retrieve the version
306
- # of the latest supported release; if no supported release is found, the version
307
- # of this project is not modified.
308
- # Raises an error if no release history for the project is found (presumably
309
- # because no such project exists on drupal.org).
308
+ # Updates the version of this project to the latest (stable) release.
310
309
  #
311
- # *Requires:* a network connection.
310
+ # Retrieves the release information for this project from http://updates.drupal.org.
311
+ #
312
+ # See also: Drupid::Project.best_release
312
313
  def update_version
313
- v = recommended_release
314
- v = supported_release unless v
315
- if v
316
- self.version = core.to_s + '-' + v
317
- debug "Version updated: #{extended_name}"
314
+ self.fetch_release_history if @release_xml.nil?
315
+ return self.version unless @release_xml
316
+ version_list = []
317
+ version_nodes = @release_xml.xpath("/project/releases/release[status='published']/version")
318
+ version_nodes.each do |n|
319
+ v = n.child.to_s
320
+ # Remove version specifications that do not start with self.core.
321
+ # This seemingly superfluous test is needed because, for example,
322
+ # imce-7.x has a 'master' version (oh my!).
323
+ next if v !~ /^#{self.core.to_i}\./
324
+ v.sub!("#{self.core}-", '') unless self.drupal?
325
+ version_list.push(Version.new(self.core, v))
326
+ end
327
+ self.version = self.best_release(version_list)
328
+ debug "Version updated: #{extended_name}"
329
+ end
330
+
331
+ # Updates the download URL for the current version of this project.
332
+ #
333
+ # Retrieves the release information for this project from http://updates.drupal.org.
334
+ def update_download_url
335
+ self.fetch_release_history if @release_xml.nil?
336
+ return if @release_xml.nil?
337
+ if @release_xml.at_xpath('/project/releases/release/files/file/variant').nil?
338
+ variant = ''
339
+ else
340
+ variant = "[variant='profile-only']"
341
+ end
342
+ v = self.drupal? ? self.version.short : self.version.long
343
+ url_node = @release_xml.at_xpath("/project/releases/release[status='published'][version='#{v}']/files/file#{variant}/url")
344
+ if url_node.nil?
345
+ owarn "Could not get download URL from http://updates.drupal.org for #{extended_name}"
346
+ else
347
+ self.download_url = url_node.child.to_s
348
+ end
349
+ end
350
+
351
+ # Fetches the release history for this project from http://updates.drupal.org.
352
+ def fetch_release_history
353
+ begin
354
+ debug "Getting release history from http://updates.drupal.org/release-history/#{self.name}/#{self.core}"
355
+ dont_debug do
356
+ @release_xml = Nokogiri::XML(open("http://updates.drupal.org/release-history/#{self.name}/#{self.core}"))
357
+ end
358
+ debug "Release history retrieved"
359
+ rescue Exception
360
+ owarn "Could not get release history for #{self.extended_name}"
361
+ blah e
362
+ @release_xml = nil
318
363
  end
319
364
  end
320
365
 
@@ -437,39 +482,33 @@ module Drupid
437
482
  end
438
483
 
439
484
  def fetch
440
- # Try to get the latest version if:
441
- # (1) the project is not local;
442
- # (2) it does not have a version already;
443
- # (3) no download type has been explicitly given.
444
- unless has_version? or download_url =~ /file:\/\// or download_type
445
- update_version
485
+ if self.version.nil? and download_url.nil? and download_type.nil?
486
+ debug "Updating version of #{self.extended_name}"
487
+ self.update_version
446
488
  end
447
489
  # If the project has no version we fetch it even if it is cached.
448
490
  # If the project has a download type, we fetch it even if it is cached
449
491
  # (say the download type is 'git' and the revision is changed in the
450
492
  # makefile, then the cached project must be updated accordingly).
451
- if has_version? and !download_type and cached_location.exist?
452
- @local_path = cached_location
453
- debug "#{extended_name} is cached"
493
+ if self.has_version? and self.download_type.nil? and self.cached_location.exist?
494
+ @local_path = self.cached_location
495
+ debug "#{self.extended_name} is cached"
454
496
  else
455
- blah "Fetching #{extended_name}"
456
- if download_type
457
- if download_url
458
- src = download_url
459
- elsif 'git' == download_type # Download from git.drupal.org
460
- src = "http://git.drupal.org/project/#{name}.git"
461
- else
462
- raise "No download URL specified for #{extended_name}" unless download_url
463
- end
464
- else
465
- src = extended_name
497
+ blah "Fetching #{self.extended_name}"
498
+ if 'git' == self.download_type and self.download_url.nil?
499
+ self.download_url = "http://git.drupal.org/project/#{name}.git"
466
500
  end
467
- downloader = Drupid.makeDownloader src, cached_location.dirname.to_s, cached_location.basename.to_s, download_specs.merge({:type => download_type})
501
+ self.update_download_url if self.download_url.nil?
502
+ raise "No download URL specified for #{self.extended_name}" unless self.download_url
503
+ downloader = Drupid.makeDownloader self.download_url.to_s,
504
+ self.cached_location.dirname.to_s,
505
+ self.cached_location.basename.to_s,
506
+ self.download_specs.merge({:type => download_type})
468
507
  downloader.fetch
469
508
  downloader.stage
470
509
  @local_path = downloader.staged_path
471
510
  end
472
- reload_project_info unless drupal?
511
+ self.reload_project_info unless self.drupal?
473
512
  end
474
513
 
475
514
  # Returns the relative path where this project should be installed
@@ -529,34 +568,20 @@ module Drupid
529
568
  super(tgt, args)
530
569
  end
531
570
 
532
- # Returns the version of the latest recommended release of this project
533
- # as a string, or nil if no recommended release can be found
534
- # or the project does not exist at drupal.org.
535
- #
536
- # *Requires:* a network connection.
537
- #
538
- # See also: Drupid::Drush.pm_releases, Drupid::Project.supported_release
539
- def recommended_release
540
- output = Drush.pm_releases(name + '-' + core.to_s)
541
- return unless output =~ /RELEASES FOR/
542
- rl = Drush.recommended_release(output)
543
- return rl.sub(/^#{core}-/, '') if rl
544
- return nil
545
- end
546
571
 
547
- # Returns the version of the latest supported release
548
- # as a string, or nil if no supported release can be found
549
- # or the project does not exist at drupal.org.
550
- #
551
- # *Requires:* a network connection.
552
- #
553
- # See also: Drupid::Drush.pm_releases, Drupid::Project.recommended_release
554
- def supported_release
555
- output = Drush.pm_releases(name + '-' + core.to_s)
556
- return nil unless output =~ /RELEASES FOR/
557
- rl = Drush.supported_release(output)
558
- return rl.sub(/^#{core}-/, '') if rl
559
- return nil
572
+ # Returns the "best" version among those in the given list.
573
+ # Returns the current version of the project when version_list is empty.
574
+ def best_release version_list
575
+ if self.has_version? # Exclude releases older than the current one
576
+ version_list = version_list.select { |v| v >= self.version }
577
+ end
578
+ return self.version if version_list.empty?
579
+ stable_releases = version_list.select { |v| v.stable? }
580
+ if stable_releases.empty?
581
+ version_list.max { |a,b| a.better b }
582
+ else
583
+ stable_releases.max { |a,b| a.better b }
584
+ end
560
585
  end
561
586
 
562
587
  end # Project
@@ -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
@@ -36,11 +36,12 @@ module Drupid
36
36
 
37
37
  # Creates a new updater for a given makefile and a given platform.
38
38
  # For multisite platforms, optionally specify a site to synchronize.
39
- def initialize(makefile, platform, site_name = nil)
39
+ def initialize(makefile, platform, options = { :site => nil, :force => false })
40
40
  @makefile = makefile
41
41
  @platform = platform
42
- @site = site_name
42
+ @site = options[:site]
43
43
  @log = Log.new
44
+ @force_changes = options[:force]
44
45
  #
45
46
  @libraries_paths = Array.new
46
47
  @core_projects = Array.new
@@ -210,10 +211,20 @@ module Drupid
210
211
  pending_delete = @platform.project_names - processed
211
212
  pending_delete.each do |p|
212
213
  proj = platform.get_project(p)
213
- if proj.installed?(site)
214
- log.error "#{proj.extended_name} cannot be deleted because it is installed"
215
- end
216
214
  log.action(DeleteAction.new(platform, proj))
215
+ if which('drush').nil?
216
+ if @force_changes
217
+ owarn "Forcing deletion."
218
+ else
219
+ log.error "#{proj.extended_name}: use --force to force deletion or install Drush >=6.0."
220
+ end
221
+ elsif proj.installed?(site)
222
+ if @force_changes
223
+ owarn "Deleting an installed/enabled project."
224
+ else
225
+ log.error "#{proj.extended_name} cannot be deleted because it is installed"
226
+ end
227
+ end
217
228
  end
218
229
  end
219
230
 
@@ -243,26 +254,35 @@ module Drupid
243
254
  if @platform.local_path + new_path != platform_project.local_path
244
255
  log.action(MoveAction.new(@platform, platform_project, new_path))
245
256
  if (@platform.local_path + new_path).exist?
246
- log.error("#{new_path} already exists. Use --force to overwrite.")
257
+ if @force_changes
258
+ owarn "Overwriting existing path: #{new_path}"
259
+ else
260
+ log.error("#{new_path} already exists. Use --force to overwrite.")
261
+ end
247
262
  end
248
263
  end
249
264
  # Compare versions and log suitable actions
250
265
  _compare_versions project, platform_project
251
-
252
- # If analyzing the platform does not detect the project (e.g., Fusion),
253
- # we try to see if the directory exists where it is supposed to be.
254
- elsif (@platform.local_path + @platform.dest_path(project)).exist?
255
- begin
256
- platform_project = PlatformProject.new(@platform, @platform.local_path + @platform.dest_path(project))
257
- rescue => ex
258
- log.error("#{platform_project.relative_path} exists, but cannot be analyzed: #{ex}")
259
- log.action(UpdateProjectAction.new(@platform, project))
266
+ else
267
+ # If analyzing the platform does not allow us to detect the project (e.g., Fusion),
268
+ # we try to see if the directory exists where it is supposed to be.
269
+ proj_path = @platform.local_path + @platform.dest_path(project)
270
+ if proj_path.exist?
271
+ begin
272
+ platform_project = PlatformProject.new(@platform, proj_path)
273
+ _compare_versions project, platform_project
274
+ rescue => ex
275
+ log.action(UpdateProjectAction.new(@platform, project))
276
+ if @force_changes
277
+ owarn "Overwriting existing path: #{proj_path}"
278
+ else
279
+ log.error("#{proj_path} exists, but was not recognized as a project (use --force to overwrite it): #{ex}")
280
+ end
281
+ end
282
+ else # new project
283
+ log.action(InstallProjectAction.new(@platform, project))
260
284
  end
261
- _compare_versions project, platform_project
262
- else # new project
263
- log.action(InstallProjectAction.new(@platform, project))
264
285
  end
265
-
266
286
  return (not has_makefile)
267
287
  end
268
288
 
@@ -308,7 +328,7 @@ module Drupid
308
328
  odie "Failed to verify the integrity of library #{lib.extended_name}: #{ex}"
309
329
  end
310
330
  if diff.empty?
311
- log.notice("[OK] #{lib.extended_name} (#{relpath})")
331
+ log.notice("#{Tty.white}[OK]#{Tty.reset} #{lib.extended_name} (#{relpath})")
312
332
  else
313
333
  log.action(UpdateLibraryAction.new(platform, lib))
314
334
  log.notice(diff.join("\n"))
@@ -337,6 +357,29 @@ module Drupid
337
357
  @derivative_builds.clear
338
358
  end
339
359
 
360
+ # Updates Drupal's database using <tt>drush updatedb</tt>.
361
+ # If #site is defined, then updates only the specified site; otherwise,
362
+ # iterates over all Platform#site_names and updates each one in turn.
363
+ #
364
+ # Returns true upon success, false otherwise.
365
+ def updatedb
366
+ ohai "Updating Drupal database..."
367
+ blah "Platform: #{self.platform.local_path}"
368
+ res = true
369
+ site_list = (self.site) ? [self.site] : self.platform.site_names
370
+ site_list.each do |s|
371
+ site_path = self.platform.sites_path + s
372
+ debug "Site path: #{site_path}"
373
+ unless site_path.exist?
374
+ debug "Skipping #{site_path} because it does not exist."
375
+ next
376
+ end
377
+ blah "Updating site: #{s}"
378
+ res = Drush.updatedb(site_path) && res
379
+ end
380
+ return res
381
+ end
382
+
340
383
  private
341
384
 
342
385
  # Returns true if the given component is successfully cached and patched;
@@ -372,25 +415,43 @@ module Drupid
372
415
  end
373
416
  p = (makefile_project.drupal?) ? '' : ' (' + (platform.contrib_path + makefile_project.target_path).to_s + ')'
374
417
  if diff.empty?
375
- @log.notice("[OK] #{platform_project.extended_name}#{p}")
418
+ @log.notice("#{Tty.white}[OK]#{Tty.reset} #{platform_project.extended_name}#{p}")
376
419
  elsif makefile_project.has_patches?
377
420
  log.action(update_action)
378
421
  log.notice "#{makefile_project.extended_name}#{p} will be patched"
379
422
  log.notice(diff.join("\n"))
380
423
  else
381
- log.error("#{platform_project.extended_name}#{p}: mismatch with cached copy:\n" + diff.join("\n"))
382
424
  log.action(update_action)
425
+ if @force_changes
426
+ owarn "Mismatch with cached copy: overwriting local copy."
427
+ else
428
+ log.error("#{platform_project.extended_name}#{p}: mismatch with cached copy:\n" + diff.join("\n"))
429
+ end
383
430
  end
384
431
  when 1 # upgrade
385
432
  log.action(update_action)
386
433
  when -1 # downgrade
387
- log.action(update_action)
388
- if platform_project.drupal?
434
+ log.action(UpdateProjectAction.new(platform, makefile_project, :downgrade => true))
435
+ if which('drush').nil?
436
+ if @force_changes
437
+ owarn "Forcing downgrade."
438
+ else
439
+ log.error("#{platform_project.extended_name}: use --force to downgrade or install Drush >=6.0.")
440
+ end
441
+ elsif platform_project.drupal?
389
442
  if @platform.bootstrapped?
390
- log.error("#{platform_project.extended_name} cannot be downgraded because it is bootstrapped")
443
+ if @force_changes
444
+ owarn "Downgrading a bootstrapped Drupal platform."
445
+ else
446
+ log.error("#{platform_project.extended_name} cannot be downgraded because it is bootstrapped (use --force to override)")
447
+ end
391
448
  end
392
449
  elsif platform_project.installed?(site)
393
- log.error("#{platform_project.extended_name}#{p} must be uninstalled before downgrading")
450
+ if @force_changes
451
+ owarn "Downgrading an installed/enabled project."
452
+ else
453
+ log.error("#{platform_project.extended_name}#{p} must be uninstalled before downgrading (use --force to override)")
454
+ end
394
455
  end
395
456
  when nil # One or both projects have no version
396
457
  # Check whether the content of the projects is consistent
@@ -400,12 +461,16 @@ module Drupid
400
461
  odie "Failed to verify the integrity of #{component.extended_name}: #{ex}"
401
462
  end
402
463
  if diff.empty?
403
- log.notice("[OK] #{platform_project.extended_name}#{p}")
464
+ log.notice("#{Tty.white}[OK]#{Tty.reset} #{platform_project.extended_name}#{p}")
404
465
  else
405
466
  log.action(update_action)
406
467
  log.notice(diff.join("\n"))
407
468
  if platform_project.has_version? and (not makefile_project.has_version?)
408
- log.error("Cannot upgrade #{makefile_project.name} from known version to unknown version")
469
+ if @force_changes
470
+ owarn "Upgrading #{makefile_project.name} to unknown version."
471
+ else
472
+ log.error("Cannot upgrade #{makefile_project.name} from known version to unknown version")
473
+ end
409
474
  end
410
475
  end
411
476
  end
@@ -453,7 +518,7 @@ module Drupid
453
518
  # Adds an error message to the log.
454
519
  def error(msg)
455
520
  @errors << msg
456
- puts @errors.last
521
+ ofail @errors.last
457
522
  end
458
523
 
459
524
  # Returns true if this log contains error messages;
@@ -465,7 +530,7 @@ module Drupid
465
530
  # Adds a warning to the log.
466
531
  def warning(msg)
467
532
  @warnings << msg
468
- puts @warnings.last
533
+ owarn @warnings.last
469
534
  end
470
535
 
471
536
  def warnings?
@@ -523,17 +588,19 @@ module Drupid
523
588
 
524
589
 
525
590
  class UpdateProjectAction < AbstractAction
526
- def initialize(p, proj)
591
+ def initialize p, proj, opts = { :downgrade => false }
527
592
  raise "#{proj.extended_name} does not exist locally" unless proj.exist?
528
593
  raise "Unknown type for #{proj.extended_name}" unless proj.proj_type
529
- super
594
+ @downgrade = opts[:downgrade]
595
+ super(p, proj)
530
596
  end
531
597
 
532
598
  def msg
599
+ label = 'Update'
533
600
  if old_project = platform.get_project(component.name)
534
- "#{Tty.blue}[Update]#{Tty.white} #{old_project.extended_name} => #{component.extended_name}#{Tty.reset} (#{platform.dest_path(component)})"
601
+ "#{Tty.blue}[#{label}]#{Tty.white} #{component.name}: #{old_project.version.long} => #{component.version.long}#{Tty.reset} (#{platform.dest_path(component)})"
535
602
  else
536
- "#{Tty.blue}[Update]#{Tty.white} #{component.extended_name}#{Tty.reset} (#{platform.dest_path(component)})"
603
+ "#{Tty.blue}[#{label}]#{Tty.white} #{component.name}: => #{component.version.long}#{Tty.reset} (#{platform.dest_path(component)})"
537
604
  end
538
605
  end
539
606
 
@@ -572,8 +639,7 @@ module Drupid
572
639
  args << '--delete'
573
640
  component.ignore_paths.each { |p| args << "--exclude=#{p}" }
574
641
  dst_path = platform.local_path + platform.dest_path(component)
575
- debug "Pathname.mkpath may raise harmless exceptions"
576
- dst_path.mkpath unless dst_path.exist?
642
+ dont_debug { dst_path.mkpath }
577
643
  args << component.local_path.to_s + '/'
578
644
  args << dst_path.to_s + '/'
579
645
  begin
@@ -616,8 +682,7 @@ module Drupid
616
682
  args << '--delete'
617
683
  component.ignore_paths.each { |p| args << "--exclude=#{p}" }
618
684
  dst_path = platform.local_path + platform.contrib_path + component.target_path
619
- debug "Pathname.mkpath may raise harmless exceptions"
620
- dst_path.mkpath unless dst_path.exist?
685
+ dont_debug { dst_path.mkpath }
621
686
  args << component.local_path.to_s + '/'
622
687
  args << dst_path.to_s + '/'
623
688
  begin
@@ -631,7 +696,7 @@ module Drupid
631
696
 
632
697
  class InstallLibraryAction < UpdateLibraryAction
633
698
  def msg
634
- "#{Tty.blue}[Install]#{Tty.white} Library #{component.extended_name}#{Tty.reset} (#{platform.contrib_path + component.target_path})"
699
+ "#{Tty.blue}[Install]#{Tty.white} Library #{component.extended_name}#{Tty.reset} (#{platform.contrib_path + component.target_path})"
635
700
  end
636
701
  end
637
702
 
@@ -648,10 +713,10 @@ module Drupid
648
713
  debug "Moving #{component.local_path} to #{dst}"
649
714
  if dst.exist?
650
715
  debug "#{dst} already exists, it will be deleted"
651
- dst.rmtree
716
+ dont_debug { dst.rmtree }
652
717
  end
653
- dst.parent.mkpath
654
- FileUtils.mv component.local_path.to_s, dst.to_s
718
+ dont_debug { dst.parent.mkpath }
719
+ dont_debug { FileUtils.mv component.local_path.to_s, dst.to_s }
655
720
  else
656
721
  blah "Cannot move #{component.local_path.relative_path_from(platform.local_path)}\n" +
657
722
  "(It does not exist any longer)"
@@ -661,14 +726,15 @@ module Drupid
661
726
 
662
727
  def msg
663
728
  src = component.local_path.relative_path_from(platform.local_path)
664
- "#{Tty.blue}[Move]#{Tty.reset} From #{src} to #{@destination}"
729
+ "#{Tty.blue}[Move]#{Tty.white} #{component.extended_name}:#{Tty.reset} #{src} => #{@destination}"
665
730
  end
666
731
  end # MoveAction
667
732
 
668
733
 
669
734
  class DeleteAction < AbstractAction
670
735
  def fire!
671
- component.local_path.rmtree if component.local_path.exist?
736
+ debug "Deleting #{component.local_path}"
737
+ dont_debug { component.local_path.rmtree if component.local_path.exist? }
672
738
  @pending = false
673
739
  end
674
740