tap 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/tap/exe.rb ADDED
@@ -0,0 +1,63 @@
1
+ module Tap
2
+ class Exe < Env
3
+
4
+ class << self
5
+ def instantiate
6
+ app = Tap::App.instance
7
+ exe = super(app, load_config(Tap::Env::GLOBAL_CONFIG_FILE), app.logger)
8
+
9
+ # add all gems if no gems are specified (Note this is VERY SLOW ~ 1/3 the overhead for tap)
10
+ if !File.exists?(Tap::Env::DEFAULT_CONFIG_FILE)
11
+ exe.gems = gemspecs(true)
12
+ end
13
+
14
+ tap = instance_for("#{File.dirname(__FILE__)}/../..")
15
+ tap.manifest(:tasks).search_paths = tap.root.glob(:lib, "tap/tasks/*").collect do |path|
16
+ [tap.root[:lib], path]
17
+ end
18
+ exe.push(tap)
19
+ exe
20
+ end
21
+
22
+ def instance_for(path)
23
+ path = pathify(path)
24
+ instances.has_key?(path) ? instances[path] : Env.instantiate(path)
25
+ end
26
+ end
27
+
28
+ config :before, nil
29
+ config :after, nil
30
+ config :aliases, {}, &c.hash_or_nil
31
+
32
+ def handle_error(err)
33
+ case
34
+ when $DEBUG
35
+ puts err.message
36
+ puts
37
+ puts err.backtrace
38
+ else puts err.message
39
+ end
40
+ end
41
+
42
+ def run(argv=ARGV)
43
+ command = argv.shift.to_s
44
+
45
+ if aliases && aliases.has_key?(command)
46
+ aliases[command].reverse_each {|arg| argv.unshift(arg)}
47
+ command = argv.shift
48
+ end
49
+
50
+ case command
51
+ when '', '--help'
52
+ yield
53
+ else
54
+ if path = search(:commands, command)
55
+ load path # run the command, if it exists
56
+ else
57
+ puts "Unknown command: '#{command}'"
58
+ puts "Type 'tap help' for usage information."
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
data/lib/tap/file_task.rb CHANGED
@@ -115,20 +115,45 @@ module Tap
115
115
  end
116
116
  end
117
117
 
118
+ # Returns the path, exchanging the extension with extname.
119
+ # A false or nil extname removes the extension, while true
120
+ # preserves the existing extension (and effectively does
121
+ # nothing).
122
+ #
123
+ # t = FileTask.new
124
+ # t.basepath('path/to/file.txt') # => 'path/to/file'
125
+ # t.basepath('path/to/file.txt', '.html') # => 'path/to/file.html'
126
+ #
127
+ # t.basepath('path/to/file.txt', false) # => 'path/to/file'
128
+ # t.basepath('path/to/file.txt', true) # => 'path/to/file.txt'
129
+ #
130
+ # Compare to basename.
131
+ def basepath(path, extname=false)
132
+ case extname
133
+ when false, nil
134
+ path.chomp(File.extname(path))
135
+ when true
136
+ path
137
+ else
138
+ extname = extname[1, extname.length-1] if extname[0] == ?.
139
+ "#{path.chomp(File.extname(path))}.#{extname}"
140
+ end
141
+ end
142
+
118
143
  # Returns the basename of path, exchanging the extension
119
- # with extname, if provided.
144
+ # with extname. A false or nil extname removes the
145
+ # extension, while true preserves the existing extension.
120
146
  #
121
147
  # t = FileTask.new
122
148
  # t.basename('path/to/file.txt') # => 'file.txt'
123
149
  # t.basename('path/to/file.txt', '.html') # => 'file.html'
124
150
  #
125
- def basename(path, extname=nil)
126
- basename = File.basename(path)
127
- unless extname == nil
128
- extname = $1 if extname =~ /^\.?(.*)/
129
- basename = "#{basename.chomp(File.extname(basename))}.#{extname}"
130
- end
131
- basename
151
+ # t.basename('path/to/file.txt', false) # => 'file'
152
+ # t.basename('path/to/file.txt', true) # => 'file.txt'
153
+ #
154
+ # Compare to basepath.
155
+ def basename(path, extname=true)
156
+ basepath(File.basename(path), extname)
132
157
  end
133
158
 
134
159
  # Constructs a filepath using the dir, name, and the specified paths.
@@ -4,38 +4,17 @@ module Tap
4
4
  module Generator
5
5
  class Base < Tap::Task
6
6
  class << self
