riffdiff 1.0.0 → 1.0.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 210ce8cd2057687ae39b1fd6f93078acb85c578d
4
- data.tar.gz: 90be3c51cad7ff1b544a5bdf70ca8f8057d531d2
3
+ metadata.gz: ab9270780987e9731750adac81951e66b7e0cf74
4
+ data.tar.gz: ae9e29dd801bf4502dcb651581ce99573946410b
5
5
  SHA512:
6
- metadata.gz: 6e0d1fb16f8140c63c52ed73e39e50b88350b50cc74fdb0da898b51d127ddadaa35a1eab71e23d952e3c6c26c01162e63d268208ff37975367395d231cf6ec17
7
- data.tar.gz: e34e17529688e520ae3638097805789a9c3a11a701f53e55ab9ec208079f173b40c3f07186d648ab6ec8800f3c97892c447d3fd106fcbe43b21d7592268be7ce
6
+ metadata.gz: eee0b5d29449d2fe3bb8201a6c8b68f8ee96b835518b8b18e6659b8657403387ae04dbe3ae767c1951dd42acaf68c2b31cb154e49e151a3700d77cb74690633b
7
+ data.tar.gz: 827c93ab1f9ea4217083d43823815390fb01397280370571e14fbd6e0f7a97daae94c9b8fb2b6f52c376b714617906c739088d80662d8f6f0ed6455991caaaa4
data/.rubocop.yml CHANGED
@@ -24,3 +24,19 @@ Style/RedundantReturn:
24
24
  # Johan thinks these are OK as long as there aren't too many of them
25
25
  Style/PerlBackrefs:
26
26
  Enabled: false
27
+
28
+ # Johan thinks "unless" is hard to read
29
+ Style/NegatedIf:
30
+ Enabled: false
31
+
32
+ # Johan finds the default method length limit of 10 silly
33
+ Metrics/MethodLength:
34
+ Max: 20
35
+
36
+ # Johan looked at some methods and concluded 21 is fine
37
+ Metrics/AbcSize:
38
+ Max: 21
39
+
40
+ # Johan looked at some methods and concluded 7 is fine
41
+ Metrics/CyclomaticComplexity:
42
+ Max: 7
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script: rake package
data/README.md CHANGED
@@ -23,9 +23,6 @@ Optionally followed by...
23
23
  ... to make git show refined diffs by default.
24
24
 
25
25
  # TODO
26
- * When highlighting an added comma at the end of a line, followed by some added
27
- lines, remove the leading + from the first line and don't color it. We should
28
- still show the comma in reverse video though.
29
26
  * Think about highlighting whitespace errors like Git does
30
27
  * Think about how to visualize an added line break together with some
31
28
  indentation on the following line.
@@ -120,3 +117,8 @@ globally on the system.
120
117
  * test dirty sources
121
118
  * not package dirty sources
122
119
  * package clean sources, dependencies not verified
120
+ * When highlighting an added comma at the end of a line, followed by some added
121
+ lines, remove the leading + from the first line and don't color it. We should
122
+ still show the comma in reverse video though. Do this when:
123
+ * One line is replaced by many
124
+ * The diff contains only additions
data/Rakefile CHANGED
@@ -7,11 +7,18 @@ include Version
7
7
 
8
8
  task default: :spec
9
9
  desc 'Run the unit tests (default)'
10
- task spec: [:deps]
10
+ task spec: [:deps, :lint]
11
11
  RSpec::Core::RakeTask.new do |t|
12
12
  t.pattern = FileList['spec/**/*_spec.rb']
13
13
  end
14
14
 
15
+ desc 'Lint the source code'
16
+ task :lint do
17
+ # Everything except bin/benchmark; it's not used in production and is unlikely
18
+ # to change anyway
19
+ sh 'rubocop lib spec bin/riff Rakefile riffdiff.gemspec'
20
+ end
21
+
15
22
  desc 'Create a .gem package'
16
23
  task package: [:spec] do
