drupid 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|