rabal 0.0.1 → 0.1.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.
Files changed (52) hide show
  1. data/CHANGES +13 -0
  2. data/README.PLUGIN +8 -8
  3. data/Rakefile +79 -0
  4. data/lib/rabal.rb +26 -28
  5. data/lib/rabal/application.rb +53 -15
  6. data/lib/rabal/directory_tree.rb +3 -3
  7. data/lib/rabal/error.rb +2 -0
  8. data/lib/rabal/file_tree.rb +9 -4
  9. data/lib/rabal/gemspec.rb +50 -0
  10. data/lib/rabal/logger.rb +15 -6
  11. data/lib/rabal/plugin.rb +9 -5
  12. data/lib/rabal/plugin/core.rb +4 -3
  13. data/lib/rabal/plugin/ext.rb +17 -0
  14. data/lib/rabal/plugin/foundation.rb +21 -10
  15. data/lib/rabal/plugin/license.rb +8 -13
  16. data/lib/rabal/plugin/rubyforge.rb +22 -0
  17. data/lib/rabal/plugin/spec.rb +6 -0
  18. data/lib/rabal/plugin/test.rb +7 -0
  19. data/lib/rabal/plugin_tree.rb +1 -2
  20. data/lib/rabal/project_tree.rb +7 -2
  21. data/lib/rabal/specification.rb +128 -0
  22. data/lib/rabal/tree.rb +19 -5
  23. data/lib/rabal/usage.rb +8 -5
  24. data/lib/rabal/util.rb +2 -2
  25. data/lib/rabal/version.rb +6 -3
  26. data/resources/trees/bin/rabal.project +3 -3
  27. data/resources/trees/core/{CHANGES → CHANGES.erb} +1 -1
  28. data/resources/trees/core/{README → README.erb} +1 -1
  29. data/resources/trees/core/Rakefile.erb +67 -0
  30. data/resources/trees/core/lib/rabal.project.rb.erb +0 -2
  31. data/resources/trees/core/lib/rabal.project/gemspec.rb.erb +51 -0
  32. data/resources/trees/core/lib/rabal.project/specification.rb.erb +128 -0
  33. data/resources/trees/core/lib/rabal.project/version.rb.erb +2 -1
  34. data/resources/trees/ext/ext/rabal.project/ext/mkrf_conf.rb.erb +7 -0
  35. data/resources/trees/ext/tasks/extension.rb.erb +15 -0
  36. data/resources/trees/rubyforge/tasks/rubyforge.rb.erb +105 -0
  37. data/resources/trees/spec/{rabal.project_spec.rb.erb → spec/rabal.project_spec.rb.erb} +0 -0
  38. data/resources/trees/spec/{spec_helper.rb.erb → spec/spec_helper.rb.erb} +0 -0
  39. data/resources/trees/spec/tasks/rspec.rb.erb +20 -0
  40. data/resources/trees/test/tasks/testunit.rb.erb +14 -0
  41. data/resources/trees/test/{rabal.project_test.rb.erb → test/rabal.project_test.rb.erb} +1 -1
  42. data/resources/trees/test/{test_helper.rb.erb → test/test_helper.rb.erb} +1 -1
  43. data/spec/application_spec.rb +47 -0
  44. data/spec/bin_plugin_spec.rb +1 -1
  45. data/spec/core_plugin_spec.rb +10 -3
  46. data/spec/license_plugin_spec.rb +10 -8
  47. data/spec/plugin_tree_spec.rb +4 -4
  48. data/spec/spec_plugin_spec.rb +1 -1
  49. data/spec/test_plugin_spec.rb +1 -1
  50. data/spec/version_spec.rb +1 -1
  51. metadata +73 -24
  52. data/resources/trees/core/Rakefile +0 -0
@@ -1,15 +1,24 @@
1
- require 'logger'
1
+ require 'rabal'
2
+
2
3
  module Rabal
3
4
  module Log
4
- LOGGER = Logger.new(STDOUT)
5
- LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S"
6
-
7
-
8
5
  class << self
