fled 0.0.2 → 0.0.3
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/README.md +459 -89
- data/bin/fled +341 -53
- data/lib/dtc/utils/exec.rb +13 -2
- data/lib/dtc/utils/interactive_edit.rb +10 -0
- data/lib/dtc/utils/meta.rb +47 -0
- data/lib/dtc/utils/text/html.rb +107 -0
- data/lib/dtc/utils/text/line_writer.rb +70 -0
- data/lib/dtc/utils/text.rb +23 -0
- data/lib/dtc/utils/visitor/dsl.rb +98 -0
- data/lib/dtc/utils/visitor/folder.rb +87 -0
- data/lib/dtc/utils/visitor.rb +272 -0
- data/lib/dtc/utils.rb +3 -1
- data/lib/fled/file_listing.rb +35 -62
- data/lib/fled/file_listing_builder.rb +43 -0
- data/lib/fled.rb +18 -5
- data/tests/helper.rb +14 -26
- data/tests/readme.rb +139 -85
- metadata +9 -3
- data/lib/dtc/utils/dsldsl.rb +0 -259
- data/lib/dtc/utils/file_visitor.rb +0 -79
@@ -0,0 +1,70 @@
|
|
1
|
+
module DTC
|
2
|
+
module Utils
|
3
|
+
module Text
|
4
|
+
# Helper class for writting lines of text,
|
5
|
+
# with some indentation processing.
|
6
|
+
#
|
7
|
+
# Blocks of text can be indented and/or
|
8
|
+
# captured.
|
9
|
+
#
|
10
|
+
# Output is written to an array in `lines`
|
11
|
+
# by `push_raw`. Other methods use `split_lines`
|
12
|
+
# and/or `indent_lines` to preprocess input.
|
13
|
+
#
|
14
|
+
# Get the result by
|
15
|
+
class LineWriter
|
16
|
+
def lines ; @lines || [] end
|
17
|
+
def to_s sep = "\n"
|
18
|
+
lines.join(sep)
|
19
|
+
end
|
20
|
+
def begin_capture
|
21
|
+
(@lines_stack ||= []) << @lines
|
22
|
+
@lines = []
|
23
|
+
if block_given?
|
24
|
+
yield
|
25
|
+
end_capture
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def end_capture
|
29
|
+
result = @lines
|
30
|
+
@lines = @lines_stack.pop
|
31
|
+
result
|
32
|
+
end
|
33
|
+
def push_raw *raw_lines
|
34
|
+
@lines = lines + raw_lines.flatten
|
35
|
+
end
|
36
|
+
def push_indent *indent, &blk
|
37
|
+
(@indents ||= []) << indent
|
38
|
+
if block_given?
|
39
|
+
yield
|
40
|
+
pop_indent
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def pop_indent
|
44
|
+
@indents.pop
|
45
|
+
end
|
46
|
+
def current_indent
|
47
|
+
@indents && @indents.last
|
48
|
+
end
|
49
|
+
def push *lines
|
50
|
+
if (indent = current_indent)
|
51
|
+
push_raw(indent_lines(split_lines(*lines), indent))
|
52
|
+
else
|
53
|
+
push_raw *lines
|
54
|
+
end
|
55
|
+
end
|
56
|
+
alias_method :<<, :push
|
57
|
+
protected
|
58
|
+
def split_lines *lines
|
59
|
+
lines.flatten
|
60
|
+
end
|
61
|
+
def indent_lines lines, indent
|
62
|
+
lines = split_lines(lines)
|
63
|
+
lines.map { |line|
|
64
|
+
indent.join("") + line
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module DTC
|
3
|
+
module Utils
|
4
|
+
module Text
|
5
|
+
def self.lines str
|
6
|
+
str.split(/\r?\n/).to_a
|
7
|
+
end
|
8
|
+
# Remove common space-only indent to all non-empty lines
|
9
|
+
def self.lines_without_indent lines
|
10
|
+
lines = self.lines(lines) unless lines.is_a?(Array)
|
11
|
+
lines.shift if lines.first.empty?
|
12
|
+
min_spaces = lines.map { |l|
|
13
|
+
l == "" ? nil : (l =~ /^( +)/ ? $1.length : 0)
|
14
|
+
}.select{ |e| e }.min || 0
|
15
|
+
lines.map { |l| (min_spaces == 0 ? l : l[min_spaces..-1]) || "" }
|
16
|
+
end
|
17
|
+
|
18
|
+
autoload :HTML, 'dtc/utils/text/html'
|
19
|
+
autoload :LineWriter, 'dtc/utils/text/line_writer'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module DTC
|
2
|
+
module Utils
|
3
|
+
module Visitor
|
4
|
+
# Utilities for visiting a DSL block
|
5
|
+
#
|
6
|
+
# Tolerates chained method calls and
|
7
|
+
# recursive blocks, as long as intermediary
|
8
|
+
# method calls have no arguments.
|
9
|
+
#
|
10
|
+
# eg: `some.calls.are.fine(true)`
|
11
|
+
# `some(true).arent`
|
12
|
+
#
|
13
|
+
# Enters/leaves for methods called with a
|
14
|
+
# block. `Visitor#enter`s return is ignored.
|
15
|
+
module DSL
|
16
|
+
# Utility class to keep track of the
|
17
|
+
# running prefix as the DSL is visited
|
18
|
+
class RecursiveDSLDelegate
|
19
|
+
def initialize visitor, prefix = nil
|
20
|
+
@visitor = visitor
|
21
|
+
@prefix = prefix
|
22
|
+
@pending_prefix = nil
|
23
|
+
@called = false
|
24
|
+
end
|
25
|
+
def prefix sym
|
26
|
+
@called = true
|
27
|
+
flush
|
28
|
+
@pending_prefix = self.class.new(@visitor, with_prefix(sym))
|
29
|
+
end
|
30
|
+
def flush
|
31
|
+
if @pending_prefix
|
32
|
+
@pending_prefix.add_unless_called
|
33
|
+
@pending_prefix = nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
def add sym, *args
|
37
|
+
@called = true
|
38
|
+
@visitor.add(with_prefix(sym), *args)
|
39
|
+
end
|
40
|
+
def enter sym, *args
|
41
|
+
flush
|
42
|
+
@called = true
|
43
|
+
@visitor.enter(with_prefix(sym), *args)
|
44
|
+
end
|
45
|
+
def leave
|
46
|
+
flush
|
47
|
+
@visitor.leave
|
48
|
+
end
|
49
|
+
protected
|
50
|
+
def with_prefix sym
|
51
|
+
@prefix ? (sym ? "#{@prefix}.#{sym}".to_sym : @prefix) : sym
|
52
|
+
end
|
53
|
+
def add_unless_called
|
54
|
+
flush
|
55
|
+
@visitor.add(@prefix) unless @called
|
56
|
+
end
|
57
|
+
end
|
58
|
+
# Blank slate object providing the `self` context
|
59
|
+
# in which DSL blocks are evaluated
|
60
|
+
class RecursiveDSLContextBlank
|
61
|
+
extend DTC::Utils::Meta
|
62
|
+
blank_class :instance_exec, :class
|
63
|
+
def initialize delegate, unprefixed = delegate
|
64
|
+
@delegate = delegate
|
65
|
+
@unprefixed = unprefixed
|
66
|
+
end
|
67
|
+
def method_missing(meth, *args, &block)
|
68
|
+
if block
|
69
|
+
@delegate.enter meth, *args
|
70
|
+
self.class.new(@unprefixed, @unprefixed).instance_exec(&block)
|
71
|
+
@unprefixed.flush
|
72
|
+
@delegate.leave
|
73
|
+
else
|
74
|
+
if args.empty?
|
75
|
+
return self.class.new(@delegate.prefix(meth), @unprefixed)
|
76
|
+
else
|
77
|
+
@delegate.add(meth, *args)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
self
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# Visit the DSL provided in `blk` using `visitor`
|
84
|
+
#
|
85
|
+
# Context and delegate classes may be subclassed.
|
86
|
+
def self.accept visitor, context_klass = RecursiveDSLContextBlank,
|
87
|
+
delegate_klass = RecursiveDSLDelegate,
|
88
|
+
&blk
|
89
|
+
visitor = visitor.new() if visitor.is_a?(Class)
|
90
|
+
builder = delegate_klass.new(visitor)
|
91
|
+
context_klass.new(builder).instance_exec(&blk)
|
92
|
+
builder.flush
|
93
|
+
visitor
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module DTC
|
2
|
+
module Utils
|
3
|
+
module Visitor
|
4
|
+
module Folder
|
5
|
+
# Forwards visits only when file/folder name
|
6
|
+
# match the suite of regexen.
|
7
|
+
class FilenameFilteringVisitor < DTC::Utils::Visitor::FilteringForwarder
|
8
|
+
# `options` may define:
|
9
|
+
#
|
10
|
+
# - `:excluded`
|
11
|
+
# - `:excluded_files`
|
12
|
+
# - `:excluded_directories`
|
13
|
+
# - `:included`
|
14
|
+
# - `:included_files`
|
15
|
+
# - `:included_directories`
|
16
|
+
#
|
17
|
+
# Each item is then included only if no includes are defined,
|
18
|
+
# or it matches one of the includes, and if no exclusions are
|
19
|
+
# defined, or it does not match one of the exclusions.
|
20
|
+
#
|
21
|
+
# Each key of `options` is an array of strings that will be
|
22
|
+
# compiled into case-insensitive regexen
|
23
|
+
def initialize listener, options = {}
|
24
|
+
super listener
|
25
|
+
@excluded = compile_regexp(options[:excluded])
|
26
|
+
@excluded_files = compile_regexp(options[:excluded_files])
|
27
|
+
@excluded_directories = compile_regexp(options[:excluded_directories])
|
28
|
+
@included = compile_regexp(options[:included])
|
29
|
+
@included_files = compile_regexp(options[:included_files])
|
30
|
+
@included_directories = compile_regexp(options[:included_directories])
|
31
|
+
end
|
32
|
+
protected
|
33
|
+
def compile_regexp(rx_list)
|
34
|
+
return nil if rx_list.nil? || rx_list.reject { |e| e.length == 0 }.empty?
|
35
|
+
Regexp.union(*rx_list.map { |e| /#{e}/i })
|
36
|
+
end
|
37
|
+
def include?(is_file, name, *args)
|
38
|
+
name = File.basename(name) unless is_file
|
39
|
+
can_include = (@included.nil? || @included.match(name)) &&
|
40
|
+
((is_file && (@included_files.nil? || @included_files.match(name))) ||
|
41
|
+
(!is_file && (@included_directories.nil? || @included_directories.match(name))))
|
42
|
+
if can_include
|
43
|
+
can_include = (@excluded.nil? || !@excluded.match(name)) &&
|
44
|
+
((is_file && (@excluded_files.nil? || !@excluded_files.match(name))) ||
|
45
|
+
(!is_file && (@excluded_directories.nil? || !@excluded_directories.match(name))))
|
46
|
+
end
|
47
|
+
can_include
|
48
|
+
end
|
49
|
+
end
|
50
|
+
# Visit the path provided using `visitor`,
|
51
|
+
# (or a transparent FilenameFilteringVisitor if options
|
52
|
+
# include filtering)
|
53
|
+
#
|
54
|
+
# `options` may include a `:max_depth` key,
|
55
|
+
# or any keys used by `FilenameFilteringVisitor`
|
56
|
+
def self.accept visitor, path, options = {}
|
57
|
+
visitor = visitor.new() if visitor.is_a?(Class)
|
58
|
+
options = options.is_a?(Fixnum) ? ({:max_depth => options}) : options.dup
|
59
|
+
max_depth = options.delete(:max_depth) { -1 }
|
60
|
+
filter = options.empty? ? visitor :
|
61
|
+
FilenameFilteringVisitor.new(visitor, options)
|
62
|
+
accept_path filter, File.expand_path(path), max_depth
|
63
|
+
visitor
|
64
|
+
end
|
65
|
+
def self.accept_path visitor, path, max_depth = -1
|
66
|
+
dir = Dir.new(path)
|
67
|
+
return unless visitor.enter path
|
68
|
+
dir.each do |f|
|
69
|
+
full_path = File.join(path, f)
|
70
|
+
next if f == "." || f == ".."
|
71
|
+
if File.directory? full_path
|
72
|
+
return unless File.readable?(path)
|
73
|
+
if max_depth == 0
|
74
|
+
visitor.leave if visitor.enter(full_path)
|
75
|
+
else
|
76
|
+
self.accept_path(visitor, full_path, max_depth - 1)
|
77
|
+
end
|
78
|
+
else
|
79
|
+
visitor.add f, full_path
|
80
|
+
end
|
81
|
+
end
|
82
|
+
visitor.leave
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,272 @@
|
|
1
|
+
module DTC
|
2
|
+
module Utils
|
3
|
+
# Utilities for objects that repond to:
|
4
|
+
#
|
5
|
+
# - `enter(*arguments)`: return true to enter branch
|
6
|
+
# - `leave()`
|
7
|
+
# - `add(*arguments)
|
8
|
+
module Visitor
|
9
|
+
autoload :DSL, 'dtc/utils/visitor/dsl'
|
10
|
+
autoload :Folder, 'dtc/utils/visitor/folder'
|
11
|
+
|
12
|
+
# Forward visitor events to current
|
13
|
+
# value of `next_visitor`. Defaults
|
14
|
+
# to returning `true` for all `enter()`
|
15
|
+
class Forwarder
|
16
|
+
attr_accessor :next_visitor
|
17
|
+
def initialize next_visitor = nil
|
18
|
+
self.next_visitor = next_visitor if next_visitor
|
19
|
+
end
|
20
|
+
def enter *args
|
21
|
+
next_visitor ? next_visitor.enter(*args) : true
|
22
|
+
end
|
23
|
+
def add *args
|
24
|
+
next_visitor.add(*args) if next_visitor
|
25
|
+
end
|
26
|
+
def leave
|
27
|
+
next_visitor.leave if next_visitor
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Base class for visitors that redirect their calls
|
32
|
+
# to other visitors for sub-branches.
|
33
|
+
#
|
34
|
+
# Override `visitor_for_subtree` and return a new visitor
|
35
|
+
# to begin receiving calls *below* current symbol.
|
36
|
+
#
|
37
|
+
# When the branch is visited and after the new visitor
|
38
|
+
# is popped, `visitor_left_subtree` is called with original
|
39
|
+
# arguments as given to `enter`.
|
40
|
+
class Switcher < Forwarder
|
41
|
+
def initialize receiver
|
42
|
+
@visitor_full_stack = [receiver]
|
43
|
+
@visitor_stack = [[receiver]]
|
44
|
+
super receiver
|
45
|
+
end
|
46
|
+
def enter *args
|
47
|
+
sub_visitor = visitor_for_subtree(*args)
|
48
|
+
@visitor_full_stack.push(sub_visitor)
|
49
|
+
if sub_visitor
|
50
|
+
@visitor_stack.push([sub_visitor, *args])
|
51
|
+
self.next_visitor = sub_visitor
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def leave
|
57
|
+
visitor = @visitor_full_stack.pop
|
58
|
+
if visitor
|
59
|
+
previous_visitor = @visitor_stack.pop
|
60
|
+
self.next_visitor = (@visitor_stack.last || []).first
|
61
|
+
visitor_left_subtree *previous_visitor
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
protected
|
67
|
+
def visitor_for_subtree *args
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
def visitor_left_subtree visitor, *args
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Printing forwarding visitor
|
75
|
+
#
|
76
|
+
# The constructor accepts a block to replace the
|
77
|
+
# default printing mecanism.
|
78
|
+
class Printer < Forwarder
|
79
|
+
def initialize next_visitor = nil, &printer # :yields: depth, method, *args
|
80
|
+
@printer = printer || lambda { |depth, method, *args|
|
81
|
+
puts(
|
82
|
+
(" " * depth) +
|
83
|
+
method.inspect +
|
84
|
+
(args.empty? ? "" : " " + args.inspect)
|
85
|
+
)
|
86
|
+
}
|
87
|
+
@depth = 0
|
88
|
+
super next_visitor
|
89
|
+
end
|
90
|
+
def enter *args
|
91
|
+
print :enter, *args
|
92
|
+
@depth += 1
|
93
|
+
super
|
94
|
+
end
|
95
|
+
def leave
|
96
|
+
@depth -= 1
|
97
|
+
super
|
98
|
+
end
|
99
|
+
def add *args
|
100
|
+
print :add, *args
|
101
|
+
super
|
102
|
+
end
|
103
|
+
protected
|
104
|
+
def print method, *args
|
105
|
+
@printer.call(@depth, method, *args)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Base class for visitors that create a data
|
110
|
+
# structure based on calls.
|
111
|
+
#
|
112
|
+
# Obtain result of visit with `root`
|
113
|
+
#
|
114
|
+
# Default behaviour is to build an
|
115
|
+
# array based structure. Override `new_inner`
|
116
|
+
# to create and return new inner nodes,
|
117
|
+
# and `new_outer` to create and return outer
|
118
|
+
# nodes.
|
119
|
+
#
|
120
|
+
# Example:
|
121
|
+
# DTC::Utils::Visitor::DSL::accept(DTC::Utils::Visitor::Builder) {
|
122
|
+
# container(:arg1) { child_item(:arg2) }
|
123
|
+
# root_child_item
|
124
|
+
# }.root
|
125
|
+
#
|
126
|
+
# =>
|
127
|
+
#
|
128
|
+
# [[:inner, [:container, :arg1], [:outer, [:child_item, :arg2]]],
|
129
|
+
# [:outer, [:root_child_item]]]
|
130
|
+
class Builder
|
131
|
+
def initialize root = []
|
132
|
+
@stack = [root]
|
133
|
+
end
|
134
|
+
def root
|
135
|
+
@stack.first
|
136
|
+
end
|
137
|
+
def enter *args
|
138
|
+
container = new_inner(*args)
|
139
|
+
@stack.push(container) if container
|
140
|
+
container
|
141
|
+
end
|
142
|
+
def leave
|
143
|
+
@stack.pop
|
144
|
+
end
|
145
|
+
def add *args
|
146
|
+
new_outer *args
|
147
|
+
end
|
148
|
+
protected
|
149
|
+
# Last value provided by `new_inner`, also
|
150
|
+
# known as "current parent"
|
151
|
+
def current_inner_node
|
152
|
+
@stack.last
|
153
|
+
end
|
154
|
+
def new_inner *args
|
155
|
+
container = [:inner, args]
|
156
|
+
current_inner_node << container
|
157
|
+
container
|
158
|
+
end
|
159
|
+
def new_outer *args
|
160
|
+
current_inner_node << [:outer, args]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Adds a replay ability to the builder visitor.
|
165
|
+
class Recorder < Builder
|
166
|
+
# Replay all calls made on self to `visitor`
|
167
|
+
def accept visitor
|
168
|
+
visitor = visitor.new if visitor.is_a?(Class)
|
169
|
+
accept_inner visitor, root
|
170
|
+
end
|
171
|
+
protected
|
172
|
+
def accept_inner visitor, inner
|
173
|
+
inner.each do |node|
|
174
|
+
case node.first
|
175
|
+
when :outer
|
176
|
+
visitor.add *node.last
|
177
|
+
when :inner
|
178
|
+
if visitor.enter(*node[1])
|
179
|
+
accept_inner(visitor, node.drop(2))
|
180
|
+
visitor.leave
|
181
|
+
else
|
182
|
+
puts"NO"
|
183
|
+
end
|
184
|
+
else
|
185
|
+
raise RuntimeError, "Unknown node: #{node.inspect}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
visitor
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Subclasses the `Builder` to create
|
193
|
+
# hash based hierarchies, using the first
|
194
|
+
# argument as the key in the parent hash
|
195
|
+
#
|
196
|
+
# Does not tolerate duplicate keys by default.
|
197
|
+
# Override `key_collision` to change this.
|
198
|
+
#
|
199
|
+
# Example:
|
200
|
+
#
|
201
|
+
# DTC::Utils::Visitor::DSL::accept(DTC::Utils::Visitor::HashBuilder) {
|
202
|
+
# container(:arg1) { child_item(:arg2) }
|
203
|
+
# root_child_item
|
204
|
+
# }.root
|
205
|
+
#
|
206
|
+
# =>
|
207
|
+
#
|
208
|
+
# {:container=>{nil=>[:arg1], :child_item=>[:arg2]}, :root_child_item=>[]}
|
209
|
+
class HashBuilder < Builder
|
210
|
+
def initialize root = {}
|
211
|
+
super root
|
212
|
+
end
|
213
|
+
protected
|
214
|
+
def key_collision key, new_args, previous_args
|
215
|
+
raise RuntimeError, "Key #{key.inspect} already defined" if container[key]
|
216
|
+
end
|
217
|
+
def add_child key, value
|
218
|
+
container = current_inner_node
|
219
|
+
if (previous = container[key])
|
220
|
+
value = key_collision(key, value, previous)
|
221
|
+
end
|
222
|
+
container[key] = value
|
223
|
+
value
|
224
|
+
end
|
225
|
+
def new_inner key, *args
|
226
|
+
container = {}
|
227
|
+
container[nil] = args unless args.empty?
|
228
|
+
add_child key, container
|
229
|
+
end
|
230
|
+
def new_outer key, *args
|
231
|
+
add_child key, args
|
232
|
+
args
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Base class for forwarding visitors
|
237
|
+
# that forward events only for items
|
238
|
+
# on which a call to `include?(is_leaf, *args)`
|
239
|
+
# returns true.
|
240
|
+
#
|
241
|
+
# You can include, but not descend,
|
242
|
+
# a node by overriding `descend?(*args)` too.
|
243
|
+
class FilteringForwarder < Forwarder
|
244
|
+
def enter *args
|
245
|
+
return false unless include?(false, *args)
|
246
|
+
if (result = super) && !descend?(*args)
|
247
|
+
leave
|
248
|
+
return false
|
249
|
+
end
|
250
|
+
result
|
251
|
+
end
|
252
|
+
def add *args
|
253
|
+
return false unless include?(true, *args)
|
254
|
+
super
|
255
|
+
end
|
256
|
+
protected
|
257
|
+
def descend?(*args) ; true ; end
|
258
|
+
def include?(is_leaf, *args) ; true ; end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Include this module in a class that
|
262
|
+
# responds to a flat tree visit, so only `add`
|
263
|
+
# methods, where the first argument is expected
|
264
|
+
# to be a symbol the class responds to
|
265
|
+
module AcceptAsFlatMethodCalls
|
266
|
+
def enter *args ; raise RuntimeError, "Blocks are not supported for #{self.class.name} (got on #{args.inspect})" ; end
|
267
|
+
def leave ; end
|
268
|
+
def add sym, *args ; self.__send__(sym, *args) ; end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
data/lib/dtc/utils.rb
CHANGED
@@ -2,8 +2,10 @@ module DTC
|
|
2
2
|
module Utils
|
3
3
|
autoload :Exec, 'dtc/utils/exec'
|
4
4
|
autoload :InteractiveEditor, 'dtc/utils/interactive_edit'
|
5
|
+
autoload :Meta, 'dtc/utils/meta'
|
5
6
|
autoload :MiniSelect, 'dtc/utils/mini_select'
|
6
|
-
autoload :DSLDSL, 'dtc/utils/dsldsl'
|
7
7
|
autoload :FileVisitor, 'dtc/utils/file_visitor'
|
8
|
+
autoload :Text, 'dtc/utils/text'
|
9
|
+
autoload :Visitor, 'dtc/utils/visitor'
|
8
10
|
end
|
9
11
|
end
|