berkes-drupal.rb 0.0.7 → 0.0.8

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.
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.0.8 / 2009-08-06
2
+
3
+ * 1 Internal rewrite, 2 new features, 1 bugfix
4
+ * Added commandline option to allow selection of Drupal version for installation.
5
+
6
+ * Rewrote install system by parsing the drupal release XML rather then scraping HTML.
7
+ * Added defaults.yml config option. When this file is present, we parse the contents and
8
+ present them as defaults in interactive mode. Quicker module-building!
9
+ * If hook "install" was chose, the .install file was not created. Fixed.
1
10
 
2
11
  === 0.0.7 / 2009-05-02
3
12
 
data/README.txt CHANGED
@@ -19,7 +19,8 @@ to quickly generate and manage Drupal modules.
19
19
 
20
20
  create module <module_name> Generates a module skeleton from an interactive wizard.
21
21
  todo list [total] Displays list of todo items or a total.
22
- install <core | project> [dir] Install a Drupal project or core itself to [dir]
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)
23
24
 
24
25
  == OPTIONS:
25
26
 
@@ -43,6 +44,18 @@ to quickly generate and manage Drupal modules.
43
44
  View total todo items only.
44
45
  drupal todo list total ./sites/all/modules
45
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
+
46
59
  == LOCAL TEMPLATES
47
60
 
48
61
  Create .drupal.rb/templates/ directories in your home-directory and put your
@@ -51,11 +64,15 @@ to quickly generate and manage Drupal modules.
51
64
  e.g. $ mkdir ~/.drupal.rb/
52
65
  $ cp -r /path/to/gems/berkes-drupal.rb-0.0.7/var/lib/drupal/templates/ \
53
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.
54
72
 
55
73
  == TODO:
56
-
57
- * Add defaults.yml-support. When .drupal.rb/defaults.yml exists, use these
58
- instead of asking them everytime.
74
+ * Move helptext into one include instead of having it on 4 places (DRY!)
75
+ * Add Drupal version support to defaults.yml.
59
76
  * Remove ':' from todo list items
60
77
  * Add formatted help option
61
78
  * Support versions for installer
data/bin/drupal CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'drupal'
4
- Drupal.new.run(ARGV)
4
+ Drupal.new.run(ARGV)
data/drupal.rb.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "drupal.rb"
3
- s.version = "0.0.7"
3
+ s.version = "0.0.8"
4
4
  s.date = "2008-10-16"
5
5
  s.summary = "Drupal development kit"
6
6
  s.email = "ber@webschuur.com"
data/lib/drupal.rb CHANGED
@@ -8,7 +8,8 @@
8
8
  #
9
9
  # create module <module_name> [dir] Generates a module skeleton from an interactive wizard. Current directory unless [dir] is specified.
10
10
  # todo list [total] Displays list of todo items or a total.
11
- # install <core | project ...> [dir] Install Drupal project(s) to [dir] or the current directory.
11
+ # install <core | project> [dir] [5.x|6.x|7.x]
12
+ # Install a Drupal project or core itself to [dir] (defaults to curent dir) for version (defaults to 6.x)
12
13
  #
13
14
  # == OPTIONS:
14
15
  #
@@ -38,6 +39,9 @@
38
39
  # Install a module when in the 'modules directory
39
40
  # drupal install devel
40
41
  #
42
+ # Install a 5.x module when in the 'modules directory
43
+ # drupal install devel . 5.x
44
+ #
41
45
  # Install several modules to the modules folder
42
46
  # drupal install devel,pathauto,err,ac ./sites/all/modules
43
47
  #
@@ -105,7 +109,8 @@ class Drupal
105
109
 
106
110
  create module <module_name> [dir] Generates a module skeleton from an interactive wizard. Current directory unless [dir] is specified.
107
111
  todo list [total] Displays list of todo items or a total.
108
- install <core | project> [dir] Install a Drupal project or core itself to [dir]
112
+ install <core | project> [dir] [5.x|6.x|7.x]
113
+ Install a Drupal project or core itself to [dir] (defaults to curent dir) for version (defaults to 6.x)
109
114
 
110
115
  EXAMPLES:
111
116
 
@@ -126,7 +131,10 @@ class Drupal
126
131
 
127
132
  Install drupal core to the current directory.
128
133
  drupal install core
129
-
134
+
135
+ Install a 5.x module when in the 'modules directory
136
+ drupal install devel . 5.x
137
+
130
138
  Install a module to the modules folder in my new installation (from drupal root)
131
139
  drupal install devel ./sites/all/modules
132
140
 
@@ -1,7 +1,8 @@
1
+ require 'yaml'
1
2
 
