daff 1.1.19 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +15 -9
- data/lib/daff.rb +0 -8
- data/lib/lib/coopy/alignment.rb +2 -2
- data/lib/lib/coopy/compare_flags.rb +12 -0
- data/lib/lib/coopy/compare_table.rb +16 -6
- data/lib/lib/coopy/coopy.rb +12 -75
- data/lib/lib/coopy/csv.rb +34 -11
- data/lib/lib/coopy/diff_render.rb +11 -6
- data/lib/lib/coopy/highlight_patch.rb +5 -5
- data/lib/lib/coopy/index_item.rb +4 -0
- data/lib/lib/coopy/index_pair.rb +0 -5
- data/lib/lib/coopy/merger.rb +4 -2
- data/lib/lib/coopy/mover.rb +3 -4
- data/lib/lib/coopy/simple_table.rb +46 -6
- data/lib/lib/coopy/simple_view.rb +0 -12
- data/lib/lib/coopy/table.rb +1 -0
- data/lib/lib/coopy/table_diff.rb +2 -2
- data/lib/lib/coopy/table_text.rb +5 -5
- data/lib/lib/coopy/unit.rb +2 -0
- data/lib/lib/coopy/view.rb +0 -3
- data/lib/lib/coopy/viterbi.rb +4 -0
- metadata +56 -67
- data/lib/lib/_list/list_iterator.rb +0 -31
- data/lib/lib/coopy/bag.rb +0 -12
- data/lib/lib/coopy/change.rb +0 -49
- data/lib/lib/coopy/change_type.rb +0 -21
- data/lib/lib/coopy/compare.rb +0 -99
- data/lib/lib/coopy/report.rb +0 -24
- data/lib/lib/coopy/simple_cell.rb +0 -24
- data/lib/lib/coopy/viewed_datum.rb +0 -38
- data/lib/lib/coopy/workspace.rb +0 -23
- data/lib/lib/haxe/log.rb +0 -16
- data/lib/lib/sys.rb +0 -65
- data/lib/lib/sys/io/file.rb +0 -19
data/README.md
CHANGED
@@ -15,10 +15,7 @@ words multiple versions of the "same" table.
|
|
15
15
|
For a live demo, see:
|
16
16
|
> http://paulfitz.github.com/daff/
|
17
17
|
|
18
|
-
|
19
|
-
> https://github.com/paulfitz/daff/releases
|
20
|
-
|
21
|
-
For certain languages you can use the command-line:
|
18
|
+
Install the library for your favorite language:
|
22
19
|
````sh
|
23
20
|
npm install daff -g # node/javascript
|
24
21
|
pip3 install daff # python3
|
@@ -26,6 +23,9 @@ gem install daff # ruby
|
|
26
23
|
composer require paulfitz/daff-php # php
|
27
24
|
````
|
28
25
|
|
26
|
+
Other translations are available here:
|
27
|
+
> https://github.com/paulfitz/daff/releases
|
28
|
+
|
29
29
|
Or use the library to view csv diffs on github via a chrome extension:
|
30
30
|
> https://github.com/theodi/csvhub
|
31
31
|
|
@@ -77,7 +77,10 @@ Using with git
|
|
77
77
|
|
78
78
|
Run `daff git csv` to install daff as a diff and merge handler
|
79
79
|
for `*.csv` files in your repository. Run `daff git` for instructions
|
80
|
-
on doing this manually.
|
80
|
+
on doing this manually. Your CSV diffs and merges will get smarter,
|
81
|
+
since git will suddenly understand about rows and columns, not just lines:
|
82
|
+
|
83
|
+
![Example CSV diff](scripts/diff.png)
|
81
84
|
|
82
85
|
The library
|
83
86
|
-----------
|
@@ -182,12 +185,12 @@ The `daff` library is written in [Haxe](http://haxe.org/), which
|
|
182
185
|
can be translated reasonably well into at least the following languages:
|
183
186
|
|
184
187
|
* Javascript
|
185
|
-
* PHP
|
186
188
|
* Python
|
187
189
|
* Java
|
188
190
|
* C#
|
189
191
|
* C++
|
190
|
-
* (
|
192
|
+
* Ruby (using an [unofficial haxe target](https://github.com/paulfitz/haxe) developed for `daff`)
|
193
|
+
* PHP
|
191
194
|
|
192
195
|
Some translations are done for you on the
|
193
196
|
[Releases](https://github.com/paulfitz/daff/releases) page.
|
@@ -205,12 +208,15 @@ make cs
|
|
205
208
|
make cpp
|
206
209
|
```
|
207
210
|
|
208
|
-
[@Floppy](https://github.com/Floppy) has made a lovingly-hand-written [native Ruby port](https://github.com/theodi/coopy-ruby) that covers core functionality. I've made a brutally-machine-converted port that is a full translation but less idiomatic.
|
209
|
-
|
210
211
|
For each language, the `daff` library expects to be handed an interface to tables you create, rather than creating them
|
211
212
|
itself. This is to avoid inefficient copies from one format to another. You'll find a `SimpleTable` class you can use if
|
212
213
|
you find this awkward.
|
213
214
|
|
215
|
+
API documentation
|
216
|
+
-----------------
|
217
|
+
|
218
|
+
* You can browse the `daff` classes at http://paulfitz.github.io/daff-doc/
|
219
|
+
|
214
220
|
Reading material
|
215
221
|
----------------
|
216
222
|
|
data/lib/daff.rb
CHANGED
@@ -38,12 +38,8 @@ require_relative 'lib/hx_sys'
|
|
38
38
|
require_relative 'lib/value_type'
|
39
39
|
require_relative 'lib/type'
|
40
40
|
require_relative 'lib/coopy/alignment'
|
41
|
-
require_relative 'lib/coopy/bag'
|
42
41
|
require_relative 'lib/coopy/cell_builder'
|
43
42
|
require_relative 'lib/coopy/cell_info'
|
44
|
-
require_relative 'lib/coopy/change'
|
45
|
-
require_relative 'lib/coopy/change_type'
|
46
|
-
require_relative 'lib/coopy/compare'
|
47
43
|
require_relative 'lib/coopy/compare_flags'
|
48
44
|
require_relative 'lib/coopy/compare_table'
|
49
45
|
require_relative 'lib/coopy/coopy'
|
@@ -60,8 +56,6 @@ require_relative 'lib/coopy/index_pair'
|
|
60
56
|
require_relative 'lib/coopy/merger'
|
61
57
|
require_relative 'lib/coopy/mover'
|
62
58
|
require_relative 'lib/coopy/ordering'
|
63
|
-
require_relative 'lib/coopy/report'
|
64
|
-
require_relative 'lib/coopy/simple_cell'
|
65
59
|
require_relative 'lib/coopy/table'
|
66
60
|
require_relative 'lib/coopy/simple_table'
|
67
61
|
require_relative 'lib/coopy/view'
|
@@ -74,9 +68,7 @@ require_relative 'lib/coopy/table_modifier'
|
|
74
68
|
require_relative 'lib/coopy/table_text'
|
75
69
|
require_relative 'lib/coopy/terminal_diff_render'
|
76
70
|
require_relative 'lib/coopy/unit'
|
77
|
-
require_relative 'lib/coopy/viewed_datum'
|
78
71
|
require_relative 'lib/coopy/viterbi'
|
79
|
-
require_relative 'lib/coopy/workspace'
|
80
72
|
require_relative 'lib/haxe/imap'
|
81
73
|
require_relative 'lib/haxe/ds/int_map'
|
82
74
|
require_relative 'lib/haxe/ds/string_map'
|
data/lib/lib/coopy/alignment.rb
CHANGED
@@ -30,6 +30,18 @@ module Coopy
|
|
30
30
|
attr_accessor :ids
|
31
31
|
attr_accessor :columns_to_ignore
|
32
32
|
|
33
|
+
def filter(act,allow)
|
34
|
+
if @acts == nil
|
35
|
+
@acts = {}
|
36
|
+
@acts["update"] = !allow
|
37
|
+
@acts["insert"] = !allow
|
38
|
+
@acts["delete"] = !allow
|
39
|
+
end
|
40
|
+
return false if !@acts.include?(act)
|
41
|
+
@acts[act] = allow
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
|
33
45
|
def allow_update
|
34
46
|
return true if @acts == nil
|
35
47
|
return @acts.include?("update")
|
@@ -4,7 +4,8 @@
|
|
4
4
|
module Coopy
|
5
5
|
class CompareTable
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize(comp)
|
8
|
+
@comp = comp
|
8
9
|
end
|
9
10
|
|
10
11
|
protected
|
@@ -14,16 +15,18 @@ module Coopy
|
|
14
15
|
|
15
16
|
public
|
16
17
|
|
17
|
-
def
|
18
|
-
@comp = comp
|
18
|
+
def run
|
19
19
|
more = self.compare_core
|
20
|
-
while(more && comp.run_to_completion)
|
20
|
+
while(more && @comp.run_to_completion)
|
21
21
|
more = self.compare_core
|
22
22
|
end
|
23
23
|
return !more
|
24
24
|
end
|
25
25
|
|
26
26
|
def align
|
27
|
+
while(!@comp.completed)
|
28
|
+
self.run
|
29
|
+
end
|
27
30
|
alignment = ::Coopy::Alignment.new
|
28
31
|
self.align_core(alignment)
|
29
32
|
return alignment
|
@@ -316,7 +319,7 @@ module Coopy
|
|
316
319
|
end
|
317
320
|
end
|
318
321
|
end
|
319
|
-
align.link(0,0)
|
322
|
+
align.link(0,0) if ha > 0 && hb > 0
|
320
323
|
end
|
321
324
|
|
322
325
|
def align_columns(align,a,b)
|
@@ -412,7 +415,14 @@ module Coopy
|
|
412
415
|
end
|
413
416
|
end
|
414
417
|
end
|
415
|
-
|
418
|
+
if ma_best == nil
|
419
|
+
if a.get_height > 0 && b.get_height == 0
|
420
|
+
align.headers(0,-1)
|
421
|
+
elsif a.get_height == 0 && b.get_height > 0
|
422
|
+
align.headers(-1,0)
|
423
|
+
end
|
424
|
+
return
|
425
|
+
end
|
416
426
|
_it2 = ::Rb::RubyIterator.new(ma_best.keys)
|
417
427
|
while(_it2.has_next) do
|
418
428
|
key3 = _it2._next
|
data/lib/lib/coopy/coopy.rb
CHANGED
@@ -88,27 +88,8 @@ module Coopy
|
|
88
88
|
end if ext == "json" || ext == ""
|
89
89
|
@format_preference = "csv"
|
90
90
|
csv = ::Coopy::Csv.new(@delim_preference)
|
91
|
-
|
92
|
-
|
93
|
-
w = 0
|
94
|
-
w = data[0].length if h > 0
|
95
|
-
output = ::Coopy::SimpleTable.new(w,h)
|
96
|
-
begin
|
97
|
-
_g = 0
|
98
|
-
while(_g < h)
|
99
|
-
i = _g
|
100
|
-
_g+=1
|
101
|
-
begin
|
102
|
-
_g1 = 0
|
103
|
-
while(_g1 < w)
|
104
|
-
j = _g1
|
105
|
-
_g1+=1
|
106
|
-
val = data[i][j]
|
107
|
-
output.set_cell(j,i,::Coopy::Coopy.cell_for(val))
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
91
|
+
output = ::Coopy::SimpleTable.new(0,0)
|
92
|
+
csv.parse_table(txt,output)
|
112
93
|
output.trim_blank if output != nil
|
113
94
|
return output
|
114
95
|
end
|
@@ -139,8 +120,6 @@ module Coopy
|
|
139
120
|
return r
|
140
121
|
end
|
141
122
|
|
142
|
-
public
|
143
|
-
|
144
123
|
def install_git_driver(io,formats)
|
145
124
|
r = 0
|
146
125
|
if @status == nil
|
@@ -290,9 +269,11 @@ module Coopy
|
|
290
269
|
return 0
|
291
270
|
end
|
292
271
|
|
272
|
+
public
|
273
|
+
|
293
274
|
def coopyhx(io)
|
294
275
|
args = io.args
|
295
|
-
return ::Coopy::Coopy.
|
276
|
+
return ::Coopy::Coopy.keep_around if args[0] == "--keep"
|
296
277
|
more = true
|
297
278
|
output = nil
|
298
279
|
css_output = nil
|
@@ -564,77 +545,31 @@ module Coopy
|
|
564
545
|
class << self
|
565
546
|
attr_accessor :version
|
566
547
|
end
|
567
|
-
@version = "1.1
|
548
|
+
@version = "1.2.1"
|
568
549
|
|
569
550
|
def Coopy.compare_tables(local,remote,flags = nil)
|
570
|
-
ct = ::Coopy::CompareTable.new
|
571
551
|
comp = ::Coopy::TableComparisonState.new
|
572
552
|
comp.a = local
|
573
553
|
comp.b = remote
|
574
554
|
comp.compare_flags = flags
|
575
|
-
ct.
|
555
|
+
ct = ::Coopy::CompareTable.new(comp)
|
576
556
|
return ct
|
577
557
|
end
|
578
558
|
|
579
559
|
def Coopy.compare_tables3(parent,local,remote,flags = nil)
|
580
|
-
ct = ::Coopy::CompareTable.new
|
581
560
|
comp = ::Coopy::TableComparisonState.new
|
582
561
|
comp.p = parent
|
583
562
|
comp.a = local
|
584
563
|
comp.b = remote
|
585
564
|
comp.compare_flags = flags
|
586
|
-
ct.
|
565
|
+
ct = ::Coopy::CompareTable.new(comp)
|
587
566
|
return ct
|
588
567
|
end
|
589
568
|
|
590
569
|
# protected - in ruby this doesn't play well with static/inline methods
|
591
570
|
|
592
|
-
def Coopy.
|
593
|
-
st = ::Coopy::SimpleTable.new(
|
594
|
-
tab = st
|
595
|
-
puts "table size is " + _hx_str(tab.get_width) + "x" + _hx_str(tab.get_height)
|
596
|
-
tab.set_cell(3,4,::Coopy::SimpleCell.new(33))
|
597
|
-
puts "element is " + _hx_str(lambda{ s = tab.get_cell(3,4)
|
598
|
-
_r = s.to_s}.call())
|
599
|
-
compare = ::Coopy::Compare.new
|
600
|
-
d1 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(10))
|
601
|
-
d2 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(10))
|
602
|
-
d3 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(20))
|
603
|
-
report = ::Coopy::Report.new
|
604
|
-
compare.compare(d1,d2,d3,report)
|
605
|
-
puts "report is " + _hx_str(report.to_s)
|
606
|
-
d2 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(50))
|
607
|
-
report.clear
|
608
|
-
compare.compare(d1,d2,d3,report)
|
609
|
-
puts "report is " + _hx_str(report.to_s)
|
610
|
-
d2 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(20))
|
611
|
-
report.clear
|
612
|
-
compare.compare(d1,d2,d3,report)
|
613
|
-
puts "report is " + _hx_str(report.to_s)
|
614
|
-
d1 = ::Coopy::ViewedDatum.get_simple_view(::Coopy::SimpleCell.new(20))
|
615
|
-
report.clear
|
616
|
-
compare.compare(d1,d2,d3,report)
|
617
|
-
puts "report is " + _hx_str(report.to_s)
|
618
|
-
comp = ::Coopy::TableComparisonState.new
|
619
|
-
ct = ::Coopy::CompareTable.new
|
620
|
-
comp.a = st
|
621
|
-
comp.b = st
|
622
|
-
ct.attach(comp)
|
623
|
-
puts "comparing tables"
|
624
|
-
t1 = ::Coopy::SimpleTable.new(3,2)
|
625
|
-
t2 = ::Coopy::SimpleTable.new(3,2)
|
626
|
-
t3 = ::Coopy::SimpleTable.new(3,2)
|
627
|
-
dt1 = ::Coopy::ViewedDatum.new(t1,::Coopy::SimpleView.new)
|
628
|
-
dt2 = ::Coopy::ViewedDatum.new(t2,::Coopy::SimpleView.new)
|
629
|
-
dt3 = ::Coopy::ViewedDatum.new(t3,::Coopy::SimpleView.new)
|
630
|
-
compare.compare(dt1,dt2,dt3,report)
|
631
|
-
puts "report is " + _hx_str(report.to_s)
|
632
|
-
t3.set_cell(1,1,::Coopy::SimpleCell.new("hello"))
|
633
|
-
compare.compare(dt1,dt2,dt3,report)
|
634
|
-
puts "report is " + _hx_str(report.to_s)
|
635
|
-
t1.set_cell(1,1,::Coopy::SimpleCell.new("hello"))
|
636
|
-
compare.compare(dt1,dt2,dt3,report)
|
637
|
-
puts "report is " + _hx_str(report.to_s)
|
571
|
+
def Coopy.keep_around
|
572
|
+
st = ::Coopy::SimpleTable.new(1,1)
|
638
573
|
v = ::Coopy::Viterbi.new
|
639
574
|
td = ::Coopy::TableDiff.new(nil,nil)
|
640
575
|
idx = ::Coopy::Index.new
|
@@ -715,6 +650,8 @@ module Coopy
|
|
715
650
|
return coopy1.coopyhx(io)
|
716
651
|
end
|
717
652
|
|
653
|
+
# protected - in ruby this doesn't play well with static/inline methods
|
654
|
+
|
718
655
|
def Coopy.show(t)
|
719
656
|
w = t.get_width
|
720
657
|
h = t.get_height
|
data/lib/lib/coopy/csv.rb
CHANGED
@@ -92,25 +92,46 @@ module Coopy
|
|
92
92
|
return result
|
93
93
|
end
|
94
94
|
|
95
|
-
def parse_table(txt)
|
95
|
+
def parse_table(txt,tab)
|
96
|
+
return false if !tab.is_resizable
|
96
97
|
@cursor = 0
|
97
98
|
@row_ended = false
|
98
99
|
@has_structure = true
|
99
|
-
|
100
|
-
|
100
|
+
tab.resize(0,0)
|
101
|
+
w = 0
|
102
|
+
h = 0
|
103
|
+
at = 0
|
104
|
+
yat = 0
|
101
105
|
while(@cursor < txt.length)
|
102
|
-
cell = self.
|
103
|
-
|
106
|
+
cell = self.parse_cell_part(txt)
|
107
|
+
if yat >= h
|
108
|
+
h = yat + 1
|
109
|
+
tab.resize(w,h)
|
110
|
+
end
|
111
|
+
if at >= w
|
112
|
+
w = at + 1
|
113
|
+
tab.resize(w,h)
|
114
|
+
end
|
115
|
+
tab.set_cell(at,h - 1,cell)
|
116
|
+
at+=1
|
104
117
|
if @row_ended
|
105
|
-
|
106
|
-
|
118
|
+
at = 0
|
119
|
+
yat+=1
|
107
120
|
end
|
108
121
|
@cursor+=1
|
109
122
|
end
|
110
|
-
return
|
123
|
+
return true
|
111
124
|
end
|
112
125
|
|
113
|
-
def
|
126
|
+
def make_table(txt)
|
127
|
+
tab = ::Coopy::SimpleTable.new(0,0)
|
128
|
+
self.parse_table(txt,tab)
|
129
|
+
return tab
|
130
|
+
end
|
131
|
+
|
132
|
+
protected
|
133
|
+
|
134
|
+
def parse_cell_part(txt)
|
114
135
|
return nil if txt == nil
|
115
136
|
@row_ended = false
|
116
137
|
first_non_underscore = txt.length
|
@@ -173,11 +194,13 @@ module Coopy
|
|
173
194
|
return result
|
174
195
|
end
|
175
196
|
|
176
|
-
|
197
|
+
public
|
198
|
+
|
199
|
+
def parse_cell(txt)
|
177
200
|
@cursor = 0
|
178
201
|
@row_ended = false
|
179
202
|
@has_structure = false
|
180
|
-
return self.
|
203
|
+
return self.parse_cell_part(txt)
|
181
204
|
end
|
182
205
|
|
183
206
|
haxe_me
|
@@ -75,12 +75,12 @@ module Coopy
|
|
75
75
|
return self.html
|
76
76
|
end
|
77
77
|
|
78
|
-
def render(
|
79
|
-
return if
|
78
|
+
def render(tab)
|
79
|
+
return self if tab.get_width == 0 || tab.get_height == 0
|
80
80
|
render = self
|
81
81
|
render.begin_table
|
82
82
|
change_row = -1
|
83
|
-
tt = ::Coopy::TableText.new(
|
83
|
+
tt = ::Coopy::TableText.new(tab)
|
84
84
|
cell = ::Coopy::CellInfo.new
|
85
85
|
corner = tt.get_cell_text(0,0)
|
86
86
|
off = nil
|
@@ -90,11 +90,11 @@ module Coopy
|
|
90
90
|
off = 0
|
91
91
|
end
|
92
92
|
if off > 0
|
93
|
-
return if
|
93
|
+
return self if tab.get_width <= 1 || tab.get_height <= 1
|
94
94
|
end
|
95
95
|
begin
|
96
96
|
_g1 = 0
|
97
|
-
_g =
|
97
|
+
_g = tab.get_height
|
98
98
|
while(_g1 < _g)
|
99
99
|
row = _g1
|
100
100
|
_g1+=1
|
@@ -107,7 +107,7 @@ module Coopy
|
|
107
107
|
render.begin_row(row_mode)
|
108
108
|
begin
|
109
109
|
_g3 = 0
|
110
|
-
_g2 =
|
110
|
+
_g2 = tab.get_width
|
111
111
|
while(_g3 < _g2)
|
112
112
|
c = _g3
|
113
113
|
_g3+=1
|
@@ -119,6 +119,7 @@ module Coopy
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
render.end_table
|
122
|
+
return self
|
122
123
|
end
|
123
124
|
|
124
125
|
def sample_css
|
@@ -212,6 +213,8 @@ module Coopy
|
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
216
|
+
# protected - in ruby this doesn't play well with static/inline methods
|
217
|
+
|
215
218
|
def DiffRender.mark_spaces(sl,sr)
|
216
219
|
return sl if sl == sr
|
217
220
|
return sl if sl == nil || sr == nil
|
@@ -239,6 +242,8 @@ module Coopy
|
|
239
242
|
return slo
|
240
243
|
end
|
241
244
|
|
245
|
+
public
|
246
|
+
|
242
247
|
def DiffRender.render_cell(tt,x,y)
|
243
248
|
cell = ::Coopy::CellInfo.new
|
244
249
|
corner = tt.get_cell_text(0,0)
|