6
+ def logger
7
+ return @logger if @logger
8
+ @logger = ::Logger.new($stdout)
9
+ @logger.datetime_format ="%Y-%m-%d %H:%M:%S"
10
+ @logger
11
+ end
12
+
13
+ def logger=(log)
14
+ @logger = ::Logger.new(log)
15
+ @logger.datetime_format ="%Y-%m-%d %H:%M:%S"
16
+ @logger
17
+ end
9
18
  %w(debug info warn error fatal).each do |m|
10
19
  module_eval <<-code
11
20
  def #{ m } *a, &b
12
- LOGGER.#{ m } *a, &b
21
+ logger.#{ m } *a, &b
13
22
  end
14
23
  code
15
24
  end
@@ -1,5 +1,9 @@
1
- require 'rubygems'
2
- require 'gem_plugin'
3
-
4
- # load up all the builtin plugins
5
- Rabal.require_all_libs_relative_to(__FILE__)
1
+ # load up all the builtin rabal/plugins
2
+ require 'rabal/plugin/bin'
3
+ require 'rabal/plugin/core'
4
+ require 'rabal/plugin/ext'
5
+ require 'rabal/plugin/foundation'
6
+ require 'rabal/plugin/license'
7
+ require 'rabal/plugin/rubyforge'
8
+ require 'rabal/plugin/spec'
9
+ require 'rabal/plugin/test'
@@ -2,8 +2,9 @@ require 'rabal/plugin/foundation'
2
2
  module Rabal
3
3
  module Plugin
4
4
  class Core < Rabal::Plugin::Base "/rabal/core"
5
- parameter "author", "Author of the project"
6
- parameter "email", "Email address of the author"
5
+ parameter "author", "Author of the project (full name)", lambda { |x| x.length > 2 }
6
+ # validating non-perfect email from regular-expressions.info
7
+ parameter "email", "Email address of the author", lambda { |x| x =~ /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\Z/i }
7
8
  use_always
8
9
  description <<-DESC
9
10
  The core functionality and baseline information needed by every project.
@@ -16,7 +17,7 @@ module Rabal
16
17
  def initialize(options)
17
18
  @parameters = OpenStruct.new(options)
18
19
  validate_parameters
19
- @tree = ProjectTree.new(options[:project] || options["project"],options)
20
+ @tree = ProjectTree.new(options[:project] || options["project"],@parameters)
20
21
  @tree << PluginTree.new({},resource_by_name(my_main_tree_name))
21
22
  end
22
23
  end
@@ -0,0 +1,17 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Ext < Rabal::Plugin::Base "/rabal/ext"
5
+ description "Add a ruby extension"
6
+ parameter "soname", "Name of the resulting .so file (e.g. myext)"
7
+ parameter "lib_name", "Library to link against (e.g. libsomething)"
8
+ parameter "lib_method", "Check for the existence of this method in the library"
9
+
10
+ def initialize(options)
11
+ @parameters = OpenStruct.new(options)
12
+ validate_parameters
13
+ @tree = PluginTree.new(@parameters.marshal_dump, resource_by_name(my_main_tree_name))
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
- require 'rabal'
2
- require 'rubygems'
3
- require 'main'
1
+ require 'gem_plugin'
2
+ require 'highline/import'
3
+ require 'rabal/logger'
4
4
 
5
5
  module Rabal
6
6
  module Plugin
@@ -38,12 +38,14 @@ module Rabal
38
38
  attribute :register_as => nil
39
39
 
40
40
  # part of the mini DSL for describing a Plugin
41
- def parameter(pname,description)
41
+ def parameter(pname,description,block = nil)
42
42
  @parameters ||= {}
43
- @parameters[pname] = [pname, description]
43
+ @parameters[pname] = {:name => pname,
44
+ :desc => description,
45
+ :proc => block}
44
46
  end
45
47
 
46
- # get the parameters bac
48
+ # get the parameters back
47
49
  def parameters
48
50
  @parameters ||= {}
49
51
  end
@@ -86,19 +88,28 @@ module Rabal
86
88
  # child plugins
87
89
  ############################################################
88
90
 
89
- #
90
91
  # validate the parameters of the plugin in the simplest way
91
92
  # possible. Make sure that each listend parameters is not