2
3
  class Drupal
3
4
  class Create_Module
4
-
5
+
5
6
  # Create a module using the module builing wizard.
6
7
  def run(arguments)
7
8
  @arguments = arguments
@@ -9,44 +10,46 @@ class Drupal
9
10
  self.check_module_name
10
11
  self.run_wizard
11
12
  end
12
-
13
+
13
14
  # Ensure module name is supplied and that it is
14
15
  # formatted correctly as module names must be alphanumeric
15
16
  # and must begin with a letter.
16
17
  def check_module_name
17
- case
18
+ case
18
19
  when @arguments.empty?; puts 'Module name required.'; exit 3
19
20
  when !@arguments[0].match(/^[a-z][\w]+/); puts 'Invalid module name.'; exit 4
20
21
  else @module = @arguments[0]
21
22
  end
22
23
  end
23
-
24
+
24
25
  # Run module generation wizard.
25
26
  def run_wizard
26
27
  # TODO create self.log() with padding to even output
28
+ defaults = get_defaults
29
+
27
30
  # Info
28
- @author = self.ask('What is your name?:')
29
- @link = self.ask('What is the URI to your companies website?:')
30
- @email = self.ask('What is your email?:')
31
- @module_name = self.ask('Enter a human readable name for your module:')
32
- @module_description = self.ask('Enter a short description of your module:')
33
- @module_dependencies = self.ask('Enter a list of dependencies for your module:', true)
31
+ @author = self.ask('What is your name?:', defaults[:author])
32
+ @link = self.ask('What is the URI to your companies website?:', defaults[:link])
33
+ @email = self.ask('What is your email?:', defaults[:email])
34
+ @module_name = self.ask('Enter a human readable name for your module:', defaults[:module_name])
35
+ @module_description = self.ask('Enter a short description of your module:', defaults[:module_description])
36
+ @module_dependencies = self.ask('Enter a list of dependencies for your module:', defaults[:module_dependencies], true)
34
37
  # Hooks
35
38
  puts self.list_templates('Hooks:', 'hooks')
36
- @hooks = self.ask('Which hooks would you like to implement?:', true)
39
+ @hooks = self.ask('Which hooks would you like to implement?:', '', true)
37
40
  # Files
38
41
  puts self.list_templates('Files:', 'txt')
39
- @files = self.ask('Which additional files would you like to include?:', true)
42
+ @files = self.ask('Which additional files would you like to include?:', '', true)
40
43
  # Dirs
41
44
  puts "\nCommon directories:"
42
45
  puts ['js', 'images', 'css'].collect{ |d| " - " << d }
43
- @dirs = self.ask('Which directories would you like to create?:', true)
46
+ @dirs = self.ask('Which directories would you like to create?:', '', true)
44
47
  # Finish
45
48
  self.create_tokens
46
49
  self.create_hook_weights
47
50
  self.create_module
48
51
  end
49
-
52
+
50
53
  # Create global tokens.
51
54
  def create_tokens
52
55
  @tokens = {
@@ -59,7 +62,7 @@ class Drupal
59
62
  :module_dependencies => @module_dependencies,
60
63
  }
61
64
  end
62
-
65
+
63
66
  # Register hook weights
64
67
  def create_hook_weights
65
68
  @hook_weights = [
@@ -75,7 +78,7 @@ class Drupal
75
78
  'block',
76
79
  ]
77
80
  end
78
-
81
+
79
82
  # Create module from wizard results.
80
83
  def create_module
81
84
  puts "\n... Creating module '#{@module}' in '#{@dir}'"
@@ -88,21 +91,21 @@ class Drupal
88
91
  self.create_module_info_file
89
92
  puts 'Module created :)'
90
93
  end
91
-
94
+
92
95
  # Create directories.
93
96
  def create_module_dirs
94
97
  @dirs.each{ |dir| create_dir("#{@module}/#{dir}") }
95
98
  end
96
-
99
+
97
100
  # Create file templates.
98
101
  def create_module_files
99
102
  @files.each do |file|
100
103
  filepath = "#{file.upcase}.txt"
101
104
  create_file(filepath)
102
105
  append_template(filepath, "txt/#{file}", @tokens)
103
- end
106
+ end
104
107
  end
105
-
108
+
106
109
  # Create .module file.
107
110
  def create_module_file
108
111
  create_file("#{@module}.module", "<?php\n")
@@ -112,20 +115,20 @@ class Drupal
112
115
  if @hooks.include?(hook)
113
116
  append_template("#{@module}.module", "hooks/#{hook}", @tokens) unless hook.match /^install|schema/
114
117
  end
115
- end
118
+ end
116
119
  end