17
24
  fail 'Cannot package when there are uncommitted sources' if dirty?
data/lib/diff_string.rb CHANGED
@@ -7,6 +7,7 @@ require 'colors'
7
7
  class DiffString
8
8
  include Colors
9
9
 
10
+ # Note that the color argument can be the empty string
10
11
  def initialize(prefix, color)
11
12
  @reverse = false
12
13
  @prefix = prefix
data/lib/options.rb CHANGED
@@ -5,9 +5,7 @@ require 'version'
5
5
  module Options
6
6
  include Version
7
7
 
8
- def handle_options
9
- opts = Slop::Options.new do |o|
10
- o.banner = <<-EOS
8
+ BANNER = <<-EOS
11
9
  Usage: diff ... | riff
12
10
  Colors diff and highlights what parts of changed lines have changed.
13
11
 
@@ -15,6 +13,10 @@ Git integration:
15
13
  git config --global pager.diff riff
16
14
  git config --global pager.show riff
17
15
  EOS
16
+
17
+ def create_opts
18
+ return Slop::Options.new do |o|
19
+ o.banner = BANNER
18
20
  o.separator 'Options:'
19
21
  o.on '--version', 'Print version information and exit' do
20
22
  puts "riff #{version}"
@@ -31,6 +33,10 @@ EOS
31
33
  exit
32
34
  end
33
35
  end
36
+ end
37
+
38
+ def handle_options
39
+ opts = create_opts()
34
40
 
35
41
  begin
36
42
  opts.parse(ARGV)
data/lib/refiner.rb CHANGED
@@ -95,20 +95,62 @@ class Refiner
95
95
  return try_highlight(old, new)
96
96
  end
97
97
 
98
+ def render_refinement(prefix, color, string, highlights, base_index = 0)
99
+ return_me = DiffString.new(prefix, color)
100
+ string.each_char.with_index do |char, index|
101
+ return_me.add(char, highlights.include?(index + base_index))
102
+ end
103
+ return return_me.to_s
104
+ end
105
+
106
+ # After returning from this method, both @refined_old and @refined_new must
107
+ # have been set to reasonable values.
108
+ def create_refinements(old, new, old_highlights, new_highlights)
109
+ @refined_old = render_refinement('-', RED, old, old_highlights)
110
+ @refined_new = render_refinement('+', GREEN, new, new_highlights)
111
+ end
112
+
113
+ # After returning from this method, both @refined_old and @refined_new must
114
+ # have been set to reasonable values.
115
+ #
116
+ # Returns false if the preconditions for using this method aren't fulfilled
117
+ def create_one_to_many_refinements(old, new, old_highlights, new_highlights)
118
+ if old_highlights.count > 0
119
+ return false
120
+ end
121
+ if old.lines.count != 1
122
+ return false
123
+ end
124
+ lines = new.lines
125
+ if lines.count < 2
126
+ return false
127
+ end
128
+
129
+ @refined_old = ''
130
+
131
+ refined_line_1 = render_refinement(' ', '', lines[0], new_highlights)
132
+
133
+ line_2_index_0 = lines[0].length
134
+ refined_remaining_lines = render_refinement('+', GREEN,
135
+ lines[1..-1].join,
136
+ new_highlights,
137
+ line_2_index_0)
138
+
139
+ @refined_new = refined_line_1 + refined_remaining_lines
140
+
141
+ return true
142
+ end
143
+
98
144
  def initialize(old, new)
99
145
  old_highlights, new_highlights = try_highlight(old, new)
100
146
  if old_highlights.size == 0 && new_highlights.size == 0
101
147
  old_highlights, new_highlights = try_highlight_initial_lines(old, new)
102
148
  end
103
149
 