92
93
  # null. This assumes that @parameters has a method for each
93
94
  # parameter naem
94
95
  #
95
96
  def validate_parameters
96
- self.class.parameters.each do |param,desc|
97
- if not @parameters.respond_to?(param) or @parameters.send(param).nil? then
98
- raise PluginParameterMissingError, "Missing parameter '#{param}' from #{self.class.use_name} plugin. See --use-#{self.class.use_name} --help"
97
+ self.class.parameters.each do |name,param_info|
98
+ if not @parameters.respond_to?(name) or @parameters.send(name).nil? then
99
+ value = prompt_for_param(param_info[:name],param_info[:desc],param_info[:proc])
100
+ @parameters.send("#{name}=",value)
99
101
  end
100
102
  end
101
103
  end
104
+
105
+ # prompt the user for the value that we want from them
106
+ def prompt_for_param(param,desc,validation_proc = nil)
107
+ ask("#{desc} ? ") do |q|
108
+ q.readline = true
109
+ q.validate = validation_proc
110
+ end
111
+ end
112
+
102
113
  # What gem a plugin belongs to. This is necessary to access
103
114
  # the resources of the gem the plugin may use. Overload
104
115
  # this in a child plugin to return what you want. By
@@ -7,28 +7,23 @@ module Rabal
7
7
  # BSD, GPL, LGPG, MIT and Ruby
8
8
  #
9
9
  class License < Rabal::Plugin::Base "/rabal/license"
10
- TYPES = %w[BSD GPL LGPL MIT Ruby]
11
- parameter "flavor", "Flavor of License for your project: #{TYPES.join(', ')}"
10
+ TYPES = %w[BSD GPL LGPL MIT RUBY]
11
+ parameter "flavor", "Flavor of License for your project: #{TYPES.join(', ')}", lambda { |x| TYPES.include?(x.upcase) }
12
12
  description "Indicate under what license your project is released."
13
13
  use_always
14
14
 
15
15
  def initialize(options)
16
16
  @parameters = OpenStruct.new(options)
17
- if not @parameters.respond_to?(:flavor) then
18
- raise PluginParameterMissingError, "Missing parameter 'flavor' from license plugin. See --use-license --help"
19
- end
17
+ validate_parameters
20
18
  suffix = @parameters.flavor
19
+
21
20
  # look at all files in our resource directory and any
22
21
  # that have the same suffix as the 'flavor' load it into
23
22
  # the tree.
24
- if TYPES.include?(suffix) then
25
- resource_dir = resource_by_name(my_main_tree_name)
26
- @tree = DirectoryTree.new(".")
27
- Dir.glob(File.join(resource_dir,"*.#{suffix.downcase}")).each do |file|
28
- @tree << FileTree.from_file(file)
29
- end
30
- else
31
- raise PluginParameterMissingError, "Invalid value '#{suffix}' for 'flavor' parameter from license plugin. Only #{TYPES.join(",")} are currently supported."
23
+ resource_dir = resource_by_name(my_main_tree_name)
24
+ @tree = DirectoryTree.new(".")
25
+ Dir.glob(File.join(resource_dir,"*.#{suffix.downcase}")).each do |file|
26
+ @tree << FileTree.from_file(file)
32
27
  end
33
28
  end
34
29
  end
@@ -0,0 +1,22 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Rubyforge < Rabal::Plugin::Base "/rabal/rubyforge"
5
+ description "Add rubyforge support"
6
+ parameter "rubyforge_project", "The Rubyforge project/umbrella under which this project resides."
7
+
8
+ def initialize(options)
9
+ begin
10
+ require 'rubyforge'
11
+ rescue LoadError
12
+ Log::fatal("Unable to use the rubyforge plugin, the rubyforge library is required.")
13
+ exit 1
14
+ end
15
+
16
+ @parameters = OpenStruct.new(options)
17
+ validate_parameters
18
+ @tree = PluginTree.new(@parameters.marshal_dump, resource_by_name(my_main_tree_name))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,6 +3,12 @@ module Rabal
3
3
  module Plugin
4
4
  class Spec < Rabal::Plugin::Base "/rabal/spec"
