From 0e61be8be7820d25ece66f127278ff4d78c7a6b8 Mon Sep 17 00:00:00 2001 From: Kevin Paulisse Date: Mon, 5 Jun 2017 18:52:40 -0500 Subject: [PATCH 1/2] Add --to-save-catalog and --from-save-catalog --- .../cli/options/save_catalog.rb | 34 +++++++++ .../tests/cli/options/save_catalog_spec.rb | 70 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 lib/octocatalog-diff/cli/options/save_catalog.rb create mode 100644 spec/octocatalog-diff/tests/cli/options/save_catalog_spec.rb diff --git a/lib/octocatalog-diff/cli/options/save_catalog.rb b/lib/octocatalog-diff/cli/options/save_catalog.rb new file mode 100644 index 00000000..34884559 --- /dev/null +++ b/lib/octocatalog-diff/cli/options/save_catalog.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# Allow catalogs to be saved to a file before they are diff'd. +# @param parser [OptionParser object] The OptionParser argument +# @param options [Hash] Options hash being constructed; this is modified in this method. +OctocatalogDiff::Cli::Options::Option.newoption(:save_catalog) do + has_weight 155 + + def parse(parser, options) + OctocatalogDiff::Cli::Options.option_globally_or_per_branch( + parser: parser, + options: options, + cli_name: 'save-catalog', + option_name: 'save_catalog', + desc: 'Save intermediate catalogs into files', + datatype: '', + validator: lambda do |catalog_file| + target_dir = File.dirname(catalog_file) + unless File.directory?(target_dir) + raise Errno::ENOENT, "Cannot save catalog to #{catalog_file} because parent directory does not exist" + end + if File.exist?(catalog_file) && !File.file?(catalog_file) + raise ArgumentError, "Cannot overwrite #{catalog_file} which is not a file" + end + true + end, + post_process: lambda do |opts| + if opts[:to_save_catalog] && opts[:to_save_catalog] == opts[:from_save_catalog] + raise ArgumentError, 'Cannot use the same file for --to-save-catalog and --from-save-catalog' + end + end + ) + end +end diff --git a/spec/octocatalog-diff/tests/cli/options/save_catalog_spec.rb b/spec/octocatalog-diff/tests/cli/options/save_catalog_spec.rb new file mode 100644 index 00000000..16e23099 --- /dev/null +++ b/spec/octocatalog-diff/tests/cli/options/save_catalog_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require_relative '../options_helper' + +describe OctocatalogDiff::Cli::Options do + describe '#opt_save_catalog' do + it 'should raise error if catalog parent directory does not exist' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('non/exists/catalog.json') + ] + expect { run_optparse(args) }.to raise_error(Errno::ENOENT, /parent directory does not exist/) + end + + it 'should raise error if catalog exists but is not a file' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('repos/default') + ] + expect { run_optparse(args) }.to raise_error(ArgumentError, /Cannot overwrite/) + end + + it 'should not raise error if catalog file already exists' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/catalog-1.json') + ] + result = run_optparse(args) + expect(result[:to_save_catalog]).to eq(OctocatalogDiff::Spec.fixture_path('catalogs/catalog-1.json')) + end + + it 'should not raise error if catalog file does not exist' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json') + ] + result = run_optparse(args) + expect(result[:to_save_catalog]).to eq(OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json')) + end + + it 'should raise error if --to-save-catalog == --from-save-catalog' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json'), + '--from-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json') + ] + expect { run_optparse(args) }.to raise_error(ArgumentError, /Cannot use the same file for/) + end + + it 'should not raise error if --to-save-catalog and --from-save-catalog are both nil' do + args = [] + result = run_optparse(args) + expect(result[:to_save_catalog]).to be_nil + expect(result[:from_save_catalog]).to be_nil + end + + it 'should set option correctly' do + args = [ + '--to-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json'), + '--from-save-catalog', + OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-2.json') + ] + result = run_optparse(args) + expect(result[:to_save_catalog]).to eq(OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-1.json')) + expect(result[:from_save_catalog]).to eq(OctocatalogDiff::Spec.fixture_path('catalogs/brand-new-catalog-2.json')) + end + end +end From a64adc3efb5bfd7803ff97c343190f338388a712 Mon Sep 17 00:00:00 2001 From: Kevin Paulisse Date: Mon, 5 Jun 2017 19:02:02 -0500 Subject: [PATCH 2/2] Support catalog saving --- lib/octocatalog-diff/util/catalogs.rb | 5 +++++ .../tests/util/catalogs_spec.rb | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/octocatalog-diff/util/catalogs.rb b/lib/octocatalog-diff/util/catalogs.rb index 625a0a45..5508a1fe 100644 --- a/lib/octocatalog-diff/util/catalogs.rb +++ b/lib/octocatalog-diff/util/catalogs.rb @@ -197,6 +197,11 @@ def add_parallel_result(result, parallel_catalog_obj, key_task_tuple) if catalog.valid? # The catalog was successfully compiled. result[key] = parallel_catalog_obj.output + + if task.args[:save_catalog] + File.open(task.args[:save_catalog], 'w') { |f| f.write(catalog.catalog_json) } + @logger.debug "Saved catalog to #{task.args[:save_catalog]}" + end else # The catalog failed, but a catalog object was returned so that better error reporting # can take place. In this error reporting, we will replace 'Error:' with '[Puppet Error]' diff --git a/spec/octocatalog-diff/tests/util/catalogs_spec.rb b/spec/octocatalog-diff/tests/util/catalogs_spec.rb index 991d63c5..8be2d8a9 100644 --- a/spec/octocatalog-diff/tests/util/catalogs_spec.rb +++ b/spec/octocatalog-diff/tests/util/catalogs_spec.rb @@ -330,6 +330,27 @@ def valid? expect(result[:from]).to eq('blank') end + context 'saving the catalog' do + before(:each) { @tmpdir = Dir.mktmpdir } + after(:each) { OctocatalogDiff::Spec.clean_up_tmpdir(@tmpdir) } + + it 'should save the catalog when requested' do + filename = File.join(@tmpdir, 'catalog.json') + options = { + to_catalog: OctocatalogDiff::Spec.fixture_path('catalogs/tiny-catalog.json'), + from_catalog: OctocatalogDiff::Spec.fixture_path('catalogs/catalog-test-file.json'), + from_save_catalog: filename + } + + logger, logger_str = OctocatalogDiff::Spec.setup_logger + testobj = OctocatalogDiff::Util::Catalogs.new(options, logger) + result = testobj.send(:build_catalog_parallelizer) + + expect(logger_str.string).to match(Regexp.escape("Saved catalog to #{filename}")) + expect(File.read(filename)).to eq(result[:from].catalog_json) + end + end + it 'should format error and raise error when a catalog compile fails' do error_lines = [ 'Debug: You do not care about this',