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.
- checksums.yaml +7 -0
- data/bin/drupid +24 -6
- data/lib/drupid.rb +2 -2
- data/lib/drupid/component.rb +8 -5
- data/lib/drupid/download_strategy.rb +26 -42
- data/lib/drupid/drush.rb +28 -136
- data/lib/drupid/extend/pathname.rb +3 -1
- data/lib/drupid/library.rb +3 -2
- data/lib/drupid/makefile.rb +1 -1
- data/lib/drupid/patch.rb +2 -1
- data/lib/drupid/platform.rb +30 -10
- data/lib/drupid/platform_project.rb +1 -1
- data/lib/drupid/project.rb +88 -63
- data/lib/drupid/updater.rb +111 -45
- data/lib/drupid/utils.rb +18 -9
- data/lib/drupid/version.rb +49 -3
- metadata +12 -15
data/lib/drupid/library.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/drupid/makefile.rb
CHANGED
data/lib/drupid/patch.rb
CHANGED
@@ -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
|
data/lib/drupid/platform.rb
CHANGED
@@ -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 #
|
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 #
|
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
|
-
|
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
|
data/lib/drupid/project.rb
CHANGED
@@ -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
|
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
|
-
#
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
441
|
-
|
442
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
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
|
data/lib/drupid/updater.rb
CHANGED
@@ -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,
|
39
|
+
def initialize(makefile, platform, options = { :site => nil, :force => false })
|
40
40
|
@makefile = makefile
|
41
41
|
@platform = platform
|
42
|
-
@site =
|
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
|
-
|
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
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
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]
|
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]
|
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(
|
388
|
-
if
|
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
|
-
|
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
|
-
|
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]
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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}[
|
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}[
|
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
|
-
|
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
|
-
|
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}
|
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}
|
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
|
-
|
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
|
|