drupid 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/drupid +270 -0
- data/lib/drupid/component.rb +236 -0
- data/lib/drupid/download_strategy.rb +585 -0
- data/lib/drupid/drush.rb +185 -0
- data/lib/drupid/extend/pathname.rb +114 -0
- data/lib/drupid/library.rb +52 -0
- data/lib/drupid/makefile.rb +423 -0
- data/lib/drupid/patch.rb +92 -0
- data/lib/drupid/platform.rb +234 -0
- data/lib/drupid/platform_project.rb +91 -0
- data/lib/drupid/project.rb +563 -0
- data/lib/drupid/updater.rb +683 -0
- data/lib/drupid/utils.rb +301 -0
- data/lib/drupid/version.rb +230 -0
- data/lib/drupid.rb +56 -0
- metadata +76 -0
data/lib/drupid/utils.rb
ADDED
@@ -0,0 +1,301 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2012 Lifepillar
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
# Portions Copyright 2009-2011 Max Howell and other contributors.
|
24
|
+
#
|
25
|
+
# Redistribution and use in source and binary forms, with or without
|
26
|
+
# modification, are permitted provided that the following conditions
|
27
|
+
# are met:
|
28
|
+
#
|
29
|
+
# 1. Redistributions of source code must retain the above copyright
|
30
|
+
# notice, this list of conditions and the following disclaimer.
|
31
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
32
|
+
# notice, this list of conditions and the following disclaimer in the
|
33
|
+
# documentation and/or other materials provided with the distribution.
|
34
|
+
#
|
35
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
36
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
37
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
38
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
39
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
40
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
41
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
42
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
43
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
44
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
45
|
+
|
46
|
+
require 'shellwords'
|
47
|
+
|
48
|
+
# Common methods, borrowed from Homebrew, which can be mixed-in by a class.
|
49
|
+
module Drupid
|
50
|
+
module Utils
|
51
|
+
|
52
|
+
class ErrorDuringExecution < RuntimeError
|
53
|
+
end
|
54
|
+
|
55
|
+
class NotAnArchiveError < RuntimeError
|
56
|
+
end
|
57
|
+
|
58
|
+
class Tty
|
59
|
+
class <<self
|
60
|
+
def blue; bold 34; end
|
61
|
+
def white; bold 39; end
|
62
|
+
def red; underline 31; end
|
63
|
+
def yellow; bold 33; end
|
64
|
+
def purple; bold 35; end
|
65
|
+
def reset; escape 0; end
|
66
|
+
def em; underline 39; end
|
67
|
+
def green; color 92; end
|
68
|
+
|
69
|
+
private
|
70
|
+
def color n
|
71
|
+
escape "0;#{n}"
|
72
|
+
end
|
73
|
+
def bold n
|
74
|
+
escape "1;#{n}"
|
75
|
+
end
|
76
|
+
def underline n
|
77
|
+
escape "4;#{n}"
|
78
|
+
end
|
79
|
+
def escape n
|
80
|
+
"\033[#{n}m" if $stdout.tty?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Prints a message.
|
86
|
+
def ohai title, *sput
|
87
|
+
puts "#{Tty.green}==>#{Tty.white} #{title}#{Tty.reset}"
|
88
|
+
puts sput unless sput.empty?
|
89
|
+
end
|
90
|
+
|
91
|
+
# Print a warning message.
|
92
|
+
def owarn warning
|
93
|
+
puts "#{Tty.red}Warning#{Tty.reset}: #{warning}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# Prints an error message.
|
97
|
+
def ofail error, *info
|
98
|
+
puts "#{Tty.red}Error#{Tty.reset}: #{error}"
|
99
|
+
puts info unless info.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
# Prints an error message and exits.
|
103
|
+
def odie error
|
104
|
+
ofail error
|
105
|
+
exit 1
|
106
|
+
end
|
107
|
+
|
108
|
+
# Prints debug information.
|
109
|
+
def debug title, *info
|
110
|
+
return unless $DEBUG
|
111
|
+
puts "#{Tty.purple}[DEBUG]#{Tty.white} #{title}#{Tty.reset}"
|
112
|
+
info.each do |chunk|
|
113
|
+
chunk.each_line do |l|
|
114
|
+
puts "#{Tty.purple}[DEBUG]#{Tty.reset} #{l.chomp!}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Prints a notice if in verbose mode.
|
120
|
+
def blah notice
|
121
|
+
return unless $VERBOSE
|
122
|
+
puts notice.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
# Executes a command. Returns the output of the command.
|
126
|
+
# Raises a Drupid::ErrorDuringExecution error if the command does not
|
127
|
+
# exit successfully.
|
128
|
+
#
|
129
|
+
# [command] A String or Pathname object
|
130
|
+
# [arguments] An optional Array of arguments
|
131
|
+
# [options] An optional Hash of options
|
132
|
+
#
|
133
|
+
# Options: out, err, redirect_stderr_to_stdout, dry
|
134
|
+
def runBabyRun command, arguments = [], options = {}
|
135
|
+
opts = { :dry => false }.merge!(options)
|
136
|
+
cmd = String.new(command.to_s)
|
137
|
+
raise "Not an array" unless arguments.is_a?(Array)
|
138
|
+
args = arguments.map { |arg| arg.to_s }
|
139
|
+
cmd << ' ' + args.shelljoin
|
140
|
+
cmd << ' >' + Shellwords.shellescape(opts[:out]) if opts[:out]
|
141
|
+
cmd << ' 2>' + Shellwords.shellescape(opts[:err]) if opts[:err]
|
142
|
+
cmd << ' 2>&1' if opts[:redirect_stderr_to_stdout]
|
143
|
+
debug cmd
|
144
|
+
return cmd if opts[:dry]
|
145
|
+
output = %x|#{cmd}| # Run baby run!
|
146
|
+
unless $?.success?
|
147
|
+
debug 'Command failed', output
|
148
|
+
raise ErrorDuringExecution, output
|
149
|
+
end
|
150
|
+
return output
|
151
|
+
end
|
152
|
+
|
153
|
+
def curl *args
|
154
|
+
curl = Pathname.new(which 'curl')
|
155
|
+
raise "curl not found" unless curl.exist?
|
156
|
+
raise "curl is not executable" unless curl.executable?
|
157
|
+
|
158
|
+
args = ['-qf#LA', DRUPID_USER_AGENT, *args]
|
159
|
+
args << "--insecure" #if MacOS.version < 10.6
|
160
|
+
args << "--silent" unless $VERBOSE
|
161
|
+
|
162
|
+
runBabyRun curl, args
|
163
|
+
end
|
164
|
+
|
165
|
+
def git *args
|
166
|
+
git = Pathname.new(which 'git')
|
167
|
+
raise "git not found" unless git.exist?
|
168
|
+
raise "git is not executable" unless git.executable?
|
169
|
+
runBabyRun git, args, :redirect_stderr_to_stdout => true
|
170
|
+
end
|
171
|
+
|
172
|
+
def svn *args
|
173
|
+
svn = Pathname.new(which 'svn')
|
174
|
+
raise "svn not found" unless svn.exist?
|
175
|
+
raise "svn is not executable" unless svn.executable?
|
176
|
+
runBabyRun svn, args, :redirect_stderr_to_stdout => true
|
177
|
+
end
|
178
|
+
|
179
|
+
def cvs *args
|
180
|
+
cvs = Pathname.new(which 'cvs')
|
181
|
+
raise "cvs not found" unless cvs.exist?
|
182
|
+
raise "cvs is not executable" unless cvs.executable?
|
183
|
+
runBabyRun cvs, args, :redirect_stderr_to_stdout => true
|
184
|
+
end
|
185
|
+
|
186
|
+
def hg *args
|
187
|
+
hg = Pathname.new(which 'hg')
|
188
|
+
raise "hg not found" unless hg.exist?
|
189
|
+
raise "hg is not executable" unless hg.executable?
|
190
|
+
runBabyRun hg, args, :redirect_stderr_to_stdout => true
|
191
|
+
end
|
192
|
+
|
193
|
+
def bzr *args
|
194
|
+
bzr = Pathname.new(which 'bzr')
|
195
|
+
raise "bzr not found" unless bzr.exist?
|
196
|
+
raise "bzr is not executable" unless bzr.executable?
|
197
|
+
runBabyRun bzr, args, :redirect_stderr_to_stdout => true
|
198
|
+
end
|
199
|
+
|
200
|
+
# Uncompresses an archive in the current directory.
|
201
|
+
# [archive] A Pathname object representing the full path to the archive.
|
202
|
+
# The the :type options is used, the archive is interpreted as the given
|
203
|
+
# type (:zip, :gzip, :bzip2, :compress, :tar, :xz, :rar), otherwise
|
204
|
+
# the type is guessed based on the file content.
|
205
|
+
#
|
206
|
+
# Options: type
|
207
|
+
def uncompress archive, options = {}
|
208
|
+
type = options[:type] ? options[:type] : archive.compression_type
|
209
|
+
case type
|
210
|
+
when :zip
|
211
|
+
runBabyRun 'unzip', ['-qq', archive]
|
212
|
+
when :gzip, :bzip2, :compress, :tar
|
213
|
+
# Assume these are also tarred
|
214
|
+
# TODO check if it's really a tar archive
|
215
|
+
runBabyRun 'tar', ['xf', archive]
|
216
|
+
when :xz
|
217
|
+
runBabyRun "xz -dc \"#{archive}\" | tar xf -"
|
218
|
+
when :rar
|
219
|
+
runBabyRun 'unrar', ['x', '-inul', archive]
|
220
|
+
else
|
221
|
+
raise NotAnArchiveError
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Creates a temporary directory then yield. When the block returns,
|
226
|
+
# recursively delete the temporary directory.
|
227
|
+
def tempdir
|
228
|
+
# I used /tmp rather than `mktemp -td` because that generates a directory
|
229
|
+
# name with exotic characters like + in it, and these break badly written
|
230
|
+
# scripts that don't escape strings before trying to regexp them :(
|
231
|
+
|
232
|
+
# If the user has FileVault enabled, then we can't mv symlinks from the
|
233
|
+
# /tmp volume to the other volume. So we let the user override the tmp
|
234
|
+
# prefix if they need to.
|
235
|
+
tmp_prefix = '/tmp'
|
236
|
+
tmp = Pathname.new `mktemp -d #{tmp_prefix}/temp_item-XXXXXX`.strip
|
237
|
+
raise "Couldn't create temporary directory" if not tmp.directory? or $? != 0
|
238
|
+
begin
|
239
|
+
wd = Dir.pwd
|
240
|
+
FileUtils.chdir tmp
|
241
|
+
yield
|
242
|
+
ensure
|
243
|
+
FileUtils.chdir wd
|
244
|
+
tmp.rmtree
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Compares the content of two directories using rsync.
|
249
|
+
# Changes in timestamps only are ignored.
|
250
|
+
# Returns a possibly empty list of differences.
|
251
|
+
def compare_paths src, tgt, additional_rsync_options = []
|
252
|
+
p1 = Pathname.new(src).realpath.to_s + '/'
|
253
|
+
p2 = Pathname.new(tgt).realpath.to_s + '/'
|
254
|
+
args = Array.new
|
255
|
+
args << '-rlD'
|
256
|
+
args << '--dry-run'
|
257
|
+
args << '--delete'
|
258
|
+
args << '--itemize-changes'
|
259
|
+
args += additional_rsync_options
|
260
|
+
args << p1
|
261
|
+
args << p2
|
262
|
+
output = runBabyRun 'rsync', args, :verbose => false
|
263
|
+
changes = Array.new
|
264
|
+
output.each_line do |l|
|
265
|
+
next if l =~ /[fdLDS]\.\.[tT]\.\.\.\./ # Skip changes in timestamps only
|
266
|
+
changes << l.strip
|
267
|
+
end
|
268
|
+
return changes
|
269
|
+
end
|
270
|
+
|
271
|
+
def which cmd
|
272
|
+
path = `which #{cmd} 2>/dev/null`.chomp
|
273
|
+
path.empty? ? nil : Pathname.new(path)
|
274
|
+
end
|
275
|
+
|
276
|
+
def ignore_interrupts
|
277
|
+
std_trap = trap("INT") {}
|
278
|
+
yield
|
279
|
+
ensure
|
280
|
+
trap("INT", std_trap)
|
281
|
+
end
|
282
|
+
|
283
|
+
def interactive_shell
|
284
|
+
fork {exec ENV['SHELL'] }
|
285
|
+
Process.wait
|
286
|
+
unless $?.success?
|
287
|
+
owarn "Non-zero exit status: #{$?}"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# Creates the specified file with the given content.
|
292
|
+
# The file is overwritten if it exists.
|
293
|
+
def writeFile path, content
|
294
|
+
p = Pathname.new(path)
|
295
|
+
blah "Writing #{p}"
|
296
|
+
p.open("w") { |f| f.write(content) }
|
297
|
+
end
|
298
|
+
|
299
|
+
end # Utils
|
300
|
+
end # Drupid
|
301
|
+
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2012 Lifepillar
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
module Drupid
|
24
|
+
|
25
|
+
class NotDrupalVersionError < RuntimeError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Represents the core attribute of a version object (e.g., '7.x').
|
29
|
+
# A VersionCore object can be initialized from a number, a string,
|
30
|
+
# a Drupid::VersionCore object or a Drupid::Version object.
|
31
|
+
#
|
32
|
+
# Examples:
|
33
|
+
# core = Drupid::VersionCore.new '8.x'
|
34
|
+
# core = Drupid::VersionCore.new '8'
|
35
|
+
# core = Drupid::VersionCore.new '8.x-1.0'
|
36
|
+
# core = Drupid::VersionCore.new 8
|
37
|
+
# core = Drupid::VersionCore.new(Drupid::Version.new(8, '1.0'))
|
38
|
+
class VersionCore
|
39
|
+
include Comparable
|
40
|
+
|
41
|
+
attr :core
|
42
|
+
|
43
|
+
def initialize spec
|
44
|
+
if spec.is_a?(String)
|
45
|
+
spec.strip.match(/^(\d+)(\.x)?($|-)/)
|
46
|
+
raise NotDrupalVersionError, "Wrong core specification: #{core}" unless $1
|
47
|
+
@core = $1.to_i
|
48
|
+
elsif spec.is_a?(Version)
|
49
|
+
@core = spec.core.to_i
|
50
|
+
elsif spec.is_a?(VersionCore)
|
51
|
+
@core = spec.to_i
|
52
|
+
elsif spec.is_a?(Numeric)
|
53
|
+
@core = spec.to_i # to_i truncates a Float object (so that 7.9 correctly becomes 7)
|
54
|
+
else
|
55
|
+
raise NotDrupalVersionError, "Wrong core specification: #{core}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the core number as a string, e.g., '8.x'.
|
60
|
+
def to_s
|
61
|
+
@core.to_s + '.x'
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the core number as a Fixnum object.
|
65
|
+
def to_i
|
66
|
+
@core
|
67
|
+
end
|
68
|
+
|
69
|
+
def <=>(other)
|
70
|
+
@core <=> other.core
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Represents a project's version. A version has the form:
|
75
|
+
# <core>.x-<major>.<patch level>[-<extra>]
|
76
|
+
# Examples of versions include: '7.x-1.0', '7.x-1.2-beta2', '8.x-1.x-dev'.
|
77
|
+
#
|
78
|
+
# See also: http://drupal.org/node/467026
|
79
|
+
class Version
|
80
|
+
include Comparable
|
81
|
+
# The core number, e.g., in 7.x-3.2.beta1, it is 7.
|
82
|
+
attr :core
|
83
|
+
# The major version number, e.g., in 7.x-3.2-beta1, it is 3 (Fixnum).
|
84
|
+
attr :major
|
85
|
+
# The patch level, e.g., in 7.x-3.2-beta1, it is 2 (Fixnum).
|
86
|
+
attr :patchlevel
|
87
|
+
# The project's type, which is one of the constants UNSTABLE,
|
88
|
+
# ALPHA, BETA, RC, DEVELOPMENT, EMPTY or UNKNOWN.
|
89
|
+
# For example, for 7.x-3.2-beta1, it is BETA.
|
90
|
+
attr :extra_type
|
91
|
+
# The numeric part of the extra description, e.g., 7.x-3.2-beta1, it is 1 (Fixnum).
|
92
|
+
attr :extra_num
|
93
|
+
|
94
|
+
UNKNOWN = -1
|
95
|
+
DEVELOPMENT = 1
|
96
|
+
UNSTABLE = 2
|
97
|
+
ALPHA = 4
|
98
|
+
BETA = 8
|
99
|
+
RC = 16
|
100
|
+
EMPTY = 32
|
101
|
+
|
102
|
+
def initialize(core_num, v)
|
103
|
+
raise 'Drupal version is not a string.' unless v.is_a?(String)
|
104
|
+
@core = Drupid::VersionCore.new(core_num)
|
105
|
+
@major = v.match(/^(\d+)/)[1].to_i
|
106
|
+
@patchlevel = $~.post_match.match(/\.(\d+|x)/)[1]
|
107
|
+
@patchlevel = @patchlevel.to_i if 'x' != @patchlevel
|
108
|
+
@extra_string = ''
|
109
|
+
encode_extra($~.post_match) # Initialize @extra_type and @extra_num
|
110
|
+
end
|
111
|
+
|
112
|
+
# Builds a Drupid::Version object from a string, e.g., '8.x-2.0rc1'.
|
113
|
+
def self.from_s v
|
114
|
+
if v.match(/^(\d+)\.x-(\d+.+)$/)
|
115
|
+
Version.new($1.to_i, $2)
|
116
|
+
else
|
117
|
+
raise NotDrupalVersionError, "Cannot build a version from this string: #{v}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns true if this version represents a development snapshot;
|
122
|
+
# returns false otherwise.
|
123
|
+
def development_snapshot?
|
124
|
+
'x' == @patchlevel
|
125
|
+
end
|
126
|
+
|
127
|
+
# A synonym for self.short.
|
128
|
+
def to_s
|
129
|
+
short
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns a short textual representation of this version, e.g., '3.2'.
|
133
|
+
def short
|
134
|
+
xtr = extra()
|
135
|
+
xtr = '-' + xtr if '' != xtr
|
136
|
+
@major.to_s + '.' + @patchlevel.to_s + xtr
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns the full textual representation of this version, e.g., '7.x-3.2'.
|
140
|
+
def long
|
141
|
+
xtr = extra()
|
142
|
+
xtr = '-' + xtr if '' != xtr
|
143
|
+
@core.to_s + '-' + @major.to_s + '.' + @patchlevel.to_s + xtr
|
144
|
+
end
|
145
|
+
|
146
|
+
# In Ruby 1.8.7, some equality tests fail with the following message:
|
147
|
+
# No visible difference.
|
148
|
+
# You should look at your implementation of ==.
|
149
|
+
# if only <=> is defined. This is why we define == explicitly.
|
150
|
+
def ==(other)
|
151
|
+
@core == other.core and
|
152
|
+
@major == other.major and
|
153
|
+
@patchlevel == other.patchlevel and
|
154
|
+
@extra_type == other.extra_type and
|
155
|
+
@extra_num == other.extra_num
|
156
|
+
end
|
157
|
+
|
158
|
+
def <=>(w)
|
159
|
+
c = @core <=> w.core
|
160
|
+
if 0 == c
|
161
|
+
c = @major <=> w.major
|
162
|
+
if 0 == c
|
163
|
+
c = @patchlevel <=> w.patchlevel
|
164
|
+
case c
|
165
|
+
when nil # e.g., 1 vs 'x'
|
166
|
+
c = ('x' == @patchlevel) ? -1 : 1
|
167
|
+
when 0
|
168
|
+
c = @extra_type <=> w.extra_type
|
169
|
+
if 0 == c
|
170
|
+
c = @extra_num <=> w.extra_num
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
c
|
176
|
+
end
|
177
|
+
|
178
|
+
def extra
|
179
|
+
case @extra_type
|
180
|
+
when EMPTY then t = ''
|
181
|
+
when UNSTABLE then t = 'unstable'
|
182
|
+
when ALPHA then t = 'alpha'
|
183
|
+
when BETA then t = 'beta'
|
184
|
+
when RC then t = 'rc'
|
185
|
+
when DEVELOPMENT then t = 'dev'
|
186
|
+
else # unknown
|
187
|
+
t = @extra_string
|
188
|
+
end
|
189
|
+
if UNKNOWN == @extra_num
|
190
|
+
t
|
191
|
+
else
|
192
|
+
t + @extra_num.to_s
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def encode_extra(e)
|
199
|
+
@extra_string = e.start_with?('-') ? e.sub(/-/, '') : e
|
200
|
+
if e.match(/dev(\d*)$/)
|
201
|
+
@patchlevel = 'x'
|
202
|
+
@extra_type = DEVELOPMENT
|
203
|
+
@extra_num = ($~[1] == '') ? UNKNOWN : $~[1].to_i
|
204
|
+
return
|
205
|
+
end
|
206
|
+
e.match(/^-{0,1}([A-z]*)(\d*)$/)
|
207
|
+
if nil != $~
|
208
|
+
t = $~[1]
|
209
|
+
n = $~[2]
|
210
|
+
case t
|
211
|
+
when /^$/ then @extra_type = EMPTY
|
212
|
+
when /dev/ then @extra_type = DEVELOPMENT
|
213
|
+
when /unstable/ then @extra_type = UNSTABLE
|
214
|
+
when /alpha/ then @extra_type = ALPHA
|
215
|
+
when /beta/ then @extra_type = BETA
|
216
|
+
when /rc/ then @extra_type = RC
|
217
|
+
else
|
218
|
+
@extra_type = UNKNOWN
|
219
|
+
end
|
220
|
+
@extra_num = ('' != n) ? n.to_i : UNKNOWN
|
221
|
+
else
|
222
|
+
@extra_type = UNKNOWN
|
223
|
+
@extra_num = UNKNOWN
|
224
|
+
end
|
225
|
+
return
|
226
|
+
end
|
227
|
+
|
228
|
+
end # class Version
|
229
|
+
|
230
|
+
end # Drupid
|
data/lib/drupid.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2012 Lifepillar
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'fileutils'
|
24
|
+
require 'drupid/extend/pathname'
|
25
|
+
|
26
|
+
# To silence (most) warnings from a required file
|
27
|
+
module Kernel
|
28
|
+
def silence_warnings
|
29
|
+
with_warnings(nil) { yield }
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_warnings(flag)
|
33
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
$VERBOSE = old_verbose
|
37
|
+
end
|
38
|
+
end unless Kernel.respond_to? :silence_warnings
|
39
|
+
|
40
|
+
module Drupid
|
41
|
+
DRUPID_VERSION = '1.0.0'
|
42
|
+
DRUPID_USER_AGENT = "Drupid #{DRUPID_VERSION} (Ruby #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}; #{RUBY_PLATFORM})"
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'drupid/utils'
|
46
|
+
require 'drupid/download_strategy'
|
47
|
+
require 'drupid/drush'
|
48
|
+
require 'drupid/patch'
|
49
|
+
require 'drupid/version'
|
50
|
+
require 'drupid/component'
|
51
|
+
require 'drupid/project'
|
52
|
+
require 'drupid/library'
|
53
|
+
require 'drupid/makefile'
|
54
|
+
require 'drupid/platform'
|
55
|
+
require 'drupid/platform_project'
|
56
|
+
require 'drupid/updater'
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: drupid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lifepillar
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rgl
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.4.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.4.0
|
30
|
+
description: Drupid keeps a Drush makefile in sync with a Drupal distribution.
|
31
|
+
email: lifepillar@lifepillar.com
|
32
|
+
executables:
|
33
|
+
- drupid
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/drupid/component.rb
|
38
|
+
- lib/drupid/download_strategy.rb
|
39
|
+
- lib/drupid/drush.rb
|
40
|
+
- lib/drupid/extend/pathname.rb
|
41
|
+
- lib/drupid/library.rb
|
42
|
+
- lib/drupid/makefile.rb
|
43
|
+
- lib/drupid/patch.rb
|
44
|
+
- lib/drupid/platform.rb
|
45
|
+
- lib/drupid/platform_project.rb
|
46
|
+
- lib/drupid/project.rb
|
47
|
+
- lib/drupid/updater.rb
|
48
|
+
- lib/drupid/utils.rb
|
49
|
+
- lib/drupid/version.rb
|
50
|
+
- lib/drupid.rb
|
51
|
+
- bin/drupid
|
52
|
+
homepage: http://lifepillar.com
|
53
|
+
licenses: []
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.8.21
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: The not-so-smart Drupal bundler!
|
76
|
+
test_files: []
|