frag 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/README.markdown +39 -27
- data/lib/frag/app.rb +149 -37
- data/lib/frag/version.rb +1 -1
- data/test/unit/test_app.rb +253 -11
- metadata +4 -4
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
@@ -23,9 +23,9 @@ Now `frag` that file:
|
|
23
23
|
|
24
24
|
frag ~/.ssh/config
|
25
25
|
|
26
|
-
and the
|
27
|
-
output from [knife sshgen][knife-sshgen]. The delimiter lines remain,
|
28
|
-
re-`frag` anytime to bring it up to date.
|
26
|
+
and the fragment delimited by the `frag:`...`frag end` lines will be filled in
|
27
|
+
with the output from [knife sshgen][knife-sshgen]. The delimiter lines remain,
|
28
|
+
so you can re-`frag` anytime to bring it up to date.
|
29
29
|
|
30
30
|
Or maybe you want your `/etc/hosts` to set a list of local subdomains from a
|
31
31
|
database:
|
@@ -38,37 +38,21 @@ database:
|
|
38
38
|
# frag: mysql myapp -Bre 'select subdomain from sites | sed -e 's/.*/127.0.0.1 &.myapp.local/'
|
39
39
|
# frag end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
Or maybe you're authoring this README and want to show all the options `frag`
|
44
|
-
takes:
|
45
|
-
|
46
|
-
<!-- frag: echo; ruby -Ilib bin/frag --help | sed -e 's/^/ /'; echo -->
|
47
|
-
|
48
|
-
USAGE: bin/frag [options] file ...
|
49
|
-
-b, --begin DELIMITER
|
50
|
-
-e, --end DELIMITER
|
51
|
-
-l, --leader STRING
|
52
|
-
-t, --trailer STRING
|
53
|
-
-p, --backup-prefix PREFIX
|
54
|
-
-s, --backup-suffix SUFFIX
|
55
|
-
|
56
|
-
<!-- frag end -->
|
57
|
-
|
58
|
-
(Check the source... ;-)
|
41
|
+
The command is passed through the [standard shell][standard-shell], so pipelines
|
42
|
+
work fine.
|
59
43
|
|
60
44
|
[chef]: http://www.opscode.com/chef
|
61
45
|
[knife-sshgen]: https://github.com/harvesthq/knife-plugins/blob/master/.chef/plugins/knife/sshgen.rb
|
46
|
+
[standard-shell]: http://www.ruby-doc.org/core-1.9.3/Process.html#method-c-exec
|
62
47
|
|
63
48
|
## Too simple?
|
64
49
|
|
65
|
-
Make
|
50
|
+
Make life complicated with these customizable options.
|
66
51
|
|
67
52
|
### Comment Syntax
|
68
53
|
|
69
|
-
By default, frag assumes the
|
70
|
-
|
71
|
-
`--leader`:
|
54
|
+
By default, frag assumes the fragment delimiters start with a '#' (followed by
|
55
|
+
optional whitespace). Change that with`-l` or `--leader`:
|
72
56
|
|
73
57
|
frag -l '--' magic.hs
|
74
58
|
|
@@ -82,7 +66,7 @@ If you want to choose your own delimiters.
|
|
82
66
|
|
83
67
|
frag -b 'FRAGGED BY' -e 'FRAGGED' file.txt
|
84
68
|
|
85
|
-
Now your
|
69
|
+
Now your fragments can look like:
|
86
70
|
|
87
71
|
# FRAGGED BY ...
|
88
72
|
...
|
@@ -96,7 +80,35 @@ Back up the original file by providing a suffix:
|
|
96
80
|
|
97
81
|
Or dump all your backups into a directory with a prefix:
|
98
82
|
|
99
|
-
frag -p ~/.frag-backups file.txt
|
83
|
+
frag -p ~/.frag-backups/ file.txt
|
84
|
+
|
85
|
+
### Embedded options
|
86
|
+
|
87
|
+
If you actually do need those options above, it's a pain to type them on the
|
88
|
+
command line every time. Instead, you can embed the frag options in the file
|
89
|
+
itself:
|
90
|
+
|
91
|
+
<!-- $frag-config: -b BEGIN -e END -->
|
92
|
+
<!-- BEGIN echo hi -->
|
93
|
+
<!-- END -->
|
94
|
+
|
95
|
+
The leader and trailer will be taken from that of the $frag-config line itself,
|
96
|
+
so you don't need to specify them with the `-l` and `-t` options like earlier.
|
97
|
+
|
98
|
+
You can also use this if you need different comment syntaxes for different parts
|
99
|
+
of the file. For example, if you're embedding CSS in HTML:
|
100
|
+
|
101
|
+
<!-- $frag-config: -->
|
102
|
+
<!-- frag: echo hi -->
|
103
|
+
<!-- frag end -->
|
104
|
+
|
105
|
+
...
|
106
|
+
|
107
|
+
/* $frag-config: */
|
108
|
+
/* frag: echo hi */
|
109
|
+
/* frag end */
|
110
|
+
|
111
|
+
...
|
100
112
|
|
101
113
|
## Note on Patches/Pull Requests
|
102
114
|
|
data/lib/frag/app.rb
CHANGED
@@ -1,54 +1,29 @@
|
|
1
1
|
require 'tempfile'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'optparse'
|
4
|
+
require 'shellwords'
|
4
5
|
|
5
6
|
module Frag
|
6
7
|
class App
|
7
8
|
def initialize(args, input=STDIN, output=STDOUT, error=STDERR)
|
8
9
|
@input, @output, @error = input, output, error
|
9
10
|
@status = 0
|
11
|
+
@version_printed = false
|
10
12
|
|
11
|
-
|
12
|
-
ending = 'frag end'
|
13
|
-
leader = '#'
|
14
|
-
trailer = ''
|
15
|
-
@backup_prefix = @backup_suffix = nil
|
16
|
-
|
17
|
-
parser = OptionParser.new do |parser|
|
18
|
-
parser.banner = "USAGE: #$0 [options] file ..."
|
19
|
-
|
20
|
-
parser.on '-b', '--begin DELIMITER' do |value|
|
21
|
-
beginning = Regexp.escape(value)
|
22
|
-
end
|
23
|
-
parser.on '-e', '--end DELIMITER' do |value|
|
24
|
-
ending = Regexp.escape(value)
|
25
|
-
end
|
26
|
-
parser.on '-l', '--leader STRING' do |value|
|
27
|
-
leader = Regexp.escape(value)
|
28
|
-
end
|
29
|
-
parser.on '-t', '--trailer STRING' do |value|
|
30
|
-
trailer = Regexp.escape(value)
|
31
|
-
end
|
32
|
-
parser.on '-p', '--backup-prefix PREFIX' do |value|
|
33
|
-
@backup_prefix = value
|
34
|
-
end
|
35
|
-
parser.on '-s', '--backup-suffix SUFFIX' do |value|
|
36
|
-
@backup_suffix = value
|
37
|
-
end
|
38
|
-
end
|
13
|
+
@state = State.new('frag:', 'frag end', '#', '', nil, nil)
|
39
14
|
|
40
15
|
parser.parse!(args)
|
41
|
-
args.size > 0 or
|
16
|
+
args.size > 0 || @version_printed or
|
42
17
|
return error "no files given"
|
43
18
|
|
44
|
-
@begin_line = Regexp.new(['^', leader, beginning, '(.*)', trailer, '$'].reject(&:empty?).join('\\s*'))
|
45
|
-
@end_line = Regexp.new(['^', leader, ending, trailer, '$'].reject(&:empty?).join('\\s*'))
|
46
19
|
@input_paths = args
|
47
20
|
end
|
48
21
|
|
49
22
|
def run
|
50
23
|
return @status if @status != 0
|
24
|
+
global_state = @state.dup
|
51
25
|
@input_paths.each do |input_path|
|
26
|
+
@state = global_state.dup
|
52
27
|
manage_files(input_path) do |input, output|
|
53
28
|
process(input, output)
|
54
29
|
end
|
@@ -66,6 +41,79 @@ module Frag
|
|
66
41
|
false
|
67
42
|
end
|
68
43
|
|
44
|
+
def warn(message)
|
45
|
+
@error.puts "warning: #{message}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def parser
|
49
|
+
@parser ||= OptionParser.new do |parser|
|
50
|
+
parser.banner = "USAGE: #$0 [options] file ..."
|
51
|
+
parser.separator "\nOptions:"
|
52
|
+
|
53
|
+
parser.on '-b', '--begin DELIMITER', "Delimiter that begins each generated fragment. Default: 'frag:'" do |value|
|
54
|
+
@state.beginning = value
|
55
|
+
end
|
56
|
+
parser.on '-e', '--end DELIMITER', "Delimiter that ends each generated fragment. Default: 'frag end'" do |value|
|
57
|
+
@state.ending = value
|
58
|
+
end
|
59
|
+
parser.on '-l', '--leader STRING', "String that precedes each begin or end delimiter. Default: '#'" do |value|
|
60
|
+
if parser.parsing_subconfig
|
61
|
+
warn "-l / --leader is unnecessary in $frag-config line"
|
62
|
+
end
|
63
|
+
@state.leader = value
|
64
|
+
end
|
65
|
+
parser.on '-t', '--trailer STRING', "String that succeeds each begin or end delimiter. Default: ''" do |value|
|
66
|
+
if parser.parsing_subconfig
|
67
|
+
warn "-t / --trailer is unnecessary in $frag-config line"
|
68
|
+
end
|
69
|
+
@state.trailer = value
|
70
|
+
end
|
71
|
+
parser.on '-p', '--backup-prefix PREFIX', "Back up original files with the given prefix. May be a directory." do |value|
|
72
|
+
@state.backup_prefix = value
|
73
|
+
end
|
74
|
+
parser.on '-s', '--backup-suffix SUFFIX', "Back up original files with the given suffix." do |value|
|
75
|
+
@state.backup_suffix = value
|
76
|
+
end
|
77
|
+
parser.on '-v', '--version', "" do
|
78
|
+
@output.puts "Frag version #{Frag::VERSION}"
|
79
|
+
@version_printed = true
|
80
|
+
end
|
81
|
+
|
82
|
+
parser.separator <<-EOS.gsub(/^ *\|/, '')
|
83
|
+
|
|
84
|
+
|## Embedded options
|
85
|
+
|
|
86
|
+
|Options may also be embedded in the file itself via a line that
|
87
|
+
|contains "$frag-config:". Example:
|
88
|
+
|
|
89
|
+
| <!-- $frag-config: -p ~/.frag-backups/ -->
|
90
|
+
|
|
91
|
+
|Note that the leader and trailer are always taken from the strings
|
92
|
+
|that preceed the "$frag-config" and succeed the last option
|
93
|
+
|respectively. They need not be set with --leader and --trailer.
|
94
|
+
|
|
95
|
+
EOS
|
96
|
+
|
97
|
+
class << parser
|
98
|
+
attr_accessor :parsing_subconfig
|
99
|
+
|
100
|
+
def parse_subconfig!(args)
|
101
|
+
self.parsing_subconfig = true
|
102
|
+
# OptionParser will error on an argument like like "-->".
|
103
|
+
if args.last =~ /\A--?(?:\W|\z)/
|
104
|
+
last_arg = args.pop
|
105
|
+
parse!(args)
|
106
|
+
args << last_arg
|
107
|
+
else
|
108
|
+
parse!(args)
|
109
|
+
end
|
110
|
+
ensure
|
111
|
+
self.parsing_subconfig = false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
69
117
|
def manage_files(input_path)
|
70
118
|
File.exist?(input_path) or
|
71
119
|
return error "file not found: #{input_path}"
|
@@ -82,8 +130,8 @@ module Frag
|
|
82
130
|
output
|
83
131
|
end
|
84
132
|
end
|
85
|
-
if @backup_prefix || @backup_suffix
|
86
|
-
backup_path = "#{@backup_prefix}#{File.expand_path(input_path)}#{@backup_suffix}"
|
133
|
+
if @state.backup_prefix || @state.backup_suffix
|
134
|
+
backup_path = "#{@state.backup_prefix}#{File.expand_path(input_path)}#{@state.backup_suffix}"
|
87
135
|
FileUtils.mkdir_p File.dirname(backup_path)
|
88
136
|
FileUtils.cp input_path, backup_path
|
89
137
|
end
|
@@ -98,26 +146,90 @@ module Frag
|
|
98
146
|
output.puts line
|
99
147
|
end
|
100
148
|
case line
|
101
|
-
when @begin_line
|
149
|
+
when @state.begin_line
|
102
150
|
region_start.nil? or
|
103
151
|
return error "#{input.lineno}: nested region"
|
104
152
|
command = $1
|
105
153
|
region_start = input.lineno
|
106
|
-
when @end_line
|
154
|
+
when @state.end_line
|
107
155
|
region_start or
|
108
|
-
return error "#{input.lineno}: unmatched
|
156
|
+
return error "#{input.lineno}: unmatched end delimiter"
|
109
157
|
output.puts `#{command}`
|
110
158
|
if !$?.success?
|
111
159
|
return error "#{region_start}: failed: (#{$?.exitstatus}) #{command}"
|
112
160
|
end
|
113
161
|
region_start = nil
|
114
162
|
output.puts line
|
163
|
+
when /\A\s*(?:(\S+)\s*)?\$frag-config:\s*(.*)$/
|
164
|
+
args = Shellwords.shellsplit($2)
|
165
|
+
parser.parse_subconfig!(args)
|
166
|
+
args.size <= 1 or
|
167
|
+
return error "#{input.lineno}: unexpected argument(s): #{args[0..-2].join(' ')}"
|
168
|
+
@state.leader = $1 || ''
|
169
|
+
@state.trailer = args.first || ''
|
115
170
|
end
|
116
171
|
end
|
117
172
|
if region_start
|
118
|
-
return error "#{region_start}: unmatched
|
173
|
+
return error "#{region_start}: unmatched begin delimiter"
|
119
174
|
end
|
120
175
|
true
|
121
176
|
end
|
122
177
|
end
|
178
|
+
|
179
|
+
class State
|
180
|
+
def initialize(beginning, ending, leader, trailer, backup_prefix, backup_suffix)
|
181
|
+
@beginning = beginning
|
182
|
+
@ending = ending
|
183
|
+
@leader = leader
|
184
|
+
@trailer = trailer
|
185
|
+
@backup_prefix = backup_prefix
|
186
|
+
@backup_suffix = backup_suffix
|
187
|
+
end
|
188
|
+
|
189
|
+
attr_reader :beginning, :ending, :leader, :trailer, :backup_prefix, :backup_suffix
|
190
|
+
|
191
|
+
def beginning=(value)
|
192
|
+
@beginning = value
|
193
|
+
@begin_line = nil
|
194
|
+
end
|
195
|
+
|
196
|
+
def ending=(value)
|
197
|
+
@ending = value
|
198
|
+
@end_line = nil
|
199
|
+
end
|
200
|
+
|
201
|
+
def leader=(value)
|
202
|
+
@leader = value
|
203
|
+
@begin_line = @end_line = nil
|
204
|
+
end
|
205
|
+
|
206
|
+
def trailer=(value)
|
207
|
+
@trailer = value
|
208
|
+
@begin_line = @end_line = nil
|
209
|
+
end
|
210
|
+
|
211
|
+
attr_writer :backup_prefix, :backup_suffix
|
212
|
+
|
213
|
+
def begin_line
|
214
|
+
@begin_line ||= build_begin_line
|
215
|
+
end
|
216
|
+
|
217
|
+
def end_line
|
218
|
+
@end_line ||= build_end_line
|
219
|
+
end
|
220
|
+
|
221
|
+
def build_begin_line
|
222
|
+
leader = Regexp.escape(@leader)
|
223
|
+
beginning = Regexp.escape(@beginning)
|
224
|
+
trailer = Regexp.escape(@trailer)
|
225
|
+
@begin_line = Regexp.new(['^', leader, beginning, '(.*)', trailer, '$'].reject(&:empty?).join('\\s*'))
|
226
|
+
end
|
227
|
+
|
228
|
+
def build_end_line
|
229
|
+
leader = Regexp.escape(@leader)
|
230
|
+
ending = Regexp.escape(@ending)
|
231
|
+
trailer = Regexp.escape(@trailer)
|
232
|
+
@end_line = Regexp.new(['^', leader, ending, trailer, '$'].reject(&:empty?).join('\\s*'))
|
233
|
+
end
|
234
|
+
end
|
123
235
|
end
|
data/lib/frag/version.rb
CHANGED
data/test/unit/test_app.rb
CHANGED
@@ -156,30 +156,30 @@ describe Frag::App do
|
|
156
156
|
['-t', '--trailer'].each do |option|
|
157
157
|
it "uses the delimiter trailer given by #{option}" do
|
158
158
|
write_file 'input', <<-EOS.demargin
|
159
|
-
|# frag: echo one
|
160
|
-
|# frag end
|
159
|
+
|# frag: echo one @@
|
160
|
+
|# frag end @@
|
161
161
|
EOS
|
162
|
-
frag(option, '
|
162
|
+
frag(option, '@@', 'input').must_equal 0
|
163
163
|
(output.string + error.string).must_equal ''
|
164
164
|
File.read('input').must_equal <<-EOS.demargin
|
165
|
-
|# frag: echo one
|
165
|
+
|# frag: echo one @@
|
166
166
|
|one
|
167
|
-
|# frag end
|
167
|
+
|# frag end @@
|
168
168
|
EOS
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
172
|
it "supports using delimiter options together" do
|
173
173
|
write_file 'input', <<-EOS.demargin
|
174
|
-
|
175
|
-
|
174
|
+
|/* BEGIN echo one */
|
175
|
+
|/* END */
|
176
176
|
EOS
|
177
|
-
frag('-b', 'BEGIN', '-e', 'END', '-l', '
|
177
|
+
frag('-b', 'BEGIN', '-e', 'END', '-l', '/*', '-t', '*/', 'input').must_equal 0
|
178
178
|
(output.string + error.string).must_equal ''
|
179
179
|
File.read('input').must_equal <<-EOS.demargin
|
180
|
-
|
180
|
+
|/* BEGIN echo one */
|
181
181
|
|one
|
182
|
-
|
182
|
+
|/* END */
|
183
183
|
EOS
|
184
184
|
end
|
185
185
|
end
|
@@ -249,7 +249,7 @@ describe Frag::App do
|
|
249
249
|
EOS
|
250
250
|
end
|
251
251
|
|
252
|
-
it "does not back up files which
|
252
|
+
it "does not back up files which produce errors" do
|
253
253
|
write_file 'a', <<-EOS.demargin
|
254
254
|
|# frag: true
|
255
255
|
|# frag end
|
@@ -269,6 +269,248 @@ describe Frag::App do
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
|
+
['-v', '--version'].each do |option|
|
273
|
+
it "prints the version if the #{option} option is given" do
|
274
|
+
frag(option).must_equal 0
|
275
|
+
output.string.must_equal "Frag version #{Frag::VERSION}\n"
|
276
|
+
error.string.must_equal ''
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe "a $frag-config line" do
|
281
|
+
it "honors the --begin option" do
|
282
|
+
write_file 'input', <<-EOS.demargin
|
283
|
+
|# BEGIN echo one
|
284
|
+
|# frag: echo one
|
285
|
+
|# frag end
|
286
|
+
|# $frag-config: --begin BEGIN
|
287
|
+
|# BEGIN echo one
|
288
|
+
|# frag: echo one
|
289
|
+
|# frag end
|
290
|
+
EOS
|
291
|
+
frag('input').must_equal 0
|
292
|
+
(output.string + error.string).must_equal ''
|
293
|
+
File.read('input').must_equal <<-EOS.demargin
|
294
|
+
|# BEGIN echo one
|
295
|
+
|# frag: echo one
|
296
|
+
|one
|
297
|
+
|# frag end
|
298
|
+
|# $frag-config: --begin BEGIN
|
299
|
+
|# BEGIN echo one
|
300
|
+
|one
|
301
|
+
|# frag end
|
302
|
+
EOS
|
303
|
+
end
|
304
|
+
|
305
|
+
it "honors the --end option" do
|
306
|
+
write_file 'input', <<-EOS.demargin
|
307
|
+
|# frag: echo one
|
308
|
+
|# END
|
309
|
+
|# frag end
|
310
|
+
|# $frag-config: --end END
|
311
|
+
|# frag: echo one
|
312
|
+
|# END
|
313
|
+
|# frag end
|
314
|
+
EOS
|
315
|
+
frag('input').must_equal 0
|
316
|
+
(output.string + error.string).must_equal ''
|
317
|
+
File.read('input').must_equal <<-EOS.demargin
|
318
|
+
|# frag: echo one
|
319
|
+
|one
|
320
|
+
|# frag end
|
321
|
+
|# $frag-config: --end END
|
322
|
+
|# frag: echo one
|
323
|
+
|one
|
324
|
+
|# END
|
325
|
+
|# frag end
|
326
|
+
EOS
|
327
|
+
end
|
328
|
+
|
329
|
+
it "infers the leader and trailer" do
|
330
|
+
write_file 'input', <<-EOS.demargin
|
331
|
+
|/* frag: echo one */
|
332
|
+
|/* frag end */
|
333
|
+
|/* $frag-config: */
|
334
|
+
|/* frag: echo one */
|
335
|
+
|/* frag end */
|
336
|
+
EOS
|
337
|
+
frag('input').must_equal 0
|
338
|
+
(output.string + error.string).must_equal ''
|
339
|
+
File.read('input').must_equal <<-EOS.demargin
|
340
|
+
|/* frag: echo one */
|
341
|
+
|/* frag end */
|
342
|
+
|/* $frag-config: */
|
343
|
+
|/* frag: echo one */
|
344
|
+
|one
|
345
|
+
|/* frag end */
|
346
|
+
EOS
|
347
|
+
end
|
348
|
+
|
349
|
+
it "can nullify the leader and trailer" do
|
350
|
+
write_file 'input', <<-EOS.demargin
|
351
|
+
|frag: echo one
|
352
|
+
|frag end
|
353
|
+
|$frag-config:
|
354
|
+
|frag: echo one
|
355
|
+
|frag end
|
356
|
+
EOS
|
357
|
+
frag('input').must_equal 0
|
358
|
+
(output.string + error.string).must_equal ''
|
359
|
+
File.read('input').must_equal <<-EOS.demargin
|
360
|
+
|frag: echo one
|
361
|
+
|frag end
|
362
|
+
|$frag-config:
|
363
|
+
|frag: echo one
|
364
|
+
|one
|
365
|
+
|frag end
|
366
|
+
EOS
|
367
|
+
end
|
368
|
+
|
369
|
+
it "warns if the leader is set via an option" do
|
370
|
+
write_file 'input', <<-EOS.demargin
|
371
|
+
|# $frag-config: --leader %
|
372
|
+
EOS
|
373
|
+
frag('input').must_equal 0
|
374
|
+
error.string.must_equal "warning: -l / --leader is unnecessary in $frag-config line\n"
|
375
|
+
end
|
376
|
+
|
377
|
+
it "warns if the trailer is set via an option" do
|
378
|
+
write_file 'input', <<-EOS.demargin
|
379
|
+
|# $frag-config: --trailer %
|
380
|
+
EOS
|
381
|
+
frag('input').must_equal 0
|
382
|
+
error.string.must_equal "warning: -t / --trailer is unnecessary in $frag-config line\n"
|
383
|
+
end
|
384
|
+
|
385
|
+
it "handles trailers that start with '-', which can trick optparse" do
|
386
|
+
write_file 'input', <<-EOS.demargin
|
387
|
+
|<!-- frag: echo one -->
|
388
|
+
|<!-- frag end -->
|
389
|
+
|<!-- $frag-config: -->
|
390
|
+
|<!-- frag: echo one -->
|
391
|
+
|<!-- frag end -->
|
392
|
+
EOS
|
393
|
+
frag('input').must_equal 0
|
394
|
+
(output.string + error.string).must_equal ''
|
395
|
+
File.read('input').must_equal <<-EOS.demargin
|
396
|
+
|<!-- frag: echo one -->
|
397
|
+
|<!-- frag end -->
|
398
|
+
|<!-- $frag-config: -->
|
399
|
+
|<!-- frag: echo one -->
|
400
|
+
|one
|
401
|
+
|<!-- frag end -->
|
402
|
+
EOS
|
403
|
+
end
|
404
|
+
|
405
|
+
it "honors the --backup-prefix option" do
|
406
|
+
write_file 'input', <<-EOS.demargin
|
407
|
+
|# $frag-config: --backup-prefix path/to/backups
|
408
|
+
|# frag: echo new
|
409
|
+
|old
|
410
|
+
|# frag end
|
411
|
+
EOS
|
412
|
+
frag('input').must_equal 0
|
413
|
+
(output.string + error.string).must_equal ''
|
414
|
+
File.read('input').must_equal <<-EOS.demargin
|
415
|
+
|# $frag-config: --backup-prefix path/to/backups
|
416
|
+
|# frag: echo new
|
417
|
+
|new
|
418
|
+
|# frag end
|
419
|
+
EOS
|
420
|
+
File.read("path/to/backups/#{File.expand_path('input')}").must_equal <<-EOS.demargin
|
421
|
+
|# $frag-config: --backup-prefix path/to/backups
|
422
|
+
|# frag: echo new
|
423
|
+
|old
|
424
|
+
|# frag end
|
425
|
+
EOS
|
426
|
+
end
|
427
|
+
|
428
|
+
it "honors the --backup-suffix option" do
|
429
|
+
write_file 'input', <<-EOS.demargin
|
430
|
+
|# $frag-config: --backup-suffix .backup
|
431
|
+
|# frag: echo new
|
432
|
+
|old
|
433
|
+
|# frag end
|
434
|
+
EOS
|
435
|
+
frag('input').must_equal 0
|
436
|
+
(output.string + error.string).must_equal ''
|
437
|
+
File.read('input').must_equal <<-EOS.demargin
|
438
|
+
|# $frag-config: --backup-suffix .backup
|
439
|
+
|# frag: echo new
|
440
|
+
|new
|
441
|
+
|# frag end
|
442
|
+
EOS
|
443
|
+
File.read('input.backup').must_equal <<-EOS.demargin
|
444
|
+
|# $frag-config: --backup-suffix .backup
|
445
|
+
|# frag: echo new
|
446
|
+
|old
|
447
|
+
|# frag end
|
448
|
+
EOS
|
449
|
+
end
|
450
|
+
|
451
|
+
it "scopes options to the file it appears in" do
|
452
|
+
write_file 'a', <<-EOS.demargin
|
453
|
+
|/* $frag-config: -b BEGIN -e END */
|
454
|
+
|/* BEGIN echo a */
|
455
|
+
|/* END */
|
456
|
+
EOS
|
457
|
+
write_file 'b', <<-EOS.demargin
|
458
|
+
|/* BEGIN echo b */
|
459
|
+
|/* END */
|
460
|
+
|# frag: echo b
|
461
|
+
|# frag end
|
462
|
+
EOS
|
463
|
+
frag('a', 'b').must_equal 0
|
464
|
+
(output.string + error.string).must_equal ''
|
465
|
+
File.read('a').must_equal <<-EOS.demargin
|
466
|
+
|/* $frag-config: -b BEGIN -e END */
|
467
|
+
|/* BEGIN echo a */
|
468
|
+
|a
|
469
|
+
|/* END */
|
470
|
+
EOS
|
471
|
+
File.read('b').must_equal <<-EOS.demargin
|
472
|
+
|/* BEGIN echo b */
|
473
|
+
|/* END */
|
474
|
+
|# frag: echo b
|
475
|
+
|b
|
476
|
+
|# frag end
|
477
|
+
EOS
|
478
|
+
end
|
479
|
+
|
480
|
+
it "can be used more than once in a file" do
|
481
|
+
write_file 'input', <<-EOS.demargin
|
482
|
+
|// $frag-config:
|
483
|
+
|// frag: echo one
|
484
|
+
|// frag end
|
485
|
+
|
|
486
|
+
|/* $frag-config: */
|
487
|
+
|/* frag: echo one */
|
488
|
+
|/* frag end */
|
489
|
+
EOS
|
490
|
+
frag('input', '--trailer', '1').must_equal 0
|
491
|
+
(output.string + error.string).must_equal ''
|
492
|
+
File.read('input').must_equal <<-EOS.demargin
|
493
|
+
|// $frag-config:
|
494
|
+
|// frag: echo one
|
495
|
+
|one
|
496
|
+
|// frag end
|
497
|
+
|
|
498
|
+
|/* $frag-config: */
|
499
|
+
|/* frag: echo one */
|
500
|
+
|one
|
501
|
+
|/* frag end */
|
502
|
+
EOS
|
503
|
+
end
|
504
|
+
|
505
|
+
it "errors if there are stray arguments" do
|
506
|
+
write_file 'input', <<-EOS.demargin
|
507
|
+
|# $frag-config: arg trailer
|
508
|
+
EOS
|
509
|
+
frag('input').must_equal 1
|
510
|
+
(output.string + error.string).must_match /unexpected argument/
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
272
514
|
it "prints an error and leaves the input file unchanged if a command fails" do
|
273
515
|
write_file 'input', <<-EOS.demargin
|
274
516
|
|# frag: echo new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ritual
|
@@ -64,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
64
|
version: '0'
|
65
65
|
segments:
|
66
66
|
- 0
|
67
|
-
hash: -
|
67
|
+
hash: -1830703405673240469
|
68
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
69
|
none: false
|
70
70
|
requirements:
|
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
73
|
version: '0'
|
74
74
|
segments:
|
75
75
|
- 0
|
76
|
-
hash: -
|
76
|
+
hash: -1830703405673240469
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
79
|
rubygems_version: 1.8.24
|