yadtfp 1.0.2

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 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