5
5
  description "Add an RSpec framework."
6
+
7
+ def initialize(options)
8
+ @parameters = OpenStruct.new(options)
9
+ validate_parameters
10
+ @tree = PluginTree.new({}, resource_by_name(my_main_tree_name))
11
+ end
6
12
  end
7
13
  end
8
14
  end
@@ -3,6 +3,13 @@ module Rabal
3
3
  module Plugin
4
4
  class Test < Rabal::Plugin::Base "/rabal/test"
5
5
  description "Add a Test::Unit framework."
6
+
7
+ def initialize(options)
8
+ @parameters = OpenStruct.new(options)
9
+ validate_parameters
10
+ main_tree_name = my_main_tree_name
11
+ @tree = PluginTree.new({}, resource_by_name(main_tree_name))
12
+ end
6
13
  end
7
14
  end
8
15
  end
@@ -1,6 +1,4 @@
1
1
  require 'rabal'
2
- require 'find'
3
- require 'rabal/util'
4
2
 
5
3
  module Rabal
6
4
  #
@@ -47,6 +45,7 @@ module Rabal
47
45
  Dir.entries(".").each do |entry|
48
46
  next if entry[0] == ?.
49
47
  next if pwd == entry
48
+ next if entry[-1] == ?~
50
49
 
51
50
  if File.file?(entry) then
52
51
  tree << FileTree.from_file(entry,true,replace_known_words(entry))
@@ -1,4 +1,5 @@
1
- require 'rabal/directory_tree'
1
+ require 'rabal'
2
+
2
3
  module Rabal
3
4
  #
4
5
  # The ProjectTree represents the master configuration/specification
@@ -10,8 +11,12 @@ module Rabal
10
11
  # and delegate items to a Gem specification.
11
12
  def initialize(project_name,options)
12
13
  super(project_name)
14
+ if options.kind_of?(OpenStruct) then
15
+ options = options.marshal_dump
16
+ end
13
17
  @parameters = OpenStruct.new(options)
14
- @parameters.project_name = project_name
18
+ @parameters.raw_project_name = project_name
19
+ @parameters.project_name = project_name.gsub(/^ruby-/,'')
15
20
  end
16
21
  end
17
22
  end
