tap 0.10.0 → 0.10.1

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/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