├── tests ├── no_files │ ├── .gitkeep │ └── expected ├── broken │ ├── expected │ ├── Rakefile │ └── metadata.json ├── types │ ├── expected │ ├── Rakefile │ └── metadata.json ├── duplicate-dep │ ├── expected │ ├── Rakefile │ └── metadata.json ├── missing_newline │ ├── expected │ ├── Rakefile │ └── metadata.json ├── duplicate-requirement │ ├── expected │ ├── Rakefile │ └── metadata.json ├── noname │ ├── expected │ ├── Rakefile │ └── metadata.json ├── bad_license │ ├── expected │ ├── Rakefile │ └── metadata.json ├── invalid_escape_char │ ├── expected │ ├── Rakefile │ └── metadata.json ├── long_summary │ ├── expected │ ├── Rakefile │ └── metadata.json ├── tags_no_array │ ├── expected │ ├── Rakefile │ └── metadata.json ├── missing_version_requirement │ ├── expected │ ├── Rakefile │ └── metadata.json ├── no_pe │ ├── Rakefile │ └── metadata.json ├── open_ended_dependency │ ├── expected │ ├── Rakefile │ └── metadata.json ├── perfect │ ├── Rakefile │ └── metadata.json ├── rake_global_options │ ├── expected │ ├── Rakefile │ └── metadata.json ├── json_format │ ├── Rakefile │ ├── expected │ └── metadata.json ├── proprietary │ ├── Rakefile │ └── metadata.json ├── multiple_problems │ ├── Rakefile │ ├── expected │ └── metadata.json ├── no_dependencies │ ├── Rakefile │ └── metadata.json ├── no_version_range │ ├── Rakefile │ └── metadata.json ├── tags_with_array │ ├── Rakefile │ └── metadata.json ├── mixed_version_syntax │ ├── Rakefile │ ├── expected │ └── metadata.json ├── non_array_requirements │ ├── Rakefile │ ├── expected │ └── metadata.json ├── requirements_eol_version │ ├── Rakefile │ ├── expected │ └── metadata.json ├── rake_chaining │ ├── Rakefile │ └── metadata.json ├── rake_multiple_json_options │ ├── Rakefile │ ├── metadata_ok.json │ └── metadata_license.json └── test.sh ├── .rspec ├── .rubocop.yml ├── .gitignore ├── bin └── metadata-json-lint ├── Gemfile ├── lib ├── metadata-json-lint │ ├── rake_task.rb │ ├── version_requirement.rb │ └── schema.rb └── metadata_json_lint.rb ├── .github ├── dependabot.yml ├── release.yml └── workflows │ ├── test.yml │ └── release.yml ├── metadata-json-lint.gemspec ├── Rakefile ├── spec ├── metadata_json_lint │ ├── version_requirement_spec.rb │ └── schema_spec.rb ├── spec_helper.rb └── metadata_json_lint_spec.rb ├── .rubocop_todo.yml ├── HISTORY.md ├── README.md ├── LICENSE └── CHANGELOG.md /tests/no_files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /tests/broken/expected: -------------------------------------------------------------------------------- 1 | Error: Unable to parse metadata.json: 2 | -------------------------------------------------------------------------------- /tests/types/expected: -------------------------------------------------------------------------------- 1 | Deprecated field 'types' found in metadata.json. 2 | -------------------------------------------------------------------------------- /tests/duplicate-dep/expected: -------------------------------------------------------------------------------- 1 | Duplicate dependencies on puppetlabs/stdlib 2 | -------------------------------------------------------------------------------- /tests/no_files/expected: -------------------------------------------------------------------------------- 1 | Error: Unable to read metadata file: No such file or directory 2 | -------------------------------------------------------------------------------- /tests/missing_newline/expected: -------------------------------------------------------------------------------- 1 | Error: metadata.json does not have a valid newline at the end 2 | -------------------------------------------------------------------------------- /tests/duplicate-requirement/expected: -------------------------------------------------------------------------------- 1 | Duplicate entries in the 'requirements' list with the name 'puppet' 2 | -------------------------------------------------------------------------------- /tests/noname/expected: -------------------------------------------------------------------------------- 1 | (ERROR) required_fields: The file did not contain a required property of 'name' 2 | -------------------------------------------------------------------------------- /tests/bad_license/expected: -------------------------------------------------------------------------------- 1 | License identifier Unknown-1.0 is not in the SPDX list: http://spdx.org/licenses/ 2 | -------------------------------------------------------------------------------- /tests/invalid_escape_char/expected: -------------------------------------------------------------------------------- 1 | Error: Unable to parse metadata.json: Invalid escape character in string 2 | -------------------------------------------------------------------------------- /tests/long_summary/expected: -------------------------------------------------------------------------------- 1 | (ERROR) summary: The property 'summary' was not of a maximum string length of 144 2 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | inherit_from: .rubocop_todo.yml 3 | 4 | inherit_gem: 5 | voxpupuli-rubocop: rubocop.yml 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw? 2 | *.gem 3 | Gemfile.lock 4 | /.bundle 5 | /vendor 6 | tests/*/last_*output 7 | .idea/ 8 | .vendor/ 9 | -------------------------------------------------------------------------------- /tests/tags_no_array/expected: -------------------------------------------------------------------------------- 1 | (ERROR) tags: The property 'tags' of type string did not match the following type: array 2 | -------------------------------------------------------------------------------- /tests/broken/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/missing_version_requirement/expected: -------------------------------------------------------------------------------- 1 | Dependency puppetlabs/stdlib has an open ended dependency version requirement 2 | -------------------------------------------------------------------------------- /tests/no_pe/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/noname/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/open_ended_dependency/expected: -------------------------------------------------------------------------------- 1 | Dependency puppetlabs/stdlib has an open ended dependency version requirement >= 3.2.0 2 | -------------------------------------------------------------------------------- /tests/perfect/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/rake_global_options/expected: -------------------------------------------------------------------------------- 1 | License identifier invalid_license is not in the SPDX list: http://spdx.org/licenses/ 2 | -------------------------------------------------------------------------------- /tests/types/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/bad_license/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/json_format/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/long_summary/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/proprietary/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/duplicate-dep/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/missing_newline/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/multiple_problems/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/no_dependencies/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/no_version_range/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/tags_no_array/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/tags_with_array/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/duplicate-requirement/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/invalid_escape_char/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/mixed_version_syntax/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/non_array_requirements/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/open_ended_dependency/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/missing_version_requirement/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/non_array_requirements/expected: -------------------------------------------------------------------------------- 1 | (ERROR) requirements: The property 'requirements' of type string did not match the following type: array 2 | -------------------------------------------------------------------------------- /tests/requirements_eol_version/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | -------------------------------------------------------------------------------- /tests/json_format/expected: -------------------------------------------------------------------------------- 1 | "warnings":\[{"check":"license","msg":"License identifier Unknown-1.0 is not in the SPDX list: http://spdx.org/licenses/"}\] 2 | -------------------------------------------------------------------------------- /tests/multiple_problems/expected: -------------------------------------------------------------------------------- 1 | Required field 'license' not found in metadata.json. 2 | Required field 'summary' not found in metadata.json. 3 | Deprecated field 'types' found in metadata.json. 4 | -------------------------------------------------------------------------------- /tests/mixed_version_syntax/expected: -------------------------------------------------------------------------------- 1 | (WARN) dependencies: Mixing "x" or "\*" version syntax with operators is not recommended in metadata.json, use one style in the puppetlabs/stdlib dependency: >= 3.2.x 2 | -------------------------------------------------------------------------------- /bin/metadata-json-lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | lib = File.expand_path('../lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | 6 | require 'metadata_json_lint' 7 | 8 | MetadataJsonLint.run 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | group :release, optional: true do 6 | gem 'faraday-retry', '~> 2.1', require: false 7 | gem 'github_changelog_generator', '~> 1.16.4', require: false 8 | end 9 | -------------------------------------------------------------------------------- /tests/rake_chaining/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | 4 | task test: %i[metadata_lint success] 5 | task :success do 6 | puts 'Successfully linted' 7 | end 8 | -------------------------------------------------------------------------------- /tests/rake_global_options/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata-json-lint/rake_task' 3 | MetadataJsonLint.options.strict_license = false 4 | MetadataJsonLint.options.fail_on_warnings = false 5 | -------------------------------------------------------------------------------- /tests/requirements_eol_version/expected: -------------------------------------------------------------------------------- 1 | (WARN) requirements: 3.2.0 is no longer supported. Minimum supported version is 4.10.0(WARN) requirement: 3.2.0 is no longer supported. Minimum supported version is 4.10.0 2 | Warnings found in metadata.json 3 | -------------------------------------------------------------------------------- /lib/metadata-json-lint/rake_task.rb: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/tasklib' 3 | require 'metadata_json_lint' 4 | require 'json' 5 | 6 | desc 'Run metadata-json-lint' 7 | task :metadata_lint do 8 | abort if File.exist?('metadata.json') && !MetadataJsonLint.parse('metadata.json') 9 | end 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # raise PRs for gem updates 4 | - package-ecosystem: bundler 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | time: "13:00" 9 | open-pull-requests-limit: 10 10 | 11 | # Maintain dependencies for GitHub Actions 12 | - package-ecosystem: github-actions 13 | directory: "/" 14 | schedule: 15 | interval: daily 16 | time: "13:00" 17 | open-pull-requests-limit: 10 18 | -------------------------------------------------------------------------------- /tests/rake_multiple_json_options/Rakefile: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) 2 | require 'metadata_json_lint' 3 | MetadataJsonLint.options.fail_on_warnings = false 4 | 5 | desc "Test metadata_lint on multiple files. Don't fail" 6 | task :metadata_lint_multi do 7 | MetadataJsonLint.parse('metadata_license.json') do |options| 8 | options.strict_license = false 9 | end 10 | MetadataJsonLint.parse('metadata_ok.json') do |options| 11 | options.strict_license = true 12 | options.fail_on_warnings = true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /tests/missing_newline/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "A metadata.json file without a newline at the end", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | ], 12 | "requirements": [ 13 | ], 14 | "dependencies": [ 15 | ] 16 | } -------------------------------------------------------------------------------- /tests/invalid_escape_char/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "A description with an invalid \( escape sequence", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | ], 12 | "requirements": [ 13 | ], 14 | "dependencies": [ 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/long_summary/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foo-bar", 3 | "version": "1.0.0", 4 | "author": "foo/bar", 5 | "summary": "This is obviously a way way tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long", 6 | "license": "Apache-2.0", 7 | "source": "", 8 | "project_page": "", 9 | "issues_url": "", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | } 19 | ], 20 | "requirements": [ 21 | ], 22 | "dependencies": [ 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/missing_version_requirement/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "7" 15 | ] 16 | } 17 | ], 18 | "requirements": [ 19 | { 20 | "name": "puppet", 21 | "version_requirement": "3.x" 22 | } 23 | ], 24 | "dependencies": [ 25 | { "name": "puppetlabs/stdlib" } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/mixed_version_syntax/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "7" 15 | ] 16 | } 17 | ], 18 | "requirements": [ 19 | { 20 | "name": "puppet", 21 | "version_requirement": "3.x" 22 | } 23 | ], 24 | "dependencies": [ 25 | { 26 | "name": "puppetlabs/stdlib", 27 | "version_requirement": ">= 3.2.x" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/open_ended_dependency/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "7" 15 | ] 16 | } 17 | ], 18 | "requirements": [ 19 | { 20 | "name": "puppet", 21 | "version_requirement": "3.x" 22 | } 23 | ], 24 | "dependencies": [ 25 | { 26 | "name": "puppetlabs/stdlib", 27 | "version_requirement": ">= 3.2.0" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/no_pe/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "7" 15 | ] 16 | } 17 | ], 18 | "requirements": [ 19 | { 20 | "name": "pe", 21 | "version_requirement": ">= 3.2.0 < 3.4.0" 22 | }, 23 | { 24 | "name": "puppet", 25 | "version_requirement": "3.x" 26 | } 27 | ], 28 | "dependencies": [ 29 | { "name": "puppetlabs/stdlib" } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 3 | 4 | changelog: 5 | exclude: 6 | labels: 7 | - duplicate 8 | - invalid 9 | - modulesync 10 | - question 11 | - skip-changelog 12 | - wont-fix 13 | - wontfix 14 | - github_actions 15 | 16 | categories: 17 | - title: Breaking Changes 🛠 18 | labels: 19 | - backwards-incompatible 20 | 21 | - title: New Features 🎉 22 | labels: 23 | - enhancement 24 | 25 | - title: Bug Fixes 🐛 26 | labels: 27 | - bug 28 | - bugfix 29 | 30 | - title: Documentation Updates 📚 31 | labels: 32 | - documentation 33 | - docs 34 | 35 | - title: Dependency Updates ⬆️ 36 | labels: 37 | - dependencies 38 | 39 | - title: Other Changes 40 | labels: 41 | - "*" 42 | -------------------------------------------------------------------------------- /tests/no_version_range/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "7" 15 | ] 16 | } 17 | ], 18 | "requirements": [ 19 | { 20 | "name": "pe", 21 | "version_requirement": ">= 3.2.0 < 3.4.0" 22 | }, 23 | { 24 | "name": "puppet", 25 | "version_requirement": "3.x" 26 | } 27 | ], 28 | "dependencies": [ 29 | { 30 | "name": "puppetlabs/stdlib", 31 | "version_range": ">= 1.0.0" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /metadata-json-lint.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = 'metadata-json-lint' 3 | s.version = '5.0.0' 4 | s.summary = 'metadata-json-lint /path/to/metadata.json' 5 | s.description = 'Utility to verify Puppet metadata.json files' 6 | s.authors = ['Vox Pupuli'] 7 | s.email = 'voxpupuli@groups.io' 8 | 9 | s.files = `git ls-files -z`.split("\x0") 10 | s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } 11 | 12 | s.homepage = 'https://github.com/voxpupuli/metadata-json-lint' 13 | s.license = 'Apache-2.0' 14 | 15 | s.required_ruby_version = '>= 3.2.0' 16 | 17 | s.add_dependency 'json-schema', '>= 2.8', '< 7.0' 18 | s.add_dependency 'semantic_puppet', '~> 1.0' 19 | s.add_dependency 'spdx-licenses', '~> 1.0' 20 | s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6' 21 | s.add_development_dependency 'rspec', '~> 3.12' 22 | s.add_development_dependency 'voxpupuli-rubocop', '~> 5.1.0' 23 | end 24 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc 'Run all tests' 2 | task test: %i[spec test:acceptance] 3 | 4 | begin 5 | require 'voxpupuli/rubocop/rake' 6 | rescue LoadError 7 | # the voxpupuli-rubocop gem is optional 8 | end 9 | 10 | namespace :test do 11 | desc 'Acceptance suite under test/ which runs metadata-json-lint against sample files with expected output' 12 | task :acceptance do 13 | sh 'tests/test.sh' 14 | end 15 | end 16 | 17 | require 'rspec/core/rake_task' 18 | RSpec::Core::RakeTask.new(:spec) 19 | 20 | begin 21 | require 'rubygems' 22 | require 'github_changelog_generator/task' 23 | rescue LoadError 24 | # github_changelog_generator is in the optional `release` group 25 | else 26 | GitHubChangelogGenerator::RakeTask.new :changelog do |config| 27 | config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog github_actions dependencies] 28 | config.user = 'voxpupuli' 29 | config.project = 'metadata-json-lint' 30 | gem_version = Gem::Specification.load("#{config.project}.gemspec").version 31 | config.future_release = gem_version 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /tests/non_array_requirements/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": "aoeu", 60 | "dependencies": [] 61 | } 62 | -------------------------------------------------------------------------------- /spec/metadata_json_lint/version_requirement_spec.rb: -------------------------------------------------------------------------------- 1 | describe MetadataJsonLint::VersionRequirement do 2 | describe '.new' do 3 | it { expect(described_class.new('')).to be_a(MetadataJsonLint::VersionRequirement) } 4 | it { expect(described_class.new('>= 1.0')).to be_a(MetadataJsonLint::VersionRequirement) } 5 | it { expect { described_class.new('## 1.0') }.to raise_error(ArgumentError) } 6 | end 7 | 8 | describe '#mixed_syntax?' do 9 | it { expect(described_class.new('>= 1.0.0').mixed_syntax?).to be false } 10 | it { expect(described_class.new('1.0.x').mixed_syntax?).to be false } 11 | it { expect(described_class.new('>= 1.0.0 < 2.0').mixed_syntax?).to be false } 12 | it { expect(described_class.new('< 2.0').mixed_syntax?).to be false } 13 | 14 | it { expect(described_class.new('>= 1.0.x').mixed_syntax?).to be true } 15 | it { expect(described_class.new('>= 1.0.*').mixed_syntax?).to be true } 16 | it { expect(described_class.new('>= 1.x').mixed_syntax?).to be true } 17 | it { expect(described_class.new('>= 1.x.x').mixed_syntax?).to be true } 18 | it { expect(described_class.new('>= 1.*').mixed_syntax?).to be true } 19 | it { expect(described_class.new('>= 1.0.0 < 2.x').mixed_syntax?).to be true } 20 | it { expect(described_class.new('<2.x').mixed_syntax?).to be true } 21 | end 22 | 23 | describe '#open_ended?' do 24 | it { expect(described_class.new('>= 1.0 < 2.0').open_ended?).to be false } 25 | it { expect(described_class.new('>= 1.0').open_ended?).to be true } 26 | it { expect(described_class.new('').open_ended?).to be true } 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test 3 | 4 | on: 5 | pull_request: {} 6 | push: 7 | branches: 8 | - master 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | rubocop_and_matrix: 15 | runs-on: ubuntu-latest 16 | outputs: 17 | ruby: ${{ steps.ruby.outputs.versions }} 18 | steps: 19 | - uses: actions/checkout@v6 20 | - name: Install Ruby 3.4 21 | uses: ruby/setup-ruby@v1 22 | with: 23 | ruby-version: '3.4' 24 | bundler-cache: true 25 | - name: Run RuboCop 26 | run: bundle exec rake rubocop 27 | - id: ruby 28 | uses: voxpupuli/ruby-version@v1 29 | 30 | test: 31 | name: "Ruby ${{ matrix.ruby }}" 32 | runs-on: ubuntu-latest 33 | needs: rubocop_and_matrix 34 | strategy: 35 | fail-fast: false 36 | matrix: 37 | ruby: ${{ fromJSON(needs.rubocop_and_matrix.outputs.ruby) }} 38 | steps: 39 | - uses: actions/checkout@v6 40 | - name: Setup ruby 41 | uses: ruby/setup-ruby@v1 42 | with: 43 | ruby-version: ${{ matrix.ruby }} 44 | bundler-cache: true 45 | - name: Run tests 46 | run: bundle exec rake test 47 | - name: Build the gem 48 | run: gem build --strict --verbose *.gemspec 49 | 50 | tests: 51 | if: always() 52 | needs: 53 | - test 54 | runs-on: ubuntu-24.04 55 | name: Test suite 56 | steps: 57 | - name: Decide whether the needed jobs succeeded or failed 58 | uses: re-actors/alls-green@release/v1 59 | with: 60 | jobs: ${{ toJSON(needs) }} 61 | -------------------------------------------------------------------------------- /tests/no_dependencies/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [] 66 | } 67 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'metadata_json_lint' 2 | 3 | # This file was generated by the `rspec --init` command 4 | # 5 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 6 | RSpec.configure do |config| 7 | # rspec-expectations config goes here. You can use an alternate 8 | # assertion/expectation library such as wrong or the stdlib/minitest 9 | # assertions if you prefer. 10 | config.expect_with :rspec do |expectations| 11 | # This option will default to `true` in RSpec 4. It makes the `description` 12 | # and `failure_message` of custom matchers include text for helper methods 13 | # defined using `chain`, e.g.: 14 | # be_bigger_than(2).and_smaller_than(4).description 15 | # # => "be bigger than 2 and smaller than 4" 16 | # ...rather than: 17 | # # => "be bigger than 2" 18 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 19 | end 20 | 21 | # rspec-mocks config goes here. You can use an alternate test double 22 | # library (such as bogus or mocha) by changing the `mock_with` option here. 23 | config.mock_with :rspec do |mocks| 24 | # Prevents you from mocking or stubbing a method that does not exist on 25 | # a real object. This is generally recommended, and will default to 26 | # `true` in RSpec 4. 27 | mocks.verify_partial_doubles = true 28 | end 29 | 30 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will 31 | # have no way to turn it off -- the option exists only for backwards 32 | # compatibility in RSpec 3). It causes shared context metadata to be 33 | # inherited by the metadata hash of host groups and examples, rather than 34 | # triggering implicit auto-inclusion in groups with matching metadata. 35 | config.shared_context_metadata_behavior = :apply_to_host_groups 36 | end 37 | -------------------------------------------------------------------------------- /tests/proprietary/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "proprietary", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": ">=1.1.0 <2.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/concat", 76 | "version_requirement": ">= 1.1.0 <2.0.0" 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /tests/rake_global_options/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "invalid_license", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": ">=1.1.0 <2.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/concat", 76 | "version_requirement": ">= 1.1.0 <2.0.0" 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /tests/rake_multiple_json_options/metadata_ok.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": ">=1.1.0 <2.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/concat", 76 | "version_requirement": ">= 1.1.0 <2.0.0" 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /tests/rake_multiple_json_options/metadata_license.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "invalid_license", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": ">=1.1.0 <2.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/concat", 76 | "version_requirement": ">= 1.1.0 <2.0.0" 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /tests/bad_license/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Unknown-1.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/firewall", 72 | "version_requirement": ">= 0.0.4 <1.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/apt", 76 | "version_requirement": ">=1.1.0 <2.0.0" 77 | }, 78 | { 79 | "name": "puppetlabs/concat", 80 | "version_requirement": ">= 1.1.0 <2.0.0" 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /tests/json_format/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Unknown-1.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/firewall", 72 | "version_requirement": ">= 0.0.4 <1.0.0" 73 | }, 74 | { 75 | "name": "puppetlabs/apt", 76 | "version_requirement": ">=1.1.0 <2.0.0" 77 | }, 78 | { 79 | "name": "puppetlabs/concat", 80 | "version_requirement": ">= 1.1.0 <2.0.0" 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /spec/metadata_json_lint_spec.rb: -------------------------------------------------------------------------------- 1 | describe MetadataJsonLint do 2 | describe '.validate_requirements!' do 3 | context 'empty requirements' do 4 | let :requirements do 5 | [] 6 | end 7 | 8 | it { expect { described_class.validate_requirements!(requirements) }.not_to raise_error } 9 | end 10 | 11 | context 'with openvox' do 12 | let :requirements do 13 | [ 14 | { 'name' => 'openvox', 'version_requirement' => '>= 7.0.0 < 9.0.0' }, 15 | ] 16 | end 17 | 18 | it { expect { described_class.validate_requirements!(requirements) }.not_to raise_error } 19 | end 20 | 21 | context 'with openvox and puppet' do 22 | let :requirements do 23 | [ 24 | { 'name' => 'puppet', 'version_requirement' => '>= 6.0.0 < 8.0.0' }, 25 | { 'name' => 'openvox', 'version_requirement' => '>= 7.0.0 < 9.0.0' }, 26 | ] 27 | end 28 | 29 | it { expect { described_class.validate_requirements!(requirements) }.not_to raise_error } 30 | end 31 | 32 | context 'with pe' do 33 | let :requirements do 34 | [ 35 | { 'name' => 'pe' }, 36 | ] 37 | end 38 | 39 | it do 40 | expect(described_class).to receive('warn').with(:requirements, 41 | "The 'pe' requirement is no longer supported by the Forge.") 42 | expect { described_class.validate_requirements!(requirements) }.not_to raise_error 43 | end 44 | end 45 | 46 | context 'with invalid requirement' do 47 | let :requirements do 48 | [ 49 | { 'name' => 'puppet', 'version_requirement' => 'a' }, 50 | ] 51 | end 52 | 53 | it do 54 | expect(described_class).to receive('error').with(:requirements, 55 | "Invalid 'version_requirement' field in metadata.json: Unparsable version range: \"a\"") 56 | expect { described_class.validate_requirements!(requirements) }.not_to raise_error 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /tests/multiple_problems/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "types": "stuff", 6 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 7 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 8 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 9 | "operatingsystem_support": [ 10 | { 11 | "operatingsystem": "RedHat", 12 | "operatingsystemrelease": [ 13 | "5", 14 | "6", 15 | "7" 16 | ] 17 | }, 18 | { 19 | "operatingsystem": "CentOS", 20 | "operatingsystemrelease": [ 21 | "5", 22 | "6", 23 | "7" 24 | ] 25 | }, 26 | { 27 | "operatingsystem": "OracleLinux", 28 | "operatingsystemrelease": [ 29 | "5", 30 | "6", 31 | "7" 32 | ] 33 | }, 34 | { 35 | "operatingsystem": "Scientific", 36 | "operatingsystemrelease": [ 37 | "5", 38 | "6", 39 | "7" 40 | ] 41 | }, 42 | { 43 | "operatingsystem": "Debian", 44 | "operatingsystemrelease": [ 45 | "6", 46 | "7" 47 | ] 48 | }, 49 | { 50 | "operatingsystem": "Ubuntu", 51 | "operatingsystemrelease": [ 52 | "10.04", 53 | "12.04", 54 | "14.04" 55 | ] 56 | } 57 | ], 58 | "requirements": [ 59 | { 60 | "name": "pe", 61 | "version_requirement": ">= 3.2.0 < 3.4.0" 62 | }, 63 | { 64 | "name": "puppet", 65 | "version_requirement": "3.x" 66 | } 67 | ], 68 | "dependencies": [ 69 | { 70 | "name": "puppetlabs/stdlib", 71 | "version_requirement": "4.x" 72 | }, 73 | { 74 | "name": "puppetlabs/firewall", 75 | "version_requirement": ">= 0.0.4" 76 | }, 77 | { 78 | "name": "puppetlabs/apt", 79 | "version_requirement": ">=1.1.0 <2.0.0" 80 | }, 81 | { 82 | "name": "puppetlabs/concat", 83 | "version_requirement": ">= 1.1.0 <2.0.0" 84 | } 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /spec/metadata_json_lint/schema_spec.rb: -------------------------------------------------------------------------------- 1 | describe MetadataJsonLint::Schema do 2 | describe '#schema' do 3 | it { expect(subject.schema).to be_a(Hash) } 4 | end 5 | 6 | describe '#validate' do 7 | let(:minimal) do 8 | { author: '', dependencies: [], license: 'A', name: 'a-a', source: '', summary: '', version: '1.0.0' } 9 | end 10 | 11 | context 'with empty hash' do 12 | subject { described_class.new.validate({}) } 13 | 14 | it { is_expected.to be_a(Array) } 15 | it { expect(subject.size).to eq(7) } 16 | it { is_expected.to include(field: 'root', message: "The file did not contain a required property of 'author'") } 17 | end 18 | 19 | context 'with minimal entries' do 20 | subject { described_class.new.validate(minimal) } 21 | 22 | it { is_expected.to eq([]) } 23 | end 24 | 25 | context 'with validation error on entry' do 26 | subject { described_class.new.validate(minimal.merge(summary: 'A' * 145)) } 27 | 28 | it { 29 | expect(subject).to eq([{ field: 'summary', 30 | message: "The property 'summary' was not of a maximum string length of 144", }]) 31 | } 32 | end 33 | 34 | context 'with validation error on nested entry' do 35 | subject { described_class.new.validate(minimal.merge(dependencies: [{ name: 'in###id' }])) } 36 | 37 | it { expect(subject.size).to eq(1) } 38 | 39 | it { 40 | expect(subject).to include(field: 'dependencies', 41 | message: a_string_matching(%r{The property 'dependencies/0/name' value "in###id" did not match the regex})) 42 | } 43 | end 44 | 45 | context 'with semver validation failure' do 46 | subject { described_class.new.validate(minimal.merge(version: 'a')) } 47 | 48 | it { expect(subject.size).to eq(1) } 49 | 50 | it { 51 | expect(subject).to include(field: 'version', 52 | message: a_string_matching(/The property 'version' must be a valid semantic version/)) 53 | } 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /tests/noname/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.4.1", 3 | "author": "Inkling/Puppet Labs", 4 | "summary": "PostgreSQL defined resource types", 5 | "license": "Apache-2.0", 6 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 7 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 8 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 9 | "operatingsystem_support": [ 10 | { 11 | "operatingsystem": "RedHat", 12 | "operatingsystemrelease": [ 13 | "5", 14 | "6", 15 | "7" 16 | ] 17 | }, 18 | { 19 | "operatingsystem": "CentOS", 20 | "operatingsystemrelease": [ 21 | "5", 22 | "6", 23 | "7" 24 | ] 25 | }, 26 | { 27 | "operatingsystem": "OracleLinux", 28 | "operatingsystemrelease": [ 29 | "5", 30 | "6", 31 | "7" 32 | ] 33 | }, 34 | { 35 | "operatingsystem": "Scientific", 36 | "operatingsystemrelease": [ 37 | "5", 38 | "6", 39 | "7" 40 | ] 41 | }, 42 | { 43 | "operatingsystem": "Debian", 44 | "operatingsystemrelease": [ 45 | "6", 46 | "7" 47 | ] 48 | }, 49 | { 50 | "operatingsystem": "Ubuntu", 51 | "operatingsystemrelease": [ 52 | "10.04", 53 | "12.04", 54 | "14.04" 55 | ] 56 | } 57 | ], 58 | "requirements": [ 59 | { 60 | "name": "pe", 61 | "version_requirement": ">= 3.2.0 < 3.4.0" 62 | }, 63 | { 64 | "name": "puppet", 65 | "version_requirement": "3.x" 66 | } 67 | ], 68 | "dependencies": [ 69 | { 70 | "name": "puppetlabs/stdlib", 71 | "version_requirement": "4.x" 72 | }, 73 | { 74 | "name": "puppetlabs/firewall", 75 | "version_requirement": ">= 0.0.4" 76 | }, 77 | { 78 | "name": "puppetlabs/apt", 79 | "version_requirement": ">=1.1.0 <2.0.0" 80 | }, 81 | { 82 | "name": "puppetlabs/concat", 83 | "version_requirement": ">= 1.1.0 <2.0.0" 84 | } 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /tests/broken/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql" 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "pe", 62 | "version_requirement": ">= 3.2.0 < 3.4.0" 63 | }, 64 | { 65 | "name": "puppet", 66 | "version_requirement": "3.x" 67 | } 68 | ], 69 | "dependencies": [ 70 | { 71 | "name": "puppetlabs/stdlib", 72 | "version_requirement": "4.x" 73 | }, 74 | { 75 | "name": "puppetlabs/firewall", 76 | "version_requirement": ">= 0.0.4" 77 | }, 78 | { 79 | "name": "puppetlabs/apt", 80 | "version_requirement": ">=1.1.0 <2.0.0" 81 | }, 82 | { 83 | "name": "puppetlabs/concat", 84 | "version_requirement": ">= 1.1.0 <2.0.0" 85 | } 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /tests/duplicate-dep/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "5.5.1" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "4.x" 69 | }, 70 | { 71 | "name": "puppetlabs/stdlib", 72 | "version_requirement": "4.x" 73 | }, 74 | { 75 | "name": "puppetlabs/firewall", 76 | "version_requirement": ">= 0.0.4" 77 | }, 78 | { 79 | "name": "puppetlabs/apt", 80 | "version_requirement": ">=1.1.0 <2.0.0" 81 | }, 82 | { 83 | "name": "puppetlabs/concat", 84 | "version_requirement": ">= 1.1.0 <2.0.0" 85 | } 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /tests/duplicate-requirement/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "5.5.1" 63 | }, 64 | { 65 | "name": "puppet", 66 | "version_requirement": "6.11.0" 67 | } 68 | ], 69 | "dependencies": [ 70 | { 71 | "name": "puppetlabs/stdlib", 72 | "version_requirement": "4.x" 73 | }, 74 | { 75 | "name": "puppetlabs/firewall", 76 | "version_requirement": ">= 0.0.4" 77 | }, 78 | { 79 | "name": "puppetlabs/apt", 80 | "version_requirement": ">=1.1.0 <2.0.0" 81 | }, 82 | { 83 | "name": "puppetlabs/concat", 84 | "version_requirement": ">= 1.1.0 <2.0.0" 85 | } 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /tests/types/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "types": "balls", 4 | "version": "3.4.1", 5 | "author": "Inkling/Puppet Labs", 6 | "summary": "PostgreSQL defined resource types", 7 | "license": "Apache-2.0", 8 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 9 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 10 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 11 | "operatingsystem_support": [ 12 | { 13 | "operatingsystem": "RedHat", 14 | "operatingsystemrelease": [ 15 | "5", 16 | "6", 17 | "7" 18 | ] 19 | }, 20 | { 21 | "operatingsystem": "CentOS", 22 | "operatingsystemrelease": [ 23 | "5", 24 | "6", 25 | "7" 26 | ] 27 | }, 28 | { 29 | "operatingsystem": "OracleLinux", 30 | "operatingsystemrelease": [ 31 | "5", 32 | "6", 33 | "7" 34 | ] 35 | }, 36 | { 37 | "operatingsystem": "Scientific", 38 | "operatingsystemrelease": [ 39 | "5", 40 | "6", 41 | "7" 42 | ] 43 | }, 44 | { 45 | "operatingsystem": "Debian", 46 | "operatingsystemrelease": [ 47 | "6", 48 | "7" 49 | ] 50 | }, 51 | { 52 | "operatingsystem": "Ubuntu", 53 | "operatingsystemrelease": [ 54 | "10.04", 55 | "12.04", 56 | "14.04" 57 | ] 58 | } 59 | ], 60 | "requirements": [ 61 | { 62 | "name": "pe", 63 | "version_requirement": ">= 3.2.0 < 3.4.0" 64 | }, 65 | { 66 | "name": "puppet", 67 | "version_requirement": "3.x" 68 | } 69 | ], 70 | "dependencies": [ 71 | { 72 | "name": "puppetlabs/stdlib", 73 | "version_requirement": "4.x" 74 | }, 75 | { 76 | "name": "puppetlabs/firewall", 77 | "version_requirement": ">= 0.0.4" 78 | }, 79 | { 80 | "name": "puppetlabs/apt", 81 | "version_requirement": ">=1.1.0 <2.0.0" 82 | }, 83 | { 84 | "name": "puppetlabs/concat", 85 | "version_requirement": ">= 1.1.0 <2.0.0" 86 | } 87 | ] 88 | } 89 | -------------------------------------------------------------------------------- /tests/perfect/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "1.2.3" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": "< 1.2.3" 73 | }, 74 | { 75 | "name": "puppetlabs/puppetdb", 76 | "version_requirement": "<= 1.2.3" 77 | }, 78 | { 79 | "name": "puppetlabs/vcsrepo", 80 | "version_requirement": ">= 1.0.0 < 2.0.0" 81 | }, 82 | { 83 | "name": "puppetlabs/rabbitmq", 84 | "version_requirement": "1.x" 85 | }, 86 | { 87 | "name": "puppetlabs/motd", 88 | "version_requirement": "1.2.x" 89 | } 90 | ] 91 | } 92 | -------------------------------------------------------------------------------- /tests/rake_chaining/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "operatingsystem_support": [ 11 | { 12 | "operatingsystem": "RedHat", 13 | "operatingsystemrelease": [ 14 | "5", 15 | "6", 16 | "7" 17 | ] 18 | }, 19 | { 20 | "operatingsystem": "CentOS", 21 | "operatingsystemrelease": [ 22 | "5", 23 | "6", 24 | "7" 25 | ] 26 | }, 27 | { 28 | "operatingsystem": "OracleLinux", 29 | "operatingsystemrelease": [ 30 | "5", 31 | "6", 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "5", 39 | "6", 40 | "7" 41 | ] 42 | }, 43 | { 44 | "operatingsystem": "Debian", 45 | "operatingsystemrelease": [ 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "Ubuntu", 52 | "operatingsystemrelease": [ 53 | "10.04", 54 | "12.04", 55 | "14.04" 56 | ] 57 | } 58 | ], 59 | "requirements": [ 60 | { 61 | "name": "puppet", 62 | "version_requirement": "3.x" 63 | } 64 | ], 65 | "dependencies": [ 66 | { 67 | "name": "puppetlabs/stdlib", 68 | "version_requirement": "1.2.3" 69 | }, 70 | { 71 | "name": "puppetlabs/apt", 72 | "version_requirement": "< 1.2.3" 73 | }, 74 | { 75 | "name": "puppetlabs/puppetdb", 76 | "version_requirement": "<= 1.2.3" 77 | }, 78 | { 79 | "name": "puppetlabs/vcsrepo", 80 | "version_requirement": ">= 1.0.0 < 2.0.0" 81 | }, 82 | { 83 | "name": "puppetlabs/rabbitmq", 84 | "version_requirement": "1.x" 85 | }, 86 | { 87 | "name": "puppetlabs/motd", 88 | "version_requirement": "1.2.x" 89 | } 90 | ] 91 | } 92 | -------------------------------------------------------------------------------- /tests/tags_with_array/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "tags": ["postgres"], 11 | "operatingsystem_support": [ 12 | { 13 | "operatingsystem": "RedHat", 14 | "operatingsystemrelease": [ 15 | "5", 16 | "6", 17 | "7" 18 | ] 19 | }, 20 | { 21 | "operatingsystem": "CentOS", 22 | "operatingsystemrelease": [ 23 | "5", 24 | "6", 25 | "7" 26 | ] 27 | }, 28 | { 29 | "operatingsystem": "OracleLinux", 30 | "operatingsystemrelease": [ 31 | "5", 32 | "6", 33 | "7" 34 | ] 35 | }, 36 | { 37 | "operatingsystem": "Scientific", 38 | "operatingsystemrelease": [ 39 | "5", 40 | "6", 41 | "7" 42 | ] 43 | }, 44 | { 45 | "operatingsystem": "Debian", 46 | "operatingsystemrelease": [ 47 | "6", 48 | "7" 49 | ] 50 | }, 51 | { 52 | "operatingsystem": "Ubuntu", 53 | "operatingsystemrelease": [ 54 | "10.04", 55 | "12.04", 56 | "14.04" 57 | ] 58 | } 59 | ], 60 | "requirements": [ 61 | { 62 | "name": "puppet", 63 | "version_requirement": "3.x" 64 | } 65 | ], 66 | "dependencies": [ 67 | { 68 | "name": "puppetlabs/stdlib", 69 | "version_requirement": "1.2.3" 70 | }, 71 | { 72 | "name": "puppetlabs/apt", 73 | "version_requirement": "< 1.2.3" 74 | }, 75 | { 76 | "name": "puppetlabs/puppetdb", 77 | "version_requirement": "<= 1.2.3" 78 | }, 79 | { 80 | "name": "puppetlabs/vcsrepo", 81 | "version_requirement": ">= 1.0.0 < 2.0.0" 82 | }, 83 | { 84 | "name": "puppetlabs/rabbitmq", 85 | "version_requirement": "1.x" 86 | }, 87 | { 88 | "name": "puppetlabs/motd", 89 | "version_requirement": "1.2.x" 90 | } 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /tests/requirements_eol_version/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "tags": [ "postgres" ], 11 | "operatingsystem_support": [ 12 | { 13 | "operatingsystem": "RedHat", 14 | "operatingsystemrelease": [ 15 | "5", 16 | "6", 17 | "7" 18 | ] 19 | }, 20 | { 21 | "operatingsystem": "CentOS", 22 | "operatingsystemrelease": [ 23 | "5", 24 | "6", 25 | "7" 26 | ] 27 | }, 28 | { 29 | "operatingsystem": "OracleLinux", 30 | "operatingsystemrelease": [ 31 | "5", 32 | "6", 33 | "7" 34 | ] 35 | }, 36 | { 37 | "operatingsystem": "Scientific", 38 | "operatingsystemrelease": [ 39 | "5", 40 | "6", 41 | "7" 42 | ] 43 | }, 44 | { 45 | "operatingsystem": "Debian", 46 | "operatingsystemrelease": [ 47 | "6", 48 | "7" 49 | ] 50 | }, 51 | { 52 | "operatingsystem": "Ubuntu", 53 | "operatingsystemrelease": [ 54 | "10.04", 55 | "12.04", 56 | "14.04" 57 | ] 58 | } 59 | ], 60 | "requirements": [ 61 | { 62 | "name": "puppet", 63 | "version_requirement": "3.2.0" 64 | } 65 | ], 66 | "dependencies": [ 67 | { 68 | "name": "puppetlabs/stdlib", 69 | "version_requirement": "1.2.3" 70 | }, 71 | { 72 | "name": "puppetlabs/apt", 73 | "version_requirement": "< 1.2.3" 74 | }, 75 | { 76 | "name": "puppetlabs/puppetdb", 77 | "version_requirement": "<= 1.2.3" 78 | }, 79 | { 80 | "name": "puppetlabs/vcsrepo", 81 | "version_requirement": ">= 1.0.0 < 2.0.0" 82 | }, 83 | { 84 | "name": "puppetlabs/rabbitmq", 85 | "version_requirement": "1.x" 86 | }, 87 | { 88 | "name": "puppetlabs/motd", 89 | "version_requirement": "1.2.x" 90 | } 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /lib/metadata-json-lint/version_requirement.rb: -------------------------------------------------------------------------------- 1 | module MetadataJsonLint 2 | # Parses a string module version requirement with semantic_puppet and 3 | # provides methods to analyse it for lint warnings 4 | class VersionRequirement 5 | def initialize(requirement) 6 | @requirement = requirement 7 | 8 | if defined?(SemanticPuppet::VersionRange) 9 | @range = SemanticPuppet::VersionRange.parse(requirement) 10 | if @range == SemanticPuppet::VersionRange::EMPTY_RANGE 11 | raise ArgumentError, 12 | "Range matches no versions: \"#{requirement}\"" 13 | end 14 | elsif requirement.match(/\A[a-z0-9*.\-^~><=|\t ]*\Z/i).nil? 15 | raise ArgumentError, "Unparsable version range: \"#{requirement}\"" 16 | end 17 | end 18 | 19 | # Whether the range uses a comparison operator (e.g. >=) with a wildcard 20 | # syntax, such as ">= 1.x" or "< 2.0.x" 21 | def mixed_syntax? 22 | !/ 23 | [><=^~]{1,2} # comparison operators 24 | \s* 25 | \d\. # MAJOR 26 | (?: 27 | (?:x|\*) # MINOR is wildcard 28 | | 29 | \d\.(?:x|\*) # MINOR is digit and PATCH is wildcard 30 | ) 31 | /x.match(requirement).nil? 32 | end 33 | 34 | def open_ended? 35 | if range 36 | range.end == SemanticPuppet::Version::MAX 37 | else 38 | # Empty requirement strings are open-ended. 39 | return true if requirement.strip.empty? 40 | 41 | # Strip superfluous whitespace. 42 | range_set = requirement.gsub(/([><=~^])(?:\s+|\s*v)/, '\1') 43 | 44 | # Split on logical OR 45 | ranges = range_set.split(/\s*\|\|\s*/) 46 | 47 | # Returns true if any range includes a '>' but not a corresponding '<' 48 | # which should be the only way to declare an open-ended range. 49 | ranges.select { |r| r.include?('>') }.any? { |r| !r.include?('<') } 50 | end 51 | end 52 | 53 | def puppet_eol? 54 | true if range.begin < SemanticPuppet::Version.parse(MIN_PUPPET_VER) 55 | end 56 | 57 | def ver_range 58 | range 59 | end 60 | 61 | def min 62 | range.begin 63 | end 64 | 65 | def max 66 | range.end 67 | end 68 | 69 | private 70 | 71 | attr_reader :range, :requirement 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /tests/tags_no_array/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-postgresql", 3 | "version": "3.4.1", 4 | "author": "Inkling/Puppet Labs", 5 | "summary": "PostgreSQL defined resource types", 6 | "license": "Apache-2.0", 7 | "source": "git://github.com/puppetlabs/puppet-postgresql.git", 8 | "project_page": "https://github.com/puppetlabs/puppet-postgresql", 9 | "issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues", 10 | "tags": "postgres", 11 | "operatingsystem_support": [ 12 | { 13 | "operatingsystem": "RedHat", 14 | "operatingsystemrelease": [ 15 | "5", 16 | "6", 17 | "7" 18 | ] 19 | }, 20 | { 21 | "operatingsystem": "CentOS", 22 | "operatingsystemrelease": [ 23 | "5", 24 | "6", 25 | "7" 26 | ] 27 | }, 28 | { 29 | "operatingsystem": "OracleLinux", 30 | "operatingsystemrelease": [ 31 | "5", 32 | "6", 33 | "7" 34 | ] 35 | }, 36 | { 37 | "operatingsystem": "Scientific", 38 | "operatingsystemrelease": [ 39 | "5", 40 | "6", 41 | "7" 42 | ] 43 | }, 44 | { 45 | "operatingsystem": "Debian", 46 | "operatingsystemrelease": [ 47 | "6", 48 | "7" 49 | ] 50 | }, 51 | { 52 | "operatingsystem": "Ubuntu", 53 | "operatingsystemrelease": [ 54 | "10.04", 55 | "12.04", 56 | "14.04" 57 | ] 58 | } 59 | ], 60 | "requirements": [ 61 | { 62 | "name": "pe", 63 | "version_requirement": ">= 3.2.0 < 3.4.0" 64 | }, 65 | { 66 | "name": "puppet", 67 | "version_requirement": "3.x" 68 | } 69 | ], 70 | "dependencies": [ 71 | { 72 | "name": "puppetlabs/stdlib", 73 | "version_requirement": "1.2.3" 74 | }, 75 | { 76 | "name": "puppetlabs/apt", 77 | "version_requirement": "< 1.2.3" 78 | }, 79 | { 80 | "name": "puppetlabs/puppetdb", 81 | "version_requirement": "<= 1.2.3" 82 | }, 83 | { 84 | "name": "puppetlabs/vcsrepo", 85 | "version_requirement": ">= 1.0.0 < 2.0.0" 86 | }, 87 | { 88 | "name": "puppetlabs/rabbitmq", 89 | "version_requirement": "1.x" 90 | }, 91 | { 92 | "name": "puppetlabs/motd", 93 | "version_requirement": "1.2.x" 94 | } 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config --no-auto-gen-timestamp` 3 | # using RuboCop version 1.79.2. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 2 10 | Lint/RescueException: 11 | Exclude: 12 | - 'lib/metadata_json_lint.rb' 13 | 14 | # Offense count: 1 15 | # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates. 16 | # AllowedMethods: call 17 | # WaywardPredicates: nonzero? 18 | Naming/PredicateMethod: 19 | Exclude: 20 | - 'lib/metadata_json_lint.rb' 21 | 22 | # Offense count: 1 23 | # Configuration parameters: Prefixes, AllowedPatterns. 24 | # Prefixes: when, with, without 25 | RSpec/ContextWording: 26 | Exclude: 27 | - 'spec/metadata_json_lint_spec.rb' 28 | 29 | # Offense count: 2 30 | # This cop supports unsafe autocorrection (--autocorrect-all). 31 | # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants. 32 | # SupportedStyles: described_class, explicit 33 | RSpec/DescribedClass: 34 | Exclude: 35 | - 'spec/metadata_json_lint/version_requirement_spec.rb' 36 | 37 | # Offense count: 2 38 | # Configuration parameters: . 39 | # SupportedStyles: have_received, receive 40 | RSpec/MessageSpies: 41 | EnforcedStyle: receive 42 | 43 | # Offense count: 7 44 | # Configuration parameters: EnforcedStyle, IgnoreSharedExamples. 45 | # SupportedStyles: always, named_only 46 | RSpec/NamedSubject: 47 | Exclude: 48 | - 'spec/metadata_json_lint/schema_spec.rb' 49 | 50 | # Offense count: 1 51 | # Configuration parameters: AllowedConstants. 52 | Style/Documentation: 53 | Exclude: 54 | - 'spec/**/*' 55 | - 'test/**/*' 56 | - 'lib/metadata_json_lint.rb' 57 | 58 | # Offense count: 38 59 | # This cop supports unsafe autocorrection (--autocorrect-all). 60 | # Configuration parameters: EnforcedStyle. 61 | # SupportedStyles: always, always_true, never 62 | Style/FrozenStringLiteralComment: 63 | Enabled: false 64 | 65 | # Offense count: 6 66 | # This cop supports safe autocorrection (--autocorrect). 67 | # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. 68 | # URISchemes: http, https 69 | Layout/LineLength: 70 | Max: 153 71 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Gem Release 3 | 4 | on: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | permissions: {} 10 | 11 | jobs: 12 | build-release: 13 | # Prevent releases from forked repositories 14 | if: github.repository_owner == 'voxpupuli' 15 | name: Build the gem 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v6 19 | - name: Install Ruby 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: 'ruby' 23 | - name: Build gem 24 | shell: bash 25 | run: gem build --verbose *.gemspec 26 | - name: Upload gem to GitHub cache 27 | uses: actions/upload-artifact@v6 28 | with: 29 | name: gem-artifact 30 | path: '*.gem' 31 | retention-days: 1 32 | compression-level: 0 33 | 34 | create-github-release: 35 | needs: build-release 36 | name: Create GitHub release 37 | runs-on: ubuntu-24.04 38 | permissions: 39 | contents: write # clone repo and create release 40 | steps: 41 | - name: Download gem from GitHub cache 42 | uses: actions/download-artifact@v7 43 | with: 44 | name: gem-artifact 45 | - name: Create Release 46 | shell: bash 47 | env: 48 | GH_TOKEN: ${{ github.token }} 49 | run: gh release create --repo ${{ github.repository }} ${{ github.ref_name }} --generate-notes *.gem 50 | 51 | release-to-github: 52 | needs: build-release 53 | name: Release to GitHub 54 | runs-on: ubuntu-24.04 55 | permissions: 56 | packages: write # publish to rubygems.pkg.github.com 57 | steps: 58 | - name: Download gem from GitHub cache 59 | uses: actions/download-artifact@v7 60 | with: 61 | name: gem-artifact 62 | - name: Publish gem to GitHub packages 63 | run: gem push --host https://rubygems.pkg.github.com/${{ github.repository_owner }} *.gem 64 | env: 65 | GEM_HOST_API_KEY: ${{ secrets.GITHUB_TOKEN }} 66 | 67 | release-to-rubygems: 68 | needs: build-release 69 | name: Release gem to rubygems.org 70 | runs-on: ubuntu-24.04 71 | environment: release # recommended by rubygems.org 72 | permissions: 73 | id-token: write # rubygems.org authentication 74 | steps: 75 | - name: Download gem from GitHub cache 76 | uses: actions/download-artifact@v7 77 | with: 78 | name: gem-artifact 79 | - uses: rubygems/configure-rubygems-credentials@v1.0.0 80 | - name: Publish gem to rubygems.org 81 | shell: bash 82 | run: gem push *.gem 83 | 84 | release-verification: 85 | name: Check that all releases are done 86 | runs-on: ubuntu-24.04 87 | permissions: 88 | contents: read # minimal permissions that we have to grant 89 | needs: 90 | - create-github-release 91 | - release-to-github 92 | - release-to-rubygems 93 | steps: 94 | - name: Download gem from GitHub cache 95 | uses: actions/download-artifact@v7 96 | with: 97 | name: gem-artifact 98 | - name: Install Ruby 99 | uses: ruby/setup-ruby@v1 100 | with: 101 | ruby-version: 'ruby' 102 | - name: Wait for release to propagate 103 | shell: bash 104 | run: | 105 | gem install rubygems-await 106 | gem await *.gem 107 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | ## 2.3.0 2 | 3 | * Add duplicate testing in requirements list 4 | * Fix wrong license file content so GitHub can properly detect it 5 | * Fix a typo in the README.md 6 | 7 | ## 2.2.0 8 | 9 | * Validate Puppet version_requirement [#99](https://github.com/voxpupuli/metadata-json-lint/issues/99) 10 | * Add optional check `--strict-puppet-version` to validate the Puppet Agent Version is not EOL or open ended [#100](https://github.com/voxpupuli/metadata-json-lint/pull/100) 11 | 12 | ## 2.1.0 13 | 14 | ### Changes 15 | 16 | * Improve rendering of post\_install message by trimming unnecessary leading 17 | spaces [#89](https://github.com/voxpupuli/metadata-json-lint/pull/89) 18 | * Fail when checking version requirements if the version range is empty 19 | [#91](https://github.com/voxpupuli/metadata-json-lint/pull/91) 20 | * Pin `public_suffix` gem to < 3 for Ruby <= 2.0 21 | [#93](https://github.com/voxpupuli/metadata-json-lint/pull/93) 22 | 23 | ### Fixed 24 | 25 | * Prevent metadata-json-lint from crashing when the `requirements` field does 26 | not contain an array 27 | [#94](https://github.com/voxpupuli/metadata-json-lint/pull/94) 28 | * Fix loading of `semantic_puppet` so that it supports using version vendored 29 | in Puppet (if available) 30 | [#96](https://github.com/voxpupuli/metadata-json-lint/pull/96) 31 | 32 | ## 2.0.2 33 | 34 | ### Changes 35 | 36 | * Make SemanticPuppet completely optional and remove dependency on Puppet [#86](https://github.com/voxpupuli/metadata-json-lint/pull/86) 37 | * Only log open dependency warning with --strict-dependencies [#78](https://github.com/voxpupuli/metadata-json-lint/pull/78) 38 | 39 | ### Fixed 40 | 41 | * Fix readme for gemfile usage [#84](https://github.com/voxpupuli/metadata-json-lint/pull/84) 42 | 43 | ## 2.0.1 44 | 45 | ### Changes 46 | 47 | * Puppet 4.9.0 and newer uses the vendored `semantic_puppet` packaged with Puppet. 48 | * If using Puppet 4.8.x and earlier, adding `semantic_puppet` to your Gemfile is required 49 | as the vendored `semantic_puppet` was not packaged with Puppet prior to `4.9.0` 50 | * Add test environment for Ruby 2.4.1 51 | 52 | ## 2.0.0 53 | 54 | ### Changes 55 | 56 | * The `semantic_puppet` gem is no longer included as a runtime dependency due to conflicts with Puppet 5.x libraries that break the `puppet module` command. As such, `semantic_puppet` must be added to a user's Gemfile in Puppet <= 4.x. See [Installation](https://github.com/voxpupuli/metadata-json-lint#installation) docs for more info 57 | * `metadata-json-lint` now officially only supports Ruby >= 2.0.0 58 | 59 | ### Fixed 60 | 61 | * Fix puppet 5.x `semantic_puppet` conflicts ([#79](https://github.com/voxpupuli/metadata-json-lint/issues/79)) 62 | * Clarify Ruby >= 2.x only support ([#74](https://github.com/voxpupuli/metadata-json-lint/issues/74)) 63 | 64 | ## 1.2.2 65 | 66 | ### Fixed 67 | 68 | * Fix `metadata_lint` rake task exiting on success, not continuing ([#70](https://github.com/voxpupuli/metadata-json-lint/issues/70)) 69 | * Fix failure on incorrect license warning when `--no-strict-license` used ([#69](https://github.com/voxpupuli/metadata-json-lint/issues/69)) 70 | 71 | ## 1.2.1 72 | 73 | ### Fixed 74 | 75 | * Fix missing lib/ files in published gem 76 | 77 | ## 1.2.0 78 | 79 | ### Added 80 | 81 | * Add `--format`/`-f` option to support a JSON output format 82 | * Add warning for mixed version range syntax, supported only in Puppet 5 83 | 84 | ### Changed 85 | 86 | * The default text format mode now outputs more structured messages 87 | * README has been edited and clarity improved 88 | 89 | ### Fixed 90 | 91 | * Fix non-zero exit code caused by some checks 92 | 93 | ## 1.1.0 94 | 95 | ### Added 96 | 97 | * Ensure module `tags` are correctly specified as an array ([#44](https://github.com/voxpupuli/metadata-json-lint/issues/44)) 98 | * Ensure `requirements` doesn't list the deprecated `pe` key ([#46](https://github.com/voxpupuli/metadata-json-lint/issues/46)) 99 | * Ensure `dependencies` aren't listed with `version_range` keys ([#47](https://github.com/voxpupuli/metadata-json-lint/issues/47)) 100 | * Support strictness configuration via Ruby API, for use in rake tasks definitions 101 | * Show default strictness option values in `--help` output 102 | 103 | ### Fixed 104 | 105 | * Fix unclear error message when metadata.json does not exist 106 | * Fix gem publishing date 107 | * Various test improvements, ensuring failures are caught accurately and precisely 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # metadata-json-lint 2 | 3 | [![License](https://img.shields.io/github/license/voxpupuli/metadata-json-lint.svg)](https://github.com/voxpupuli/metadata-json-lint/blob/master/LICENSE) 4 | [![Test](https://github.com/voxpupuli/metadata-json-lint/actions/workflows/test.yml/badge.svg)](https://github.com/voxpupuli/metadata-json-lint/actions/workflows/test.yml) 5 | [![codecov](https://codecov.io/gh/voxpupuli/metadata-json-lint/branch/master/graph/badge.svg)](https://codecov.io/gh/voxpupuli/metadata-json-lint) 6 | [![Release](https://github.com/voxpupuli/metadata-json-lint/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/metadata-json-lint/actions/workflows/release.yml) 7 | [![RubyGem Version](https://img.shields.io/gem/v/metadata-json-lint.svg)](https://rubygems.org/gems/metadata-json-lint) 8 | [![RubyGem Downloads](https://img.shields.io/gem/dt/metadata-json-lint.svg)](https://rubygems.org/gems/metadata-json-lint) 9 | 10 | The metadata-json-lint tool validates and lints `metadata.json` files in Puppet modules against style guidelines from the [Puppet Forge module metadata](https://docs.puppet.com/puppet/latest/modules_publishing.html#write-a-metadatajson-file) recommendations. 11 | 12 | ## Compatibility 13 | 14 | metadata-json-lint is tested on Ruby 2.7 to 3.3. The the authoritative source, 15 | check the `required_ruby_version` attribute in the gemspec file. 16 | 17 | ## Installation 18 | 19 | via `gem` command: 20 | ``` shell 21 | gem install metadata-json-lint 22 | ``` 23 | 24 | via Gemfile: 25 | ``` ruby 26 | gem 'metadata-json-lint' 27 | ``` 28 | 29 | ## Usage 30 | 31 | ### Testing with metadata-json-lint 32 | 33 | On the command line, run `metadata-json-lint` with the path of your `metadata.json` file: 34 | 35 | ```shell 36 | metadata-json-lint /path/to/metadata.json 37 | ``` 38 | 39 | ### Testing with metadata-json-lint as a Rake task 40 | 41 | If you are already using `puppet_spec_helper`, the 'validate' task already includes `metadata-json-lint`. 42 | 43 | You can also integrate `metadata-json-lint` checks into your tests using the Rake task. Add `require 'metadata-json-lint/rake_task'` to your `Rakefile`, and then run: 44 | 45 | ```ruby 46 | rake metadata_lint 47 | ``` 48 | 49 | To set options for the Rake task, include them when you define the task: 50 | 51 | ```ruby 52 | require 'metadata_json_lint' 53 | task :metadata_lint do 54 | MetadataJsonLint.parse('metadata.json') do |options| 55 | options.strict_license = false 56 | end 57 | end 58 | ``` 59 | 60 | Alternatively, set the option after requiring the Rake task: 61 | 62 | ```ruby 63 | require 'metadata-json-lint/rake_task' 64 | MetadataJsonLint.options.strict_license = false 65 | ``` 66 | 67 | ### Options 68 | 69 | * `--[no-]strict-dependencies`: Whether to fail if module version dependencies are open-ended. Defaults to `false`. 70 | * `--[no-]strict-license`: Whether to fail on strict license check. Defaults to `true`. 71 | * `--[no-]fail-on-warnings`: Whether to fail on warnings. Defaults to `true`. 72 | * `--[no-]strict-puppet-version`: Whether to fail if Puppet version requirements are open-ended or no longer supported. Defaults to `false`. 73 | 74 | ## Contributors 75 | 76 | A big thank you to the [contributors](https://github.com/voxpupuli/metadata-json-lint/graphs/contributors). 77 | 78 | ## Making a new release 79 | 80 | How to make a new release? 81 | 82 | * update the gemspec file with the desired version 83 | 84 | ```console 85 | $ git diff 86 | diff --git a/metadata-json-lint.gemspec b/metadata-json-lint.gemspec 87 | index c86668e..6a3ad38 100644 88 | --- a/metadata-json-lint.gemspec 89 | +++ b/metadata-json-lint.gemspec 90 | @@ -2,7 +2,7 @@ require 'date' 91 | 92 | Gem::Specification.new do |s| 93 | s.name = 'metadata-json-lint' 94 | - s.version = '2.4.0' 95 | + s.version = '2.5.0' 96 | s.date = Date.today.to_s 97 | s.summary = 'metadata-json-lint /path/to/metadata.json' 98 | s.description = 'Utility to verify Puppet metadata.json files' 99 | ``` 100 | 101 | * export a GitHub access token as environment variable: 102 | 103 | ```console 104 | export CHANGELOG_GITHUB_TOKEN=*token* 105 | ``` 106 | 107 | * Install deps and generate the changelog 108 | 109 | ```console 110 | $ bundle install --path .vendor/ --jobs=$(nproc) --with release 111 | $ bundle exec rake changelog 112 | Found 25 tags 113 | Fetching tags dates: 25/25 114 | Sorting tags... 115 | Received issues: 103 116 | Pull Request count: 77 117 | Filtered pull requests: 72 118 | Filtered issues: 26 119 | Fetching events for issues and PR: 98 120 | Fetching closed dates for issues: 98/98 121 | Fetching SHAs for tags: 25 122 | Associating PRs with tags: 72/72 123 | Generating entry... 124 | Done! 125 | Generated log placed in ~/metadata-json-lint/CHANGELOG.md 126 | ``` 127 | 128 | * Check the diff for `CHANGELOG.md`. Does it contain a breaking change but the 129 | new version is only a minor bump? Does the new release only contains bug fixes? 130 | Adjust the version properly while honouring semantic versioning. If required, 131 | regenerate the `CHANGELOG.md`. Afterwards submit it as a PR. 132 | 133 | * If it gets approved, merge the PR, create a git tag on that and push it. 134 | -------------------------------------------------------------------------------- /lib/metadata-json-lint/schema.rb: -------------------------------------------------------------------------------- 1 | require 'json-schema' 2 | 3 | module MetadataJsonLint 4 | # Provides validation of metadata.json against a JSON schema document 5 | # maintained in this class. Provides a good first pass over the metadata with 6 | # type checking and basic format/length validations. 7 | ## schema data structure is quite large 8 | class Schema 9 | # Based on https://docs.puppet.com/puppet/latest/modules_metadata.html 10 | # 11 | def schema 12 | { 13 | '$schema' => 'http://json-schema.org/draft-04/schema#', 14 | 'properties' => { 15 | 'author' => { 16 | 'type' => 'string', 17 | }, 18 | 'data_provider' => { 19 | 'type' => %w[null string], 20 | }, 21 | 'dependencies' => { 22 | 'type' => 'array', 23 | 'items' => { 24 | 'properties' => { 25 | 'name' => { 26 | 'type' => 'string', 27 | 'pattern' => '^\w+[/-][a-z][a-z0-9_]*$', 28 | }, 29 | 'version_requirement' => { 30 | 'type' => 'string', 31 | }, 32 | }, 33 | 'required' => %w[ 34 | name 35 | ], 36 | }, 37 | }, 38 | 'description' => { 39 | 'type' => 'string', 40 | }, 41 | 'issues_url' => { 42 | 'type' => 'string', 43 | 'format' => 'uri', 44 | }, 45 | 'license' => { 46 | 'type' => 'string', 47 | }, 48 | 'operatingsystem_support' => { 49 | 'type' => 'array', 50 | 'items' => { 51 | 'properties' => { 52 | 'operatingsystem' => { 53 | 'type' => 'string', 54 | }, 55 | 'operatingsystemrelease' => { 56 | 'type' => 'array', 57 | 'items' => { 58 | 'type' => 'string', 59 | }, 60 | }, 61 | }, 62 | 'required' => %w[ 63 | operatingsystem 64 | ], 65 | }, 66 | }, 67 | 'name' => { 68 | 'type' => 'string', 69 | 'pattern' => '^\w+-[a-z][a-z0-9_]*$', 70 | }, 71 | 'project_page' => { 72 | 'type' => 'string', 73 | 'format' => 'uri', 74 | }, 75 | # Undocumented but in use: https://tickets.puppetlabs.com/browse/DOCUMENT-387 76 | 'requirements' => { 77 | 'type' => 'array', 78 | 'items' => { 79 | 'properties' => { 80 | 'name' => { 81 | 'type' => 'string', 82 | }, 83 | 'version_requirement' => { 84 | 'type' => 'string', 85 | }, 86 | }, 87 | 'required' => %w[ 88 | name 89 | ], 90 | }, 91 | }, 92 | 'source' => { 93 | 'type' => 'string', 94 | }, 95 | 'summary' => { 96 | 'type' => 'string', 97 | 'maxLength' => 144, 98 | }, 99 | 'tags' => { 100 | 'type' => 'array', 101 | 'items' => { 102 | 'type' => 'string', 103 | }, 104 | }, 105 | 'version' => { 106 | 'type' => 'string', 107 | 'format' => 'semver', 108 | }, 109 | }, 110 | # from https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file 111 | 'required' => %w[ 112 | author 113 | dependencies 114 | license 115 | name 116 | source 117 | summary 118 | version 119 | ], 120 | } 121 | end 122 | 123 | def validate(data, options = {}) 124 | JSON::Validator.register_format_validator('semver', method(:semver_validator)) 125 | 126 | JSON::Validator.fully_validate(schema, data, options.merge(errors_as_objects: true)).map do |error| 127 | field = error[:fragment].split('/')[1] 128 | field = 'root' if field.nil? || field.empty? 129 | 130 | message = error[:message] 131 | .sub(/ in schema [\w-]+/, '') # remove schema UUID, not needed in output 132 | .sub(%r{'#/}, "'") # remove root #/ prefix from document paths 133 | .sub("property ''", 'file') # call the root #/ node the file 134 | 135 | { field: field, message: message } 136 | end 137 | end 138 | 139 | private 140 | 141 | def semver_full_regex 142 | @semver_full_regex ||= begin 143 | # Version string matching regexes 144 | numeric = '(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)' # Major . Minor . Patch 145 | pre = '(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?' # Prerelease 146 | build = '(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?' # Build 147 | full = numeric + pre + build 148 | 149 | /\A#{full}\Z/ 150 | end 151 | end 152 | 153 | def semver_validator(value) 154 | if defined?(SemanticPuppet::Version) 155 | begin 156 | SemanticPuppet::Version.parse(value) 157 | rescue SemanticPuppet::Version::ValidationFailure => e 158 | raise JSON::Schema::CustomFormatError, "must be a valid semantic version: #{e.message}" 159 | end 160 | elsif value.match(semver_full_regex).nil? 161 | raise JSON::Schema::CustomFormatError, 162 | "must be a valid semantic version: Unable to parse '#{value}' as a semantic version identifier" 163 | end 164 | end 165 | end 166 | end 167 | -------------------------------------------------------------------------------- /tests/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u 3 | 4 | # Ensure this can be called from outside its directory. 5 | cd $(dirname $0) 6 | 7 | SUCCESS=0 8 | FAILURE=1 9 | STATUS=0 10 | 11 | fail() { 12 | echo $* 13 | STATUS=1 14 | } 15 | 16 | # Tests the metadata-json-lint bin and if no additional arguments are given, also the rake task. 17 | test() { 18 | local name=$1; shift 19 | local expect=$1; shift 20 | 21 | test_bin $name $expect $* 22 | # Only check the Rakefile when no additional arguments were passed to metadata-json-lint. 23 | # In these cases, rake will likely have the opposite return code and cause false failures. 24 | if [ $# -eq 0 ]; then 25 | test_rake $name $expect metadata_lint 26 | fi 27 | } 28 | 29 | test_bin() { 30 | local name=$1; shift 31 | local expect=$1; shift 32 | local RESULT=-1 33 | cd $name; 34 | bundle exec metadata-json-lint $* metadata.json >last_output 2>&1 35 | RESULT=$? 36 | if [ $RESULT -ne $expect ]; then 37 | fail "Failing Test '${name}' (unexpected exit code '${RESULT}' instead of '${expect}') (bin)" 38 | echo " Note: you can examine '${name}/last_output' for any output" 39 | else 40 | # If the test is not expected to succeed then it should match an expected output 41 | if [ $expect -eq $SUCCESS ]; then 42 | echo "Successful Test '${name}' (bin)" 43 | else 44 | if [ -f expected ]; then 45 | if grep --quiet -f expected last_output; then 46 | echo "Successful Test '${name}' (bin)" 47 | else 48 | fail "Failing Test '${name}' (did not get expected output) (bin)" 49 | echo " Comparing '${name}/expected' with '${name}/last_output':" 50 | echo " Expected: '`cat expected`'" 51 | echo " Actual: '`cat last_output`'" 52 | fi 53 | else 54 | fail "Failing Test '${name}' (expected output file ${name}/expected is missing) (bin)" 55 | echo " Actual output that needs tested ('${name}/last_output'): '`cat last_output`'" 56 | fi 57 | fi 58 | fi 59 | cd .. 60 | } 61 | 62 | test_rake() { 63 | local name=$1; shift 64 | local expect=$1; shift 65 | local rake_task="${1-metadata_lint}" 66 | local RESULT=-1; 67 | 68 | cd $name; 69 | bundle exec rake $rake_task >last_rake_output 2>&1 70 | RESULT=$? 71 | if [ $RESULT -ne $expect ]; then 72 | fail "Failing Test '${name}' (rake: ${rake_task})" 73 | else 74 | echo "Successful Test '${name}' (rake: ${rake_task})" 75 | fi; 76 | cd .. 77 | } 78 | 79 | # Run a broken one, expect FAILURE 80 | test "broken" $FAILURE 81 | 82 | # Run a perfect one, expect SUCCESS 83 | test "perfect" $SUCCESS 84 | 85 | # Run a broken one, expect FAILURE 86 | test "noname" $FAILURE 87 | 88 | # Run a broken one, expect FAILURE 89 | test "types" $FAILURE 90 | 91 | # Run a broken one, expect FAILURE 92 | test "multiple_problems" $FAILURE 93 | 94 | # Run a broken one, expect FAILURE 95 | test "duplicate-dep" $FAILURE 96 | # Run with --no-fail-on-warnings, expect SUCCESS 97 | test "duplicate-dep" $SUCCESS --no-fail-on-warnings 98 | 99 | # Run a broken one, expect FAILURE 100 | test "bad_license" $FAILURE 101 | # Run with --no-strict-license only, expect SUCCESS 102 | test "bad_license" $SUCCESS --no-strict-license 103 | # Run with --no-fail-on-warnings, expect SUCCESS 104 | test "bad_license" $SUCCESS --no-fail-on-warnings 105 | 106 | # Run a broken one, expect FAILURE 107 | test "invalid_escape_char" $FAILURE 108 | 109 | # Run a broken one, expect FAILURE 110 | test "missing_newline" $FAILURE 111 | 112 | # Run a broken one, expect FAILURE 113 | test "long_summary" $FAILURE 114 | 115 | # Run a broken one, expect FAILURE 116 | test "mixed_version_syntax" $FAILURE 117 | 118 | # Run one with empty dependencies array, expect SUCCESS 119 | test "no_dependencies" $SUCCESS 120 | 121 | # Run one with open ended dependency, expect SUCCESS as strict deps is off by default 122 | test "open_ended_dependency" $SUCCESS 123 | # Run one with open ended dependency and --strict-dependencies, expect FAILURE 124 | test "open_ended_dependency" $FAILURE --strict-dependencies 125 | # Run one with open ended dependency and --strict-dependencies, but pass on warnings, expect SUCCESS 126 | test "open_ended_dependency" $SUCCESS --strict-dependencies --no-fail-on-warnings 127 | 128 | # Run one with missing version_requirement and --no-strict-dependency, expect SUCCESS 129 | test "missing_version_requirement" $SUCCESS 130 | # Run one with open ended dependency and --strict-dependencies, expect FAILURE 131 | test "missing_version_requirement" $FAILURE --strict-dependencies 132 | # Run one with open ended dependency and --strict-dependencies, but pass on warnings, expect SUCCESS 133 | test "missing_version_requirement" $SUCCESS --strict-dependencies --no-fail-on-warnings 134 | 135 | # Run test for "proprietary"-licensed modules, expect SUCCESS 136 | test "proprietary" $SUCCESS 137 | 138 | # Run without a metadata.json or Rakefile, expect FAILURE 139 | test "no_files" $FAILURE 140 | 141 | # Run with tags in an array in metadata.json, expect SUCCESS 142 | test "tags_with_array" $SUCCESS 143 | 144 | # Run with tags not in an array in metadata.json, expect FAILURE 145 | test "tags_no_array" $FAILURE 146 | 147 | # Run with json output format 148 | test "json_format" $FAILURE --format json 149 | 150 | # Run against a metadata.json with a string for the requirements 151 | test "non_array_requirements" $FAILURE 152 | 153 | # Run against a metadata.json with an unsupported minimum Puppet version for the requirements 154 | test "requirements_eol_version" $FAILURE --strict-puppet-version 155 | 156 | # Run a broken one, expect FAILURE 157 | test "duplicate-requirement" $FAILURE 158 | 159 | # Test running without specifying file to parse 160 | cd perfect 161 | bundle exec metadata-json-lint 162 | if [ $? -ne 0 ]; then 163 | fail "Failing Test 'running without specifying metadata.json' (bin)" 164 | else 165 | echo "Successful Test 'running without specifying metadata.json' (bin)" 166 | fi 167 | cd .. 168 | 169 | # Test changing the rake task using settings 170 | # The bin test will fail due to strict licensing 171 | # The rake test should pass due to licensing option being set in Rakefile 172 | test_bin "rake_global_options" $FAILURE 173 | test_rake "rake_global_options" $SUCCESS 174 | 175 | # Test multiple lints with different options 176 | test_rake "rake_multiple_json_options" $SUCCESS metadata_lint_multi 177 | 178 | # Test successful lint followed by further tasks 179 | test_rake "rake_chaining" $SUCCESS test 180 | if ! grep -qx "Successfully linted" rake_chaining/last_rake_output; then 181 | fail "Failing Test 'rake_chaining' failed to run second rake task" 182 | fi 183 | 184 | exit $STATUS 185 | -------------------------------------------------------------------------------- /lib/metadata_json_lint.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require 'spdx-licenses' 3 | require 'optparse' 4 | require 'semantic_puppet' 5 | 6 | require 'metadata-json-lint/schema' 7 | require 'metadata-json-lint/version_requirement' 8 | 9 | module MetadataJsonLint 10 | MIN_PUPPET_VER = '4.10.0'.freeze 11 | # Regex looks for: 12 | # 1. Invalid escape sequences (\x or incomplete \u) 13 | INVALID_ESCAPE_REGEX = %r{\\[^"/bfnrtu]|\\u(?![0-9a-fA-F]{4})} 14 | 15 | def options 16 | @options ||= Struct.new( 17 | :fail_on_warnings, 18 | :strict_license, 19 | :strict_dependencies, 20 | :strict_puppet_version, 21 | :format, 22 | ).new( 23 | true, # fail_on_warnings 24 | true, # strict_license 25 | false, # strict_dependencies 26 | false, # strict_puppet_version 27 | 'text', # format 28 | ) 29 | end 30 | module_function :options 31 | 32 | def run 33 | OptionParser.new do |opts| 34 | opts.banner = 'Usage: metadata-json-lint [options] [metadata.json]' 35 | 36 | opts.on('--[no-]strict-dependencies', 37 | "Fail on open-ended module version dependencies. Defaults to '#{options[:strict_dependencies]}'.") do |v| 38 | options[:strict_dependencies] = v 39 | end 40 | 41 | opts.on('--[no-]strict-license', 42 | "Don't fail on strict license check. Defaults to '#{options[:strict_license]}'.") do |v| 43 | options[:strict_license] = v 44 | end 45 | 46 | opts.on('--[no-]fail-on-warnings', "Fail on any warnings. Defaults to '#{options[:fail_on_warnings]}'.") do |v| 47 | options[:fail_on_warnings] = v 48 | end 49 | 50 | opts.on('--[no-]strict-puppet-version', 51 | "Fail on strict Puppet Version check based on current supported Puppet versions. Defaults to '#{options[:strict_puppet_version]}'.") do |v| 52 | options[:strict_puppet_version] = v 53 | end 54 | 55 | opts.on('-f', '--format FORMAT', %i[text json], 56 | 'The format in which results will be output (text, json)') do |format| 57 | options[:format] = format 58 | end 59 | end.parse! 60 | 61 | mj = if ARGV[0].nil? 62 | if File.readable?('metadata.json') 63 | 'metadata.json' 64 | else 65 | abort('Error: metadata.json is not readable or does not exist.') 66 | end 67 | else 68 | ARGV[0] 69 | end 70 | 71 | exit(MetadataJsonLint.parse(mj) ? 0 : 1) 72 | end 73 | module_function :run 74 | 75 | def contains_invalid_escape?(content) 76 | content.match?(INVALID_ESCAPE_REGEX) 77 | end 78 | module_function :contains_invalid_escape? 79 | 80 | def misses_newline_at_end?(content) 81 | content[-1] != "\n" 82 | end 83 | module_function :misses_newline_at_end? 84 | 85 | def parse(metadata) 86 | @errors = [] 87 | @warnings = [] 88 | 89 | # Small hack to use the module settings as defaults but allow overriding for different rake tasks 90 | options = options().clone 91 | # Configuration from rake tasks 92 | yield options if block_given? 93 | begin 94 | f = File.read(metadata) 95 | rescue Exception => e 96 | abort("Error: Unable to read metadata file: #{e.exception}") 97 | end 98 | 99 | abort('Error: metadata.json does not have a valid newline at the end') if misses_newline_at_end?(f) 100 | 101 | abort('Error: Unable to parse metadata.json: Invalid escape character in string') if contains_invalid_escape?(f) 102 | 103 | begin 104 | parsed = JSON.parse(f) 105 | rescue Exception => e 106 | abort("Error: Unable to parse metadata.json: #{e.exception}") 107 | end 108 | 109 | # Validate basic structure against JSON schema 110 | schema_errors = Schema.new.validate(parsed) 111 | schema_errors.each do |err| 112 | error ((err[:field] == 'root') ? :required_fields : err[:field]), err[:message] 113 | end 114 | 115 | validate_dependencies!(parsed['dependencies']) if parsed['dependencies'] 116 | 117 | # Deprecated fields 118 | # From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file 119 | deprecated_fields = %w[types checksum] 120 | deprecated_fields.each do |field| 121 | error :deprecated_fields, "Deprecated field '#{field}' found in metadata.json." unless parsed[field].nil? 122 | end 123 | 124 | # The nested 'requirements' name of 'pe' is deprecated as well. 125 | # https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/puppet-users/nkRPvG4q0Oo/GmXa109aJQAJ 126 | validate_requirements!(parsed['requirements']) if parsed['requirements'] 127 | 128 | # Shoulds/recommendations 129 | # From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file 130 | # 131 | if options[:strict_license] && !parsed['license'].nil? && !SpdxLicenses.exist?(parsed['license']) && parsed['license'] != 'proprietary' 132 | msg = "License identifier #{parsed['license']} is not in the SPDX list: http://spdx.org/licenses/" 133 | warn(:license, msg) 134 | end 135 | 136 | if !@errors.empty? || !@warnings.empty? 137 | result = @errors.empty? ? "Warnings found in #{metadata}" : "Errors found in #{metadata}" 138 | 139 | case options[:format] 140 | when :json 141 | puts JSON.fast_generate(result: result, warnings: @warnings, errors: @errors) 142 | else 143 | @warnings.each { |warn| puts "(WARN) #{warn}" } 144 | @errors.each { |err| puts "(ERROR) #{err}" } 145 | puts result 146 | end 147 | 148 | return false if !@errors.empty? || (!@warnings.empty? && (options[:fail_on_warnings] == true)) 149 | end 150 | 151 | true 152 | end 153 | module_function :parse 154 | 155 | def validate_requirements_unique(requirements) 156 | names = requirements.map { |x| x['name'] } 157 | counts = Hash.new(0) 158 | 159 | names.each { |name| counts[name.downcase] += 1 } 160 | 161 | counts.each do |k, v| 162 | error :requirements, "Duplicate entries in the 'requirements' list with the name '#{k}'" if v > 1 163 | end 164 | end 165 | module_function :validate_requirements_unique 166 | 167 | def validate_requirements!(requirements) 168 | return unless requirements.is_a?(Array) 169 | 170 | requirements.each do |requirement| 171 | warn :requirements, "The 'pe' requirement is no longer supported by the Forge." if requirement['name'] == 'pe' 172 | 173 | begin 174 | puppet_req = VersionRequirement.new(requirement.fetch('version_requirement', '')) 175 | rescue ArgumentError => e 176 | # Raised when the version_requirement provided could not be parsed 177 | error :requirements, "Invalid 'version_requirement' field in metadata.json: #{e}" 178 | end 179 | 180 | validate_puppet_ver!(puppet_req) unless puppet_req.instance_variable_get(:@requirement).nil? 181 | end 182 | 183 | validate_requirements_unique(requirements) 184 | end 185 | module_function :validate_requirements! 186 | 187 | def validate_puppet_ver!(requirement) 188 | if options[:strict_puppet_version] && requirement.open_ended? 189 | warn(:requirement, "Puppet has an open ended version requirement #{requirement.ver_range}") 190 | end 191 | 192 | if options[:strict_puppet_version] && requirement.puppet_eol? 193 | warn(:requirement, "#{requirement.min} is no longer supported. Minimum supported version is #{MIN_PUPPET_VER}") 194 | end 195 | 196 | return unless requirement.mixed_syntax? 197 | 198 | warn(:requirement, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \ 199 | "metadata.json, use one style in the puppet version: #{requirement.instance_variable_get(:@requirement)}") 200 | end 201 | module_function :validate_puppet_ver! 202 | 203 | def validate_dependencies!(deps) 204 | dep_names = [] 205 | deps.each do |dep| 206 | warn :dependencies, "Duplicate dependencies on #{dep['name']}" if dep_names.include?(dep['name']) 207 | dep_names << dep['name'] 208 | 209 | begin 210 | requirement = VersionRequirement.new(dep.fetch('version_requirement', '')) 211 | rescue ArgumentError => e 212 | # Raised when the version_requirement provided could not be parsed 213 | error :dependencies, "Invalid 'version_requirement' field in metadata.json: #{e}" 214 | # Skip to the next dependency 215 | next 216 | end 217 | validate_version_requirement!(dep, requirement) 218 | 219 | # 'version_range' is no longer used by the forge 220 | # See https://tickets.puppetlabs.com/browse/PUP-2781 221 | if dep.key?('version_range') 222 | warn :dependencies, "Dependency #{dep['name']} has a 'version_range' attribute " \ 223 | 'which is no longer used by the forge.' 224 | end 225 | end 226 | end 227 | module_function :validate_dependencies! 228 | 229 | def validate_version_requirement!(dep, requirement) 230 | # Open ended dependency 231 | # From: https://docs.puppet.com/puppet/latest/reference/modules_metadata.html#best-practice-set-an-upper-bound-for-dependencies 232 | if options[:strict_dependencies] && requirement.open_ended? 233 | msg = "Dependency #{dep['name']} has an open " \ 234 | "ended dependency version requirement #{dep['version_requirement']}" 235 | warn(:dependencies, msg) 236 | end 237 | 238 | # Mixing operator and wildcard version syntax 239 | # From: https://docs.puppet.com/puppet/latest/modules_metadata.html#version-specifiers 240 | # Supported in Puppet 5 and higher, but the syntax is unclear and incompatible with older versions 241 | return unless requirement.mixed_syntax? 242 | 243 | warn(:dependencies, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \ 244 | "metadata.json, use one style in the #{dep['name']} dependency: #{dep['version_requirement']}") 245 | end 246 | module_function :validate_version_requirement! 247 | 248 | def format_error(check, msg) 249 | case options[:format] 250 | when :json 251 | { check: check, msg: msg } 252 | else 253 | "#{check}: #{msg}" 254 | end 255 | end 256 | module_function :format_error 257 | 258 | def warn(check, msg) 259 | @warnings ||= [] 260 | 261 | @warnings << format_error(check, msg) 262 | end 263 | module_function :warn 264 | 265 | def error(check, msg) 266 | @errors ||= [] 267 | 268 | @errors << format_error(check, msg) 269 | end 270 | module_function :error 271 | end 272 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 HP Development Corporation L.P. 2 | 3 | Apache License 4 | Version 2.0, January 2004 5 | http://www.apache.org/licenses/ 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, 12 | and distribution as defined by Sections 1 through 9 of this document. 13 | 14 | "Licensor" shall mean the copyright owner or entity authorized by 15 | the copyright owner that is granting the License. 16 | 17 | "Legal Entity" shall mean the union of the acting entity and all 18 | other entities that control, are controlled by, or are under common 19 | control with that entity. For the purposes of this definition, 20 | "control" means (i) the power, direct or indirect, to cause the 21 | direction or management of such entity, whether by contract or 22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 23 | outstanding shares, or (iii) beneficial ownership of such entity. 24 | 25 | "You" (or "Your") shall mean an individual or Legal Entity 26 | exercising permissions granted by this License. 27 | 28 | "Source" form shall mean the preferred form for making modifications, 29 | including but not limited to software source code, documentation 30 | source, and configuration files. 31 | 32 | "Object" form shall mean any form resulting from mechanical 33 | transformation or translation of a Source form, including but 34 | not limited to compiled object code, generated documentation, 35 | and conversions to other media types. 36 | 37 | "Work" shall mean the work of authorship, whether in Source or 38 | Object form, made available under the License, as indicated by a 39 | copyright notice that is included in or attached to the work 40 | (an example is provided in the Appendix below). 41 | 42 | "Derivative Works" shall mean any work, whether in Source or Object 43 | form, that is based on (or derived from) the Work and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. For the purposes 46 | of this License, Derivative Works shall not include works that remain 47 | separable from, or merely link (or bind by name) to the interfaces of, 48 | the Work and Derivative Works thereof. 49 | 50 | "Contribution" shall mean any work of authorship, including 51 | the original version of the Work and any modifications or additions 52 | to that Work or Derivative Works thereof, that is intentionally 53 | submitted to Licensor for inclusion in the Work by the copyright owner 54 | or by an individual or Legal Entity authorized to submit on behalf of 55 | the copyright owner. For the purposes of this definition, "submitted" 56 | means any form of electronic, verbal, or written communication sent 57 | to the Licensor or its representatives, including but not limited to 58 | communication on electronic mailing lists, source code control systems, 59 | and issue tracking systems that are managed by, or on behalf of, the 60 | Licensor for the purpose of discussing and improving the Work, but 61 | excluding communication that is conspicuously marked or otherwise 62 | designated in writing by the copyright owner as "Not a Contribution." 63 | 64 | "Contributor" shall mean Licensor and any individual or Legal Entity 65 | on behalf of whom a Contribution has been received by Licensor and 66 | subsequently incorporated within the Work. 67 | 68 | 2. Grant of Copyright License. Subject to the terms and conditions of 69 | this License, each Contributor hereby grants to You a perpetual, 70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 71 | copyright license to reproduce, prepare Derivative Works of, 72 | publicly display, publicly perform, sublicense, and distribute the 73 | Work and such Derivative Works in Source or Object form. 74 | 75 | 3. Grant of Patent License. Subject to the terms and conditions of 76 | this License, each Contributor hereby grants to You a perpetual, 77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 78 | (except as stated in this section) patent license to make, have made, 79 | use, offer to sell, sell, import, and otherwise transfer the Work, 80 | where such license applies only to those patent claims licensable 81 | by such Contributor that are necessarily infringed by their 82 | Contribution(s) alone or by combination of their Contribution(s) 83 | with the Work to which such Contribution(s) was submitted. If You 84 | institute patent litigation against any entity (including a 85 | cross-claim or counterclaim in a lawsuit) alleging that the Work 86 | or a Contribution incorporated within the Work constitutes direct 87 | or contributory patent infringement, then any patent licenses 88 | granted to You under this License for that Work shall terminate 89 | as of the date such litigation is filed. 90 | 91 | 4. Redistribution. You may reproduce and distribute copies of the 92 | Work or Derivative Works thereof in any medium, with or without 93 | modifications, and in Source or Object form, provided that You 94 | meet the following conditions: 95 | 96 | (a) You must give any other recipients of the Work or 97 | Derivative Works a copy of this License; and 98 | 99 | (b) You must cause any modified files to carry prominent notices 100 | stating that You changed the files; and 101 | 102 | (c) You must retain, in the Source form of any Derivative Works 103 | that You distribute, all copyright, patent, trademark, and 104 | attribution notices from the Source form of the Work, 105 | excluding those notices that do not pertain to any part of 106 | the Derivative Works; and 107 | 108 | (d) If the Work includes a "NOTICE" text file as part of its 109 | distribution, then any Derivative Works that You distribute must 110 | include a readable copy of the attribution notices contained 111 | within such NOTICE file, excluding those notices that do not 112 | pertain to any part of the Derivative Works, in at least one 113 | of the following places: within a NOTICE text file distributed 114 | as part of the Derivative Works; within the Source form or 115 | documentation, if provided along with the Derivative Works; or, 116 | within a display generated by the Derivative Works, if and 117 | wherever such third-party notices normally appear. The contents 118 | of the NOTICE file are for informational purposes only and 119 | do not modify the License. You may add Your own attribution 120 | notices within Derivative Works that You distribute, alongside 121 | or as an addendum to the NOTICE text from the Work, provided 122 | that such additional attribution notices cannot be construed 123 | as modifying the License. 124 | 125 | You may add Your own copyright statement to Your modifications and 126 | may provide additional or different license terms and conditions 127 | for use, reproduction, or distribution of Your modifications, or 128 | for any such Derivative Works as a whole, provided Your use, 129 | reproduction, and distribution of the Work otherwise complies with 130 | the conditions stated in this License. 131 | 132 | 5. Submission of Contributions. Unless You explicitly state otherwise, 133 | any Contribution intentionally submitted for inclusion in the Work 134 | by You to the Licensor shall be under the terms and conditions of 135 | this License, without any additional terms or conditions. 136 | Notwithstanding the above, nothing herein shall supersede or modify 137 | the terms of any separate license agreement you may have executed 138 | with Licensor regarding such Contributions. 139 | 140 | 6. Trademarks. This License does not grant permission to use the trade 141 | names, trademarks, service marks, or product names of the Licensor, 142 | except as required for reasonable and customary use in describing the 143 | origin of the Work and reproducing the content of the NOTICE file. 144 | 145 | 7. Disclaimer of Warranty. Unless required by applicable law or 146 | agreed to in writing, Licensor provides the Work (and each 147 | Contributor provides its Contributions) on an "AS IS" BASIS, 148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 149 | implied, including, without limitation, any warranties or conditions 150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any 153 | risks associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, 156 | whether in tort (including negligence), contract, or otherwise, 157 | unless required by applicable law (such as deliberate and grossly 158 | negligent acts) or agreed to in writing, shall any Contributor be 159 | liable to You for damages, including any direct, indirect, special, 160 | incidental, or consequential damages of any character arising as a 161 | result of this License or out of the use or inability to use the 162 | Work (including but not limited to damages for loss of goodwill, 163 | work stoppage, computer failure or malfunction, or any and all 164 | other commercial damages or losses), even if such Contributor 165 | has been advised of the possibility of such damages. 166 | 167 | 9. Accepting Warranty or Additional Liability. While redistributing 168 | the Work or Derivative Works thereof, You may choose to offer, 169 | and charge a fee for, acceptance of support, warranty, indemnity, 170 | or other liability obligations and/or rights consistent with this 171 | License. However, in accepting such obligations, You may act only 172 | on Your own behalf and on Your sole responsibility, not on behalf 173 | of any other Contributor, and only if You agree to indemnify, 174 | defend, and hold each Contributor harmless for any liability 175 | incurred by, or claims asserted against, such Contributor by reason 176 | of your accepting any such warranty or additional liability. 177 | 178 | END OF TERMS AND CONDITIONS 179 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [5.0.0](https://github.com/voxpupuli/metadata-json-lint/tree/5.0.0) (2025-08-12) 4 | 5 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/4.3.0...5.0.0) 6 | 7 | **Breaking changes:** 8 | 9 | - Require Ruby 3.2 or newer [\#167](https://github.com/voxpupuli/metadata-json-lint/pull/167) ([bastelfreak](https://github.com/bastelfreak)) 10 | 11 | ## [4.3.0](https://github.com/voxpupuli/metadata-json-lint/tree/4.3.0) (2025-08-12) 12 | 13 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/4.2.1...4.3.0) 14 | 15 | **Implemented enhancements:** 16 | 17 | - json-schema: Allow 6.x [\#164](https://github.com/voxpupuli/metadata-json-lint/pull/164) ([bastelfreak](https://github.com/bastelfreak)) 18 | 19 | ## [4.2.1](https://github.com/voxpupuli/metadata-json-lint/tree/4.2.1) (2025-02-23) 20 | 21 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/4.2.0...4.2.1) 22 | 23 | **Fixed bugs:** 24 | 25 | - Update test for new json 2.10.0 release [\#159](https://github.com/voxpupuli/metadata-json-lint/pull/159) ([bastelfreak](https://github.com/bastelfreak)) 26 | 27 | **Merged pull requests:** 28 | 29 | - Add test for openvox requirement [\#148](https://github.com/voxpupuli/metadata-json-lint/pull/148) ([bastelfreak](https://github.com/bastelfreak)) 30 | 31 | ## [4.2.0](https://github.com/voxpupuli/metadata-json-lint/tree/4.2.0) (2025-01-24) 32 | 33 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/4.1.0...4.2.0) 34 | 35 | **Implemented enhancements:** 36 | 37 | - Fail if metadata.json has no proper newline [\#154](https://github.com/voxpupuli/metadata-json-lint/pull/154) ([bastelfreak](https://github.com/bastelfreak)) 38 | - Fail on escape sequences in metadata.json [\#152](https://github.com/voxpupuli/metadata-json-lint/pull/152) ([bastelfreak](https://github.com/bastelfreak)) 39 | - Rake: Use RuboCop tasks from voxpupuli-rubocop [\#150](https://github.com/voxpupuli/metadata-json-lint/pull/150) ([bastelfreak](https://github.com/bastelfreak)) 40 | - Add Ruby 3.4 to CI [\#149](https://github.com/voxpupuli/metadata-json-lint/pull/149) ([bastelfreak](https://github.com/bastelfreak)) 41 | 42 | **Merged pull requests:** 43 | 44 | - CI: Switch to voxpupuli/ruby-version [\#156](https://github.com/voxpupuli/metadata-json-lint/pull/156) ([bastelfreak](https://github.com/bastelfreak)) 45 | - Drop code coverage in testing [\#153](https://github.com/voxpupuli/metadata-json-lint/pull/153) ([ekohl](https://github.com/ekohl)) 46 | 47 | ## [4.1.0](https://github.com/voxpupuli/metadata-json-lint/tree/4.1.0) (2024-08-19) 48 | 49 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/4.0.0...4.1.0) 50 | 51 | **Implemented enhancements:** 52 | 53 | - json-schema: Allow 5.x [\#145](https://github.com/voxpupuli/metadata-json-lint/pull/145) ([bastelfreak](https://github.com/bastelfreak)) 54 | - Add Ruby 3.3 to CI [\#142](https://github.com/voxpupuli/metadata-json-lint/pull/142) ([bastelfreak](https://github.com/bastelfreak)) 55 | 56 | ## [4.0.0](https://github.com/voxpupuli/metadata-json-lint/tree/4.0.0) (2023-09-15) 57 | 58 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/3.0.3...4.0.0) 59 | 60 | **Breaking changes:** 61 | 62 | - Drop Ruby 2.5/2.6 & switch to voxpupuli-rubocop [\#137](https://github.com/voxpupuli/metadata-json-lint/pull/137) ([bastelfreak](https://github.com/bastelfreak)) 63 | - Drop Ruby =\< 2.4 support [\#125](https://github.com/voxpupuli/metadata-json-lint/pull/125) ([bastelfreak](https://github.com/bastelfreak)) 64 | 65 | **Implemented enhancements:** 66 | 67 | - CI: Build gems with strictness and verbosity & Add upper version limits to gemspec [\#135](https://github.com/voxpupuli/metadata-json-lint/pull/135) ([bastelfreak](https://github.com/bastelfreak)) 68 | - Add Ruby 3.1/3.2 support [\#133](https://github.com/voxpupuli/metadata-json-lint/pull/133) ([bastelfreak](https://github.com/bastelfreak)) 69 | 70 | **Merged pull requests:** 71 | 72 | - Make semantic\_puppet a hard dependency [\#136](https://github.com/voxpupuli/metadata-json-lint/pull/136) ([bastelfreak](https://github.com/bastelfreak)) 73 | - Drop pry development dependency [\#134](https://github.com/voxpupuli/metadata-json-lint/pull/134) ([bastelfreak](https://github.com/bastelfreak)) 74 | - GCG: Add faraday-retry dep [\#132](https://github.com/voxpupuli/metadata-json-lint/pull/132) ([bastelfreak](https://github.com/bastelfreak)) 75 | - Add dummy CI job we can depend on [\#131](https://github.com/voxpupuli/metadata-json-lint/pull/131) ([bastelfreak](https://github.com/bastelfreak)) 76 | 77 | ## [3.0.3](https://github.com/voxpupuli/metadata-json-lint/tree/3.0.3) (2023-04-24) 78 | 79 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/3.0.2...3.0.3) 80 | 81 | **Fixed bugs:** 82 | 83 | - gemspec: drop deprecated `date` attribute [\#129](https://github.com/voxpupuli/metadata-json-lint/pull/129) ([bastelfreak](https://github.com/bastelfreak)) 84 | 85 | **Merged pull requests:** 86 | 87 | - Allow json-schema 4.x [\#128](https://github.com/voxpupuli/metadata-json-lint/pull/128) ([chelnak](https://github.com/chelnak)) 88 | 89 | ## [3.0.2](https://github.com/voxpupuli/metadata-json-lint/tree/3.0.2) (2022-05-03) 90 | 91 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/3.0.1...3.0.2) 92 | 93 | ## [3.0.1](https://github.com/voxpupuli/metadata-json-lint/tree/3.0.1) (2021-08-13) 94 | 95 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/3.0.0...3.0.1) 96 | 97 | **Closed issues:** 98 | 99 | - For the license: missing a file and license headers in source files [\#115](https://github.com/voxpupuli/metadata-json-lint/issues/115) 100 | - one test fails against ruby 2.7 when semantic\_puppet is not present [\#114](https://github.com/voxpupuli/metadata-json-lint/issues/114) 101 | - Missing possibility to set options via spec\_helper.rb like rspec [\#18](https://github.com/voxpupuli/metadata-json-lint/issues/18) 102 | 103 | **Merged pull requests:** 104 | 105 | - Add GitHub actions + badges [\#116](https://github.com/voxpupuli/metadata-json-lint/pull/116) ([bastelfreak](https://github.com/bastelfreak)) 106 | 107 | ## [3.0.0](https://github.com/voxpupuli/metadata-json-lint/tree/3.0.0) (2020-11-24) 108 | 109 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/2.4.0...3.0.0) 110 | 111 | **Merged pull requests:** 112 | 113 | - Require Ruby 2.1 and drop post\_install\_message [\#112](https://github.com/voxpupuli/metadata-json-lint/pull/112) ([ekohl](https://github.com/ekohl)) 114 | 115 | ## [2.4.0](https://github.com/voxpupuli/metadata-json-lint/tree/2.4.0) (2020-06-12) 116 | 117 | [Full Changelog](https://github.com/voxpupuli/metadata-json-lint/compare/2.3.0...2.4.0) 118 | 119 | **Merged pull requests:** 120 | 121 | - Add ruby 2.7 to test matrix [\#110](https://github.com/voxpupuli/metadata-json-lint/pull/110) ([DavidS](https://github.com/DavidS)) 122 | - Publish gem only on one rvm job [\#109](https://github.com/voxpupuli/metadata-json-lint/pull/109) ([bastelfreak](https://github.com/bastelfreak)) 123 | 124 | ## 2.3.0 125 | 126 | * Add duplicate testing in requirements list 127 | * Fix wrong license file content so GitHub can properly detect it 128 | * Fix a typo in the README.md 129 | 130 | ## 2.2.0 131 | 132 | * Validate Puppet version_requirement [#99](https://github.com/voxpupuli/metadata-json-lint/issues/99) 133 | * Add optional check `--strict-puppet-version` to validate the Puppet Agent Version is not EOL or open ended [#100](https://github.com/voxpupuli/metadata-json-lint/pull/100) 134 | 135 | ## 2.1.0 136 | 137 | ### Changes 138 | 139 | * Improve rendering of post\_install message by trimming unnecessary leading 140 | spaces [#89](https://github.com/voxpupuli/metadata-json-lint/pull/89) 141 | * Fail when checking version requirements if the version range is empty 142 | [#91](https://github.com/voxpupuli/metadata-json-lint/pull/91) 143 | * Pin `public_suffix` gem to < 3 for Ruby <= 2.0 144 | [#93](https://github.com/voxpupuli/metadata-json-lint/pull/93) 145 | 146 | ### Fixed 147 | 148 | * Prevent metadata-json-lint from crashing when the `requirements` field does 149 | not contain an array 150 | [#94](https://github.com/voxpupuli/metadata-json-lint/pull/94) 151 | * Fix loading of `semantic_puppet` so that it supports using version vendored 152 | in Puppet (if available) 153 | [#96](https://github.com/voxpupuli/metadata-json-lint/pull/96) 154 | 155 | ## 2.0.2 156 | 157 | ### Changes 158 | 159 | * Make SemanticPuppet completely optional and remove dependency on Puppet [#86](https://github.com/voxpupuli/metadata-json-lint/pull/86) 160 | * Only log open dependency warning with --strict-dependencies [#78](https://github.com/voxpupuli/metadata-json-lint/pull/78) 161 | 162 | ### Fixed 163 | 164 | * Fix readme for gemfile usage [#84](https://github.com/voxpupuli/metadata-json-lint/pull/84) 165 | 166 | ## 2.0.1 167 | 168 | ### Changes 169 | 170 | * Puppet 4.9.0 and newer uses the vendored `semantic_puppet` packaged with Puppet. 171 | * If using Puppet 4.8.x and earlier, adding `semantic_puppet` to your Gemfile is required 172 | as the vendored `semantic_puppet` was not packaged with Puppet prior to `4.9.0` 173 | * Add test environment for Ruby 2.4.1 174 | 175 | ## 2.0.0 176 | 177 | ### Changes 178 | 179 | * The `semantic_puppet` gem is no longer included as a runtime dependency due to conflicts with Puppet 5.x libraries that break the `puppet module` command. As such, `semantic_puppet` must be added to a user's Gemfile in Puppet <= 4.x. See [Installation](https://github.com/voxpupuli/metadata-json-lint#installation) docs for more info 180 | * `metadata-json-lint` now officially only supports Ruby >= 2.0.0 181 | 182 | ### Fixed 183 | 184 | * Fix puppet 5.x `semantic_puppet` conflicts ([#79](https://github.com/voxpupuli/metadata-json-lint/issues/79)) 185 | * Clarify Ruby >= 2.x only support ([#74](https://github.com/voxpupuli/metadata-json-lint/issues/74)) 186 | 187 | ## 1.2.2 188 | 189 | ### Fixed 190 | 191 | * Fix `metadata_lint` rake task exiting on success, not continuing ([#70](https://github.com/voxpupuli/metadata-json-lint/issues/70)) 192 | * Fix failure on incorrect license warning when `--no-strict-license` used ([#69](https://github.com/voxpupuli/metadata-json-lint/issues/69)) 193 | 194 | ## 1.2.1 195 | 196 | ### Fixed 197 | 198 | * Fix missing lib/ files in published gem 199 | 200 | ## 1.2.0 201 | 202 | ### Added 203 | 204 | * Add `--format`/`-f` option to support a JSON output format 205 | * Add warning for mixed version range syntax, supported only in Puppet 5 206 | 207 | ### Changed 208 | 209 | * The default text format mode now outputs more structured messages 210 | * README has been edited and clarity improved 211 | 212 | ### Fixed 213 | 214 | * Fix non-zero exit code caused by some checks 215 | 216 | ## 1.1.0 217 | 218 | ### Added 219 | 220 | * Ensure module `tags` are correctly specified as an array ([#44](https://github.com/voxpupuli/metadata-json-lint/issues/44)) 221 | * Ensure `requirements` doesn't list the deprecated `pe` key ([#46](https://github.com/voxpupuli/metadata-json-lint/issues/46)) 222 | * Ensure `dependencies` aren't listed with `version_range` keys ([#47](https://github.com/voxpupuli/metadata-json-lint/issues/47)) 223 | * Support strictness configuration via Ruby API, for use in rake tasks definitions 224 | * Show default strictness option values in `--help` output 225 | 226 | ### Fixed 227 | 228 | * Fix unclear error message when metadata.json does not exist 229 | * Fix gem publishing date 230 | * Various test improvements, ensuring failures are caught accurately and precisely 231 | 232 | 233 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 234 | --------------------------------------------------------------------------------