117
-
120
+
118
121
  # Create .install file.
119
122
  def create_module_install_file
120
- if @hooks.include?('schema') || @hooks.include?('schema')
123
+ if @hooks.include?('schema') || @hooks.include?('install')
121
124
  create_file("#{@module}.install", "<?php\n")
122
125
  append_template("#{@module}.install", 'comments/file', @tokens)
123
126
  @hooks.each do |hook|
124
127
  append_template("#{@module}.install", "hooks/#{hook}", @tokens) if hook.match /^install|schema/
125
128
  end
126
- end
129
+ end
127
130
  end
128
-
131
+
129
132
  # Create info file.
130
133
  def create_module_info_file
131
134
  contents = '; $Id$'
@@ -137,14 +140,14 @@ class Drupal
137
140
  end
138
141
  create_file("#{@module}.info", contents)
139
142
  end
140
-
143
+
141
144
  # Create a new directory.
142
145
  def create_dir(dir)
143
146
  dir = "#{@dir}/#{dir}"
144
147
  puts "... Creating directory '#{dir}'"
145
148
  Dir.mkdir(dir)
146
149
  end
147
-
150
+
148
151
  # Create a new file.
149
152
  def create_file(filepath, contents = '')
150
153
  filepath = "#{@dir}/#{@module}/#{filepath}"
@@ -153,7 +156,7 @@ class Drupal
153
156
  f.write contents
154
157
  end
155
158
  end
156
-
159
+
157
160
  # Append a tokenized template template to a file.
158
161
  def append_template(filepath, template, tokens = {})
159
162
  # TODO: ensure template exists
@@ -172,28 +175,36 @@ class Drupal
172
175
  f.write contents
173
176
  end
174
177
  end
175
-
178
+
176
179
  # Prompt user for input
177
- def ask(question, list = false)
180
+ def ask(question, default = '', list = false)
181
+ if not default.to_s.empty? then question = question << " (#{default})" end
178
182
  puts "\n" << question
183
+
179
184
  # TODO: support 'all'
180
185
  # TODO: why is gets not working?
181
186
  # TODO: not catching exception when CTRL+C ?
182
187
  begin
183
188
  case list
184
- when true; STDIN.gets.split
185
- when false; STDIN.gets.gsub!(/\n/, '')
189
+ when true; input = STDIN.gets.split
190
+ when false; input = STDIN.gets.gsub!(/\n/, '')
186
191
  end
187
192
  rescue => e
188
193
  puts ':)'
189
194
  end
195
+
196
+ if input.empty?
197
+ return default
198
+ else
199
+ return input
200
+ end
190
201
  end
191
-
202
+
192
203
  # List templates available of a certain type.
193
204
  def list_templates(title, type)
194
205
  "\n" << title << self.get_templates(type).collect{ |t| "\n - " << File.basename(t) }.join
195
206
  end
196
-
207
+
197
208
  # Get array of templates of a certain type.
198
209
  def get_templates(type)
199
210
  Dir[get_template_location << type << '/*']
@@ -202,11 +213,36 @@ class Drupal
202
213
 
203
214
  private
204
215
  def get_template_location
205
- location = File.expand_path '~/.drupal.rb/templates/'
216
+ location = File.expand_path '~/.drupal.rb/templates'
217
+
206
218
  unless File.directory? location
207
- location = File.dirname(__FILE__) + '/templates/'
219
+ location = File.dirname(__FILE__) + '/templates'
220
+ end
221
+
222
+ return location + '/'
223
+ end
224
+
225
+ # @TODO: implement defaults that can be altered for list of hooks and files
226
+ def get_defaults
227
+ defaults = {}
228
+ location = File.expand_path '~/.drupal.rb/defaults.yml'
229
+ if File.readable? location
230
+ defaults_yml = File.open( location ) { |yf| YAML::load( yf ) }
231
+
232
+ # @TODO: There is most probably a much nicer Rubyism for this nested looping.
233
+ # If you know Ruby better then I do, please chime in and change this.
234
+ create_tokens().each do |token|
235
+ defaults_yml.each do |d|
236
+ if (d.has_key? token.first.to_s)
237
+ defaults[token.first] = d[token.first.to_s]
238
+ end
239
+ end
240
+ end
241
+ else
242
+ defaults = create_tokens
208
243
  end
209
- return location
244
+
245
+ return defaults
210
246
  end
211
247
  end
212
248
  end
@@ -1,23 +1,24 @@
1
-
2
1
  require 'zlib'
3
2
  require 'net/http'
3
+ require 'rexml/document'
4
4
 
5
5
  class Drupal
6
6
  class Install
7
-
7
+ include REXML
8
8
  # Attempt to download core installation or module.
