drupid 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,185 @@
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
+ # A wrapper around drush.
26
+ module Drush extend Drupid::Utils
27
+
28
+ DRUSH = `which drush`.strip
29
+
30
+ def self.drush *args
31
+ runBabyRun DRUSH, args
32
+ end
33
+
34
+ # Executes 'drush core-status' at the given path and
35
+ # returns the output of the command.
36
+ def self.status path, options = {}
37
+ output = nil
38
+ FileUtils.cd(path) do
39
+ output = drush 'core-status', '--pipe'
40
+ end
41
+ output
42
+ end
43
+
44
+ # Executes 'drush pm-releases --all' for the given project and
45
+ # returns the output of the command.
46
+ def self.pm_releases project_name, options = {}
47
+ drush 'pm-releases', '--all', project_name
48
+ end
49
+
50
+ # Parses the output of 'drush pm-releases' and returns
51
+ # the version of the latest recommended release, or nil
52
+ # if no such release exists.
53
+ def self.recommended_release pm_releases_output
54
+ pm_releases_output.each_line do |l|
55
+ return $~[1] if (l.match(/^\s*([^\s]+).*Recommended/))
56
+ end
57
+ nil
58
+ end
59
+
60
+ # Parses the output of 'drush pm-releases' and returns
61
+ # the version of the latest supported release, or nil
62
+ # if no such release exists.
63
+ def self.supported_release pm_releases_output
64
+ pm_releases_output.each_line do |l|
65
+ return $~[1] if (l.match(/^\s*([^\s]+).*Supported/))
66
+ end
67
+ nil
68
+ end
69
+
70
+ # Executes 'drush pm-download <project_name>' and
71
+ # returns the output of the command.
72
+ # If :working_dir is set to an existing directory, move into that directory before
73
+ # executing the command.
74
+ #
75
+ # Options: source, destination, working_dir
76
+ def self.pm_download project_name, options = {}
77
+ args = ['pm-download', '-y']
78
+ args << "--source=#{options[:source]}" if options[:source]
79
+ args << "--destination\=#{options[:destination]}" if options[:destination]
80
+ args << "--variant=profile-only"
81
+ args << "--verbose" if $VERBOSE
82
+ args << project_name
83
+ if options[:working_dir] and File.directory?(options[:working_dir])
84
+ wd = options[:working_dir]
85
+ else
86
+ wd = FileUtils.pwd
87
+ end
88
+ output = nil
89
+ FileUtils.cd(wd) do
90
+ output = runBabyRun DRUSH, args, :redirect_stderr_to_stdout => true
91
+ end
92
+ output
93
+ end
94
+
95
+ # Parses the output of 'drush pm-download' and returns
96
+ # the path to the downloaded project, or nil
97
+ # if the path cannot be determined.
98
+ def self.download_path pm_download_output
99
+ pm_download_output.match(/^\s*Project.+downloaded to *(.\[.+[\n\r])?\s*(.+)\./)
100
+ return File.expand_path($~[2]) if $~
101
+ return nil
102
+ end
103
+
104
+ # Parses the output of 'drush pm-download' and returns
105
+ # the version of the downloaded project, or nil
106
+ # if the version cannot be determined.
107
+ def self.downloaded_version pm_download_output
108
+ pm_download_output.match(/^\s*Project.+\((.+)\) +downloaded +to/)
109
+ return $~[1] if $~
110
+ return nil
111
+ end
112
+
113
+ # Executes 'drush pm-info' at the given path and with an
114
+ # optional list of projects.
115
+ # Returns the output of the command.
116
+ def self.pm_info path, projects = [], options = {}
117
+ output = nil
118
+ args = Array.new
119
+ args << 'pm-info'
120
+ args << projects.join(' ') unless nil != projects and projects.empty?
121
+ FileUtils.cd(path) do
122
+ output = runBabyRun DRUSH, args, :redirect_stderr_to_stdout => true
123
+ end
124
+ output
125
+ end
126
+
127
+ # Returns the version of Drupal (e.g., '7.12')
128
+ # if the given path contains Drupal;
129
+ # returns nil otherwise.
130
+ def self.drupal_version path, options = {}
131
+ st = self.status(path, options)
132
+ return nil unless st.match(/drupal_version=(\d+\.\d+)/)
133
+ return $~[1]
134
+ end
135
+
136
+ # Returns true if a Drupal's site is bootstrapped at the given path;
137
+ # returns false otherwise.
138
+ def self.bootstrapped?(path, options = {})
139
+ st = self.status(path, options)
140
+ st.match(/drupal_bootstrap=Successful/) ? true : false
141
+ end
142
+
143
+ # Returns true if the project at the given path is an enabled theme
144
+ # or an installed (enabled or disabled) module in the given site;
145
+ # returns false otherwise. The project's path must be relative
146
+ # to the Drupal installation (e.g., 'sites/all/modules').
147
+ # Note that the project path is necessary because, in general,
148
+ # there may be several copies of the same modules at different locations
149
+ # within a platform (in 'sites/all', in 'profiles/' and in site-specific locations).
150
+ #
151
+ # Options: verbose
152
+ def self.installed?(site_path, project_name, project_path, options = {})
153
+ st = ''
154
+ begin
155
+ st = self.pm_info(site_path, [project_name], options)
156
+ rescue # site not fully bootstrapped
157
+ return false
158
+ end
159
+ return false unless st.match(/Path +: +#{project_path}/)
160
+ return false unless st.match(/Type +: +([^\s]+)/)
161
+ type = $~[1]
162
+ return false unless st.match(/Status +: +(.+)$/)
163
+ project_status = $~[1]
164
+ ('module' == type and project_status !~ /not installed/) or
165
+ ('theme' == type and project_status =~ /^enabled/)
166
+ end
167
+
168
+ # Executes 'drush make' and returns the output of the command.
169
+ #
170
+ # Options: contrib_path, nocore, dry, verbose
171
+ def self.make(makefile, target, options = {})
172
+ args = Array.new
173
+ args << 'make'
174
+ args << '-y'
175
+ args << '--no-core' if options[:nocore]
176
+ args << "--contrib-destination=#{options[:contrib_path]}" if options[:contrib_path]
177
+ args << "--no-patch-txt"
178
+ args << makefile
179
+ args << target
180
+ drush(*args)
181
+ end
182
+
183
+ end # module Drush
184
+
185
+ end # Drupid
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2012 Lifepillar
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ # Portions Copyright 2009-2011 Max Howell and other contributors.
22
+ #
23
+ # Redistribution and use in source and binary forms, with or without
24
+ # modification, are permitted provided that the following conditions
25
+ # are met:
26
+ #
27
+ # 1. Redistributions of source code must retain the above copyright
28
+ # notice, this list of conditions and the following disclaimer.
29
+ # 2. Redistributions in binary form must reproduce the above copyright
30
+ # notice, this list of conditions and the following disclaimer in the
31
+ # documentation and/or other materials provided with the distribution.
32
+ #
33
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
34
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
36
+ # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
37
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38
+ # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
42
+ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
+
44
+ require 'pathname'
45
+
46
+ # Code borrowed from Homebrew ;)
47
+ class Pathname
48
+ def compression_type
49
+ return nil if self.directory?
50
+ # Don't treat jars or wars as compressed
51
+ return nil if self.extname == '.jar'
52
+ return nil if self.extname == '.war'
53
+
54
+ # OS X installer package
55
+ return :pkg if self.extname == '.pkg'
56
+
57
+ # Get enough of the file to detect common file types
58
+ # POSIX tar magic has a 257 byte offset
59
+ magic_bytes = nil
60
+ File.open(self) { |f| magic_bytes = f.read(262) }
61
+
62
+ # magic numbers stolen from /usr/share/file/magic/
63
+ case magic_bytes
64
+ when /^PK\003\004/ then :zip
65
+ when /^\037\213/ then :gzip
66
+ when /^BZh/ then :bzip2
67
+ when /^\037\235/ then :compress
68
+ when /^.{257}ustar/ then :tar
69
+ when /^\xFD7zXZ\x00/ then :xz
70
+ when /^Rar!/ then :rar
71
+ else
72
+ # Assume it is not an archive
73
+ nil
74
+ end
75
+ end
76
+
77
+ def cd
78
+ Dir.chdir(self) { yield }
79
+ end
80
+
81
+ # Copies a file to another location or
82
+ # the content of a directory into the specified directory.
83
+ def ditto dst
84
+ d = Pathname.new(dst)
85
+ if file?
86
+ FileUtils.cp to_s, d.to_s, :verbose => $DEBUG
87
+ return (d.directory?) ? d+basename : d
88
+ else
89
+ d.mkpath
90
+ FileUtils.cp_r to_s + '/.', d.to_s, :verbose => $DEBUG
91
+ return d
92
+ end
93
+ end
94
+
95
+ # extended to support common double extensions
96
+ alias extname_old extname
97
+ def extname
98
+ /(\.(tar|cpio)\.(gz|bz2|xz|Z))$/.match to_s
99
+ return $1 if $1
100
+ return File.extname(to_s)
101
+ end
102
+
103
+ # Pathname in Ruby 1.8.x does not define #sub_ext.
104
+ unless self.method_defined? :sub_ext
105
+ # Return a pathname which the extension of the basename is substituted by
106
+ # <i>repl</i>.
107
+ #
108
+ # If self has no extension part, <i>repl</i> is appended.
109
+ def sub_ext(repl)
110
+ ext = File.extname(@path)
111
+ self.class.new(@path.chomp(ext) + repl)
112
+ end
113
+ end
114
+ end # Pathname
@@ -0,0 +1,52 @@
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
+ class Library < Component
25
+
26
+ def initialize name
27
+ super
28
+ self.download_type = 'file' # Default download type
29
+ @destination = nil
30
+ end
31
+
32
+ def destination
33
+ return Pathname.new('libraries') unless @destination
34
+ return Pathname.new(@destination)
35
+ end
36
+
37
+ def destination=(d)
38
+ @destination = d
39
+ end
40
+
41
+ # Returns the relative path where this library should be installed
42
+ # within a platform. This is 'libraries/#name' by default.
43
+ def target_path
44
+ return destination + subdir + directory_name
45
+ end
46
+
47
+ def fetch
48
+ cached_location.rmtree if cached_location.exist?
49
+ super
50
+ end
51
+ end # Library
52
+ end # Drupid