berkes-drupal.rb 0.0.7 → 0.0.8

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