chirp 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/History.txt +0 -0
- data/Manifest.txt +44 -2
- data/README.txt +10 -2
- data/Rakefile +1 -1
- data/bin/chirp +6 -4
- data/lib/chirp.rb +7 -3
- data/lib/chirp/application.rb +248 -159
- data/lib/chirp/context.rb +101 -0
- data/lib/chirp/fs_expression.rb +180 -0
- data/lib/chirp/path_filter.rb +58 -0
- data/lib/chirp/pathmap.rb +200 -0
- data/lib/chirp/span.rb +38 -0
- data/test/account.dir/input +0 -0
- data/test/account.dir/output +0 -0
- data/test/account.dir/program.chirp +7 -4
- data/test/action.dir/input +0 -0
- data/test/action.dir/output +0 -0
- data/test/action.dir/program.chirp +2 -2
- data/test/beforeafter.dir/input +0 -0
- data/test/beforeafter.dir/output +0 -0
- data/test/beforeafter.dir/program.chirp +3 -3
- data/test/copy1.dir/input +0 -0
- data/test/copy1.dir/output +5 -0
- data/test/copy1.dir/program.chirp +9 -0
- data/test/copy1.dir/source +2 -0
- data/test/copy2.dir/input +0 -0
- data/test/copy2.dir/output +5 -0
- data/test/copy2.dir/program.chirp +9 -0
- data/test/copy2.dir/source +2 -0
- data/test/copy3.dir/input +0 -0
- data/test/copy3.dir/output +5 -0
- data/test/copy3.dir/program.chirp +7 -0
- data/test/copy3.dir/source +2 -0
- data/test/copy_file.dir/a.txt +1 -0
- data/test/copy_file.dir/b.txt +1 -0
- data/test/copy_file.dir/c.txt +1 -0
- data/test/copy_file.dir/input +0 -0
- data/test/copy_file.dir/output +2 -0
- data/test/copy_file.dir/program.chirp +5 -0
- data/test/fields.dir/input +0 -0
- data/test/fields.dir/output +0 -0
- data/test/fields.dir/program.chirp +2 -2
- data/test/fields_sep.dir/input +0 -0
- data/test/fields_sep.dir/output +0 -0
- data/test/fields_sep.dir/program.chirp +1 -2
- data/test/files.dir/a.ignore +0 -0
- data/test/files.dir/a.txt +0 -0
- data/test/files.dir/b.txt +0 -0
- data/test/files.dir/c.stuff +0 -0
- data/test/files.dir/input +0 -0
- data/test/files.dir/output +3 -0
- data/test/files.dir/program.chirp +7 -3
- data/test/fs_expr.dir/aa.txt +1 -0
- data/test/fs_expr.dir/bb.txt +9 -0
- data/test/fs_expr.dir/cc.txt +0 -0
- data/test/fs_expr.dir/dir1/dir2/dir3/a.txt +1 -0
- data/test/fs_expr.dir/input +0 -0
- data/test/fs_expr.dir/output +7 -0
- data/test/fs_expr.dir/program.chirp +17 -0
- data/test/inplace.dir/a.txt +0 -0
- data/test/inplace.dir/b.txt +0 -0
- data/test/inplace.dir/input +0 -0
- data/test/inplace.dir/output +0 -0
- data/test/inplace.dir/program.chirp +4 -6
- data/test/line_no.dir/input +0 -0
- data/test/line_no.dir/output +1 -0
- data/test/line_no.dir/program.chirp +5 -1
- data/test/match.dir/input +0 -0
- data/test/match.dir/output +0 -0
- data/test/match.dir/program.chirp +1 -1
- data/test/path.dir/dir1/dir2/dir3/a.txt +1 -0
- data/test/path.dir/input +0 -0
- data/test/path.dir/new +5 -0
- data/test/path.dir/output +20 -0
- data/test/path.dir/program.chirp +44 -0
- data/test/proc.dir/input +0 -0
- data/test/proc.dir/output +0 -0
- data/test/proc.dir/program.chirp +2 -2
- data/test/rename_file.dir/a.txt +4 -0
- data/test/rename_file.dir/b.txt +4 -0
- data/test/rename_file.dir/c.txt +4 -0
- data/test/rename_file.dir/input +0 -0
- data/test/rename_file.dir/output +2 -0
- data/test/rename_file.dir/program.chirp +7 -0
- data/test/requires.rb +6 -0
- data/test/span.dir/input +0 -0
- data/test/span.dir/output +0 -0
- data/test/span.dir/program.chirp +1 -1
- data/test/span2.dir/input +0 -0
- data/test/span2.dir/output +0 -0
- data/test/span2.dir/program.chirp +3 -1
- data/test/string.dir/input +0 -0
- data/test/string.dir/output +0 -0
- data/test/string.dir/program.chirp +1 -1
- data/test/test_application.rb +14 -9
- data/test/test_fs_expression.rb +99 -0
- data/test/test_span.rb +36 -0
- metadata +64 -7
- data/lib/chirp/statement.rb +0 -91
- data/test/test_statement.rb +0 -118
data/History.txt
CHANGED
|
File without changes
|
data/Manifest.txt
CHANGED
|
@@ -5,8 +5,17 @@ Rakefile
|
|
|
5
5
|
bin/chirp
|
|
6
6
|
lib/chirp.rb
|
|
7
7
|
lib/chirp/application.rb
|
|
8
|
-
lib/chirp/
|
|
9
|
-
|
|
8
|
+
lib/chirp/pathmap.rb
|
|
9
|
+
lib/chirp/context.rb
|
|
10
|
+
lib/chirp/fs_expression.rb
|
|
11
|
+
lib/chirp/span.rb
|
|
12
|
+
lib/chirp/path_filter.rb
|
|
13
|
+
test/copy_file.dir/output
|
|
14
|
+
test/copy_file.dir/input
|
|
15
|
+
test/copy_file.dir/program.chirp
|
|
16
|
+
test/copy_file.dir/a.txt
|
|
17
|
+
test/copy_file.dir/b.txt
|
|
18
|
+
test/copy_file.dir/c.txt
|
|
10
19
|
test/test_application.rb
|
|
11
20
|
test/span.dir/output
|
|
12
21
|
test/span.dir/input
|
|
@@ -53,3 +62,36 @@ test/proc.dir/program.chirp
|
|
|
53
62
|
test/account.dir/program.chirp
|
|
54
63
|
test/account.dir/output
|
|
55
64
|
test/account.dir/input
|
|
65
|
+
test/path.dir/output
|
|
66
|
+
test/path.dir/input
|
|
67
|
+
test/path.dir/program.chirp
|
|
68
|
+
test/path.dir/new
|
|
69
|
+
test/path.dir/dir1/dir2/dir3/a.txt
|
|
70
|
+
test/test_span.rb
|
|
71
|
+
test/rename_file.dir/output
|
|
72
|
+
test/rename_file.dir/input
|
|
73
|
+
test/rename_file.dir/program.chirp
|
|
74
|
+
test/rename_file.dir/a.txt
|
|
75
|
+
test/rename_file.dir/b.txt
|
|
76
|
+
test/rename_file.dir/c.txt
|
|
77
|
+
test/copy1.dir/program.chirp
|
|
78
|
+
test/copy1.dir/source
|
|
79
|
+
test/copy1.dir/input
|
|
80
|
+
test/copy1.dir/output
|
|
81
|
+
test/copy2.dir/program.chirp
|
|
82
|
+
test/copy2.dir/source
|
|
83
|
+
test/copy2.dir/input
|
|
84
|
+
test/copy2.dir/output
|
|
85
|
+
test/copy3.dir/program.chirp
|
|
86
|
+
test/copy3.dir/source
|
|
87
|
+
test/copy3.dir/input
|
|
88
|
+
test/copy3.dir/output
|
|
89
|
+
test/test_fs_expression.rb
|
|
90
|
+
test/fs_expr.dir/output
|
|
91
|
+
test/fs_expr.dir/input
|
|
92
|
+
test/fs_expr.dir/program.chirp
|
|
93
|
+
test/fs_expr.dir/dir1/dir2/dir3/a.txt
|
|
94
|
+
test/fs_expr.dir/bb.txt
|
|
95
|
+
test/fs_expr.dir/aa.txt
|
|
96
|
+
test/fs_expr.dir/cc.txt
|
|
97
|
+
test/requires.rb
|
data/README.txt
CHANGED
|
@@ -4,11 +4,19 @@ chirp
|
|
|
4
4
|
|
|
5
5
|
== DESCRIPTION:
|
|
6
6
|
|
|
7
|
-
Chirp is a Ruby based DSL inspiried by awk.
|
|
7
|
+
Chirp is a Ruby based DSL originally inspiried by awk.
|
|
8
8
|
|
|
9
9
|
== FEATURES/PROBLEMS:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Chirp is a DSL for manipulating file systems. In the same
|
|
12
|
+
way that rake is aimed at making system buildig easy,
|
|
13
|
+
chirp is designed to make doing things to entire file
|
|
14
|
+
systems easy.
|
|
15
|
+
|
|
16
|
+
Chirp is still very much in development and you should
|
|
17
|
+
be very careful with it: since chirp does operate on
|
|
18
|
+
whole directory trees, it is capable of doing a lot of
|
|
19
|
+
damage.
|
|
12
20
|
|
|
13
21
|
== SYNOPSIS:
|
|
14
22
|
|
data/Rakefile
CHANGED
|
@@ -9,7 +9,7 @@ Hoe.new('chirp', Chirp::VERSION) do |p|
|
|
|
9
9
|
p.author = 'Russ Olsen'
|
|
10
10
|
p.email = 'russ@russolsen.com'
|
|
11
11
|
p.summary = 'Chirp is a Ruby based text processing DSL similar to awk'
|
|
12
|
-
|
|
12
|
+
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
|
13
13
|
# p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
|
14
14
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
|
15
15
|
end
|
data/bin/chirp
CHANGED
|
@@ -12,7 +12,7 @@ program_text=nil
|
|
|
12
12
|
verbose=false
|
|
13
13
|
|
|
14
14
|
option_parser = OptionParser.new do |op|
|
|
15
|
-
op.banner = "Usage:
|
|
15
|
+
op.banner = "Usage: chirp [-v] [-e chirp_program_text] [chirp_program_file] [input_file ...]"
|
|
16
16
|
|
|
17
17
|
op.on('-p', '--program [chirp-program-text]',
|
|
18
18
|
'Execute this Chirp program') do |string|
|
|
@@ -33,10 +33,12 @@ if files.empty? and program_text.nil?
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
program_text = File.read(files.shift) unless program_text
|
|
36
|
+
ARGV.replace(files)
|
|
36
37
|
|
|
37
|
-
app = Chirp::Application.new
|
|
38
|
-
app.
|
|
39
|
-
app.
|
|
38
|
+
app = Chirp::Application.new
|
|
39
|
+
app.program(program_text)
|
|
40
|
+
app.verbose(verbose)
|
|
41
|
+
app.execute
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
|
data/lib/chirp.rb
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
# Chirp is distributed under the same license as Ruby itself.
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
-
ChirpLibDir=File.dirname(__FILE__)
|
|
7
|
+
ChirpLibDir=File.dirname(__FILE__) unless self.class.const_defined?(:ChirpLibDir)
|
|
8
8
|
|
|
9
|
-
require "#{ChirpLibDir}/chirp/
|
|
9
|
+
require "#{ChirpLibDir}/chirp/pathmap"
|
|
10
|
+
require "#{ChirpLibDir}/chirp/fs_expression"
|
|
11
|
+
require "#{ChirpLibDir}/chirp/context"
|
|
12
|
+
require "#{ChirpLibDir}/chirp/path_filter"
|
|
13
|
+
require "#{ChirpLibDir}/chirp/span"
|
|
10
14
|
require "#{ChirpLibDir}/chirp/application"
|
|
11
15
|
|
|
12
16
|
module Chirp
|
|
13
|
-
VERSION = '0.
|
|
17
|
+
VERSION = '0.3'
|
|
14
18
|
end
|
data/lib/chirp/application.rb
CHANGED
|
@@ -1,252 +1,341 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require 'pathname'
|
|
7
|
-
require 'ftools'
|
|
8
|
-
require 'fileutils'
|
|
1
|
+
require 'pp'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
require 'set'
|
|
4
|
+
require 'find'
|
|
9
5
|
|
|
10
6
|
module Chirp
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
old_stdin, $stdin = $stdin,
|
|
7
|
+
|
|
8
|
+
def self.run_with_input_stream(in_stream, &block)
|
|
9
|
+
old_stdin, $stdin = $stdin, in_stream
|
|
14
10
|
begin
|
|
15
11
|
block.call
|
|
16
12
|
ensure
|
|
17
|
-
$stdin
|
|
13
|
+
$stdin = old_stdin
|
|
18
14
|
end
|
|
19
15
|
end
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
def self.run_with_output_stream(out_stream, &block)
|
|
18
|
+
old_stdout, $stdout = $stdout, out_stream
|
|
19
|
+
begin
|
|
20
|
+
block.call
|
|
21
|
+
ensure
|
|
22
|
+
$stdout = old_stdout
|
|
23
|
+
end
|
|
24
|
+
end
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
def self.run_with_input_file(in_file, &block)
|
|
27
|
+
File.open(in_file) {|f| run_with_input_stream(f, &block)}
|
|
28
|
+
end
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
def self.run_with_output_file(out_file, create_backups=false, &block)
|
|
31
|
+
temp_file = Tempfile.new('chirp').path
|
|
32
|
+
File.open(temp_file, 'w') do |out_stream|
|
|
33
|
+
run_with_output_stream(out_stream, &block)
|
|
29
34
|
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
backup_file = nil
|
|
36
|
+
if create_backups and File.exist?(out_file)
|
|
37
|
+
backup_file = Tempfile.new('chirp').path
|
|
38
|
+
FileUtils.cp(out_file, backup_file) if File.exist?(out_file)
|
|
33
39
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
FileUtils.cp(temp_file, out_file)
|
|
41
|
+
FileUtils.rm(temp_file)
|
|
42
|
+
if backup_file
|
|
43
|
+
FileUtils.cp(backup_file, "#{out_file}.bak")
|
|
44
|
+
FileUtils.rm(backup_file)
|
|
37
45
|
end
|
|
46
|
+
end
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
|
|
49
|
+
def self.debug(*msg)
|
|
50
|
+
STDERR.puts msg.join(' ')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class PathProcessor
|
|
55
|
+
def initialize(context, options={}, &block)
|
|
56
|
+
@context = context
|
|
57
|
+
@filter = PathFilter.new(options)
|
|
58
|
+
@block = block
|
|
41
59
|
end
|
|
42
|
-
|
|
43
|
-
def
|
|
44
|
-
@
|
|
60
|
+
|
|
61
|
+
def execute
|
|
62
|
+
@context.debug("PathProcessor execute for #{@context.path}")
|
|
63
|
+
if @filter.passes?(@context.path)
|
|
64
|
+
@context.execute(@block)
|
|
65
|
+
else
|
|
66
|
+
@context.debug("Filter blocked #{@context.path}")
|
|
67
|
+
@context.debug("Filter: #{@filter}")
|
|
68
|
+
end
|
|
45
69
|
end
|
|
46
70
|
end
|
|
47
71
|
|
|
48
|
-
class
|
|
72
|
+
class LineProcessor
|
|
73
|
+
DEFAULT_ACTION = lambda { puts(line) }
|
|
74
|
+
|
|
75
|
+
def initialize(context, options={}, &block)
|
|
76
|
+
|
|
77
|
+
@context = context
|
|
78
|
+
@expression = options[:expr]
|
|
79
|
+
@pattern = options[:pattern]
|
|
80
|
+
@match = options[:match]
|
|
81
|
+
@number = options[:number]
|
|
82
|
+
if options[:start]
|
|
83
|
+
@span = Span.new(options[:start], options[:end])
|
|
84
|
+
else
|
|
85
|
+
@span=nil
|
|
86
|
+
end
|
|
87
|
+
@options = options
|
|
88
|
+
@block = block || DEFAULT_ACTION
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def execute
|
|
92
|
+
if @match
|
|
93
|
+
return unless @match == @context.line
|
|
94
|
+
end
|
|
95
|
+
if @pattern
|
|
96
|
+
return unless @pattern =~ @context.line
|
|
97
|
+
end
|
|
98
|
+
if @number
|
|
99
|
+
return unless @number == @context.line_no
|
|
100
|
+
end
|
|
101
|
+
if @expression
|
|
102
|
+
return unless @context.execute(@expression)
|
|
103
|
+
end
|
|
104
|
+
if @span
|
|
105
|
+
return unless @span.evaluate(@context)
|
|
106
|
+
end
|
|
107
|
+
@context.execute(@block)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def reset
|
|
111
|
+
@span.reset if @span
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class NowProcessor
|
|
49
116
|
def initialize(context, &block)
|
|
50
117
|
@context = context
|
|
51
118
|
@block = block
|
|
52
119
|
end
|
|
53
120
|
|
|
54
|
-
def
|
|
55
|
-
@context.path = path
|
|
121
|
+
def execute
|
|
56
122
|
@context.execute(@block)
|
|
57
123
|
end
|
|
124
|
+
end
|
|
58
125
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@context
|
|
126
|
+
class StaringWithProcessor
|
|
127
|
+
def initialize(context, path)
|
|
128
|
+
@context = context
|
|
129
|
+
@path = path
|
|
62
130
|
end
|
|
63
131
|
|
|
132
|
+
def execute
|
|
133
|
+
@context.dir = @path
|
|
134
|
+
end
|
|
64
135
|
end
|
|
65
136
|
|
|
66
|
-
class
|
|
67
|
-
DEFAULT_ACTION = lambda {puts line}
|
|
137
|
+
class EachProcessor
|
|
68
138
|
|
|
69
|
-
|
|
139
|
+
include Chirp::FSSugar
|
|
70
140
|
|
|
71
|
-
def initialize(
|
|
72
|
-
@glob = glob
|
|
141
|
+
def initialize(context, options={}, &block)
|
|
73
142
|
@context = context
|
|
74
|
-
@
|
|
75
|
-
@
|
|
76
|
-
@
|
|
77
|
-
@
|
|
78
|
-
@
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@
|
|
143
|
+
@filter = PathFilter.new(options)
|
|
144
|
+
@field_separator = options[:field_separator]
|
|
145
|
+
@block = block
|
|
146
|
+
@output_spec = options[:output]
|
|
147
|
+
@create_backups = options[:create_backups]
|
|
148
|
+
@redirect_output = options.key?(:redirect_output) ? options[:redirect_output] : true
|
|
149
|
+
@context = context
|
|
150
|
+
@before_processors = []
|
|
151
|
+
@content_processors = []
|
|
152
|
+
@after_processors = []
|
|
153
|
+
instance_eval(&block) if block
|
|
84
154
|
end
|
|
85
155
|
|
|
86
|
-
def
|
|
87
|
-
@
|
|
156
|
+
def before(options={}, &block)
|
|
157
|
+
@before_processors << PathProcessor.new(@context, options, &block)
|
|
88
158
|
end
|
|
89
159
|
|
|
90
|
-
def
|
|
91
|
-
@context
|
|
92
|
-
paths.each do |path|
|
|
93
|
-
evaluate_path(path)
|
|
94
|
-
end
|
|
160
|
+
def after(options={}, &block)
|
|
161
|
+
@after_processors << PathProcessor.new(@context, options, &block)
|
|
95
162
|
end
|
|
96
163
|
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if arg1.nil? and arg2.nil?
|
|
101
|
-
@match_statements << Statement.new( MatchPredicate.new(/.*/), action)
|
|
102
|
-
elsif arg2.nil?
|
|
103
|
-
@match_statements << Statement.new( predicate_for(arg1), action)
|
|
104
|
-
else
|
|
105
|
-
@match_statements << Statement.new(
|
|
106
|
-
SpanPredicate.new(predicate_for(arg1), predicate_for(arg2)), action)
|
|
107
|
-
end
|
|
164
|
+
def path(options={}, &block)
|
|
165
|
+
before(options, &block)
|
|
108
166
|
end
|
|
109
167
|
|
|
110
|
-
def
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def after(&block)
|
|
115
|
-
@after_actions << block
|
|
168
|
+
def file(options={}, &block)
|
|
169
|
+
new_options = options.clone
|
|
170
|
+
new_options[:type] = :file
|
|
171
|
+
before(new_options, &block)
|
|
116
172
|
end
|
|
117
173
|
|
|
118
|
-
def
|
|
119
|
-
|
|
174
|
+
def dir(options={}, &block)
|
|
175
|
+
new_options = options.clone
|
|
176
|
+
new_options[:type] = :dir
|
|
177
|
+
before(new_options, &block)
|
|
120
178
|
end
|
|
121
179
|
|
|
122
|
-
def
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
180
|
+
def line(options={}, &block)
|
|
181
|
+
@content_processors << LineProcessor.new(@context, options, &block)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def execute
|
|
185
|
+
@context.paths = filtered_files(@context.dir)
|
|
186
|
+
@context.paths.each do |path|
|
|
187
|
+
@context.debug( "Trying out processor #{self} for #{path} and #{@filter}" )
|
|
188
|
+
@context.path = path
|
|
189
|
+
@context.debug( "Executing processor #{self} for #{path}" )
|
|
190
|
+
@context.output_path = @context.path.pathmap(@output_spec) if @output_spec
|
|
191
|
+
if @output_spec and @redirect_output
|
|
192
|
+
Chirp::run_with_output_file(@context.output_path, @create_backups) {process}
|
|
193
|
+
else
|
|
194
|
+
process
|
|
134
195
|
end
|
|
135
196
|
end
|
|
136
|
-
end
|
|
137
197
|
end
|
|
138
198
|
|
|
139
|
-
def
|
|
140
|
-
@
|
|
199
|
+
def process
|
|
200
|
+
@before_processors.each {|p| p.execute}
|
|
201
|
+
process_contents
|
|
202
|
+
@after_processors.each {|p| p.execute}
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def process_contents
|
|
206
|
+
return if @content_processors.empty?
|
|
207
|
+
return unless File.file?(@context.full_path)
|
|
208
|
+
|
|
209
|
+
@content_processors.each {|p| p.reset}
|
|
141
210
|
@context.field_separator = @field_separator
|
|
142
|
-
|
|
143
|
-
|
|
211
|
+
|
|
212
|
+
Chirp::run_with_input_file(@context.full_path) do
|
|
144
213
|
@context.line_no = 1
|
|
145
214
|
while not $stdin.eof?
|
|
146
|
-
@context.fields=nil
|
|
147
215
|
@context.line = $stdin.readline.chomp
|
|
148
|
-
@
|
|
149
|
-
statement.evaluate(@context)
|
|
150
|
-
end
|
|
216
|
+
@content_processors.each {|p| p.execute}
|
|
151
217
|
@context.line_no += 1
|
|
152
218
|
end
|
|
219
|
+
@context.contents = nil
|
|
153
220
|
end
|
|
154
|
-
@context.contents = nil
|
|
155
|
-
@after_actions.each {|a| @context.execute(a)}
|
|
156
221
|
end
|
|
157
222
|
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
223
|
+
def filtered_files(dir)
|
|
224
|
+
results = Set.new
|
|
225
|
+
FileUtils.chdir(dir) do
|
|
226
|
+
Find.find('.') do |p|
|
|
227
|
+
path = p.sub(/^\.\//, '')
|
|
228
|
+
next if path == '.'
|
|
229
|
+
next if path == '..'
|
|
230
|
+
next unless @filter.passes?(path)
|
|
231
|
+
results << path
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
results.sort
|
|
165
235
|
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
236
|
|
|
237
|
+
end
|
|
169
238
|
|
|
170
239
|
class Application
|
|
240
|
+
include Chirp::FSSugar
|
|
171
241
|
|
|
172
|
-
|
|
242
|
+
def initialize
|
|
243
|
+
@processors = []
|
|
244
|
+
@context = Context.new
|
|
245
|
+
end
|
|
173
246
|
|
|
174
|
-
|
|
247
|
+
def program(chirp_string, file='-')
|
|
248
|
+
instance_eval(chirp_string, file)
|
|
249
|
+
end
|
|
175
250
|
|
|
176
|
-
def
|
|
177
|
-
@
|
|
178
|
-
@actions=[]
|
|
179
|
-
@verbose=verbose
|
|
180
|
-
@context = Chirp::Context.new(/[ \t]/)
|
|
181
|
-
self.program=program_string if program_string
|
|
251
|
+
def dir(path)
|
|
252
|
+
@processors << StaringWithProcessor.new(@context, path)
|
|
182
253
|
end
|
|
183
254
|
|
|
184
|
-
def
|
|
185
|
-
|
|
255
|
+
def verbose(setting=true)
|
|
256
|
+
@context.verbose = setting
|
|
186
257
|
end
|
|
187
258
|
|
|
188
|
-
def
|
|
189
|
-
|
|
259
|
+
def now(&block)
|
|
260
|
+
@context.debug('Processing now command:', block)
|
|
261
|
+
@processors << NowProcessor.new(@context, &block)
|
|
190
262
|
end
|
|
191
263
|
|
|
192
|
-
def
|
|
193
|
-
@
|
|
264
|
+
def comment(*args)
|
|
265
|
+
@context.comment(*args)
|
|
194
266
|
end
|
|
195
267
|
|
|
196
|
-
def
|
|
197
|
-
@
|
|
268
|
+
def each(options={}, &block)
|
|
269
|
+
@context.debug('Processing each command:', block)
|
|
270
|
+
@processors << EachProcessor.new(@context, options, &block)
|
|
198
271
|
end
|
|
199
272
|
|
|
200
|
-
def
|
|
201
|
-
@
|
|
202
|
-
|
|
273
|
+
def mv(options={})
|
|
274
|
+
@context.debug('Processing mv command:', options)
|
|
275
|
+
options = options.clone
|
|
276
|
+
options[:create_backups] = false unless options.key?(:create_backups)
|
|
277
|
+
options[:redirect_output]= false
|
|
278
|
+
each_path options do
|
|
279
|
+
raise "Output path not specified for rename" unless output_path
|
|
280
|
+
mv full_path, output_path
|
|
281
|
+
end
|
|
203
282
|
end
|
|
204
283
|
|
|
205
|
-
def
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
log('Running after actions')
|
|
284
|
+
def copy(options={})
|
|
285
|
+
options = options.clone
|
|
286
|
+
options[:create_backups] = false unless options.key?(:create_backups)
|
|
287
|
+
options[:redirect_output]= false
|
|
288
|
+
@context.debug('Processing copy command:', options)
|
|
289
|
+
each_path options do
|
|
290
|
+
raise "Output path not specified for copy" unless output_path
|
|
291
|
+
cp full_path, output_path unless options[:recursive]
|
|
292
|
+
cp_r full_path, output_path if options[:recursive]
|
|
215
293
|
end
|
|
216
|
-
log('Chirp program done')
|
|
217
294
|
end
|
|
218
295
|
|
|
219
|
-
def
|
|
220
|
-
@
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
end
|
|
296
|
+
def each_path(options={}, &block)
|
|
297
|
+
@context.debug('Processing each_path command:', options, block)
|
|
298
|
+
each(options) do
|
|
299
|
+
before(&block)
|
|
224
300
|
end
|
|
225
301
|
end
|
|
226
302
|
|
|
227
|
-
def
|
|
228
|
-
@
|
|
229
|
-
|
|
230
|
-
|
|
303
|
+
def each_file(options={}, &block)
|
|
304
|
+
@context.debug('Processing each_file command:', options, block)
|
|
305
|
+
new_options = options.clone
|
|
306
|
+
new_options[:type] = :file
|
|
307
|
+
each_path(new_options, &block)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def each_line(options={}, &block)
|
|
311
|
+
@context.debug('Processing each_line command:', options, block)
|
|
312
|
+
each(options) do
|
|
313
|
+
line(options,&block)
|
|
231
314
|
end
|
|
232
315
|
end
|
|
233
316
|
|
|
234
|
-
def
|
|
235
|
-
|
|
236
|
-
|
|
317
|
+
def each_dir(options={}, &block)
|
|
318
|
+
@context.debug('Processing each_dir command:', options, block)
|
|
319
|
+
new_options = options.clone
|
|
320
|
+
new_options[:type] = :dir
|
|
321
|
+
each_path(new_options, &block)
|
|
237
322
|
end
|
|
238
323
|
|
|
239
|
-
def
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
324
|
+
def execute(in_stream=$stdin, out_stream=$stdout)
|
|
325
|
+
@context.debug('Application execute')
|
|
326
|
+
|
|
327
|
+
temp_file = nil
|
|
328
|
+
@context.debug('Sources: ', *@context.paths)
|
|
329
|
+
Chirp::run_with_input_stream(in_stream) do
|
|
330
|
+
Chirp::run_with_output_stream(out_stream) do
|
|
331
|
+
@processors.each do |processor|
|
|
332
|
+
@context.debug('Calling ', processor)
|
|
333
|
+
processor.execute
|
|
334
|
+
end
|
|
245
335
|
end
|
|
246
|
-
this_glob_results.sort!
|
|
247
|
-
results << this_glob_results
|
|
248
336
|
end
|
|
249
|
-
|
|
337
|
+
temp_file.unlink if temp_file
|
|
250
338
|
end
|
|
251
339
|
end
|
|
252
340
|
end
|
|
341
|
+
|