yadtfp 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc0e6391243b1ba24c96baf22543c06008664671
4
+ data.tar.gz: d704c04bc9e32111dacd3af5e3f1cb78c9f4a6f4
5
+ SHA512:
6
+ metadata.gz: 75acbe5a35c0c8abfb6da4c2d433a4cf0fbfbc677bc0785c3fb9dec6dcd79440a4583f51df82a2f14887562fcde63f7ec4a34a2ed52471f4e2ce55684aaec5d9
7
+ data.tar.gz: 4c760dfd15403f535f6b4304fcd411e48d36fdf6239585a799ded329fe5643903bdc8766fe78c24e90b498913803382911819a542a866341274ba85574a95b8e
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.yardopts ADDED
@@ -0,0 +1,9 @@
1
+ --charset utf-8
2
+ --readme README.md
3
+ --markup markdown
4
+ --title "Yadtfp Documentation"
5
+ --protected
6
+ --private
7
+ -
8
+ MIT-LICENSE.txt
9
+ CONTRIBUTING.md
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,9 @@
1
+ # Contributing
2
+
3
+ Contributions are welcome.
4
+
5
+ 1. Fork it ( https://github.com/vinodadhikary/yadtfp/fork )
6
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
7
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
8
+ 4. Push to the branch (`git push origin my-new-feature`)
9
+ 5. Create a new Pull Request
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in yadtfp.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ guard :rspec, cmd: 'rspec --color --format doc' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^spec/fabricators/.+_fabricator\.rb$}) { 'spec' }
4
+ watch(%r{^spec/support/.+\.rb$}) { 'spec' }
5
+ watch('spec/spec_helper.rb') { 'spec' }
6
+
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
8
+ watch(%r{^lib/(.+)/(.+)\.rb$}) { |m| "spec/#{m[2]}_spec.rb" }
9
+ watch(%r{^lib/(.+)/(.+)/(.+)\.rb$}) { |m| "spec/#{m[2]}/#{m[3]}_spec.rb" }
10
+ end
11
+
12
+
13
+ # Run `yard` documentation server
14
+ guard 'yard', port: '8808' do
15
+ watch(%r{^(.+)\.md|rb$}) { 'yardoc' }
16
+ end
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) Vinod Adhikary 2014.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # Yadtfp
2
+
3
+ `yadtfp` is a diff tool that takes two [well formed](http://en.wikipedia.org/wiki/Well-formed_document)
4
+ [xml](https://en.wikipedia.org/wiki/XML) documents and generates the differences in an easy to read, concise output.
5
+ The difference algorithm operates on element values producing a very precise diff possible.
6
+
7
+ The name is an acronym for "Yet Another Diff Tool For Param". The original motivation of `yadtfp` was to make it a
8
+ [`CLI`](http://en.wikipedia.org/wiki/Command-line_interface) tool to compare two xml files containing application
9
+ configuration parameters, which is how it got it's name, we think.
10
+
11
+ `yadtfp` parses each input XML into an array of flat hashes, applies filter and compares the two. The result is an
12
+ array of difference hashes. The result array is then passed to the selected outputter which prints the output to
13
+ console.
14
+
15
+
16
+ ## Installation
17
+
18
+ $ gem install yadtfp
19
+
20
+
21
+ ## Documentation
22
+
23
+ The code base documentation is [available here](/_index.html).
24
+
25
+
26
+ ## Parsers
27
+
28
+ Currently `yadtfp` supports [`Ox`](https://github.com/ohler55/ox) parser which is the default.
29
+
30
+
31
+ ## Outputters
32
+
33
+ Currently `yadtfp` supports `Yadtfp::Outputters::Pretty` outputter which is the default.
34
+
35
+
36
+ ### Pretty Outputter
37
+
38
+ Pretty outputter generates the output in the following format:
39
+
40
+ Changes (Replace left value with right value)
41
+ ---------------------------------------------
42
+
43
+ Appends (Add values to left)
44
+ ----------------------------
45
+
46
+ Deletes (Remove values from left)
47
+ ---------------------------------
48
+
49
+ Summary of differences
50
+ ----------------------
51
+ Number of differences: x
52
+ Changes 'c': x
53
+ Appends 'a': x
54
+ Deletes 'd': x
55
+
56
+ *where `x` is an integer value for each difference.*
57
+
58
+ **Note**: In "Summary of differences", Changes, Appends and Deletes are included only if the diff contains respective
59
+ difference, i.e. if a diff does not contain "Deletes" then "Summary of differences" excludes "Deletes", and likewise for
60
+ "Appends" and "Changes".
61
+
62
+
63
+ ## Other topics of interest
64
+
65
+
66
+ ### Path generation
67
+
68
+ Path to each XML component, e.g. attribute, comment, cdata, text are based on the following:
69
+
70
+ **1. Attribute**
71
+
72
+ Attributes are prefixed with `@` sign.
73
+
74
+ # Input XML
75
+ <xml id='foo' />
76
+
77
+ # Path to attribute `id`
78
+ /xml/@id
79
+
80
+ **2. Comment**
81
+
82
+ Comments are denoted by `comment()`.
83
+
84
+ # Input XML
85
+ <xml>
86
+ <!-- Root node -->
87
+ </xml>
88
+
89
+ # Path to comment
90
+ /xml/comment()
91
+
92
+ **3. CData**
93
+
94
+ CData are denoted by `cdata()`.
95
+
96
+ # Input XML
97
+ <xml>
98
+ <![CDATA[ Foo ]]>
99
+ </xml>
100
+
101
+ # Path to cdata
102
+ /xml/cdata()
103
+
104
+ **4. Text**
105
+
106
+ Texts are denoted by path to the node containing the text.
107
+
108
+ # Input XML
109
+ <xml>Foo</xml>
110
+
111
+ # Path to text
112
+ /xml
113
+
114
+
115
+ ### Flat hash
116
+
117
+ Each input xml document is parsed into an array of hashes. This hash's key is the path to the element from the path
118
+ specified in the filter and it's value is the text or value in the xml. If no filter is specified, the default filter
119
+ is used.
120
+
121
+ Example of flat hash data structure, given an input xml:
122
+
123
+ # Input XML
124
+ <xml id='root'>
125
+ <!-- Root node -->
126
+ <child id='child'>Foo</child>
127
+ <![CDATA[ Bar ]]>
128
+ </xml>
129
+
130
+ # Output Array of hashes
131
+ [
132
+ { '/xml/@id' => 'root' },
133
+ { '/xml/comment()' => [ 'Root node' ] },
134
+ { '/xml/cdata()' => [ 'Bar' ] },
135
+ { '/xml/child/@id' => 'child' },
136
+ { '/xml/child' => 'Foo' }
137
+ ]
138
+
139
+
140
+ ### Difference hash
141
+
142
+ There are altogether three types of differences:
143
+
144
+ 1. Change - `c`
145
+ 2. Append - `a`
146
+ 3. Delete - `d`
147
+
148
+ Example difference hash for each difference type is as follows:
149
+
150
+ # Change
151
+ { type: `c`, path: '', lvalue: '', rvalue: '' }
152
+
153
+ # Append
154
+ { type: 'a', path: '', lvalue: '', rvalue: '' }
155
+
156
+ # Delete
157
+ { type: 'd', path: '', lvalue: '', rvalue: '' }
158
+
159
+
160
+
161
+ ### Configuration options
162
+
163
+ `yadtfp` supports the following three parameters:
164
+
165
+ 1. `--filter` to filter content of xml. This is usually applied to perform diff on a subset of input xml.
166
+ Defaults to `"*"`.
167
+
168
+ 2. `--parser` to parse input xml. Defaults to `:ox`.
169
+
170
+ 3. `--outputter` to output result diff. Defaults to `:pretty`.
171
+
172
+
173
+ Each filter option has a shorthand to save a little typing! but **only in the CLI**. The shorthand mapping of each
174
+ options are:
175
+
176
+ 1. `--filter`: `-f`
177
+ 2. `--parser`: `-p`
178
+ 3. `--outputter`: `-o`
179
+
180
+ Each configuration option is prefixed with double dash `--` except for shorthand notations which are prefixed by a
181
+ single dash `-`.
182
+
183
+
184
+ ### Filters
185
+
186
+ Filters are based on [`::Ox::Element#locate()`](http://www.ohler.com/ox/Ox/Element.html#locate-instance_method)
187
+
188
+ Examples sourced from documentation for `#Ox::Element#locate()`:
189
+
190
+ Family/Pete/* - All children of Pete element
191
+ Family/?[1] - First element in Family element
192
+ Family/?[<3]* - First 3 elements in Family element
193
+ Family/?/@age - Age attribute for each child in Family element
194
+ Family/*/@type - Type attribute value for decendents of Family element
195
+ Family/^Comment - Comment children of Family element
196
+
197
+
198
+
199
+ ## CLI Usage
200
+
201
+ **1. `yadtfp` two xml strings using default options**
202
+
203
+ $ yadtfp -- "<xml id='root' />" "<xml name='root_node' />"
204
+ Changes (Replace left value with right value)
205
+ ---------------------------------------------
206
+
207
+ Appends (Add values to left)
208
+ ----------------------------
209
+
210
+ 1. Path: /xml/@name
211
+ Left:
212
+ Right: root_node
213
+
214
+ Deletes (Remove values from left)
215
+ ---------------------------------
216
+
217
+ 1. Path: /xml/@id
218
+ Left: root
219
+ Right:
220
+
221
+
222
+ Summary of differences
223
+ ----------------------
224
+ Number of differences: 2
225
+ Appends 'a': 1
226
+ Deletes 'd': 1
227
+
228
+ The above command can be substituted with:
229
+
230
+ $ yadtfp --filter "*" --parser "ox" --outputter "pretty" "<xml id='root' />" "<xml name='root_node' />"
231
+
232
+ or using shorthand options:
233
+
234
+ $ yadtfp -f "*" -p "ox" -o "pretty" "<xml id='root' />" "<xml name='root_node' />"
235
+
236
+
237
+ **2. `yadtfp` two xml files using default options**
238
+
239
+ Given two xml files `file1.xml` and `file2.xml`:
240
+
241
+ # file1.xml
242
+ <?xml version='1.0' encoding='utf-8' ?>
243
+ <xml>Foo</xml>
244
+
245
+ # file2.xml
246
+ <?xml version='1.0' encoding='utf-8' ?>
247
+ <xml>Bar</xml>
248
+
249
+ Execute `yadtfp diff`:
250
+
251
+ $ yadtfp -- file1.xml file2.xml
252
+ Changes (Replace left value with right value)
253
+ ---------------------------------------------
254
+
255
+ 1. Path: /xml
256
+ Left: Foo
257
+ Right: Bar
258
+
259
+ Appends (Add values to left)
260
+ ----------------------------
261
+
262
+ Deletes (Remove values from left)
263
+ ---------------------------------
264
+
265
+
266
+ Summary of differences
267
+ ----------------------
268
+ Number of differences: 1
269
+ Changes 'c': 1
270
+
271
+
272
+ The above command can be substituted with:
273
+
274
+ $ yadtfp --filter "*" -parser "ox" -outputter "pretty" file1.xml file2.xml
275
+
276
+ or using shorthand options:
277
+
278
+ $ yadtfp -f "*" -p "ox" -o "pretty" file1.xml file2.xml
279
+
280
+ **Note**: File paths may be absolute or relative from the present working directory.
281
+
282
+
283
+ ## Contributing
284
+
285
+ Please see [CONTRIBUTING.md](file.CONTRIBUTING.html)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/yadtfp ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'yadtfp/cli'
3
+ Yadtfp::CLI.start
data/lib/yadtfp.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'yadtfp/version'
2
+ require 'yadtfp/configuration'
3
+ require 'yadtfp/parsers'
4
+ require 'yadtfp/outputters'
5
+
6
+
7
+
8
+ module Yadtfp
9
+
10
+ def self.configuration
11
+ @configuration = Configuration.instance
12
+ end
13
+
14
+
15
+
16
+
17
+ def self.configure
18
+ yield(configuration)
19
+ end
20
+
21
+ end
data/lib/yadtfp/cli.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'thor'
2
+ require 'yadtfp'
3
+
4
+ module Yadtfp
5
+
6
+ class CLI < Thor
7
+
8
+
9
+ class_option :filter, aliases: '-f', type: :string, desc: 'FILTER is path to the node in unix directory structure format'
10
+ class_option :parser, aliases: '-p', type: :string, desc: "PARSER is either 'ox' or 'nokogiri'"
11
+ class_option :outputter, aliases: '-o', type: :string, desc: "OUTPUTTER is 'pretty'"
12
+
13
+
14
+
15
+ desc "diff [OPTIONS]... LEFT RIGHT", "Diff left and right xml documents"
16
+ long_desc <<-LONGDESC
17
+ `diff LEFT RIGHT` will compare `LEFT` and `RIGHT` and print the result to the terminal.
18
+
19
+ When none of the options are specified the default options will apply.
20
+
21
+ The default for each options are:
22
+ \x5 --filter="/"
23
+ \x5 --parser="ox"
24
+ \x5 --outputter="pretty"
25
+
26
+ Examples:
27
+ diff file1.xml file2.xml - Diffs two xml files using default options and pretty prints the result to the terminal.
28
+ LONGDESC
29
+ def diff(file1, file2)
30
+
31
+ # Load config
32
+ config = Yadtfp::Configuration.parse_options(options)
33
+
34
+
35
+ # Parse
36
+ parser = Yadtfp::ParsersFactory.create(config.parser)
37
+
38
+ left = parser.parse(file1)
39
+ right = parser.parse(file2)
40
+
41
+
42
+ # Diff
43
+ diff = parser.diff(left, right)
44
+
45
+
46
+ # Output
47
+ out = Yadtfp::OutputtersFactory.create(config.outputter, diff)
48
+ out.print
49
+
50
+ end
51
+
52
+ default_task :diff
53
+
54
+ end
55
+ end