frag 0.1.0 → 0.2.0
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/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
|