104
- @refined_old = DiffString.new('-', RED)
105
- old.each_char.with_index do |char, index|
106
- @refined_old.add(char, old_highlights.include?(index))
107
- end
108
-
109
- @refined_new = DiffString.new('+', GREEN)
110
- new.each_char.with_index do |char, index|
111
- @refined_new.add(char, new_highlights.include?(index))
150
+ if !create_one_to_many_refinements(old, new,
151
+ old_highlights,
152
+ new_highlights)
153
+ create_refinements(old, new, old_highlights, new_highlights)
112
154
  end
113
155
  end
114
156
  end
data/lib/riff.rb CHANGED
@@ -4,6 +4,8 @@ require 'diff_string'
4
4
 
5
5
  # Call do_stream() with the output of some diff-like tool (diff,
6
6
  # diff3, git diff, ...) and it will highlight that output for you.
7
+ #
8
+ # rubocop:disable Metrics/ClassLength
7
9
  class Riff
8
10
  DIFF_HEADER = /^diff /
9
11
  DIFF_HUNK_HEADER = /^@@ /
@@ -107,8 +109,8 @@ class Riff
107
109
  return '' if @replace_old.empty? && @replace_new.empty?
108
110
 
109
111
  refiner = Refiner.new(@replace_old, @replace_new)
110
- return_me = refiner.refined_old.to_s
111
- return_me += refiner.refined_new.to_s
112
+ return_me = refiner.refined_old
113
+ return_me += refiner.refined_new
112
114
 
113
115
  @replace_old = ''
114
116
  @replace_new = ''
data/riffdiff.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.name = 'riffdiff'
8
8
  s.version = semantic_version
9
9
  s.summary = 'A diff highlighter showing what parts of lines have changed'
10
- s.description = %{== Riff
10
+ s.description = %(== Riff
11
11
  Riff is a wrapper around diff that highlights not only which lines have changed,
12
12
  but also which parts of the lines that have changed.
13
13
 
@@ -23,7 +23,7 @@ $ git config --global pager.show riff
23
23
 
24
24
  ... then all future 'git diff's and 'git show's will be
25
25
  refined.
26
- }
26
+ )
27
27
  s.authors = ['Johan Walles']
28
28
  s.email = 'johan.walles@gmail.com'
29
29
  s.homepage = 'http://github.com/walles/riff'
@@ -39,7 +39,9 @@ refined.
39
39
  s.required_ruby_version = '~> 2.0'
40
40
 
41
41
  s.add_development_dependency 'rspec', '~> 3.0'
42
+ s.add_development_dependency 'rubocop', '~> 0.29.1'
43
+ s.add_development_dependency 'rake', '~> 0.9'
42
44
 
43
- s.add_runtime_dependency 'diff-lcs', '~> 1.2.5'
44
- s.add_runtime_dependency 'slop', '~> 4.1.0'
45
+ s.add_runtime_dependency 'diff-lcs', '~> 1.2'
46
+ s.add_runtime_dependency 'slop', '~> 4.1'
45
47
  end
data/spec/refiner_spec.rb CHANGED
@@ -9,9 +9,9 @@ RSpec.describe Refiner, '#new' do
9
9
  refiner = Refiner.new(%('quoted'\n), %("quoted"\n))
10
10
 
11
11
  it 'highlights the quotes and nothing else' do
