diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f47b156..a5738ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,5 +15,3 @@ jobs: needs: Spec uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" secrets: "inherit" - with: - flags: "--nightly" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 16b2be3..1b06c47 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -14,5 +14,3 @@ jobs: needs: Spec uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" secrets: "inherit" - with: - flags: "--nightly" diff --git a/.gitignore b/.gitignore index 6260da8..2803e56 100644 --- a/.gitignore +++ b/.gitignore @@ -33,33 +33,3 @@ .plan_cache.json .rerun.json bolt-debug.log - -# ── GSD baseline (auto-generated) ── -.gsd -.gsd-id -.mcp.json -.bg-shell/ -Thumbs.db -*.swp -*.swo -*~ -.idea/ -.vscode/ -*.code-workspace -.env -.env.* -!.env.example -node_modules/ -.next/ -dist/ -build/ -__pycache__/ -*.pyc -.venv/ -venv/ -target/ -vendor/ -*.log -coverage/ -.cache/ -tmp/ diff --git a/.puppet-lint.rc b/.puppet-lint.rc index a63b90e..9e15c6e 100644 --- a/.puppet-lint.rc +++ b/.puppet-lint.rc @@ -6,5 +6,4 @@ --no-autoloader_layout-check --no-documentation-check --no-single_quote_string_with_variables-check ---no-anchor_resource-check --ignore-paths=.vendor/**/*.pp,.bundle/**/*.pp,pkg/**/*.pp,spec/**/*.pp,tests/**/*.pp,types/**/*.pp,vendor/**/*.pp diff --git a/.rubocop.yml b/.rubocop.yml index 47b1aad..4899d2e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,10 @@ --- -require: +plugins: - rubocop-performance - rubocop-rspec +- rubocop-rspec_rails +- rubocop-factory_bot +- rubocop-capybara AllCops: NewCops: enable DisplayCopNames: true @@ -121,6 +124,12 @@ Capybara/CurrentPathExpectation: Enabled: false Capybara/VisibilityMatcher: Enabled: false +FactoryBot/AttributeDefinedStatically: + Enabled: false +FactoryBot/CreateList: + Enabled: false +FactoryBot/FactoryClassName: + Enabled: false Gemspec/DuplicatedAssignment: Enabled: false Gemspec/OrderedDependencies: @@ -295,8 +304,6 @@ Performance/UriDefaultParser: Enabled: false RSpec/Be: Enabled: false -RSpec/Capybara/FeatureMethods: - Enabled: false RSpec/ContainExactly: Enabled: false RSpec/ContextMethod: @@ -305,6 +312,8 @@ RSpec/ContextWording: Enabled: false RSpec/DescribeClass: Enabled: false +RSpec/Dialect: + Enabled: false RSpec/EmptyHook: Enabled: false RSpec/EmptyLineAfterExample: @@ -321,12 +330,6 @@ RSpec/ExpectChange: Enabled: false RSpec/ExpectInHook: Enabled: false -RSpec/FactoryBot/AttributeDefinedStatically: - Enabled: false -RSpec/FactoryBot/CreateList: - Enabled: false -RSpec/FactoryBot/FactoryClassName: - Enabled: false RSpec/HooksBeforeExamples: Enabled: false RSpec/ImplicitBlockExpectation: @@ -501,6 +504,12 @@ Capybara/SpecificFinders: Enabled: false Capybara/SpecificMatcher: Enabled: false +FactoryBot/ConsistentParenthesesStyle: + Enabled: false +FactoryBot/FactoryNameStyle: + Enabled: false +FactoryBot/SyntaxMethods: + Enabled: false Gemspec/DeprecatedAttributeAssignment: Enabled: false Gemspec/DevelopmentDependencies: @@ -601,28 +610,12 @@ RSpec/DuplicatedMetadata: Enabled: false RSpec/ExcessiveDocstringSpacing: Enabled: false -RSpec/FactoryBot/ConsistentParenthesesStyle: - Enabled: false -RSpec/FactoryBot/FactoryNameStyle: - Enabled: false -RSpec/FactoryBot/SyntaxMethods: - Enabled: false RSpec/IdenticalEqualityAssertion: Enabled: false RSpec/NoExpectationExample: Enabled: false RSpec/PendingWithoutReason: Enabled: false -RSpec/Rails/AvoidSetupHook: - Enabled: false -RSpec/Rails/HaveHttpStatus: - Enabled: false -RSpec/Rails/InferredSpecType: - Enabled: false -RSpec/Rails/MinitestAssertions: - Enabled: false -RSpec/Rails/TravelAround: - Enabled: false RSpec/RedundantAround: Enabled: false RSpec/SkipBlockInsideExample: @@ -633,6 +626,16 @@ RSpec/SubjectDeclaration: Enabled: false RSpec/VerifiedDoubleReference: Enabled: false +RSpecRails/AvoidSetupHook: + Enabled: false +RSpecRails/HaveHttpStatus: + Enabled: false +RSpecRails/InferredSpecType: + Enabled: false +RSpecRails/MinitestAssertions: + Enabled: false +RSpecRails/TravelAround: + Enabled: false Security/CompoundHash: Enabled: false Security/IoMethods: diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6da8d47 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "puppet.puppet-vscode", + "Shopify.ruby-lsp" + ] +} diff --git a/Gemfile b/Gemfile index 1e4c3b7..c3137d3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,15 +1,37 @@ -source ENV['GEM_SOURCE'] || 'https://rubygems.org' +# frozen_string_literal: true -def location_for(place_or_version, fake_version = nil) - git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} - file_url_regex = %r{\Afile:\/\/(?.*)} +# For puppetcore, set GEM_SOURCE_PUPPETCORE = 'https://rubygems-puppetcore.puppet.com' +gemsource_default = ENV['GEM_SOURCE'] || 'https://rubygems.org' +gemsource_puppetcore = if ENV['PUPPET_FORGE_TOKEN'] + 'https://rubygems-puppetcore.puppet.com' +else + ENV['GEM_SOURCE_PUPPETCORE'] || gemsource_default +end +source gemsource_default + +def location_for(place_or_constraint, fake_constraint = nil, opts = {}) + git_url_regex = /\A(?(?:https?|git)[:@][^#]*)(?:#(?.*))?/ + file_url_regex = %r{\Afile://(?.*)} + + if place_or_constraint && (git_url = place_or_constraint.match(git_url_regex)) + # Git source → ignore :source, keep fake_constraint + [fake_constraint, { git: git_url[:url], branch: git_url[:branch], require: false }].compact + + elsif place_or_constraint && (file_url = place_or_constraint.match(file_url_regex)) + # File source → ignore :source, keep fake_constraint or default >= 0 + [fake_constraint || '>= 0', { path: File.expand_path(file_url[:path]), require: false }] - if place_or_version && (git_url = place_or_version.match(git_url_regex)) - [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact - elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) - ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] else - [place_or_version, { require: false }] + # Plain version constraint → merge opts (including :source if provided) + [place_or_constraint, { require: false }.merge(opts)] + end +end + +# Print debug information if DEBUG_GEMS or VERBOSE is set +def print_gem_statement_for(gems) + puts 'DEBUG: Gem definitions that will be generated:' + gems.each do |gem_name, gem_params| + puts "DEBUG: gem #{([gem_name.inspect] + gem_params.map(&:inspect)).join(', ')}" end end @@ -30,11 +52,14 @@ group :development do gem "pry", '~> 0.10', require: false gem "simplecov-console", '~> 0.9', require: false gem "puppet-debugger", '~> 1.6', require: false - gem "rubocop", '~> 1.50.0', require: false - gem "rubocop-performance", '= 1.16.0', require: false - gem "rubocop-rspec", '= 2.19.0', require: false - gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "bigdecimal", '< 3.2.2', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "rubocop", '~> 1.73.0', require: false + gem "rubocop-performance", '~> 1.24.0', require: false + gem "rubocop-rspec", '~> 3.5.0', require: false + gem "rubocop-rspec_rails", '~> 2.31.0', require: false + gem "rubocop-factory_bot", '~> 2.27.0', require: false + gem "rubocop-capybara", '~> 2.22.0', require: false + gem "rb-readline", '= 0.5.5', require: false, platforms: [:windows] + gem "bigdecimal", '< 3.2.2', require: false, platforms: [:windows] end group :development, :release_prep do gem "puppet-strings", '~> 4.0', require: false @@ -42,34 +67,25 @@ group :development, :release_prep do gem "puppet-blacksmith", '~> 7.0', require: false end group :system_tests do - gem "puppet_litmus", '~> 2.0', require: false, platforms: [:ruby, :x64_mingw] if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? - gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] if ENV['PUPPET_FORGE_TOKEN'].to_s.empty? - gem "CFPropertyList", '< 3.0.7', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "puppet_litmus", '~> 2.0', require: false, platforms: [:ruby, :windows] if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? + gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :windows] if ENV['PUPPET_FORGE_TOKEN'].to_s.empty? + gem "CFPropertyList", '< 3.0.7', require: false if RUBY_PLATFORM.include?('darwin') gem "serverspec", '~> 2.41', require: false end - gems = {} - +bolt_version = ENV.fetch('BOLT_GEM_VERSION', nil) puppet_version = ENV.fetch('PUPPET_GEM_VERSION', nil) facter_version = ENV.fetch('FACTER_GEM_VERSION', nil) hiera_version = ENV.fetch('HIERA_GEM_VERSION', nil) -# If facter or hiera versions have been specified via the environment -# variables - -# If PUPPET_FORGE_TOKEN is set then use authenticated source for both puppet and facter, since facter is a transitive dependency of puppet -# Otherwise, do as before and use location_for to fetch gems from the default source -if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? - gems['puppet'] = ['~> 8.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] - gems['facter'] = ['~> 4.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] -else - gems['puppet'] = location_for(puppet_version) - gems['facter'] = location_for(facter_version) if facter_version -end - -gems['hiera'] = location_for(hiera_version) if hiera_version +gems['bolt'] = location_for(bolt_version, nil, { source: gemsource_puppetcore }) +gems['puppet'] = location_for(puppet_version, nil, { source: gemsource_puppetcore }) +gems['facter'] = location_for(facter_version, nil, { source: gemsource_puppetcore }) +gems['hiera'] = location_for(hiera_version, nil, {}) if hiera_version +# Generate the gem definitions +print_gem_statement_for(gems) if ENV['DEBUG'] gems.each do |gem_name, gem_params| gem gem_name, *gem_params end @@ -77,12 +93,14 @@ end # Evaluate Gemfile.local and ~/.gemfile if they exist extra_gemfiles = [ "#{__FILE__}.local", - File.join(Dir.home, '.gemfile'), + File.join(Dir.home, '.gemfile') ] extra_gemfiles.each do |gemfile| - if File.file?(gemfile) && File.readable?(gemfile) - eval(File.read(gemfile), binding) - end + next unless File.file?(gemfile) && File.readable?(gemfile) + + # rubocop:disable Security/Eval + eval(File.read(gemfile), binding) + # rubocop:enable Security/Eval end # vim: syntax=ruby diff --git a/metadata.json b/metadata.json index 9025adb..03eeed4 100644 --- a/metadata.json +++ b/metadata.json @@ -78,7 +78,7 @@ } ], "description": "Tasks that manipulate a package", - "pdk-version": "3.5.0 (ga43db72)", + "pdk-version": "3.6.1", "template-url": "https://github.com/puppetlabs/pdk-templates.git#main", - "template-ref": "heads/main-0-g11c0f3d" + "template-ref": "tags/3.6.1.2-0-g30cf4f7" } diff --git a/spec/acceptance/init_spec.rb b/spec/acceptance/init_spec.rb index 0c9f9bd..03d0ad2 100644 --- a/spec/acceptance/init_spec.rb +++ b/spec/acceptance/init_spec.rb @@ -78,7 +78,7 @@ end end - describe 'upgrade', if: (operating_system_fact == 'CentOS' && os[:release].to_i == 7) do + describe 'upgrade', if: operating_system_fact == 'CentOS' && os[:release].to_i == 7 do before(:all) do apply_manifest('package { "httpd": ensure => "present", }') end diff --git a/spec/acceptance/linux_spec.rb b/spec/acceptance/linux_spec.rb index 5bed2f5..888667c 100644 --- a/spec/acceptance/linux_spec.rb +++ b/spec/acceptance/linux_spec.rb @@ -23,7 +23,7 @@ expect(result['result']['_error']).to include('msg') expect(result['result']['_error']).to include('kind' => 'bash-error') expect(result['result']['_error']).to include('details') - elsif result['result']['status'] == 'success' || result['result']['status'] == 'uninstalled' + elsif ['success', 'uninstalled'].include?(result['result']['status']) expect(result['result']).to include('status' => 'uninstalled') else raise "Unexpected result: #{result}" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ae7c1f6..2f7fdae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -26,7 +26,7 @@ begin require 'deep_merge' - default_facts.deep_merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) + default_facts.deep_merge!(YAML.safe_load_file(f, permitted_classes: [], permitted_symbols: [], aliases: true)) rescue StandardError => e RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" end