rabal 0.0.1 → 0.1.0

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