12
- expect(refiner.refined_old.to_s).to eq(
12
+ expect(refiner.refined_old).to eq(
13
13
  %(#{RED}-#{reversed("'")}quoted#{reversed("'")}#{RESET}\n))
14
- expect(refiner.refined_new.to_s).to eq(
14
+ expect(refiner.refined_new).to eq(
15
15
  %(#{GREEN}+#{reversed('"')}quoted#{reversed('"')}#{RESET}\n))
16
16
  end
17
17
  end
@@ -20,11 +20,11 @@ RSpec.describe Refiner, '#new' do
20
20
  refiner = Refiner.new('', "something\n")
21
21
 
22
22
  it 'refines old to the empty string' do
23
- expect(refiner.refined_old.to_s).to eq('')
23
+ expect(refiner.refined_old).to eq('')
24
24
  end
25
25
 
26
26
  it 'does not highlight anything in new' do
27
- expect(refiner.refined_new.to_s).to eq(
27
+ expect(refiner.refined_new).to eq(
28
28
  %(#{GREEN}+something#{RESET}\n))
29
29
  end
30
30
  end
@@ -33,12 +33,12 @@ RSpec.describe Refiner, '#new' do
33
33
  refiner = Refiner.new("something\n", '')
34
34
 
35
35
  it 'does not highlight anything in old' do
36
- expect(refiner.refined_old.to_s).to eq(
36
+ expect(refiner.refined_old).to eq(
37
37
  %(#{RED}-something#{RESET}\n))
38
38
  end
39
39
 
40
40
  it 'refines new to the empty string' do
41
- expect(refiner.refined_new.to_s).to eq('')
41
+ expect(refiner.refined_new).to eq('')
42
42
  end
43
43
  end
44
44
 
@@ -46,9 +46,9 @@ RSpec.describe Refiner, '#new' do
46
46
  refiner = Refiner.new(%(x "hej"\n), %(x 'hej'\n))
47
47
 
48
48
  it 'highlights the quotes and nothing else' do
49
- expect(refiner.refined_old.to_s).to eq(
49
+ expect(refiner.refined_old).to eq(
50
50
  %(#{RED}-x #{reversed('"')}hej#{reversed('"')}#{RESET}\n))
51
- expect(refiner.refined_new.to_s).to eq(
51
+ expect(refiner.refined_new).to eq(
52
52
  %(#{GREEN}+x #{reversed("'")}hej#{reversed("'")}#{RESET}\n))
53
53
  end
54
54
  end
@@ -58,9 +58,9 @@ RSpec.describe Refiner, '#new' do
58
58
  "abcdefghij\n")
59
59
 
60
60
  it %(doesn't highlight anything) do
61
- expect(refiner.refined_old.to_s).to eq(
61
+ expect(refiner.refined_old).to eq(
62
62
  %(#{RED}-0123456789#{RESET}\n))
63
- expect(refiner.refined_new.to_s).to eq(
63
+ expect(refiner.refined_new).to eq(
64
64
  %(#{GREEN}+abcdefghij#{RESET}\n))
65
65
  end
66
66
  end
@@ -70,15 +70,15 @@ RSpec.describe Refiner, '#new' do
70
70
  "abcde\n")
71
71
 
72
72
  it %(highlights the newline) do
73
- expect(refiner.refined_old.to_s).to eq(
73
+ expect(refiner.refined_old).to eq(
74
74
  %(#{RED}-abcde#{RESET}\n))
75
- expect(refiner.refined_new.to_s).to eq(
75
+ expect(refiner.refined_new).to eq(
76
76
  %(#{GREEN}+abcde#{reversed('↵')}#{RESET}\n))
77
77
  end
78
78
 
79
79
  it %(ends in a newline) do
80
- expect(refiner.refined_old.to_s).to end_with("\n")
81
- expect(refiner.refined_new.to_s).to end_with("\n")
80
+ expect(refiner.refined_old).to end_with("\n")
81
+ expect(refiner.refined_new).to end_with("\n")
82
82
  end
83
83
  end
84
84
 
@@ -87,15 +87,15 @@ RSpec.describe Refiner, '#new' do
87
87
  'abcde')
88
88
 
89
89
  it %(highlights the newline) do
90
- expect(refiner.refined_old.to_s).to eq(
90
+ expect(refiner.refined_old).to eq(
91
91
  %(#{RED}-abcde#{reversed('↵')}#{RESET}\n))
92
- expect(refiner.refined_new.to_s).to eq(
92
+ expect(refiner.refined_new).to eq(
93
93
  %(#{GREEN}+abcde#{RESET}\n))
94
94
  end
95
95
 
96
96
  it %(ends in a newline) do
97
- expect(refiner.refined_old.to_s).to end_with("\n")
98
- expect(refiner.refined_new.to_s).to end_with("\n")
97
+ expect(refiner.refined_old).to end_with("\n")
98
+ expect(refiner.refined_new).to end_with("\n")
99
99
  end
100
100
  end
101
101
 
@@ -105,11 +105,44 @@ RSpec.describe Refiner, '#new' do
105
105
  "fffff,\n" \
106
106
  "ggggg\n")
107
107
 
108
- it %(highlights the comma on the first line, but not the two extra lines) do
109
- expect(refiner.refined_old.to_s).to eq(
110
- %(#{RED}-abcde#{RESET}\n))
111
- expect(refiner.refined_new.to_s).to eq(
108
+ it %(pretends first line is unchanged, but highlights comma) do
109
+ expect(refiner.refined_old).to eq('')
110
+ expect(refiner.refined_new).to eq(
111
+ %( abcde#{reversed(',')}\n) +
112
+ %(#{GREEN}+fffff,\n) +
113
+ %(#{GREEN}+ggggg#{RESET}\n))
114
+ end
115
+ end
116
+
117
+ context %(with two lines turning into many) do
118
+ refiner = Refiner.new("abcde\n" \
119
+ "fffff\n",
120
+ "abcde,\n" \
121
+ "fffff,\n" \
122
+ "ggggg\n")
123
+
124
+ it %(highlights the comma on the first two lines, but not the extra line) do
125
+ expect(refiner.refined_old).to eq(
126
+ %(#{RED}-abcde\n) +
127
+ %(#{RED}-fffff#{RESET}\n))
128
+ expect(refiner.refined_new).to eq(
112
129
  %(#{GREEN}+abcde#{reversed(',')}\n) +
130
+ %(#{GREEN}+fffff#{reversed(',')}\n) +
131
+ %(#{GREEN}+ggggg#{RESET}\n))
132
+ end
133
+ end
134
+
135
+ context %(with one line being replaced with many) do
136
+ refiner = Refiner.new("abcdx\n",
137
+ "abcde,\n" \
138
+ "fffff,\n" \
139
+ "ggggg\n")
140
+
141
+ it %(highlights both adds and removes on the first line) do
142
+ expect(refiner.refined_old).to eq(
143
+ %(#{RED}-abcd#{reversed('x')}#{RESET}\n))
144
+ expect(refiner.refined_new).to eq(
145
+ %(#{GREEN}+abcd#{reversed('e,')}\n) +
113
146
  %(#{GREEN}+fffff,\n) +
114
147
  %(#{GREEN}+ggggg#{RESET}\n))
115
148
  end
@@ -122,11 +155,11 @@ RSpec.describe Refiner, '#new' do
122
155
  "abcde\n")
123
156
 
124
157
  it %(highlights the first removed comma, but not the two removed lines) do
125
- expect(refiner.refined_old.to_s).to eq(
158
+ expect(refiner.refined_old).to eq(
126
159
  %(#{RED}-abcde#{reversed(',')}\n) +
127
160
  %(#{RED}-fffff,\n) +
128
161
  %(#{RED}-ggggg#{RESET}\n))
129
- expect(refiner.refined_new.to_s).to eq(
162
+ expect(refiner.refined_new).to eq(
130
163
  %(#{GREEN}+abcde#{RESET}\n))
131
164
  end
132
165
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riffdiff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johan Walles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-07 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,34 +24,62 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.29.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.29.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: diff-lcs
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: 1.2.5
61
+ version: '1.2'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: 1.2.5
68
+ version: '1.2'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: slop
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: 4.1.0
75
+ version: '4.1'
48
76
  type: :runtime
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: 4.1.0
82
+ version: '4.1'
55
83
  description: |
56
84
  == Riff
57
85
  Riff is a wrapper around diff that highlights not only which lines have changed,
@@ -77,6 +105,7 @@ extra_rdoc_files: []
77
105
  files:
78
106
  - ".gitignore"
79
107
  - ".rubocop.yml"
108
+ - ".travis.yml"
80
109
  - Gemfile
81
110
  - LICENSE
82
111
  - README.md