@@ -0,0 +1,128 @@
1
+ require 'rubygems'
2
+ require 'rubygems/specification'
3
+ require 'rake'
4
+
5
+ module Rabal
6
+ # Add some additional items to Gem::Specification
7
+ # A Rabal::Specification adds additional pieces of information the
8
+ # typical gem specification
9
+ class Specification
10
+
11
+ RUBYFORGE_ROOT = "/var/www/gforge-projects/"
12
+
13
+ # user that accesses remote site
14
+ attr_accessor :remote_user
15
+
16
+ # remote host, default 'rubyforge.org'
17
+ attr_accessor :remote_host
18
+
19
+ # name the rdoc main
20
+ attr_accessor :rdoc_main
21
+
22
+ # local directory in development holding the generated rdoc
23
+ # default 'doc'
24
+ attr_accessor :local_rdoc_dir
25
+
26
+ # remote directory for storing rdoc, default 'doc'
27
+ attr_accessor :remote_rdoc_dir
28
+
29
+ # local directory for coverage report
30
+ attr_accessor :local_coverage_dir
31
+
32
+ # remote directory for storing coverage reports
33
+ # This defaults to 'coverage'
34
+ attr_accessor :remote_coverage_dir
35
+
36
+ # local directory for generated website, default +site/public+
37
+ attr_accessor :local_site_dir
38
+
39
+ # remote directory relative to +remote_root+ for the website.
40
+ # website.
41
+ attr_accessor :remote_site_dir
42
+
43
+ # is a .tgz to be created?, default 'true'
44
+ attr_accessor :need_tar
45
+
46
+ # is a .zip to be created, default 'true'
47
+ attr_accessor :need_zip
48
+
49
+
50
+ def initialize
51
+ @remote_user = nil
52
+ @remote_host = "rubyforge.org"
53
+
54
+ @rdoc_main = "README"
55
+ @local_rdoc_dir = "doc"
56
+ @remote_rdoc_dir = "doc"
57
+ @local_coverage_dir = "coverage"
58
+ @remote_coverage_dir = "coverage"
59
+ @local_site_dir = "site/public"
60
+ @remote_site_dir = "."
61
+
62
+ @need_tar = true
63
+ @need_zip = true
64
+
65
+ @spec = Gem::Specification.new
66
+
67
+ yield self if block_given?
68
+
69
+ # update rdoc options to take care of the rdoc_main if it is
70
+ # there, and add a default title if one is not given
71
+ if not @spec.rdoc_options.include?("--main") then
72
+ @spec.rdoc_options.concat(["--main", rdoc_main])
73
+ end
74
+
75
+ if not @spec.rdoc_options.include?("--title") then
76
+ @spec.rdoc_options.concat(["--title","'#{name} -- #{summary}'"])
77
+ end
78
+ end
79
+
80
+ # if this gets set then it overwrites what would be the
81
+ # rubyforge default. If rubyforge project is not set then use
82
+ # name. If rubyforge project and name are set, but they are
83
+ # different then assume that name is a subproject of the
84
+ # rubyforge project
85
+ def remote_root
86
+ if rubyforge_project.nil? or
87
+ rubyforge_project == name then
88
+ return RUBYFORGE_ROOT + "#{name}/"
89
+ else
90
+ return RUBYFORGE_ROOT + "#{rubyforge_project}/#{name}/"
91
+ end
92
+ end
93
+
94
+ # rdoc files is the same as what would be generated during gem
95
+ # installation. That is, everything in the require paths plus
96
+ # the extra_rdoc_files
97
+ #
98
+ def rdoc_files
99
+ flist = extra_rdoc_files.dup
100
+ @spec.require_paths.each do |rp|
101
+ flist << FileList["#{rp}/**/*.rb"]
102
+ end
103
+ flist.flatten.uniq
104
+ end
105
+
106
+ # calculate the remote directories
107
+ def remote_root_location
108
+ "#{remote_user}@#{remote_host}:#{remote_root}"
109
+ end
110
+
111
+ def remote_rdoc_location
112
+ remote_root_location + @remote_rdoc_dir
113
+ end
114
+
115
+ def remote_coverage_location
116
+ remote_root_loation + @remote_coverage_dir
117
+ end
118
+
119
+ def remote_site_location
120
+ remote_root_location + @remote_site_dir
121
+ end
122
+
123
+ # we delegate any other calls to spec
124
+ def method_missing(method_id,*params,&block)
125
+ @spec.send method_id, *params, &block
126
+ end
127
+ end
128
+ end
@@ -1,4 +1,4 @@
1
- require 'rabal'
1
+ require 'rabal/logger'
2
2
 
3
3
  module Rabal
4
4
  #
@@ -120,10 +120,14 @@ module Rabal
120
120
  end
121
121
 
122
122
  subtree.parent = self
123
+
124
+ # FIXME: techinically this should no longer be called 'post_add'
125
+ # but maybe 'add_hook'
126
+ subtree.post_add
123
127
 
124
128
  # Don't overwrite any existing children with the same name,
125
- # just put this one's children in that one, I think this
126
- # works recursively now.
129
+ # just put the new subtree's children into the children of
130
+ # the already existing subtree.
127
131
  if children.has_key?(subtree.name) then
128
132
  subtree.children.each do |n,tree|
129
133
  children[n] = tree
@@ -131,8 +135,6 @@ module Rabal
131
135
  else
132
136
  children[subtree.name] = subtree
133
137
  end
134
-
135
- subtree.post_add
136
138
 
137
139
  return self
138
140
  end
@@ -213,6 +215,18 @@ module Rabal
213
215
  end
214
216
  end
215
217
 
218
+ #
219
+ # Return true of false if the given subtree exists or not
220
+ #
221
+ def has_subtree?(path)
222
+ begin
223
+ find_subtree(path)
224
+ return true
225
+ rescue PathNotFoundError
226
+ return false
227
+ end
228
+ end
229
+
216
230
  private
217
231
 
218
232
  #