drupal.rb 0.0.12

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.
Files changed (40) hide show
  1. data/History.txt +53 -0
  2. data/Manifest.txt +23 -0
  3. data/README.txt +108 -0
  4. data/Rakefile +21 -0
  5. data/bin/drupal +4 -0
  6. data/drupal.rb.gemspec +59 -0
  7. data/lib/drupal/create_module.rb +276 -0
  8. data/lib/drupal/install.rb +143 -0
  9. data/lib/drupal/templates/5.x/base/info +6 -0
  10. data/lib/drupal/templates/5.x/comments/file +9 -0
  11. data/lib/drupal/templates/5.x/comments/large +6 -0
  12. data/lib/drupal/templates/5.x/hooks/block +44 -0
  13. data/lib/drupal/templates/5.x/hooks/cron +7 -0
  14. data/lib/drupal/templates/5.x/hooks/form_alter +14 -0
  15. data/lib/drupal/templates/5.x/hooks/init +7 -0
  16. data/lib/drupal/templates/5.x/hooks/install +15 -0
  17. data/lib/drupal/templates/5.x/hooks/menu +24 -0
  18. data/lib/drupal/templates/5.x/hooks/perm +7 -0
  19. data/lib/drupal/templates/5.x/txt/changelog +9 -0
  20. data/lib/drupal/templates/5.x/txt/readme +36 -0
  21. data/lib/drupal/templates/6.x/base/info +6 -0
  22. data/lib/drupal/templates/6.x/comments/file +9 -0
  23. data/lib/drupal/templates/6.x/comments/large +6 -0
  24. data/lib/drupal/templates/6.x/hooks/block +45 -0
  25. data/lib/drupal/templates/6.x/hooks/boot +7 -0
  26. data/lib/drupal/templates/6.x/hooks/cron +7 -0
  27. data/lib/drupal/templates/6.x/hooks/form_alter +11 -0
  28. data/lib/drupal/templates/6.x/hooks/init +8 -0
  29. data/lib/drupal/templates/6.x/hooks/menu +17 -0
  30. data/lib/drupal/templates/6.x/hooks/perm +7 -0
  31. data/lib/drupal/templates/6.x/hooks/theme +11 -0
  32. data/lib/drupal/templates/6.x/txt/changelog +9 -0
  33. data/lib/drupal/templates/6.x/txt/readme +36 -0
  34. data/lib/drupal/todo_list.rb +72 -0
  35. data/lib/drupal.rb +156 -0
  36. data/test/test_create_module.rb +1 -0
  37. data/test/test_drupal.rb +6 -0
  38. data/test/test_install.rb +23 -0
  39. data/test/test_todo_list.rb +0 -0
  40. metadata +145 -0