9
9
  def run(arguments)
10
10
  @project = arguments[0]
11
- @dest = arguments[1] || '.'
11
+ @dest = arguments[1] || '.'
12
+ @version = arguments[2] || '6.x'
12
13
  abort "Destination #{@dest} is not a directory." unless File.directory?(@dest)
13
14
  abort 'Project name required (core | <project>).' if arguments.empty?
14
15
  install_projects
15
16
  end
16
-
17
+
17
18
  def debug(message)
18
19
  puts '... ' + message
19
20
  end
20
-
21
+
21
22
  # Install single project or iterate lists.
22
23
  def install_projects
23
24
  if @project.include? ','
@@ -25,71 +26,118 @@ class Drupal
25
26
  projects.each do |p|
26
27
  @project = p
27
28
  check_core
28
- install_project
29
+ install_project
29
30
  puts
30
- end
31
+ end
31
32
  else
32
33
  check_core
33
34
  install_project
34
35
  end
35
36
  end
36
-
37
+
37
38
  # Check if the destination is empty.
38
39
  def destination_empty?
39
- Dir['*'].length == 0
40
+ Dir['*'].length == 0
40
41
  end
41
-
42
+
42
43
  # Allow users to type 'core' instead of 'drupal install drupal'
43
44
  def check_core
44
45
  @project = 'drupal' if @project =~ /^core|drupal$/
45
46
  end
46
-
47
+
47
48
  # Check if a uri is available.
48
49
  def uri_available?(uri)
49
50
  open(uri) rescue false
50
51
  end
51
-
52
+
52
53
  # Install project.
54
+ # @TODO move all the updates.drupal.org xml parsing into a separate Class
53
55
  def install_project
54
- debug "Locating #{@project} page"
55
- # Locate tarball from project page
56
- begin
57
- response = Net::HTTP.get_response(URI.parse("http://drupal.org/project/#{@project}"))
58
- @markup = response.body
59
- # TODO: check 404
60
- debug 'Located the project page'
61
- rescue
62
- puts 'Failed to request page'
63
- end
64
- @markup.match /(#{@project}-6(?:.*?)\.gz)/
65
- @tarball = $1
66
- @tarpath = File.expand_path("#{@dest}/#{@tarball}")
67
- abort "Failed to find Drupal 6 tar of #{@project}" if @tarball.nil?
68
- debug "Found tarball #{@tarball}"
69
-
70
- # Fetch tarball
71
- begin
72
- response = Net::HTTP.get_response(URI.parse("http://ftp.drupal.org/files/projects/#{@tarball}"))
73
- File.open(@tarpath, 'w') do |f|
74
- f.write response.body
75
- end
76
- debug "Copied tarball to #{@tarpath}"
77
- rescue
78
- abort "Failed to copy remote tarball #{@tarball}"
79
- end
80
-
56
+ xmldoc = get_xml(@project, @version)
57
+ release = get_release(xmldoc, 'latest')
58
+ @tarpath = get_tarball(release)
59
+
81
60
  # Extract tarball
82
61
  @pwd = Dir.getwd
83
62
  Dir.chdir File.dirname(@tarpath) and debug "Changed cwd to #{File.dirname(@tarpath)}" unless @dest == '.'
84
63
  Kernel.system "tar -xf #{@tarpath}" rescue abort "Failed to extract #{@tarpath}"
85
64
  Dir.chdir @pwd and debug "Reverted cwd back to #{@pwd}" unless @dest == '.'
86
-
65
+
87
66
  # Remove tarball
88
67
  Kernel.system "rm #{@tarpath}" rescue abort "Failed to remove #{@tarpath}"
89
-
68
+
90
69
  # Installation complete
91
70
  debug "Project installed to #{File.dirname(@tarpath)}" unless @dest == '.'
92
71
  debug 'Installation complete'
93
72
  end
73
+
74
+ def get_xml project, version='6.x'
75
+ debug "Locating #{project} page"
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
+ debug "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
94
142
  end
95
- end
143
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkes-drupal.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - tj@vision-media.ca
@@ -51,6 +51,7 @@ files:
51
51
  - bin/drupal
52
52
  has_rdoc: true
53
53
  homepage: http://berkes.github.com/drupal.rb/
54
+ licenses:
54
55
  post_install_message:
55
56
  rdoc_options:
56
57
  - --main
@@ -72,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
73
  requirements: []
73
74
 
74
75
  rubyforge_project:
75
- rubygems_version: 1.2.0
76
+ rubygems_version: 1.3.5
76
77
  signing_key:
77
78
  specification_version: 2
78
79
  summary: Drupal development kit