dirb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +71 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/dirb.rb +93 -0
- data/spec/dirb_spec.rb +138 -0
- metadata +79 -0
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Dirb - Easy Diffing With Ruby
|
2
|
+
============================
|
3
|
+
|
4
|
+
Need diffs in your ruby app? Dirb has you covered. It provides a convenient
|
5
|
+
way to generate a diff from two strings. Instead of reimplementing the LCS diff
|
6
|
+
algorithm Dirb uses battle tested Unix diff to generate diffs, and focuses on
|
7
|
+
providing a convenient interface, and getting out of your way.
|
8
|
+
|
9
|
+
It provides several built in format options. Pass `:text`, `:color`, or
|
10
|
+
`:html` to `Dirb::Diff#to_s` to force that format, or set
|
11
|
+
`Dirb::Diff.default_format`
|
12
|
+
|
13
|
+
$ irb
|
14
|
+
>> require 'rubygems'
|
15
|
+
>> require 'dirb'
|
16
|
+
=> true
|
17
|
+
>> string1 = <<-TXT
|
18
|
+
>" Hello how are you
|
19
|
+
>" I'm fine
|
20
|
+
>" That's great
|
21
|
+
>" TXT
|
22
|
+
=> "Hello how are you\nI'm fine\nThat's great\n"
|
23
|
+
>> string2 = <<-TXT
|
24
|
+
>" Hello how are you?
|
25
|
+
>" I'm fine
|
26
|
+
>" That's swell
|
27
|
+
>" TXT
|
28
|
+
=> "Hello how are you?\nI'm fine\nThat's swell\n"
|
29
|
+
>> puts Dirb::Diff.new(string1, string2)
|
30
|
+
-Hello how are you
|
31
|
+
+Hello how are you?
|
32
|
+
I'm fine
|
33
|
+
-That's great
|
34
|
+
+That's swell
|
35
|
+
=> nil
|
36
|
+
>> puts Dirb::Diff.new(string1, string2).to_s(:html)
|
37
|
+
<ul class="diff">
|
38
|
+
<li class="del"><del>Hello how are you</del></li>
|
39
|
+
<li class="ins"><ins>Hello how are you?</ins></li>
|
40
|
+
<li class="unchanged"><span>I'm fine</span></li>
|
41
|
+
<li class="del"><del>That's great</del></li>
|
42
|
+
<li class="ins"><ins>That's swell</ins></li>
|
43
|
+
</ul>
|
44
|
+
=> nil
|
45
|
+
>> Dirb::Diff.default_format = :color
|
46
|
+
=> :color
|
47
|
+
irb(main):015:0> puts Dirb::Diff.new(string1, string2) # prints color in the terminal
|
48
|
+
-Hello how are you
|
49
|
+
+Hello how are you?
|
50
|
+
I'm fine
|
51
|
+
-That's great
|
52
|
+
+That's swell
|
53
|
+
=> nil
|
54
|
+
|
55
|
+
|
56
|
+
Creating custom formatted output is easy too. `Dirb::Diff` provides an
|
57
|
+
enumberable interface which lets you iterate over lines in the diff.
|
58
|
+
|
59
|
+
>> Dirb::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n").each do |line|
|
60
|
+
>* case line
|
61
|
+
>> when /^\+/ then puts "line #{line.chomp} added"
|
62
|
+
>> when /^-/ then puts "line #{line.chomp} removed"
|
63
|
+
>> end
|
64
|
+
>> end
|
65
|
+
line +baz added
|
66
|
+
=> [" foo\n", " bar\n", "+baz\n"]
|
67
|
+
|
68
|
+
Use `#map`, `#inject`, or any of Enumerable's methods. Go crazy.
|
69
|
+
|
70
|
+
Report bugs or request features at http://github.com/samg/Dirb/issues
|
71
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec/rake/spectask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc "Run all specs in spec directory"
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
9
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::RDocTask.new do |rd|
|
13
|
+
rd.main = "README"
|
14
|
+
rd.rdoc_dir = 'doc'
|
15
|
+
rd.rdoc_files.include("README", "**/*.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'jeweler'
|
20
|
+
Jeweler::Tasks.new do |s|
|
21
|
+
s.name = %q{dirb}
|
22
|
+
s.version = "0.1.0"
|
23
|
+
|
24
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
25
|
+
s.authors = ["Sam Goldstein"]
|
26
|
+
s.date = %q{2010-06-28}
|
27
|
+
s.description = %q{Convenient diffing in ruby}
|
28
|
+
s.email = %q{sgrock@gmail.com}
|
29
|
+
s.has_rdoc = true
|
30
|
+
s.homepage = "http://github.com/samg/dirb/tree/master"
|
31
|
+
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.summary = %q{A convenient way to diff string in ruby}
|
34
|
+
|
35
|
+
if s.respond_to? :specification_version then
|
36
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
37
|
+
s.specification_version = 2
|
38
|
+
|
39
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
40
|
+
s.add_runtime_dependency(%q<mime-types>, [">= 1.16"])
|
41
|
+
s.add_runtime_dependency(%q<diff-lcs>, [">= 1.1.2"])
|
42
|
+
else
|
43
|
+
s.add_dependency(%q<mime-types>, [">= 1.16"])
|
44
|
+
s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
|
45
|
+
end
|
46
|
+
else
|
47
|
+
s.add_dependency(%q<mime-types>, [">= 1.16"])
|
48
|
+
s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
rescue LoadError
|
52
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
53
|
+
end
|
54
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/dirb.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'open3'
|
4
|
+
module Dirb
|
5
|
+
class Diff
|
6
|
+
class << self
|
7
|
+
attr_writer :default_format
|
8
|
+
def default_format
|
9
|
+
@default_format || :text
|
10
|
+
end
|
11
|
+
end
|
12
|
+
include Enumerable
|
13
|
+
attr_reader :string1, :string2, :diff_options, :diff
|
14
|
+
def initialize(string1, string2, diff_options = "-U 10000")
|
15
|
+
@string1, @string2 = string1, string2
|
16
|
+
@diff_options = diff_options
|
17
|
+
end
|
18
|
+
|
19
|
+
def diff
|
20
|
+
@diff ||= Open3.popen3(
|
21
|
+
*[diff_bin, diff_options, tempfile(string1), tempfile(string2)]
|
22
|
+
) { |i, o, e| o.read }
|
23
|
+
@diff = @string1.gsub(/^/, " ") if @diff =~ /\A\s*\Z/
|
24
|
+
@diff
|
25
|
+
end
|
26
|
+
|
27
|
+
def each &block
|
28
|
+
diff.each_line.reject{|x| x =~ /^---|\+\+\+|@@/ }.each &block
|
29
|
+
end
|
30
|
+
|
31
|
+
def tempfile(string)
|
32
|
+
t = Tempfile.new('dirb')
|
33
|
+
t.print(string)
|
34
|
+
t.flush
|
35
|
+
t.path
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s(format = nil)
|
39
|
+
format ||= self.class.default_format
|
40
|
+
formats = Format.instance_methods(false)
|
41
|
+
if formats.include? format.to_s
|
42
|
+
enum = self.each
|
43
|
+
enum.extend Format
|
44
|
+
enum.send format
|
45
|
+
else
|
46
|
+
raise ArgumentError,
|
47
|
+
"Format #{format.inspect} not found in #{formats.inspect}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
private
|
51
|
+
|
52
|
+
def diff_bin
|
53
|
+
bin = `which diff`.chomp
|
54
|
+
if bin.empty?
|
55
|
+
raise "Can't find a diff executable in PATH #{ENV['PATH']}"
|
56
|
+
end
|
57
|
+
bin
|
58
|
+
end
|
59
|
+
|
60
|
+
module Format
|
61
|
+
def color
|
62
|
+
map do |line|
|
63
|
+
case line
|
64
|
+
when /^\+/
|
65
|
+
"\033[32m#{line.chomp}\033[0m"
|
66
|
+
when /^-/
|
67
|
+
"\033[31m#{line.chomp}\033[0m"
|
68
|
+
else
|
69
|
+
line.chomp
|
70
|
+
end
|
71
|
+
end.join("\n") + "\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
def text
|
75
|
+
to_a.join
|
76
|
+
end
|
77
|
+
|
78
|
+
def html
|
79
|
+
lines = map do |line|
|
80
|
+
case line
|
81
|
+
when /^\+/
|
82
|
+
' <li class="ins"><ins>' + line.gsub(/^./, '').chomp + '</ins></li>'
|
83
|
+
when /^-/
|
84
|
+
' <li class="del"><del>' + line.gsub(/^./, '').chomp + '</del></li>'
|
85
|
+
when /^ /
|
86
|
+
' <li class="unchanged"><span>' + line.gsub(/^./, '').chomp + '</span></li>'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
%'<ul class="diff">\n#{lines.join("\n")}\n</ul>\n'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/spec/dirb_spec.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dirb')
|
3
|
+
|
4
|
+
describe Dirb::Diff do
|
5
|
+
describe "#to_s" do
|
6
|
+
describe "with no line different" do
|
7
|
+
before do
|
8
|
+
@string1 = "foo\nbar\nbang\n"
|
9
|
+
@string2 = "foo\nbar\nbang\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should show everything" do
|
13
|
+
Dirb::Diff.new(@string1, @string2).to_s.should == <<-DIFF
|
14
|
+
foo
|
15
|
+
bar
|
16
|
+
bang
|
17
|
+
DIFF
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe "with one line different" do
|
21
|
+
before do
|
22
|
+
@string1 = "foo\nbar\nbang\n"
|
23
|
+
@string2 = "foo\nbang\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should show one line removed" do
|
27
|
+
Dirb::Diff.new(@string1, @string2).to_s.should == <<-DIFF
|
28
|
+
foo
|
29
|
+
-bar
|
30
|
+
bang
|
31
|
+
DIFF
|
32
|
+
end
|
33
|
+
|
34
|
+
it "to_s should accept a format key" do
|
35
|
+
Dirb::Diff.new(@string1, @string2).to_s(:color).
|
36
|
+
should == " foo\n\e[31m-bar\e[0m\n bang\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should accept a default format option" do
|
40
|
+
old_format = Dirb::Diff.default_format
|
41
|
+
Dirb::Diff.default_format = :color
|
42
|
+
Dirb::Diff.new(@string1, @string2).to_s.
|
43
|
+
should == " foo\n\e[31m-bar\e[0m\n bang\n"
|
44
|
+
Dirb::Diff.default_format = old_format
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should show one line added" do
|
48
|
+
Dirb::Diff.new(@string2, @string1).to_s.should == <<-DIFF
|
49
|
+
foo
|
50
|
+
+bar
|
51
|
+
bang
|
52
|
+
DIFF
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "with one line changed" do
|
57
|
+
before do
|
58
|
+
@string1 = "foo\nbar\nbang\n"
|
59
|
+
@string2 = "foo\nbong\nbang\n"
|
60
|
+
end
|
61
|
+
it "should show one line added and one removed" do
|
62
|
+
Dirb::Diff.new(@string1, @string2).to_s.should == <<-DIFF
|
63
|
+
foo
|
64
|
+
-bar
|
65
|
+
+bong
|
66
|
+
bang
|
67
|
+
DIFF
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "with totally different strings" do
|
72
|
+
before do
|
73
|
+
@string1 = "foo\nbar\nbang\n"
|
74
|
+
@string2 = "one\ntwo\nthree\n"
|
75
|
+
end
|
76
|
+
it "should show one line added and one removed" do
|
77
|
+
Dirb::Diff.new(@string1, @string2).to_s.should == <<-DIFF
|
78
|
+
-foo
|
79
|
+
-bar
|
80
|
+
-bang
|
81
|
+
+one
|
82
|
+
+two
|
83
|
+
+three
|
84
|
+
DIFF
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "with a somewhat complicated diff" do
|
89
|
+
before do
|
90
|
+
@string1 = "foo\nbar\nbang\nwoot\n"
|
91
|
+
@string2 = "one\ntwo\nthree\nbar\nbang\nbaz\n"
|
92
|
+
@diff = Dirb::Diff.new(@string1, @string2)
|
93
|
+
end
|
94
|
+
it "should show one line added and one removed" do
|
95
|
+
@diff.to_s.should == <<-DIFF
|
96
|
+
-foo
|
97
|
+
+one
|
98
|
+
+two
|
99
|
+
+three
|
100
|
+
bar
|
101
|
+
bang
|
102
|
+
-woot
|
103
|
+
+baz
|
104
|
+
DIFF
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should make an awesome html diff" do
|
108
|
+
@diff.to_s(:html).should == <<-HTML
|
109
|
+
<ul class="diff">
|
110
|
+
<li class="del"><del>foo</del></li>
|
111
|
+
<li class="ins"><ins>one</ins></li>
|
112
|
+
<li class="ins"><ins>two</ins></li>
|
113
|
+
<li class="ins"><ins>three</ins></li>
|
114
|
+
<li class="unchanged"><span>bar</span></li>
|
115
|
+
<li class="unchanged"><span>bang</span></li>
|
116
|
+
<li class="del"><del>woot</del></li>
|
117
|
+
<li class="ins"><ins>baz</ins></li>
|
118
|
+
</ul>
|
119
|
+
HTML
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should accept overrides to diff's options" do
|
123
|
+
@diff = Dirb::Diff.new(@string1, @string2, "--rcs")
|
124
|
+
@diff.to_s.should == <<-DIFF
|
125
|
+
d1 1
|
126
|
+
a1 3
|
127
|
+
one
|
128
|
+
two
|
129
|
+
three
|
130
|
+
d4 1
|
131
|
+
a4 1
|
132
|
+
baz
|
133
|
+
DIFF
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dirb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Goldstein
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-06-28 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: mime-types
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "1.16"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: diff-lcs
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.2
|
34
|
+
version:
|
35
|
+
description: Convenient diffing in ruby
|
36
|
+
email: sgrock@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.md
|
43
|
+
files:
|
44
|
+
- README.md
|
45
|
+
- Rakefile
|
46
|
+
- VERSION
|
47
|
+
- lib/dirb.rb
|
48
|
+
- spec/dirb_spec.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/samg/dirb/tree/master
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --inline-source
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.5
|
75
|
+
signing_key:
|
76
|
+
specification_version: 2
|
77
|
+
summary: A convenient way to diff string in ruby
|
78
|
+
test_files:
|
79
|
+
- spec/dirb_spec.rb
|