data/History.txt ADDED
@@ -0,0 +1,53 @@
1
+ === 0.0.11 / 2010-02-14
2
+ * Database scaffolding initial. Adds CRUD database includefile and schema in install.
3
+
4
+ === 0.0.8 / 2009-08-06
5
+
6
+ * 1 Internal rewrite, 2 new features, 1 bugfix
7
+ * Added commandline option to allow selection of Drupal version for installation.
8
+
9
+ * Rewrote install system by parsing the drupal release XML rather then scraping HTML.
10
+ * Added defaults.yml config option. When this file is present, we parse the contents and
11
+ present them as defaults in interactive mode. Quicker module-building!
12
+ * If hook "install" was chose, the .install file was not created. Fixed.
13
+
14
+ === 0.0.7 / 2009-05-02
15
+
16
+ * Cleanup and rename to drupal.rb
17
+ * Implemented ability to override global templates in a ~/.drupal.rb directory.
18
+
19
+ === 0.0.6 / 2008-10-16
20
+
21
+ * 1 Minor Feature:
22
+
23
+ * Added hook_install() support
24
+
25
+ === 0.0.5 / 2008-10-06
26
+
27
+ * 1 Minor Fix:
28
+
29
+ * Todo list was not parsing items starting with '@' in @todo
30
+
31
+ === 0.0.4 / 2008-10-03
32
+
33
+ * 1 Major Feature:
34
+
35
+ * Installer allows lists of projects 'err,ac,devel'
36
+
37
+ === 0.0.3 / 2008-10-03
38
+
39
+ * 1 Major Feature:
40
+
41
+ * Installer for Drupal projects
42
+
43
+ === 0.0.2 / 2008-10-02
44
+
45
+ * 2 Bug Fixes:
46
+
47
+ * Executable
48
+ * Fixed template filepath errors
49
+
50
+ === 0.0.1 / 2008-09-27
51
+
52
+ * Initial release
53
+
data/Manifest.txt ADDED
@@ -0,0 +1,23 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/drupal
6
+ lib/drupal.rb
7
+ lib/drupal/todo_list.rb
8
+ lib/drupal/create_module.rb
9
+ lib/drupal/install.rb
10
+ lib/drupal/templates/comments/file
11
+ lib/drupal/templates/comments/large
12
+ lib/drupal/templates/hooks/block
13
+ lib/drupal/templates/hooks/boot
14
+ lib/drupal/templates/hooks/install
15
+ lib/drupal/templates/hooks/cron
16
+ lib/drupal/templates/hooks/form_alter
17
+ lib/drupal/templates/hooks/init
18
+ lib/drupal/templates/hooks/menu
19
+ lib/drupal/templates/hooks/perm
20
+ lib/drupal/templates/hooks/schema
21
+ lib/drupal/templates/hooks/theme
22
+ lib/drupal/templates/txt/changelog
23
+ lib/drupal/templates/txt/readme
data/README.txt ADDED
@@ -0,0 +1,108 @@
1
+ = drupal.rb
2
+
3
+ http://berkes.github.com/drupal.rb/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Drupal is an open source Ruby development tool allowing developers
8
+ to quickly generate and manage Drupal modules.
9
+
10
+ == SYNOPSIS:
11
+
12
+ drupal [options] [arguments]
13
+
14
+ == REQUIREMENTS:
15
+
16
+ none
17
+
18
+ == ARGUMENTS:
19
+
20
+ create module <module_name> Generates a module skeleton from an interactive wizard.
21
+ todo list [total] Displays list of todo items or a total.
22
+ install <core | project> [dir] [5.x|6.x|7.x]
23
+ Install a Drupal project or core itself to [dir] (defaults to curent dir) for version (defaults to 6.x)
24
+
25
+ == OPTIONS:
26
+
27
+ -h, --help Display this help information.
28
+ -V, --version Display version of the Drupal development tool.
29
+
30
+ == EXAMPLES:
31
+
32
+ Create a new module in the current directory.
33
+ drupal create module my_module
34
+
35
+ Create a new module in a specific directory.
36
+ drupal create module my_module ./sites/all/modules
37
+
38
+ View todo list for current directory.
39
+ drupal todo list
40
+
41
+ View todo list for multiple files or directories.
42
+ drupal todo list ./sites/all/modules/mymodule
43
+
44
+ View total todo items only.
45
+ drupal todo list total ./sites/all/modules
46
+
47
+ Install drupal core to the current directory.
48
+ drupal install core
49
+
50
+ Install a 5.x module when in the 'modules directory
51
+ drupal install devel . 5.x
52
+
53
+ Install a module to the modules folder in my new installation (from drupal root)
54
+ drupal install devel ./sites/all/modules
55
+
56
+ Install a module when in the 'modules directory
57
+ drupal install devel
58
+
59
+ == LOCAL TEMPLATES
60
+
61
+ Create .drupal.rb/templates/ directories in your home-directory and put your
62
+ own templates there. Drupal.rb will pick these, instead of the global ones.
63
+
64
+ e.g. $ mkdir ~/.drupal.rb/
65
+ $ cp -r /path/to/gems/berkes-drupal.rb-0.0.7/var/lib/drupal/templates/ \
66
+ ~/.drupal.rb/templates/
67
+
68
+ == DEFAULTS
69
+ Create a file in ~/.drupal.rb/ named defaults.yml. The variables in there will
70
+ be used as defaults on the prompt when creating a module.
71
+ Alternatively you can copy the example from the doc dir in the package.
72
+
73
+ == AUTHOR:
74
+
75
+ Original:
76
+ TJ Holowaychuk
77
+ tj@vision-media.ca
78
+ http://vision-media.ca
79
+
80
+ Current Maintainer:
81
+ Bèr Kessels
82
+ ber@webschuur.com
83
+ http://webschuur.com
84
+
85
+ == LICENSE:
86
+
87
+ (The MIT License)
88
+
89
+ Copyright (c) 2008 FIX
90
+
91
+ Permission is hereby granted, free of charge, to any person obtaining
92
+ a copy of this software and associated documentation files (the
93
+ 'Software'), to deal in the Software without restriction, including
94
+ without limitation the rights to use, copy, modify, merge, publish,
95
+ distribute, sublicense, and/or sell copies of the Software, and to
96
+ permit persons to whom the Software is furnished to do so, subject to
97
+ the following conditions:
98
+
99
+ The above copyright notice and this permission notice shall be
100
+ included in all copies or substantial portions of the Software.
101
+
102
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
103
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
104
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
105
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
106
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
107
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
108
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require File.dirname(__FILE__) + '/lib/drupal'
5
+
6
+ desc 'Build and install ruby gem.'
7
+ task :build do
8
+ sh "sudo gem build ./drupal.gemspec"
9
+ sh "sudo gem install drupal-#{Drupal::VERSION}.gem"
10
+ end
11
+
12
+ desc 'Remove ruby gem build data.'
13
+ task :remove do
14
+ sh "sudo gem uninstall drupal"
15
+ sh "sudo rm drupal-#{Drupal::VERSION}.gem"
16
+ end
17
+
18
+ desc 'Run tests.'
19
+ task :test do
20
+ sh "ruby " + File.dirname(__FILE__) + '/test/test_drupal.rb' + ' -r tk'
21
+ end
data/bin/drupal ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'drupal'
4
+ Drupal.new.run(ARGV)
data/drupal.rb.gemspec ADDED
@@ -0,0 +1,59 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "drupal.rb"
3
+ s.version = "0.0.12"
4
+ s.date = "2010-02-14"
5
+ s.summary = "Drupal development kit"
6
+ s.email = "ber@webschuur.com"
7
+ s.homepage = "http://berkes.github.com/drupal.rb/"
8
+ s.description = "Drupal is an open source Ruby development tool allowing developers to quickly generate and manage Drupal modules."
9
+ s.has_rdoc = true
10
+ s.require_path = "lib"
11
+ s.authors = ["tj@vision-media.ca", "ber@webschuur.com"]
12
+ s.add_dependency("archive-tar-minitar", ">0.5.0")
13
+ s.add_dependency("active_support", ">0.0.0")
14
+ s.requirements = [
15
+ "A POSIX compliant environment (Mac, Unix, Linux, and for Windows Cygwin)",
16
+ "Minitar Gem version 0.5.0 or greater. http://raa.ruby-lang.org/project/minitar",
17
+ "Pluralize, as found in active_support, for database scaffolding." ]
18
+ s.files = ["History.txt",
19
+ "Manifest.txt",
20
+ "README.txt",
21
+ "Rakefile",
22
+ "drupal.rb.gemspec",
23
+ "lib/drupal.rb",
24
+ "lib/drupal/create_module.rb",
25
+ "lib/drupal/todo_list.rb",
26
+ "lib/drupal/install.rb",
27
+ "lib/drupal/templates/6.x/comments/file",
28
+ "lib/drupal/templates/6.x/comments/large",
29
+ "lib/drupal/templates/6.x/hooks/block",
30
+ "lib/drupal/templates/6.x/hooks/boot",
31
+ "lib/drupal/templates/6.x/hooks/cron",
32
+ "lib/drupal/templates/6.x/hooks/form_alter",
33
+ "lib/drupal/templates/6.x/hooks/init",
34
+ "lib/drupal/templates/6.x/hooks/menu",
35
+ "lib/drupal/templates/6.x/hooks/perm",
36
+ "lib/drupal/templates/6.x/hooks/theme",
37
+ "lib/drupal/templates/6.x/txt/changelog",
38
+ "lib/drupal/templates/6.x/txt/readme",
39
+ "lib/drupal/templates/6.x/base/info",
40
+
41
+ "lib/drupal/templates/5.x/comments/file",
42
+ "lib/drupal/templates/5.x/comments/large",
43
+ "lib/drupal/templates/5.x/hooks/block",
44
+ "lib/drupal/templates/5.x/hooks/install",
45
+ "lib/drupal/templates/5.x/hooks/cron",
46
+ "lib/drupal/templates/5.x/hooks/form_alter",
47
+ "lib/drupal/templates/5.x/hooks/init",
48
+ "lib/drupal/templates/5.x/hooks/menu",
49
+ "lib/drupal/templates/5.x/hooks/perm",
50
+ "lib/drupal/templates/5.x/txt/changelog",
51
+ "lib/drupal/templates/5.x/txt/readme",
52
+ "lib/drupal/templates/5.x/base/info",
53
+
54
+ "bin/drupal"]
55
+ s.executables = ["drupal"]
56
+ s.test_files = ["test/test_drupal.rb", "test/test_install.rb", "test/test_create_module.rb", "test/test_todo_list.rb"]
57
+ s.rdoc_options = ["--main", "README.txt"]
58
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
59
+ end
@@ -0,0 +1,276 @@
1
+ require 'yaml'
2
+ require 'active_support'
3
+
4
+ class Drupal
5
+ class Create_Module
6
+
7
+ # Create a module using the module builing wizard.
8
+ def run(arguments)
9
+ @arguments = arguments
10
+ @dir = @arguments[1] || '.' # TODO remove trailing slash, check validity, and existance
11
+ self.check_module_name
12
+ self.run_wizard
13
+ end
14
+
15
+ # Ensure module name is supplied and that it is
16
+ # formatted correctly as module names must be alphanumeric
17
+ # and must begin with a letter.
18
+ def check_module_name
19
+ case
20
+ when @arguments.empty?; puts 'Module name required.'; exit 3
21
+ when !@arguments[0].match(/^[a-z][\w]+/); puts 'Invalid module name.'; exit 4
22
+ else @module = @arguments[0]
23
+ end
24
+ end
25
+
26
+ # Run module generation wizard.
27
+ def run_wizard
28
+ # TODO create self.log() with padding to even output
29
+ defaults = get_defaults
30
+
31
+ # TODO make each ask have a commandline-option equivalent.
32
+ @version = self.ask('What drupal version to scaffold for?:', defaults[:version])
33
+ @author = self.ask('What is your name?:', defaults[:author])
34
+ @link = self.ask('What is the URI to your companies website?:', defaults[:link])
35
+ @email = self.ask('What is your email?:', defaults[:email])
36
+ @module_name = self.ask('Enter a human readable name for your module:', defaults[:module_name])
37
+ @table = self.ask('Database table name for your module. Without the modulename. A table name "pirates" on the module "cool_people" we would give us a table "cool_people_pirates" Leave empty for no database-scaffolding.')
38
+ @module_description = self.ask('Enter a short description of your module:', defaults[:module_description])
39
+ @module_dependencies = self.ask('Enter a list of dependencies for your module:', defaults[:module_dependencies], true)
40
+ # Hooks
41
+ puts self.list_templates('Hooks:', 'hooks')
42
+ @hooks = self.ask('Which hooks would you like to implement?:', '', true)
43
+ # Files
44
+ puts self.list_templates('Files:', 'txt')
45
+ @files = self.ask('Which additional files would you like to include?:', '', true)
46
+ # Dirs
47
+ puts "\nCommon directories:"
48
+ puts ['js', 'images', 'css'].collect{ |d| " - " << d }
49
+ @dirs = self.ask('Which directories would you like to create?:', '', true)
50
+ # Finish
51
+ self.create_tokens
52
+ self.create_hook_weights
53
+ self.create_module
54
+ end
55
+
56
+ # Create global tokens.
57
+ def create_tokens
58
+ if not @table.nil?
59
+ @record = @table.singularize
60
+ else
61
+ @record = ''
62
+ end
63
+
64
+ @tokens = {
65
+ :module => @module,
66
+ :link => @link,
67
+ :email => @email,
68
+ :author => @author,
69
+ :module_name => @module_name,
70
+ :module_description => @module_description,
71
+ :module_dependencies => @module_dependencies,
72
+ :table => @table,
73
+ :record => @record,
74
+ }
75
+ end
76
+
77
+ # Register hook weights
78
+ def create_hook_weights
79
+ @hook_weights = [
80
+ 'perm',
81
+ 'cron',
82
+ 'boot',
83
+ 'init',
84
+ 'menu',
85
+ 'theme',
86
+ 'form_alter',
87
+ 'block',
88
+ ]
89
+ end
90
+
91
+ # Create module from wizard results.
92
+ def create_module
93
+ puts "\n... Creating module '#{@module}' in '#{@dir}'"
94
+ # Base directory
95
+ create_dir("#{@module}")
96
+ self.create_module_dirs
97
+ self.create_module_files
98
+ self.create_module_file
99
+ self.create_module_database_files
100
+ self.create_module_info_file
101
+ puts 'Module created :)'
102
+ end
103
+
104
+ # Create directories.
105
+ def create_module_dirs
106
+ @dirs.each{ |dir| create_dir("#{@module}/#{dir}") }
107
+ end
108
+
109
+ # Create file templates.
110
+ def create_module_files
111
+ @files.each do |file|
112
+ filepath = "#{file.upcase}.txt"
113
+ create_file(filepath)
114
+ append_template(filepath, "txt/#{file}", @tokens)
115
+ end
116
+ end
117
+
118
+ # Create .module file.
119
+ def create_module_file
120
+ create_file("#{@module}.module", "<?php\n")
121
+ append_template("#{@module}.module", 'comments/file', @tokens)
122
+ append_template("#{@module}.module", 'comments/large', {'title' => 'Hook Implementations'})
123
+ for hook in @hook_weights
124
+ if @hooks.include?(hook)
125
+ append_template("#{@module}.module", "hooks/#{hook}", @tokens)
126
+ end
127
+ end
128
+ end
129
+
130
+ # Create .install file, database includes and schema..
131
+ def create_module_database_files
132
+ if not @table.empty?
133
+ create_file("#{@module}.install", "<?php\n")
134
+ append_template("#{@module}.install", 'comments/file', @tokens)
135
+ ['install', 'schema'].each do |hook|
136
+ append_template("#{@module}.install", "incs/#{hook}", @tokens)
137
+ end
138
+
139
+ create_file("#{@module}_db.inc", "<?php\n")
140
+ append_template("#{@module}_db.inc", 'comments/file_db', @tokens)
141
+ append_template("#{@module}_db.inc", "incs/module_db", @tokens)
142
+
143
+ append_template("#{@module}.module", "hooks/init", @tokens) unless @hooks.include('init')
144
+ end
145
+ end
146
+
147
+ # Create info file.
148
+ def create_module_info_file
149
+ tokens = {
150
+ 'module_name' => @module_name,
151
+ 'module_description' => @module_description,
152
+ 'version' => @version,
153
+ }
154
+
155
+ if !@module_dependencies.nil?
156
+ #In 6.x each dep has a new line. In 5.x they are on a single line.
157
+ if (@version == '6.x')
158
+ @module_dependencies.each do |dependency|
159
+ tokens['dependencies_chunk'] = "\ndependencies[] = #{dependency}"
160
+ end
161
+ elsif (@version == '5.x')
162
+ tokens['dependencies_chunk'] = "dependencies = " + @module_dependencies.join(',')
163
+ end
164
+ end
165
+
166
+ filepath = "#{@module}.info"
167
+ create_file(filepath)
168
+ append_template(filepath, "base/info", tokens)
169
+ end
170
+
171
+ # Create a new directory.
172
+ def create_dir(dir)
173
+ dir = "#{@dir}/#{dir}"
174
+ puts "... Creating directory '#{dir}'"
175
+ Dir.mkdir(dir)
176
+ end
177
+
178
+ # Create a new file.
179
+ def create_file(filepath, contents = '')
180
+ filepath = "#{@dir}/#{@module}/#{filepath}"
181
+ puts "... Creating file '#{filepath}'"
182
+ File.open(filepath, 'w') do |f|
183
+ f.write contents
184
+ end
185
+ end
186
+
187
+ # Append a tokenized template template to a file.
188
+ def append_template(filepath, template, tokens = {})
189
+ # TODO: ensure template exists
190
+ # TODO: is \n included with STDIN?
191
+ _template = template
192
+ filepath = "#{@dir}/#{@module}/#{filepath}"
193
+ template = get_template_location << template
194
+ puts "... Adding template '#{_template}' to '#{filepath}'"
195
+ contents = File.read(template)
196
+ tokens.each_pair do |token, value|
197
+ if value.class == String && contents.include?("[#{token}]")
198
+ contents.gsub!(/\[#{token}\]/, value)
199
+ end
200
+ end
201
+ File.open(filepath, 'a') do |f|
202
+ f.write contents
203
+ end
204
+ end
205
+
206
+ # Prompt user for input
207
+ def ask(question, default = '', list = false)
208
+ if not default.to_s.empty? then question = question << " (#{default})" end
209
+ puts "\n" << question
210
+
211
+ # TODO: support 'all'
212
+ # TODO: why is gets not working?
213
+ # TODO: not catching exception when CTRL+C ?
214
+ begin
215
+ case list
216
+ when true; input = STDIN.gets.split
217
+ when false; input = STDIN.gets.gsub!(/\n/, '')
218
+ end
219
+ rescue => e
220
+ puts ':)'
221
+ end
222
+
223
+ if input.empty?
224
+ return default
225
+ else
226
+ return input
227
+ end
228
+ end
229
+
230
+ # List templates available of a certain type.
231
+ def list_templates(title, type)
232
+ "\n" << title << self.get_templates(type).collect{ |t| "\n - " << File.basename(t) }.join
233
+ end
234
+
235
+ # Get array of templates of a certain type.
236
+ def get_templates(type)
237
+ Dir[get_template_location << type << '/*']
238
+ end
239
+
240
+
241
+ private
242
+ def get_template_location
243
+ location = File.expand_path "~/.drupal.rb/templates/#{@version}"
244
+
245
+ unless File.directory? location
246
+ location = File.dirname(__FILE__) + "/templates/#{@version}"
247
+ end
248
+
249
+ return location + '/'
250
+ end
251
+
252
+ # @TODO: implement defaults that can be altered for list of hooks and files
253
+ def get_defaults
254
+ defaults = {}
255
+ location = File.expand_path '~/.drupal.rb/defaults.yml'
256
+ if File.readable? location
257
+ defaults_yml = File.open( location ) { |yf| YAML::load( yf ) }
258
+
259
+ # @TODO: There is most probably a much nicer Rubyism for this nested looping.
260
+ # If you know Ruby better then I do, please chime in and change this.
261
+ create_tokens().each do |token|
262
+ defaults_yml.each do |d|
263
+ if (d.has_key? token.first.to_s)
264
+ defaults[token.first] = d[token.first.to_s]
265
+ end
266
+ end
267
+ end
268
+ else
269
+ defaults = create_tokens
270
+ end
271
+
272
+ return defaults
273
+ end
274
+ end
275
+ end
276
+
@@ -0,0 +1,143 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'rexml/document'
4
+ require 'zlib'
5
+ require 'archive/tar/minitar'
6
+
7
+ class Drupal
8
+ class Install
9
+ include REXML
10
+ # Attempt to download core installation or module.
11
+ def run(arguments)
12
+ @project = arguments[0]
13
+ @dest = arguments[1] || '.'
14
+ @version = arguments[2] || '6.x'
15
+ abort "Destination #{@dest} is not a directory." unless File.directory?(@dest)
16
+ abort 'Project name required (core | <project>).' if arguments.empty?
17
+ install_projects
18
+ end
19
+
20
+ def debug(message)
21
+ puts '... ' + message
22
+ end
23
+
24
+ # Install single project or iterate lists.
25
+ def install_projects
26
+ if @project.include? ','
27
+ projects = @project.split ','
28
+ projects.each do |p|
29
+ @project = p
30
+ check_core
31
+ install_project
32
+ puts
33
+ end
34
+ else
35
+ check_core
36
+ install_project
37
+ end
38
+ end
39
+
40
+ # Check if the destination is empty.
41
+ def destination_empty?
42
+ Dir['*'].length == 0
43
+ end
44
+
45
+ # Allow users to type 'core' instead of 'drupal install drupal'
46
+ def check_core
47
+ @project = 'drupal' if @project =~ /^core|drupal$/
48
+ end
49
+
50
+ # Check if a uri is available.
51
+ def uri_available?(uri)
52
+ open(uri) rescue false
53
+ end
54
+
55
+ # Install project.
56
+ # @TODO move all the updates.drupal.org xml parsing into a separate Class
57
+ def install_project
58
+ xmldoc = get_xml(@project, @version)
59
+ release = get_release(xmldoc, 'latest')
60
+ @tarpath = get_tarball(release)
61
+
62
+ # Extract tarball
63
+ tgz = Zlib::GzipReader.new(File.open(@tarpath, 'rb'))
64
+ Archive::Tar::Minitar.unpack(tgz, @dest) rescue abort "Failed to extract #{@tarpath} to #{@dest}"
65
+
66
+ # Remove tarball
67
+ File.delete(@tarpath) rescue abort "Failed to remove #{@tarpath}"
68
+
69
+ # Installation complete
70
+ debug "Project #{@project} installed to #{File.dirname(@tarpath)}" unless @dest == '.'
71
+ debug 'Installation complete'
72
+ end
73
+
74
+ def get_xml project, version='6.x'
75
+ debug "Locating #{project} page for version #{version}"
76
+ # Locate tarball from project page
77
+ begin
78
+ response = Net::HTTP.get_response(URI.parse("http://updates.drupal.org/release-history/#{project}/#{version}"))
79
+ # TODO: unhardcode the dependency on Drupal 6, make this an environment or static var.
80
+ # TODO: check 404, 403 etc.
81
+ xmldoc = Document.new response.body
82
+ if xmldoc.root.name == 'error' #TODO: better error handling here.
83
+ message = xmldoc.root.text
84
+ raise message
85
+ end
86
+ rescue
87
+ abort "Could not fetch #{project}. Error: #{message}"
88
+ end
89
+
90
+ return xmldoc
91
+ end
92
+
93
+ def get_releases(xmldoc)
94
+ releases = Hash.new
95
+
96
+ xmldoc.root.each_element('//release') do |release|
97
+ releases[release.text('version')] = release
98
+ end
99
+
100
+ return releases
101
+ end
102
+
103
+ # returns the release with releasenumber 'which' from xmldoc.
104
+ # use 'latest' for which, if you want the latest stable release
105
+ def get_release(xmldoc, which)
106
+ releases = get_releases(xmldoc)
107
+
108
+ ordered = releases.keys.sort_by {|k| k.to_s.split(/\.|-/).map {|v| v.to_i} }
109
+
110
+ if ( which == 'latest' )
111
+ release = releases[ordered.last]
112
+ elsif ordered.include? which
113
+ release = releases[which]
114
+ else
115
+ raise "Failed to find requested release #{which}"
116
+ end
117
+
118
+ return release
119
+ end
120
+
121
+ def get_tarball(release)
122
+ tarball = release.elements['//download_link'].text
123
+ tarpath = File.basename(tarball)
124
+
125
+ abort "Failed to find Drupal 6 tar of #{@project}" if tarball.nil?
126
+ debug "Found tarball #{tarball}"
127
+
128
+ # Fetch tarball
129
+ begin
130
+ response = Net::HTTP.get_response(URI.parse(tarball))
131
+ puts tarpath
132
+ File.open(tarpath, 'w') do |f|
133
+ f.write response.body
134
+ end
135
+ debug "Copied tarball to #{tarpath}"
136
+ rescue
137
+ abort "Failed to copy remote tarball #{tarball} to #{tarpath}"
138
+ end
139
+
140
+ return tarpath
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,6 @@
1
+ ; $Id$'
2
+
3
+ name = [module_name]
4
+ description = [module_description]
5
+ core = [version]
6
+ [dependencies_chunk]