7
- def lazydoc(resolve=false, args_method=:manifest)
8
- if resolve
9
- lazydoc = super(false)
10
- lazydoc.resolve(nil, /^\s*def\s+#{args_method}(\((.*?)\))?/) do |comment, match|
11
- args = match[2].to_s.split(',').collect do |arg|
12
- arg = arg.strip.upcase
13
- case arg
14
- when /^&/ then nil
15
- when /^\*/ then arg[1..-1] + "..."
16
- else arg
17
- end
18
- end
19
- args.shift
20
-
21
- comment.subject = args.join(', ')
22
- lazydoc.default_attributes['args'] ||= comment
23
- end
24
- end
25
-
26
- super(false)
27
- end
28
-
29
- def help
30
- Tap::Support::Templater.new(DEFAULT_HELP_TEMPLATE,
31
- :task_class => self,
32
- :manifest => lazydoc(true)[to_s]['generator'] || Tap::Support::Comment.new
33
- ).build
7
+ def lazydoc(resolve=true)
8
+ lazydoc = super(false)
9
+ lazydoc.register_method_pattern('args', :manifest, 1..-1) unless lazydoc.resolved?
10
+ super
34
11
  end
35
12
  end
36
13
 
37
14
  Constant = Tap::Support::Constant
38
-
15
+
16
+ lazy_attr :manifest, :generator
17
+
39
18
  config :pretend, false, &c.flag # Run but rollback any changes.
40
19
  config :force, false, &c.flag # Overwrite files that already exist.
41
20
  config :skip, false, &c.flag # Skip files that already exist.
@@ -17,12 +17,16 @@ module Tap::Generator::Generators
17
17
  # |- tap_test_suite.rb
18
18
  # `- tapfile_test.rb
19
19
  #
20
+ # By default a tapfile will be created, but not a config file.
20
21
  class RootGenerator < Tap::Generator::Base
21
22
 
23
+ config :config_file, false, &c.switch # create a tap.yml file
24
+ config :tapfile, true, &c.switch # create a tapfile
25
+
22
26
  # ::args ROOT, PROJECT_NAME=basename(ROOT)
23
- def manifest(m, root, project_name=File.basename(root))
24
- project_name = 'project' if project_name == '.'
27
+ def manifest(m, root, project_name=nil)
25
28
  r = Tap::Root.new(root)
29
+ project_name = File.basename(r.root) if project_name == nil
26
30
 
27
31
  m.directory r.root
28
32
  m.directory r['lib']
@@ -32,24 +36,26 @@ module Tap::Generator::Generators
32
36
  when File.directory?(source)
33
37
  m.directory r[target]
34
38
  when target == 'gemspec'
35
- m.template r[project_name + '.gemspec'], source, :project_name => project_name
36
- when target == 'tapfile'
37
- m.template r['tapfile.rb'], source, :project_name => project_name
39
+ m.template r[project_name + '.gemspec'], source, :project_name => project_name, :tapfile => tapfile, :config_file => config_file
40
+ when target =~ /tapfile/
41
+ next unless tapfile
42
+ target = (target == 'tapfile' ? r['tapfile.rb'] : r[target])
43
+ m.template target, source, :project_name => project_name
38
44
  else
39
45
  m.template r[target], source, :project_name => project_name
40
46
  end
41
47
  end
42
48
 
43
- # m.file(r['tap.yml']) do |file|
44
- # Tap::App.configurations.format_str(:doc, file) do |templater|
45
- # next unless templater.receiver == Tap::Root
46
- #
47
- # templater.configurations.each do |(key, config)|
48
- # config.default = nil if key.to_s == 'root'
49
- # end
50
- # end
51
- # Tap::Env.configurations.format_str(:doc, file)
52
- # end
49
+ m.file(r['tap.yml']) do |file|
50
+ Tap::App.configurations.format_str(:doc, file) do |templater|
51
+ next unless templater.receiver == Tap::Root
52
+
53
+ templater.configurations.each do |(key, config)|
54
+ config.default = nil if key.to_s == 'root'
55
+ end
56
+ end
57
+ Tap::Env.configurations.format_str(:doc, file)
58
+ end if config_file
53
59
  end
54
60
  end
55
61
  end
@@ -44,7 +44,7 @@ task :print_manifest do
44
44
 
45
45
  # sort and output the results
46
46
  files.values.sort_by {|exists, file| file }.each do |entry|
47
- puts "%-5s : %s" % entry
47
+ puts "%-5s %s" % entry
48
48
  end
49
49
  end
50
50
 
@@ -19,7 +19,8 @@ Gem::Specification.new do |s|
19
19
  # list the files you want to include here. you can
20
20
  # check this manifest using 'rake :print_manifest'
21
21
  s.files = %W{
22
- tapfile.rb
22
+ <%= config_file ? " tap.yml\n" : '' %>
23
+ <%= tapfile ? " tapfile.rb\n" : '' %>
23
24
  test/tap_test_helper.rb
24
25
  test/tap_test_suite.rb
25
26
  test/tapfile_test.rb
@@ -47,6 +47,8 @@ module Rake # :nodoc:
47
47
 
48
48
  # Loads in the patched rake_test_loader to avoid the ARGV
49
49
  # modification error, which arises within TDoc.
50
+ #--
51
+ # May be out of date...
50
52
  def rake_loader # :nodoc:
51
53
  File.expand_path(File.join(File.dirname(__FILE__), 'rake_test_loader.rb'))
52
54
  end
@@ -16,8 +16,7 @@ module Tap
16
16
  # Tracks the assignment of the config keys to receivers
17
17
  attr_reader :assignments
18
18
 
19
- # A map of config keys and instance methods used to set a
20
- # config (ie the reader and writer for a config)
19
+ # A map of (key, config) pairs.
21
20
  attr_reader :map
22
21
 
23
22
  def initialize(receiver, parent=nil)
@@ -111,8 +110,8 @@ module Tap
111
110
 
112
111
  # Initializes and returns a new InstanceConfiguration set to self
113
112
  # and bound to the receiver, if specified.
114
- def instance_config(receiver=nil)
115
- InstanceConfiguration.new(self, receiver)
113
+ def instance_config(receiver=nil, store={})
114
+ InstanceConfiguration.new(self, receiver, store)
116
115
  end
117
116
 
118
117
  # Returns a hash of the (key, config.default) values in self.
@@ -122,6 +121,7 @@ module Tap
122
121
  hash
123
122
  end
124
123
 
124
+ # An array of config descriptions that are Comment objects.
125
125
  def code_comments
126
126
  code_comments = []
127
127
  values.each do |config|
@@ -148,7 +148,6 @@ module Tap
148
148
  # templater is assigned the following attributes for use in formatting:
149
149
  #
150
150
  # receiver:: The receiver
151
- # class_doc:: The TDoc for the receiver, from Tap::Support::TDoc[receiver]
152
151
  # configurations:: An array of configurations and associated comments
153
152
  #
154
153
  # In the template these can be accessed as any ERB locals, for example:
@@ -161,7 +160,7 @@ module Tap
161
160
  # The input template may be a String or an ERB; either may be used to
162
161
  # initialize the templater.
163
162
  def format_str(template=:doc, target="")
164
- Lazydoc.resolve(code_comments)
163
+ Lazydoc.resolve_comments(code_comments)
165
164
 
166
165
  template = case template
167
166
  when :doc then File.read(DOC_TEMPLATE_PATH)
@@ -1,6 +1,6 @@
1
1
  require 'tap/support/class_configuration'
2
2
  require 'tap/support/validation'
3
- require 'tap/support/lazydoc'
3
+ require 'tap/support/lazy_attributes'
4
4
 
5
5
  module Tap
6
6
  module Support
@@ -47,13 +47,10 @@ module Tap
47
47
  # ac.one # => 'eulav'
48
48
  #
49
49
  module ConfigurableClass
50
+ include Tap::Support::LazyAttributes
50
51
 
51
52
  # A ClassConfiguration holding the class configurations.
52
53
  attr_reader :configurations
53
-
54
- # The source_file for self. By default the first file
55
- # to define the class inheriting ConfigurableClass.
56
- attr_accessor :source_file
57
54
 
58
55
  # Sets the source_file for base and initializes base.configurations.
59
56
  def self.extended(base)
@@ -82,16 +79,15 @@ module Tap
82
79
  super
83
80
  end
84
81
 
85
- # Returns the lazydoc for source_file
86
- def lazydoc(resolve=false)
87
- Lazydoc.resolve(configurations.code_comments) if resolve
88
- Lazydoc[source_file]
82
+ def lazydoc(resolve=true)
83
+ Lazydoc.resolve_comments(configurations.code_comments) if resolve
84
+ super
89
85
  end
90
86
 
91
87
  # Loads the contents of path as YAML. Returns an empty hash if the path
92
88
  # is empty, does not exist, or is not a file.
93
89
  def load_config(path)
94
- return {} if path == nil || !File.exists?(path) || File.directory?(path)
90
+ return {} if path == nil || !File.file?(path)
95
91
 
96
92
  YAML.load_file(path) || {}
97
93
  end
@@ -213,9 +209,10 @@ module Tap
213
209
  # Idiosyncratically, true, false, and nil may also be provided as
214
210
  # reader/writer options. Specifying true is the same as using the
215
211
  # default. Specifying false or nil prevents config_attr from
216
- # defining accessors, but the configuration still expects to use
217
- # the default reader/writer methods (ie <tt>key</tt> and <tt>key=</tt>)
218
- # which must be defined elsewhere.
212
+ # defining accessors; false sets the configuration to use
213
+ # the default reader/writer methods (ie <tt>key</tt> and <tt>key=</tt>,
214
+ # which must be defined elsewhere) while nil prevents read/write
215
+ # mapping of the config to a method.
219
216
  def config_attr(key, value=nil, options={}, &block)
220
217
 
221
218
  # add arg_type implied by block, if necessary
@@ -231,7 +228,7 @@ module Tap
231
228
  # define the public writer method
232
229
  case
233
230
  when options.has_key?(:writer) && options[:writer] != true
234
- raise ArgumentError.new("block may not be specified with writer") if block_given?
231
+ raise(ArgumentError, "a block may not be specified with writer option") if block_given?
235
232
  when block_given?
236
233
  define_method("#{key}=", &block)
237
234
  public "#{key}="
@@ -240,17 +237,17 @@ module Tap
240
237
  public "#{key}="
241
238
  end
242
239
 
243
- # remove any true, false, nil reader/writer declarations...
240
+ # remove any true, false reader/writer declarations...
244
241
  # implicitly reverting the option to the default reader
245
242
  # and writer methods
246
243
  [:reader, :writer].each do |option|
247
244
  case options[option]
248
- when true, false, nil then options.delete(option)
245
+ when true, false then options.delete(option)
249
246
  end
250
247
  end
251
248
 
252
- # register with TDoc so that all extra documentation can be extracted
253
- caller.each_with_index do |line, index|
249
+ # register with Lazydoc so that all extra documentation can be extracted
250
+ caller.each do |line|
254
251
  case line
255
252
  when /in .config.$/ then next
256
253
  when /^(([A-z]:)?[^:]+):(\d+)/
@@ -53,8 +53,8 @@ module Tap
53
53
  @name = name
54
54
  self.default = default
55
55
 
56
- self.reader = options.delete(:reader) || name
57
- self.writer = options.delete(:writer) || "#{name}="
56
+ self.reader = options.has_key?(:reader) ? options.delete(:reader) : name
57
+ self.writer = options.has_key?(:writer) ? options.delete(:writer) : "#{name}="
58
58
  @attributes = options
59
59
  end
60
60
 
@@ -76,14 +76,16 @@ module Tap
76
76
  duplicate && duplicable ? @default.dup : @default
77
77
  end
78
78
 
79
- # Sets the reader for self. The reader is symbolized.
79
+ # Sets the reader for self. The reader is symbolized,
80
+ # but may also be set to nil.
80
81
  def reader=(value)
81
- @reader = value.to_sym
82
+ @reader = value == nil ? value : value.to_sym
82
83
  end
83
84
 
84
- # Sets the writer for self. The writer is symbolized.
85
+ # Sets the writer for self. The writer is symbolized,
86
+ # but may also be set to nil.
85
87
  def writer=(value)
86
- @writer = value.to_sym
88
+ @writer = value == nil ? value : value.to_sym
87
89
  end
88
90
 
89
91
  def arg_name
@@ -47,7 +47,7 @@ module Tap
47
47
  protected
48
48
 
49
49
  def config(key, value=nil, options={}, &block)
50
- caller.each_with_index do |line, index|
50
+ caller.each do |line|
51
51
  case line
52
52
  when /^(([A-z]:)?[^:]+):(\d+)/
53
53
  options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
@@ -59,7 +59,7 @@ module Tap
59
59
  end
60
60
 
61
61
  def config_attr(key, value=nil, options={}, &block)
62
- caller.each_with_index do |line, index|
62
+ caller.each do |line|
63
63
  case line
64
64
  when /^(([A-z]:)?[^:]+):(\d+)/
65
65
  options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
@@ -17,6 +17,8 @@ module Tap
17
17
  mod.extend Support::BatchableClass
18
18
  mod.extend Support::ConfigurableClass
19
19
  mod.extend Support::FrameworkClass
20
+ mod.lazy_attr :manifest
21
+ mod.lazy_attr :args
20
22
  end
21
23
 
22
24
  # The application used to load config_file templates
@@ -24,6 +26,9 @@ module Tap
24
26
  attr_reader :app
25
27
 
26
28
  # The name of self.
29
+ #--
30
+ # Currently names may be any object. Audit makes use of name
31
+ # via to_s, as does app when figuring configuration filepaths.
27
32
  attr_accessor :name
28
33
 
29
34
  # Initializes a new instance and associated batch objects. Batch
@@ -34,7 +39,14 @@ module Tap
34
39
  super()
35
40
  @app = app
36
41
  @name = name || self.class.default_name
37
- initialize_config(config)
42
+
43
+ case config
44
+ when InstanceConfiguration
45
+ @config = config
46
+ config.bind(self)
47
+ else
48
+ initialize_config(config)
49
+ end
38
50
  end
39
51
 
40
52
  # Creates a new batched object and adds the object to batch. The batched object
@@ -63,7 +75,7 @@ module Tap
63
75
 
64
76
  # Returns self.name
65
77
  def to_s
66
- name
78
+ name.to_s
67
79
  end
68
80
 
69
81
  end