Skip to content

Commit d2a25a3

Browse files
authored
Merge pull request #251 from kpaulisse/kpaulisse-file-compare-force
Add "force" option for compare-file-text
2 parents 59a6b57 + d838f76 commit d2a25a3

File tree

6 files changed

+144
-3
lines changed

6 files changed

+144
-3
lines changed

doc/advanced-compare-file-text.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ However, since applying the catalog could change the content of a file on the ta
2121
This feature is available only when the catalogs are being compiled from local code. This feature is not available, and will be automatically disabled, when pulling catalogs from PuppetDB or a Puppet server.
2222

2323
Note: In Puppet >= 4.4 there is an option in Puppet itself called "static catalogs" which if enabled will cause the checksum of the file to be included in the catalog. However, the `octocatalog-diff` feature described here is still useful because it can be used to display a "diff" of the change rather than just displaying a "diff" of a checksum.
24+
2425
## Command line options
2526

2627
### `--compare-file-text` and `--no-compare-file-text`
@@ -39,6 +40,12 @@ If this feature is disabled by default in a configuration file, add `--compare-f
3940

4041
Note that the feature will be automatically disabled, regardless of configuration or command line options, if catalogs are being pulled from PuppetDB or a Puppet server.
4142

43+
### `--compare-file-text=force`
44+
45+
To force the option to be on even in situations when it would be auto-disabled, set the command line argument `--compare-file-text=force`. When the Puppet source code is available, e.g. when compiling a catalog with `--catalog-only`, this will adjust the resulting catalog.
46+
47+
If the Puppet source code is not available, forcing the feature on anyway may end up causing an exception. Use this option at your own risk.
48+
4249
### `--compare-file-text-ignore-tags`
4350

4451
To disable this feature for specific `file` resources, set a tag on the resources for which the comparison is undesired. For example:

lib/octocatalog-diff/cli/options/compare_file_text.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,30 @@
44
# the 'source' attribute and populate the 'content' attribute with the text of the file.
55
# This allows for a diff of the content, rather than a diff of the location, which is
66
# what is most often desired.
7+
#
8+
# This has historically been a binary option, so --compare-file-text with no argument will
9+
# set this to `true` and --no-compare-file-text will set this to `false`. Note that
10+
# --no-compare-file-text does not accept an argument.
11+
#
12+
# File text comparison will be auto-disabled in circumstances other than compiling and
13+
# comparing two catalogs. To force file text comparison to be enabled at other times,
14+
# set --compare-file-text=force. This allows the content of the file to be substituted
15+
# in to --catalog-only compilations, for example.
16+
#
717
# @param parser [OptionParser object] The OptionParser argument
818
# @param options [Hash] Options hash being constructed; this is modified in this method.
919
OctocatalogDiff::Cli::Options::Option.newoption(:compare_file_text) do
1020
has_weight 210
1121

1222
def parse(parser, options)
13-
parser.on('--[no-]compare-file-text', 'Compare text, not source location, of file resources') do |x|
14-
options[:compare_file_text] = x
23+
parser.on('--[no-]compare-file-text[=force]', 'Compare text, not source location, of file resources') do |x|
24+
if x == 'force'
25+
options[:compare_file_text] = :force
26+
elsif x == true || x == false
27+
options[:compare_file_text] = x
28+
else
29+
raise OptionParser::NeedlessArgument("needless argument: --compare-file-text=#{x}")
30+
end
1531
end
1632
end
1733
end

lib/octocatalog-diff/util/catalogs.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ def build_catalog_parallelizer
7171
if @options.fetch(:compare_file_text, false)
7272
result.each do |_key, builder_obj|
7373
next if builder_obj.convert_file_resources(true)
74+
75+
if @options[:compare_file_text] == :force
76+
@logger.debug "--compare-file-text is force-enabled even though it is not supported by #{builder_obj.builder}"
77+
next
78+
end
79+
7480
@logger.debug "Disabling --compare-file-text; not supported by #{builder_obj.builder}"
7581
@options[:compare_file_text] = false
7682
catalog_tasks.map! do |x|

spec/octocatalog-diff/integration/convert_file_resources_spec.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,71 @@
147147
end
148148
end
149149

150+
context 'with option auto-disabled' do
151+
before(:all) do
152+
@result = OctocatalogDiff::Integration.integration_cli(
153+
[
154+
'--fact-file', OctocatalogDiff::Spec.fixture_path('facts/facts.yaml'),
155+
'--catalog-only',
156+
'-n', 'rspec-node.github.net',
157+
'--compare-file-text',
158+
'--basedir', OctocatalogDiff::Spec.fixture_path('repos/convert-resources/new'),
159+
'--puppet-binary', OctocatalogDiff::Spec::PUPPET_BINARY,
160+
'--debug'
161+
]
162+
)
163+
end
164+
165+
it 'should compile the catalog' do
166+
expect(@result[:exitcode]).not_to eq(-1), OctocatalogDiff::Integration.format_exception(@result)
167+
expect(@result[:exitcode]).to eq(0), "Runtime error: #{@result[:logs]}"
168+
end
169+
170+
it 'should indicate that the option was disabled' do
171+
expect(@result[:stderr]).to match(/Disabling --compare-file-text; not supported by OctocatalogDiff::Catalog::Noop/)
172+
end
173+
174+
it 'should not have converted resources in the catalog' do
175+
catalog = OctocatalogDiff::Catalog::JSON.new(json: @result[:stdout])
176+
resource = catalog.resource(type: 'File', title: '/tmp/foo2')
177+
expect(resource).to be_a_kind_of(Hash)
178+
expect(resource['parameters']).to eq('source' => 'puppet:///modules/test/foo-old')
179+
end
180+
end
181+
182+
context 'with option force-enabled' do
183+
before(:all) do
184+
@result = OctocatalogDiff::Integration.integration_cli(
185+
[
186+
'--fact-file', OctocatalogDiff::Spec.fixture_path('facts/facts.yaml'),
187+
'--catalog-only',
188+
'-n', 'rspec-node.github.net',
189+
'--compare-file-text=force',
190+
'--basedir', OctocatalogDiff::Spec.fixture_path('repos/convert-resources/new'),
191+
'--puppet-binary', OctocatalogDiff::Spec::PUPPET_BINARY,
192+
'--debug'
193+
]
194+
)
195+
end
196+
197+
it 'should compile the catalog' do
198+
expect(@result[:exitcode]).not_to eq(-1), OctocatalogDiff::Integration.format_exception(@result)
199+
expect(@result[:exitcode]).to eq(0), "Runtime error: #{@result[:logs]}"
200+
end
201+
202+
it 'should indicate that the option was force-enabled' do
203+
rexp = /--compare-file-text is force-enabled even though it is not supported by OctocatalogDiff::Catalog::Noop/
204+
expect(@result[:stderr]).to match(rexp)
205+
end
206+
207+
it 'should have converted resources in the catalog' do
208+
catalog = OctocatalogDiff::Catalog::JSON.new(json: @result[:stdout])
209+
resource = catalog.resource(type: 'File', title: '/tmp/foo2')
210+
expect(resource).to be_a_kind_of(Hash)
211+
expect(resource['parameters']).to eq('content' => "content of foo-old\n")
212+
end
213+
end
214+
150215
context 'with broken reference in to-catalog' do
151216
it 'should fail' do
152217
result = OctocatalogDiff::Integration.integration(

spec/octocatalog-diff/tests/cli/options/compare_file_text_spec.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@
44

55
describe OctocatalogDiff::Cli::Options do
66
describe '#opt_compare_file_text' do
7-
include_examples 'true/false option', 'compare-file-text', :compare_file_text
7+
it 'should set options[:compare_file_text] to true when --compare-file-text is set with no extra argument' do
8+
result = run_optparse(['--compare-file-text'])
9+
expect(result[:compare_file_text]).to eq(true)
10+
end
11+
12+
it 'should set options[:compare_file_text] to :force when --compare-file-text is set to force' do
13+
result = run_optparse(['--compare-file-text=force'])
14+
expect(result[:compare_file_text]).to eq(:force)
15+
end
16+
17+
it 'should set options[:compare_file_text] to false when --no-compare-file-text is set' do
18+
result = run_optparse(['--no-compare-file-text'])
19+
expect(result[:compare_file_text]).to eq(false)
20+
end
21+
22+
it 'should raise if an unnecessary argument is passed to --compare-file-text' do
23+
expect { run_optparse(['--no-compare-file-text=blah']) }.to raise_error(OptionParser::NeedlessArgument)
24+
end
25+
26+
it 'should raise if an argument is passed to --no-compare-file-text' do
27+
expect { run_optparse(['--no-compare-file-text=force']) }.to raise_error(OptionParser::NeedlessArgument)
28+
end
829
end
930
end

spec/octocatalog-diff/tests/util/catalogs_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,32 @@ def valid?
290290
expect(result[:to].builder.to_s).to eq('OctocatalogDiff::Catalog::JSON')
291291
end
292292

293+
it 'should leave --compare-file-text enabled when forced while using a backend that does not support it' do
294+
options = {
295+
from_puppetdb: true,
296+
to_catalog: OctocatalogDiff::Spec.fixture_path('catalogs/tiny-catalog.json'),
297+
compare_file_text: :force,
298+
node: 'tiny-catalog-2-puppetdb',
299+
basedir: '/asdflkj/asdflkj/asldfjk',
300+
from_branch: 'foo'
301+
}
302+
allow(OctocatalogDiff::PuppetDB).to receive(:new) do |*_arg|
303+
OctocatalogDiff::Mocks::PuppetDB.new
304+
end
305+
logger, logger_str = OctocatalogDiff::Spec.setup_logger
306+
testobj = OctocatalogDiff::Util::Catalogs.new(options, logger)
307+
result = testobj.send(:build_catalog_parallelizer)
308+
expect(logger_str.string).to match(/Initialized OctocatalogDiff::Catalog::JSON for to-catalog/)
309+
expect(logger_str.string).to match(/Initialized OctocatalogDiff::Catalog::PuppetDB for from-catalog/)
310+
rexp = /--compare-file-text is force-enabled even though it is not supported by OctocatalogDiff::Catalog::PuppetDB/
311+
expect(logger_str.string).to match(rexp)
312+
expect(result).to be_a_kind_of(Hash)
313+
expect(result[:from]).to be_a_kind_of(OctocatalogDiff::Catalog)
314+
expect(result[:to]).to be_a_kind_of(OctocatalogDiff::Catalog)
315+
expect(result[:from].builder.to_s).to eq('OctocatalogDiff::Catalog::PuppetDB')
316+
expect(result[:to].builder.to_s).to eq('OctocatalogDiff::Catalog::JSON')
317+
end
318+
293319
it 'should raise OctocatalogDiff::Errors::CatalogError if either catalog fails' do
294320
options = {
295321
to_catalog: OctocatalogDiff::Spec.fixture_path('catalogs/tiny-catalog.json'),

0 commit comments

Comments
 (0)