diff --git a/.rubocop.yml b/.rubocop.yml index 409e494..12e57db 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,37 +1,5 @@ --- inherit_from: .rubocop_todo.yml -require: -- rubocop-performance -- rubocop-rake -- rubocop-rspec - -AllCops: - NewCops: enable - TargetRubyVersion: '2.5' - Exclude: - - vendor/**/* - -Style/TrailingCommaInHashLiteral: - Enabled: True - EnforcedStyleForMultiline: consistent_comma - -Style/TrailingCommaInArrayLiteral: - Enabled: True - EnforcedStyleForMultiline: consistent_comma - -Style/TrailingCommaInArguments: - Enabled: True - EnforcedStyleForMultiline: comma - -Gemspec/RequireMFA: - Enabled: false - -Metrics: - Enabled: false - -Style: - Enabled: false - -Layout: - Enabled: false +inherit_gem: + voxpupuli-rubocop: rubocop.yml diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f3632bc..2f11108 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2023-03-17 10:55:36 UTC using RuboCop version 1.28.2. +# on 2023-09-15 11:12:25 UTC using RuboCop version 1.54.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -11,34 +11,21 @@ Lint/RescueException: Exclude: - 'lib/metadata_json_lint.rb' -# Offense count: 3 -# This cop supports safe auto-correction (--auto-correct). -Performance/StringIdentifierArgument: - Exclude: - - 'lib/metadata-json-lint/semantic_puppet_loader.rb' - - 'lib/metadata_json_lint.rb' - # Offense count: 1 -# Configuration parameters: Prefixes. +# Configuration parameters: Prefixes, AllowedPatterns. # Prefixes: when, with, without RSpec/ContextWording: Exclude: - 'spec/metadata_json_lint_spec.rb' # Offense count: 2 -# This cop supports safe auto-correction (--auto-correct). +# This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: SkipBlocks, EnforcedStyle. # SupportedStyles: described_class, explicit RSpec/DescribedClass: Exclude: - 'spec/version_requirement_spec.rb' -# Offense count: 5 -# This cop supports safe auto-correction (--auto-correct). -RSpec/EmptyLineAfterSubject: - Exclude: - - 'spec/schema_spec.rb' - # Offense count: 2 # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. # Include: **/*_spec*rb*, **/spec/**/* @@ -57,25 +44,31 @@ RSpec/MessageSpies: RSpec/MultipleExpectations: Max: 2 -# Offense count: 4 -# Configuration parameters: IgnoreSharedExamples. +# Offense count: 7 +# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. +# SupportedStyles: always, named_only RSpec/NamedSubject: Exclude: - 'spec/schema_spec.rb' # Offense count: 1 -# This cop supports safe auto-correction (--auto-correct). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: +# Configuration parameters: AllowedConstants. +Style/Documentation: Exclude: + - 'spec/**/*' + - 'test/**/*' - 'lib/metadata_json_lint.rb' -# Offense count: 3 -# This cop supports safe auto-correction (--auto-correct). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArrayLiteral: - Exclude: - - 'spec/metadata_json_lint_spec.rb' - - 'spec/spec_helper.rb' +# Offense count: 36 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 6 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 153 diff --git a/Gemfile b/Gemfile index 8168b4c..11090d1 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,6 @@ group :release do end group :coverage, optional: ENV['COVERAGE'] != 'yes' do - gem 'codecov', :require => false - gem 'simplecov-console', :require => false + gem 'codecov', require: false + gem 'simplecov-console', require: false end diff --git a/Rakefile b/Rakefile index 4305c82..5a6dbc0 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,5 @@ desc 'Run all tests' -task :test => %i[spec test:acceptance] +task test: %i[spec test:acceptance] begin require 'rubocop/rake_task' @@ -10,9 +10,7 @@ else # These make the rubocop experience maybe slightly less terrible task.options = ['--display-cop-names', '--display-style-guide', '--extra-details'] # Use Rubocop's Github Actions formatter if possible - if ENV['GITHUB_ACTIONS'] == 'true' - task.formatters << 'github' - end + task.formatters << 'github' if ENV['GITHUB_ACTIONS'] == 'true' end end diff --git a/lib/metadata-json-lint/rake_task.rb b/lib/metadata-json-lint/rake_task.rb index c5b0d71..1b9f0ad 100644 --- a/lib/metadata-json-lint/rake_task.rb +++ b/lib/metadata-json-lint/rake_task.rb @@ -5,7 +5,5 @@ desc 'Run metadata-json-lint' task :metadata_lint do - if File.exist?('metadata.json') - abort unless MetadataJsonLint.parse('metadata.json') - end + abort if File.exist?('metadata.json') && !MetadataJsonLint.parse('metadata.json') end diff --git a/lib/metadata-json-lint/schema.rb b/lib/metadata-json-lint/schema.rb index d544ce6..77d73de 100644 --- a/lib/metadata-json-lint/schema.rb +++ b/lib/metadata-json-lint/schema.rb @@ -158,7 +158,8 @@ def semver_validator(value) raise JSON::Schema::CustomFormatError, "must be a valid semantic version: #{e.message}" end elsif value.match(semver_full_regex).nil? - raise JSON::Schema::CustomFormatError, "must be a valid semantic version: Unable to parse '#{value}' as a semantic version identifier" + raise JSON::Schema::CustomFormatError, + "must be a valid semantic version: Unable to parse '#{value}' as a semantic version identifier" end end end diff --git a/lib/metadata-json-lint/version_requirement.rb b/lib/metadata-json-lint/version_requirement.rb index 3a32026..e05810e 100644 --- a/lib/metadata-json-lint/version_requirement.rb +++ b/lib/metadata-json-lint/version_requirement.rb @@ -7,7 +7,10 @@ def initialize(requirement) if defined?(SemanticPuppet::VersionRange) @range = SemanticPuppet::VersionRange.parse(requirement) - raise ArgumentError, "Range matches no versions: \"#{requirement}\"" if @range == SemanticPuppet::VersionRange::EMPTY_RANGE + if @range == SemanticPuppet::VersionRange::EMPTY_RANGE + raise ArgumentError, + "Range matches no versions: \"#{requirement}\"" + end elsif requirement.match(/\A[a-z0-9*.\-^~><=|\t ]*\Z/i).nil? raise ArgumentError, "Unparsable version range: \"#{requirement}\"" end diff --git a/lib/metadata_json_lint.rb b/lib/metadata_json_lint.rb index a76622c..741abdf 100644 --- a/lib/metadata_json_lint.rb +++ b/lib/metadata_json_lint.rb @@ -15,7 +15,7 @@ def options :strict_license, :strict_dependencies, :strict_puppet_version, - :format + :format, ).new( true, # fail_on_warnings true, # strict_license @@ -30,11 +30,13 @@ def run OptionParser.new do |opts| opts.banner = 'Usage: metadata-json-lint [options] [metadata.json]' - opts.on('--[no-]strict-dependencies', "Fail on open-ended module version dependencies. Defaults to '#{options[:strict_dependencies]}'.") do |v| + opts.on('--[no-]strict-dependencies', + "Fail on open-ended module version dependencies. Defaults to '#{options[:strict_dependencies]}'.") do |v| options[:strict_dependencies] = v end - opts.on('--[no-]strict-license', "Don't fail on strict license check. Defaults to '#{options[:strict_license]}'.") do |v| + opts.on('--[no-]strict-license', + "Don't fail on strict license check. Defaults to '#{options[:strict_license]}'.") do |v| options[:strict_license] = v end @@ -42,11 +44,13 @@ def run options[:fail_on_warnings] = v end - opts.on('--[no-]strict-puppet-version', "Fail on strict Puppet Version check based on current supported Puppet versions. Defaults to '#{options[:strict_puppet_version]}'.") do |v| + opts.on('--[no-]strict-puppet-version', + "Fail on strict Puppet Version check based on current supported Puppet versions. Defaults to '#{options[:strict_puppet_version]}'.") do |v| options[:strict_puppet_version] = v end - opts.on('-f', '--format FORMAT', %i[text json], 'The format in which results will be output (text, json)') do |format| + opts.on('-f', '--format FORMAT', %i[text json], + 'The format in which results will be output (text, json)') do |format| options[:format] = format end end.parse! @@ -97,9 +101,7 @@ def parse(metadata) # From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file deprecated_fields = %w[types checksum] deprecated_fields.each do |field| - unless parsed[field].nil? - error :deprecated_fields, "Deprecated field '#{field}' found in metadata.json." - end + error :deprecated_fields, "Deprecated field '#{field}' found in metadata.json." unless parsed[field].nil? end # The nested 'requirements' name of 'pe' is deprecated as well. @@ -119,16 +121,14 @@ def parse(metadata) case options[:format] when :json - puts JSON.fast_generate(:result => result, :warnings => @warnings, :errors => @errors) + puts JSON.fast_generate(result: result, warnings: @warnings, errors: @errors) else @warnings.each { |warn| puts "(WARN) #{warn}" } @errors.each { |err| puts "(ERROR) #{err}" } puts result end - if !@errors.empty? || (!@warnings.empty? && (options[:fail_on_warnings] == true)) - return false - end + return false if !@errors.empty? || (!@warnings.empty? && (options[:fail_on_warnings] == true)) end true @@ -151,9 +151,7 @@ def validate_requirements!(requirements) return unless requirements.is_a?(Array) requirements.each do |requirement| - if requirement['name'] == 'pe' - warn :requirements, "The 'pe' requirement is no longer supported by the Forge." - end + warn :requirements, "The 'pe' requirement is no longer supported by the Forge." if requirement['name'] == 'pe' begin puppet_req = VersionRequirement.new(requirement.fetch('version_requirement', '')) @@ -162,7 +160,7 @@ def validate_requirements!(requirements) error :requirements, "Invalid 'version_requirement' field in metadata.json: #{e}" end - validate_puppet_ver!(puppet_req) unless puppet_req.instance_variable_get('@requirement').nil? + validate_puppet_ver!(puppet_req) unless puppet_req.instance_variable_get(:@requirement).nil? end validate_requirements_unique(requirements) @@ -179,17 +177,16 @@ def validate_puppet_ver!(requirement) end return unless requirement.mixed_syntax? + warn(:requirement, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \ - "metadata.json, use one style in the puppet version: #{requirement.instance_variable_get('@requirement')}") + "metadata.json, use one style in the puppet version: #{requirement.instance_variable_get(:@requirement)}") end module_function :validate_puppet_ver! def validate_dependencies!(deps) dep_names = [] deps.each do |dep| - if dep_names.include?(dep['name']) - warn :dependencies, "Duplicate dependencies on #{dep['name']}" - end + warn :dependencies, "Duplicate dependencies on #{dep['name']}" if dep_names.include?(dep['name']) dep_names << dep['name'] begin @@ -206,7 +203,7 @@ def validate_dependencies!(deps) # See https://tickets.puppetlabs.com/browse/PUP-2781 if dep.key?('version_range') warn :dependencies, "Dependency #{dep['name']} has a 'version_range' attribute " \ - 'which is no longer used by the forge.' + 'which is no longer used by the forge.' end end end @@ -217,7 +214,7 @@ def validate_version_requirement!(dep, requirement) # From: https://docs.puppet.com/puppet/latest/reference/modules_metadata.html#best-practice-set-an-upper-bound-for-dependencies if options[:strict_dependencies] && requirement.open_ended? msg = "Dependency #{dep['name']} has an open " \ - "ended dependency version requirement #{dep['version_requirement']}" + "ended dependency version requirement #{dep['version_requirement']}" warn(:dependencies, msg) end @@ -225,15 +222,16 @@ def validate_version_requirement!(dep, requirement) # From: https://docs.puppet.com/puppet/latest/modules_metadata.html#version-specifiers # Supported in Puppet 5 and higher, but the syntax is unclear and incompatible with older versions return unless requirement.mixed_syntax? + warn(:dependencies, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \ - "metadata.json, use one style in the #{dep['name']} dependency: #{dep['version_requirement']}") + "metadata.json, use one style in the #{dep['name']} dependency: #{dep['version_requirement']}") end module_function :validate_version_requirement! def format_error(check, msg) case options[:format] when :json - { :check => check, :msg => msg } + { check: check, msg: msg } else "#{check}: #{msg}" end diff --git a/metadata-json-lint.gemspec b/metadata-json-lint.gemspec index 9ae302a..b148580 100644 --- a/metadata-json-lint.gemspec +++ b/metadata-json-lint.gemspec @@ -8,7 +8,6 @@ Gem::Specification.new do |s| s.files = `git ls-files -z`.split("\x0") s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } - s.test_files = s.files.grep(%r{^(tests|spec)/}) s.homepage = 'https://github.com/voxpupuli/metadata-json-lint' s.license = 'Apache-2.0' @@ -20,8 +19,5 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'spdx-licenses', '~> 1.0' s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6' s.add_development_dependency 'rspec', '~> 3.12' - s.add_development_dependency 'rubocop', '~> 1.28.0' - s.add_development_dependency 'rubocop-performance', '~> 1.10' - s.add_development_dependency 'rubocop-rake', '~> 0.2' - s.add_development_dependency 'rubocop-rspec', '~> 2.10.0' + s.add_development_dependency 'voxpupuli-rubocop', '~> 1.2' end diff --git a/spec/metadata_json_lint_spec.rb b/spec/metadata_json_lint_spec.rb index 41ee345..c38afa8 100644 --- a/spec/metadata_json_lint_spec.rb +++ b/spec/metadata_json_lint_spec.rb @@ -11,12 +11,13 @@ context 'with pe' do let :requirements do [ - { 'name' => 'pe' } + { 'name' => 'pe' }, ] end it do - expect(described_class).to receive('warn').with(:requirements, "The 'pe' requirement is no longer supported by the Forge.") + expect(described_class).to receive('warn').with(:requirements, + "The 'pe' requirement is no longer supported by the Forge.") expect { described_class.validate_requirements!(requirements) }.not_to raise_error end end @@ -24,12 +25,13 @@ context 'with invalid requirement' do let :requirements do [ - { 'name' => 'puppet', 'version_requirement' => 'a' } + { 'name' => 'puppet', 'version_requirement' => 'a' }, ] end it do - expect(described_class).to receive('error').with(:requirements, "Invalid 'version_requirement' field in metadata.json: Unparsable version range: \"a\"") + expect(described_class).to receive('error').with(:requirements, + "Invalid 'version_requirement' field in metadata.json: Unparsable version range: \"a\"") expect { described_class.validate_requirements!(requirements) }.not_to raise_error end end diff --git a/spec/schema_spec.rb b/spec/schema_spec.rb index 69a5125..c741564 100644 --- a/spec/schema_spec.rb +++ b/spec/schema_spec.rb @@ -4,10 +4,13 @@ end describe '#validate' do - let(:minimal) { { author: '', dependencies: [], license: 'A', name: 'a-a', source: '', summary: '', version: '1.0.0' } } + let(:minimal) do + { author: '', dependencies: [], license: 'A', name: 'a-a', source: '', summary: '', version: '1.0.0' } + end context 'with empty hash' do subject { described_class.new.validate({}) } + it { is_expected.to be_a(Array) } it { expect(subject.size).to eq(7) } it { is_expected.to include(field: 'root', message: "The file did not contain a required property of 'author'") } @@ -15,24 +18,39 @@ context 'with minimal entries' do subject { described_class.new.validate(minimal) } + it { is_expected.to eq([]) } end context 'with validation error on entry' do subject { described_class.new.validate(minimal.merge(summary: 'A' * 145)) } - it { is_expected.to eq([{ field: 'summary', message: "The property 'summary' was not of a maximum string length of 144" }]) } + + it { + expect(subject).to eq([{ field: 'summary', + message: "The property 'summary' was not of a maximum string length of 144", }]) + } end context 'with validation error on nested entry' do subject { described_class.new.validate(minimal.merge(dependencies: [{ name: 'in###id' }])) } + it { expect(subject.size).to eq(1) } - it { is_expected.to include(field: 'dependencies', message: a_string_matching(%r{The property 'dependencies/0/name' value "in###id" did not match the regex})) } + + it { + expect(subject).to include(field: 'dependencies', + message: a_string_matching(%r{The property 'dependencies/0/name' value "in###id" did not match the regex})) + } end context 'with semver validation failure' do subject { described_class.new.validate(minimal.merge(version: 'a')) } + it { expect(subject.size).to eq(1) } - it { is_expected.to include(field: 'version', message: a_string_matching(/The property 'version' must be a valid semantic version/)) } + + it { + expect(subject).to include(field: 'version', + message: a_string_matching(/The property 'version' must be a valid semantic version/)) + } end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e87b632..4d983cf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -18,7 +18,7 @@ SimpleCov.formatters = [ SimpleCov::Formatter::Console, - SimpleCov::Formatter::Codecov + SimpleCov::Formatter::Codecov, ] end diff --git a/tests/rake_chaining/Rakefile b/tests/rake_chaining/Rakefile index 4da5788..bd554db 100644 --- a/tests/rake_chaining/Rakefile +++ b/tests/rake_chaining/Rakefile @@ -1,7 +1,7 @@ $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) require 'metadata-json-lint/rake_task' -task :test => %i[metadata_lint success] +task test: %i[metadata_lint success] task :success do puts 'Successfully linted' end