di 0.2.3 → 0.3.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/HISTORY +14 -0
- data/di.gemspec +3 -3
- data/lib/di.rb +67 -69
- metadata +5 -5
data/HISTORY
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
== 0.3.0 2012-05-14
|
2
|
+
|
3
|
+
* Fix pagerizing with Ruby 1.9+ and turn it on by default.
|
4
|
+
|
5
|
+
* Complement a missing implementation of --unidirectional-new-file.
|
6
|
+
|
7
|
+
* Complement a missing implementation of -S/--starting-file=FILE.
|
8
|
+
|
9
|
+
* Add support for --suppress-blank-empty.
|
10
|
+
|
11
|
+
* Fix handling of -T/--initial-tab.
|
12
|
+
|
13
|
+
* Remove -L which use has long been deprecated.
|
14
|
+
|
1
15
|
== 0.2.3 2012-03-29
|
2
16
|
|
3
17
|
* Fix the case where comparing two directories fails when the latter
|
data/di.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "di"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Akinori MUSHA"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-05-14"
|
13
13
|
s.description = "The di(1) command wraps around GNU diff(1) to provide reasonable\ndefault settings and some original features.\n"
|
14
14
|
s.email = "knu@idaemons.org"
|
15
15
|
s.executables = ["di"]
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.homepage = "https://github.com/knu/di"
|
33
33
|
s.require_paths = ["lib"]
|
34
34
|
s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
35
|
-
s.rubygems_version = "1.8.
|
35
|
+
s.rubygems_version = "1.8.23"
|
36
36
|
s.summary = "A wrapper around GNU diff(1)"
|
37
37
|
|
38
38
|
if s.respond_to? :specification_version then
|
data/lib/di.rb
CHANGED
@@ -28,13 +28,12 @@
|
|
28
28
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
29
29
|
# SUCH DAMAGE.
|
30
30
|
|
31
|
-
MYVERSION = "0.
|
31
|
+
MYVERSION = "0.3.0"
|
32
32
|
MYNAME = File.basename($0)
|
33
33
|
MYCOPYRIGHT = "Copyright (c) 2008, 2009, 2010, 2011, 2012 Akinori MUSHA"
|
34
34
|
|
35
35
|
DIFF_CMD = ENV.fetch('DIFF', 'diff')
|
36
36
|
ENV_NAME = "#{MYNAME.tr('-a-z', '_A-Z')}_OPTIONS"
|
37
|
-
EMPTYFILE = '/dev/null'
|
38
37
|
|
39
38
|
RSYNC_EXCLUDE_FILE_GLOBS = [
|
40
39
|
'tags', 'TAGS', 'GTAGS', 'GRTAGS', 'GSYMS', 'GPATH',
|
@@ -58,6 +57,8 @@ FIGNORE_GLOBS = ENV.fetch('FIGNORE', '').split(':').map { |pat|
|
|
58
57
|
'*' + pat
|
59
58
|
}
|
60
59
|
|
60
|
+
IO::NULL = '/dev/null' unless defined? IO::NULL
|
61
|
+
|
61
62
|
def main(args)
|
62
63
|
setup
|
63
64
|
|
@@ -116,31 +117,31 @@ usage: #{MYNAME} [flags] [files]
|
|
116
117
|
}
|
117
118
|
|
118
119
|
opts.on('--[no-]pager',
|
119
|
-
'Pipe output into pager if stdout is a terminal. [
|
120
|
-
$diff.use_pager = val if $stdout.tty?
|
120
|
+
'Pipe output into pager if stdout is a terminal. [+][*]') { |val|
|
121
|
+
$diff.use_pager = val if $stdout.tty?
|
121
122
|
}
|
122
123
|
opts.on('--[no-]color',
|
123
|
-
'Colorize output if stdout is a terminal and the format is unified or context. [
|
124
|
+
'Colorize output if stdout is a terminal and the format is unified or context. [+][*]') { |val|
|
124
125
|
$diff.colorize = val if $stdout.tty?
|
125
126
|
}
|
126
127
|
opts.on('--[no-]highlight-whitespace',
|
127
|
-
'Highlight suspicious whitespace differences in colorized output. [
|
128
|
+
'Highlight suspicious whitespace differences in colorized output. [+][*]') { |val|
|
128
129
|
$diff.highlight_whitespace = val
|
129
130
|
}
|
130
131
|
opts.on('--[no-]rsync-exclude', '--[no-]cvs-exclude',
|
131
|
-
'Exclude some kinds of files and directories a la rsync(1). [
|
132
|
+
'Exclude some kinds of files and directories a la rsync(1). [+][*]') { |val|
|
132
133
|
$diff.rsync_exclude = val
|
133
134
|
}
|
134
135
|
opts.on('--[no-]ignore-cvs-lines',
|
135
|
-
'Ignore CVS/RCS keyword lines. [
|
136
|
+
'Ignore CVS/RCS keyword lines. [+][*]') { |val|
|
136
137
|
$diff.ignore_cvs_lines = val
|
137
138
|
}
|
138
139
|
opts.on('--[no-]fignore-exclude',
|
139
|
-
'Ignore files having suffixes specified in FIGNORE. [
|
140
|
+
'Ignore files having suffixes specified in FIGNORE. [+][*]') { |val|
|
140
141
|
$diff.fignore_exclude = val
|
141
142
|
}
|
142
143
|
opts.on('-R', '--relative[=-]', miniTrueClass,
|
143
|
-
'Use relative path names.
|
144
|
+
'Use relative path names.') { |val|
|
144
145
|
$diff.relative = val
|
145
146
|
}
|
146
147
|
opts.on('-i', '--ignore-case[=-]', miniTrueClass,
|
@@ -189,19 +190,19 @@ usage: #{MYNAME} [flags] [files]
|
|
189
190
|
set_format_flag('-C', val.to_s)
|
190
191
|
}
|
191
192
|
opts.on('-u[NUM]', '--unified[=NUM]', Integer,
|
192
|
-
'Output NUM (default 3) lines of unified context. [
|
193
|
+
'Output NUM (default 3) lines of unified context. [+]') { |val|
|
193
194
|
set_format_flag('-U', val ? val.to_s : '3')
|
194
195
|
}
|
195
196
|
opts.on('-U NUM', Integer,
|
196
197
|
'Output NUM lines of unified context.') { |val|
|
197
198
|
set_format_flag('-U', val.to_s)
|
198
199
|
}
|
199
|
-
opts.on('
|
200
|
+
opts.on('--label=LABEL',
|
200
201
|
'Use LABEL instead of file name.') { |val|
|
201
|
-
set_flag('
|
202
|
+
set_flag('--label', val)
|
202
203
|
}
|
203
204
|
opts.on('-p', '--show-c-function[=-]', miniTrueClass,
|
204
|
-
'Show which C function each change is in. [
|
205
|
+
'Show which C function each change is in. [+]') { |val|
|
205
206
|
set_flag('-p', val)
|
206
207
|
}
|
207
208
|
opts.on('-F RE', '--show-function-line=RE',
|
@@ -252,37 +253,21 @@ usage: #{MYNAME} [flags] [files]
|
|
252
253
|
'Output merged file to show `#ifdef NAME\' diffs.') { |val|
|
253
254
|
set_format_flag('-D', val)
|
254
255
|
}
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
'Format new input groups with GFMT.') { |val|
|
261
|
-
set_custom_format_flag('--new-group-format', val)
|
262
|
-
}
|
263
|
-
opts.on('--changed-group-format=GFMT',
|
264
|
-
'Format changed input groups with GFMT.') { |val|
|
265
|
-
set_custom_format_flag('--changed-group-format', val)
|
266
|
-
}
|
267
|
-
opts.on('--unchanged-group-format=GFMT',
|
268
|
-
'Format unchanged input groups with GFMT.') { |val|
|
269
|
-
set_custom_format_flag('--unchanged-group-format', val)
|
256
|
+
%w[old new changed unchanged].each { |gtype|
|
257
|
+
opts.on("--#{gtype}-group-format=GFMT",
|
258
|
+
"Format #{gtype} input groups with GFMT.") { |val|
|
259
|
+
set_custom_format_flag("--#{gtype}-group-format", val)
|
260
|
+
}
|
270
261
|
}
|
271
262
|
opts.on('--line-format=LFMT',
|
272
263
|
'Format all input lines with LFMT.') { |val|
|
273
264
|
set_custom_format_flag('--line-format', val)
|
274
265
|
}
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
'Format new input lines with LFMT.') { |val|
|
281
|
-
set_custom_format_flag('--new-line-format', val)
|
282
|
-
}
|
283
|
-
opts.on('--unchanged-line-format=LFMT',
|
284
|
-
'Format unchanged input lines with LFMT.') { |val|
|
285
|
-
set_custom_format_flag('--unchanged-line-format', val)
|
266
|
+
%w[old new changed unchanged].each { |ltype|
|
267
|
+
opts.on("--#{ltype}-line-format=LFMT",
|
268
|
+
"Format #{ltype} input lines with LFMT.") { |val|
|
269
|
+
set_custom_format_flag("--#{ltype}-line-format", val)
|
270
|
+
}
|
286
271
|
}
|
287
272
|
opts.on('-l', '--paginate[=-]', miniTrueClass,
|
288
273
|
'Pass the output through `pr\' to paginate it.') { |val|
|
@@ -294,25 +279,30 @@ usage: #{MYNAME} [flags] [files]
|
|
294
279
|
}
|
295
280
|
opts.on('-T', '--initial-tab[=-]', miniTrueClass,
|
296
281
|
'Make tabs line up by prepending a tab.') { |val|
|
297
|
-
set_flag('-T',
|
282
|
+
set_flag('-T', val)
|
298
283
|
}
|
299
284
|
opts.on('--tabsize=NUM', Integer,
|
300
285
|
'Tab stops are every NUM (default 8) print columns.') { |val|
|
301
286
|
set_flag('--tabsize', val.to_s)
|
302
287
|
}
|
288
|
+
opts.on('--suppress-blank-empty[=-]', miniTrueClass,
|
289
|
+
'Suppress space or tab before empty output lines.') { |val|
|
290
|
+
set_flag('--suppress-blank-empty', val)
|
291
|
+
}
|
303
292
|
opts.on('-r', '--recursive[=-]', miniTrueClass,
|
304
|
-
'Recursively compare any subdirectories found. [
|
293
|
+
'Recursively compare any subdirectories found. [+]') { |val|
|
305
294
|
set_flag('-r', val)
|
306
295
|
$diff.recursive = val
|
307
296
|
}
|
308
297
|
opts.on('-N', '--[no-]new-file[=-]', miniTrueClass,
|
309
|
-
'Treat absent files as empty. [
|
298
|
+
'Treat absent files as empty. [+]') { |val|
|
310
299
|
set_flag('-N', val)
|
311
|
-
$diff.new_file = val
|
300
|
+
$diff.new_file = val ? :bidirectional : val
|
312
301
|
}
|
313
302
|
opts.on('--unidirectional-new-file[=-]', miniTrueClass,
|
314
303
|
'Treat absent first files as empty.') { |val|
|
315
304
|
set_flag('--unidirectional-new-file', val)
|
305
|
+
$diff.new_file = val ? :unidirectional : val
|
316
306
|
}
|
317
307
|
opts.on('-s', '--report-identical-files[=-]', miniTrueClass,
|
318
308
|
'Report when two files are the same.') { |val|
|
@@ -336,7 +326,7 @@ usage: #{MYNAME} [flags] [files]
|
|
336
326
|
}
|
337
327
|
opts.on('-S FILE', '--starting-file=FILE',
|
338
328
|
'Start with FILE when comparing directories.') { |val|
|
339
|
-
|
329
|
+
$diff.starting_file = val
|
340
330
|
}
|
341
331
|
opts.on('--from-file=FILE1',
|
342
332
|
'Compare FILE1 to all operands. FILE1 can be a directory.') { |val|
|
@@ -351,7 +341,7 @@ usage: #{MYNAME} [flags] [files]
|
|
351
341
|
set_flag('--horizon-lines', val.to_s)
|
352
342
|
}
|
353
343
|
opts.on('-d', '--minimal[=-]', miniTrueClass,
|
354
|
-
'Try hard to find a smaller set of changes. [
|
344
|
+
'Try hard to find a smaller set of changes. [+]') { |val|
|
355
345
|
set_flag('-d', val)
|
356
346
|
}
|
357
347
|
opts.on('--speed-large-files[=-]', miniTrueClass,
|
@@ -373,8 +363,8 @@ usage: #{MYNAME} [flags] [files]
|
|
373
363
|
'Output this help.') { |val|
|
374
364
|
invoke_pager
|
375
365
|
print opts, <<EOS
|
376
|
-
Options
|
377
|
-
Options marked
|
366
|
+
Options marked with [*] are this wrapper's original features.
|
367
|
+
Options marked with [+] are turned on by default. To turn them off,
|
378
368
|
specify -?- for short options and --no-??? for long options, respectively.
|
379
369
|
|
380
370
|
Environment variables:
|
@@ -466,23 +456,21 @@ def invoke_pager!
|
|
466
456
|
pr.close
|
467
457
|
pw.close
|
468
458
|
IO.select([$stdin], nil, [$stdin])
|
469
|
-
|
470
|
-
|
471
|
-
|
459
|
+
begin
|
460
|
+
exec(ENV['PAGER'] || 'more')
|
461
|
+
rescue
|
472
462
|
$stderr.puts "Pager failed."
|
473
|
-
Process.kill(:INT, ppid)
|
474
463
|
end
|
475
464
|
}
|
476
|
-
|
477
|
-
trap(:INT) { exit(130) }
|
465
|
+
|
478
466
|
$stdout.reopen(pw)
|
479
467
|
$stderr.reopen(pw) if $stderr.tty?
|
480
468
|
pw.close
|
481
469
|
at_exit {
|
482
470
|
$stdout.flush
|
483
471
|
$stderr.flush
|
484
|
-
$stdout.
|
485
|
-
$stderr.
|
472
|
+
$stdout.reopen(IO::NULL)
|
473
|
+
$stderr.reopen(IO::NULL)
|
486
474
|
Process.waitpid(pid)
|
487
475
|
}
|
488
476
|
end
|
@@ -543,7 +531,7 @@ def diff_main
|
|
543
531
|
to_file = File.expand_path(from_file, to_file)
|
544
532
|
end
|
545
533
|
|
546
|
-
diff_dirs(from_file, to_file)
|
534
|
+
diff_dirs(from_file, to_file, true)
|
547
535
|
else
|
548
536
|
if $diff.relative
|
549
537
|
from_file = File.expand_path(to_file, from_file)
|
@@ -607,9 +595,9 @@ def call_diff(*args)
|
|
607
595
|
return status
|
608
596
|
end
|
609
597
|
|
610
|
-
def diff_dirs(dir1, dir2)
|
611
|
-
entries1 = diff_entries(dir1)
|
612
|
-
entries2 = diff_entries(dir2)
|
598
|
+
def diff_dirs(dir1, dir2, toplevel_p = false)
|
599
|
+
entries1 = diff_entries(dir1, toplevel_p)
|
600
|
+
entries2 = diff_entries(dir2, toplevel_p)
|
613
601
|
|
614
602
|
common = entries1 & entries2
|
615
603
|
missing1 = entries2 - entries1
|
@@ -635,15 +623,20 @@ def diff_dirs(dir1, dir2)
|
|
635
623
|
end
|
636
624
|
|
637
625
|
if $diff.reversed
|
638
|
-
[[dir1, missing2], [dir2, missing1]]
|
626
|
+
[[dir1, missing2, true], [dir2, missing1, false]]
|
639
627
|
else
|
640
|
-
[[dir2, missing1], [dir1, missing2]]
|
641
|
-
end.each { |dir, missing|
|
628
|
+
[[dir2, missing1, true], [dir1, missing2, false]]
|
629
|
+
end.each { |dir, missing, direction|
|
642
630
|
new_files = []
|
631
|
+
case $diff.new_file
|
632
|
+
when :bidirectional
|
633
|
+
new_file = true
|
634
|
+
when :unidirectional
|
635
|
+
new_file = direction
|
636
|
+
end
|
643
637
|
missing.each { |entry|
|
644
638
|
file = File.join(dir, entry)
|
645
|
-
|
646
|
-
if $diff.new_file
|
639
|
+
if new_file
|
647
640
|
if File.directory?(file)
|
648
641
|
if dir.equal?(dir1)
|
649
642
|
diff_dirs(file, nil)
|
@@ -660,16 +653,21 @@ def diff_dirs(dir1, dir2)
|
|
660
653
|
end
|
661
654
|
}
|
662
655
|
if dir.equal?(dir1)
|
663
|
-
diff_files(new_files,
|
656
|
+
diff_files(new_files, IO::NULL)
|
664
657
|
else
|
665
|
-
diff_files(
|
658
|
+
diff_files(IO::NULL, new_files)
|
666
659
|
end
|
667
660
|
}
|
668
661
|
end
|
669
662
|
|
670
|
-
def diff_entries(dir)
|
663
|
+
def diff_entries(dir, toplevel_p)
|
671
664
|
return [] if dir.nil?
|
672
|
-
|
665
|
+
Dir.entries(dir).tap { |entries|
|
666
|
+
entries.reject! { |file| diff_exclude?(dir, file) }
|
667
|
+
if toplevel_p && (starting_file = $diff.starting_file)
|
668
|
+
entries.reject! { |file| file < starting_file }
|
669
|
+
end
|
670
|
+
}
|
673
671
|
rescue => e
|
674
672
|
warn "#{dir}: #{e}"
|
675
673
|
return []
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: di
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Akinori MUSHA
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-05-14 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: thoughtbot-shoulda
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements: []
|
86
86
|
|
87
87
|
rubyforge_project:
|
88
|
-
rubygems_version: 1.8.
|
88
|
+
rubygems_version: 1.8.23
|
89
89
|
signing_key:
|
90
90
|
specification_version: 3
|
91
91
|
summary: A wrapper around GNU diff(1)
|