{"id":15013961,"url":"https://github.com/mschuchard/puppet-check","last_synced_at":"2025-04-05T03:08:48.152Z","repository":{"id":53340131,"uuid":"56614358","full_name":"mschuchard/puppet-check","owner":"mschuchard","description":"A streamlined efficient comprehensive set of checks for your entire Puppet code and data","archived":false,"fork":false,"pushed_at":"2025-01-30T14:37:35.000Z","size":1623,"stargazers_count":59,"open_issues_count":1,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T02:05:06.775Z","etag":null,"topics":["acceptance-testing","hacktoberfest","linter","puppet","puppet-check","puppet-lint","puppet-testing","rspec-puppet","rspec-testing","ruby","style-linter","syntax-checker","testing","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mschuchard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-19T16:41:15.000Z","updated_at":"2025-01-30T14:37:39.000Z","dependencies_parsed_at":"2024-04-15T16:29:28.963Z","dependency_job_id":"97d697aa-a01b-48be-84a2-de634e2e91fc","html_url":"https://github.com/mschuchard/puppet-check","commit_stats":{"total_commits":318,"total_committers":1,"mean_commits":318.0,"dds":0.0,"last_synced_commit":"36870425fce69990af7a37e485d28926293998d1"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschuchard%2Fpuppet-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschuchard%2Fpuppet-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschuchard%2Fpuppet-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschuchard%2Fpuppet-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mschuchard","download_url":"https://codeload.github.com/mschuchard/puppet-check/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280270,"owners_count":20912967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acceptance-testing","hacktoberfest","linter","puppet","puppet-check","puppet-lint","puppet-testing","rspec-puppet","rspec-testing","ruby","style-linter","syntax-checker","testing","unit-testing"],"created_at":"2024-09-24T19:45:00.341Z","updated_at":"2025-04-05T03:08:48.133Z","avatar_url":"https://github.com/mschuchard.png","language":"Ruby","readme":"# Puppet Check\n- [Description](#description)\n- [Usage](#usage)\n  - [CLI](#cli)\n  - [Rake](#rake)\n  - [API](#api)\n  - [Docker](#docker)\n  - [Vagrant](#vagrant)\n  - [Exit Codes](#exit-codes)\n  - [Optional Dependencies](#optional-dependencies)\n- [Contributing](#contributing)\n\n## Description\nPuppet Check is a gem that provides a comprehensive, streamlined, and efficient analysis of the syntax, style, and validity of your entire Puppet code and data.\n\n**IMPORTANT**: The current support for encrypted yaml validation is experimental and should be considered a beta feature as of 2.3.0.\n\n### Former Method for Code and Data Checks\n![Old](https://raw.githubusercontent.com/mschuchard/puppet-check/master/images/puppetcheck_old.png)\n\n### Puppet Check Method for Code and Data Checks\n![New](https://raw.githubusercontent.com/mschuchard/puppet-check/master/images/puppetcheck_new.png)\n\n### Example Output\n```\nThe following files have errors:\n-- manifests/syntax.pp:\nThis Variable has no effect. A value was produced and then forgotten (one or more preceding expressions may have the wrong form) at 1:1\nIllegal variable name, The given name '' does not conform to the naming rule /^((::)?[a-z]\\w*)*((::)?[a-z_]\\w*)$/ at 1:1\nFound 2 errors. Giving up\n\n-- templates/syntax.epp:\nThis Name has no effect. A value was produced and then forgotten (one or more preceding expressions may have the wrong form) at 2:4\n\n-- lib/syntax.rb:\n(eval):1: syntax error, unexpected =\u003e, expecting end-of-input\nBEGIN {throw :good}; i =\u003e am : a '' ruby.file { with } \u0026bad syntax\n                         ^\n\n-- templates/syntax.erb:\n(erb):1: syntax error, unexpected tIDENTIFIER, expecting ')'\n... am \"; _erbout.concat(( @a ruby ).to_s); _erbout.concat \" te...\n...                               ^\n\n-- hieradata/syntax.yaml:\nblock sequence entries are not allowed in this context at line 2 column 4\n\n-- hieradata/syntax.json:\n743: unexpected token at '{\n\n-- metadata_syntax/metadata.json:\nRequired field 'version' not found.\nField 'requirements' is not an array of hashes.\nDuplicate dependencies on puppetlabs/nothing.\nDeprecated field 'checksum' found.\nSummary exceeds 144 characters.\n\n-- librarian_syntax/Puppetfile:\n(eval):3: syntax error, unexpected ':', expecting end-of-input\n    librarian: 'puppet'\n              ^\n\nThe following files have warnings:\n-- manifests/style_lint.pp:\n2:8: double quoted string containing no variables\n2:5: indentation of =\u003e is not properly aligned (expected in column 8, but found it in column 5)\n\n-- manifests/style_parser.pp:\nUnrecognized escape sequence '\\[' at 2:77\nUnrecognized escape sequence '\\]' at 2:77\n2:45: double quoted string containing no variables\n\n-- lib/style.rb:\n1:1: W: Useless assignment to variable - `hash`.\n1:10: C: Use the new Ruby 1.9 hash syntax.\n2:1: C: Do not introduce global variables.\n3:6: C: Prefer single-quoted strings when you don't need string interpolation or special symbols.\n[7]:Attribute: Issue#foobarbaz is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]\n[6]:IrresponsibleModule: Issue has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]\n\n-- templates/style.erb:\n3: already initialized constant TEMPLATE\n2: previous definition of TEMPLATE was here\n\n-- hieradata/style.yaml:\nValue(s) missing in key 'value'.\nValue(s) missing in key 'and'.\nThe string --- appears more than once in this data and Hiera will fail to parse it correctly.\n\n-- metadata_style/metadata.json:\nRecommended field 'operatingsystem_support' not found.\n'pe' is missing an upper bound.\nLicense identifier 'Imaginary' is not in the SPDX list: http://spdx.org/licenses/\n\n-- metadata_style_two/metadata.json:\nRecommended field 'operatingsystem' not found.\nRecommended field 'operatingsystemrelease' not found.\n'puppetlabs/one' has non-semantic versioning in its 'version_requirement' key.\n'puppetlabs/two' is missing an upper bound.\n\n-- librarian_style/Puppetfile:\n2:3: C: Align the parameters of a method call if they span more than one line.\n5:13: C: Use the new Ruby 1.9 hash syntax.\n\nThe following files have no errors or warnings:\n-- manifests/good.pp\n-- templates/good.epp\n-- spec/facter/facter_spec.rb\n-- lib/good.rb\n-- templates/no_method_error.erb\n-- templates/good.erb\n-- hieradata/good.yaml\n-- metadata.json\n-- hieradata/good.json\n-- metadata_good/metadata.json\n-- librarian_good/Puppetfile\n\nThe following files have unrecognized formats and therefore were not processed:\n-- foobarbaz\n```\n\n### What About Puppet Development Kit?\nThe fairly recent release of the Puppet Development Kit (PDK) will hopefully eventually bring about the capability to test and validate your Puppet code and data in a streamlined, efficient, comprehensive, and accurate fashion comparable to Puppet Check. Unfortunately, the PDK has not yet achieved feature or efficiency parity with Puppet Check. The goal is for the PDK to one day replace Puppet Check and for Puppet Check to enter maintenance mode, but for now Puppet Check is still needed to lead Puppet testing.\n\n### What About PDK now?\nAs of version 2.4.0 of the PDK, the PDK has essentially more or less achieved feature parity with Puppet Check. Although the PDK is not as efficient (including especially that Puppet Check executes significantly faster), it is still supported by Puppetlabs. Therefore, if you need an efficient and comprehensive Puppet validation solution, then you can still utilize Puppet Check, but the PDK is a recommended alternative for the future.\n\n## Usage\nPlease see the [Gemspec](puppet-check.gemspec) for dependency information.  All other dependencies should be fine with various versions. Puppet Check can be used with a CLI, Rake tasks, or API, from your system, rbenv, rvm, Docker, or Vagrant. Please note all interfaces (API by default, but can be modified) will ignore any directories named `fixtures`, or specified paths with that directory during file checks and spec tests.\n\n### CLI\n```\nusage: puppet-check [options] paths\n        --version                    Display the current version.\n        --fail-on-warnings           Fail on warnings\n    -s, --style                      Enable style checks\n        --smoke                      Enable smoke testing\n    -r, --regression                 Enable regression testing (in progress, do not use)\n        --public cert.pem            Public key for EYAML checks\n        --private cert.pem           Private key for EYAML checks\n    -o, --output format              Format for results output (default is text): text, json, or yaml\n        --octoconfig config_file     Octocatalog-diff configuration file to use\n    -n node1.example.com,node2.example.com,\n        --octonodes                  Octocatalog-diff nodes to test catalog on\n        --puppet-lint arg_one,arg_two\n                                     Arguments for PuppetLint ignored checks\n    -c, --config file                Load PuppetLint options from file\n        --rubocop arg_one,arg_two    Arguments for Rubocop disabled cops\n```\n\nThe command line interface enables the ability to select additional style checks besides the syntax checks, and to specify PuppetLint and Rubocop checks to ignore. If you require a more robust interface to PuppetLint, Rubocop, and Reek, then please use `.puppet-lint.rc`, `.rubocop.yml` and `*.reek` config files. The `.puppet-lint.rc` can be specified with the `-c` argument. If it is not specified, then PuppetLint will automatically load one from `.puppet-lint.rc`, `~/.puppet-lint.rc`, or `/etc/puppet-lint.rc`, in that order of preference. The nearest `.rubocop.yml` and `*.reek` will be automatically respected.\n\nExample:\n```\npuppet-check -s --puppet-lint no-hard_tabs-check,no-140chars-check --rubocop Metrics/LineLength,Style/Encoding -o yaml path/to/code_and_data\n```\n\n### Rake\nInterfacing with Puppet-Check via `rake` requires a `require puppet-check/tasks` in your Rakefile. This generates the following `rake` commands:\n\n```\nrake puppetcheck           # Execute all Puppet-Check checks\nrake puppetcheck:file      # Execute Puppet-Check file checks\nrake puppetcheck:spec      # Execute RSpec and RSpec-Puppet tests\nrake puppetcheck:beaker    # Execute Beaker acceptance tests\nrake puppetcheck:kitchen:* # Execute Test Kitchen acceptance tests\n```\n\n#### puppetcheck:file\nYou can add style, smoke, and regression checks to the `rake puppetcheck:file`, or change the output format, by adding the following after the require:\n\n```ruby\n# example of modifying Puppet Check behavior and creating a custom task\nsettings = {}\nsettings[:fail_on_warnings] = true # default false\nsettings[:style] = true # default false\nsettings[:smoke] = true # default false\nsettings[:regression] = true # in progress, do not use; default false\nsettings[:public] = 'public.pem' # default nil\nsettings[:private] = 'private.pem' # default nil\nsettings[:output_format] = 'yaml' # also 'json'; default 'text'\nsettings[:octoconfig] = '$HOME/octocatalog-diff.cfg.rb' # default '.octocatalog-diff.cfg.rb'\nsettings[:octonodes] = %w(server.example.com) # default: %w(localhost.localdomain)\nsettings[:puppetlint_args] = ['--puppetlint-arg-one', '--puppetlint-arg-two'] # default []\nsettings[:rubocop_args] = ['--except', 'rubocop-arg-one,rubocop-arg-two'] # default []\n\ndesc 'Execute custom Puppet-Check file checks'\ntask :file_custom do\n  Rake::Task[:'puppetcheck:file'].invoke(settings)\nend\n```\n\nPlease note that `rspec` does not support yaml output and therefore would still use the default 'progress' formatter even if `yaml` is specified as the format option to Puppet Check.\n\nThe style checks from within `rake puppetcheck:file` are directly interfaced to `puppet-lint`, `rubocop`, and `reek`. This means that all arguments and options should be specified from within your `.puppet-lint.rc`, `.rubocop.yml`, and `*.reek`. However, you can alternatively utilize the hashes listed above.\n\n#### puppetcheck:spec\nThe spec tests will be executed against everything that matches the pattern `**/{classes, defines, facter, functions, hosts, puppet, unit, types}/**/*_spec.rb`. Any of these directories inside of a `fixtures` directory will be ignored. This means everything in the current path that appears to be a Puppet module spec test for your module (not dependencies) will be regarded as such and executed during this rake task.\n\nPlease note it is perfectly acceptable to only execute standard RSpec tests in your modules and not use the extended RSpec Puppet matchers. If no Puppet module directories are identified during directory parsing, then no RSpec Puppet related actions (including those described below) will be performed.\n\nPrior to executing the spec tests, Puppet Check will parse everything in the current path and identify all `spec` directories not within `fixtures` directories. It will then execute RSpec Puppet setup actions inside all directories one level above that contain a `manifests` directory. This is assumed to be a Puppet module directory. These setup actions include creating all of the necessary directories inside of `spec/fixtures`, creating a blank `site.pp` if it is missing, symlinking everything from the module that is needed into fixtures (automatically replaces functionality of self module symlink in `.fixtures.yaml` from Puppetlabs Spec Helper), and creates the `spec_helper.rb` if it is missing. Note these setup actions can replace `rspec-puppet-init` from RSpec Puppet and currently are both faster and more accurate.\n\nPuppet Check will also automatically download specified external module dependencies for and during RSpec Puppet testing. Currently `git`, `puppet forge`, `svn`, and `hg` commands are supported. They can be implemented in the following way in your modules' `metadata.json`:\n\n```json\n\"dependencies\": [\n  {\n    \"name\": \"module-name\",\n    \"forge\": \"forge-name\",\n    \"args\": \"puppet module install optional-arguments\"\n  },\n  {\n    \"name\": \"module-name\",\n    \"git\": \"git-url\",\n    \"args\": \"git clone optional-arguments\"\n  },\n  {\n    \"name\": \"module-name\",\n    \"hg\": \"hg-url\",\n    \"args\": \"hg clone optional-arguments\"\n  },\n  {\n    \"name\": \"module-name\",\n    \"svn\": \"svn-url\",\n    \"args\": \"svn co optional arguments\"\n  }\n]\n```\n\nExample:\n\n```json\n\"dependencies\": [\n  {\n    \"name\": \"puppetlabs/stdlib\",\n    \"forge\": \"puppetlabs-stdlib\",\n    \"args\": \"--do-something-cool\"\n  },\n  {\n    \"name\": \"puppetlabs/lvm\",\n    \"git\": \"https://github.com/puppetlabs/puppetlabs-lvm.git\"\n  }\n]\n```\n\nNote that `args` will be ignored during `git pull`, `svn update`, and `hg pull/hg update` when the modules are updated instead of freshly cloned.\n\n#### puppetcheck:beaker\nThis task serves as a frontend to the `beaker_quickstart:run_test[hypervisor]` rake task that Beaker provides. It merely provides a convenient unified frontend for the task and automated as part of the `puppetcheck` tasks. Note that you should still provide a hypervisor argument to the rake task when executed individually (e.g. `rake puppetcheck:beaker[vagrant]`). The Vagrant hypervisor will be selected by default when executed as part of the `puppetcheck` task. Vagrant will also be selected by default if no hypervisor argument is provided to the individual task.\n\n#### puppetcheck:kitchen\nThis task serves as a frontend to the `kitchen:all` rake task that Test Kitchen provides. It merely provides a convenient unified frontend for the task and automated as part of the `puppetcheck` tasks.\n\n### API\n\nIf you are performing your Puppet testing from within a Ruby script or your own custom Rakefile tasks, and want to execute Puppet Check intrinsically from the Ruby script or Rakefile, then you can call its API in the following simple way:\n\n```ruby\n# file checks\nrequire 'puppet-check'\n\nsettings = {}\nsettings[:fail_on_warnings] = true # default false\nsettings[:style] = true # default false\nsettings[:smoke] = true # default false\nsettings[:regression] = true # in progress, do not use; default false\nsettings[:public] = 'public.pem' # default nil\nsettings[:private] = 'private.pem' # default nil\nsettings[:output_format] = 'yaml' # also 'json'; default 'text'\nsettings[:octoconfig] = '$HOME/octocatalog-diff.cfg.rb' # default '.octocatalog-diff.cfg.rb'\nsettings[:octonodes] = %w(server.example.com) # default: %w(localhost.localdomain)\nsettings[:puppetlint_args] = ['--puppetlint-arg-one', '--puppetlint-arg-two'] # default []\nsettings[:rubocop_args] = ['--except', 'rubocop-arg-one,rubocop-arg-two'] # default []\n\nPuppetCheck.new.run(settings, [dirs, files])\n\n# rspec checks (as part of a RSpec::Core::RakeTask.new block with |task|)\nrequire 'puppet-check/rspec_puppet_support'\n\nRSpecPuppetSupport.run\ntask.pattern = Dir.glob('**/{classes,defines,facter,functions,hosts,puppet,unit,types}/**/*_spec.rb').grep_v(/fixtures/)\n```\n\n### Docker\n\nA supported [Docker image](https://hub.docker.com/r/matthewschuchard/puppet-check) of Puppet-Check is now available from the public Docker Hub registry. Please consult the repository documentation for further usage information.\n\n### Vagrant\n\nAs an alternative to Docker, you can also use Vagrant for quick and disposable testing, but it is not as portable as Docker for these testing purposes. Below is an example `Vagrantfile` for this purpose.\n\n```ruby\nVagrant.configure(2) do |config|\n  # a reliable and small box at the moment\n  config.vm.box = 'fedora/35-cloud-base'\n\n  config.vm.provision 'shell', inline: \u003c\u003c-SHELL\n    # cd to '/vagrant'\n    cd /vagrant\n    # you need ruby and any other extra dependencies that come from packages; in this example we install git to use it for downloading external module dependencies\n    sudo dnf install ruby rubygems git -y\n    # you need puppet-check and any other extra dependencies that come from gems; in this example we install rspec-puppet and rake for extra testing\n    sudo gem install --no-document puppet-check rspec-puppet rake\n    # this is needed for the ruby json parser to not flip out on fresh os installs for some reason (change encoding value as necessary)\n    export LANG='en_US.UTF-8'\n    # execute your tests; in this example we are executing the full suite of tests\n    rake puppetcheck\n  SHELL\nend\n```\n\nTo overcome the lack of convenient portability, you could try spinning up the Vagrant instance at the top level of your Puppet code and data and then descend into directories to execute tests as necessary. Cleverness or patience will be necessary if you decide to use Vagrant for testing and desire portability.\n\n### Exit Codes\n- 0: PuppetCheck exited with no internal exceptions or errors in your code and data.\n- 1: PuppetCheck exited with an internal exception (takes preference over other non-zero exit codes) or failed spec test(s).\n- 2: PuppetCheck exited with one or more errors in your code and data. Alternatively, PuppetCheck exited with one or more warnings in your code and data, and you specified to fail on warnings.\n\n### Optional Dependencies\n- **rake** (gem): install this if you want to use Puppet Check with `rake` tasks in addition to the CLI.\n- **rspec** (gem): install this if you want to use Puppet Check to execute the spec tests for your Ruby files during `rake`.\n- **rspec-puppet** (gem): install this if you want to use Puppet Check to execute the spec tests for your Puppet files during `rake`.\n- **octocatalog-diff** (gem): install a version `\u003e= 1.0` of this if you want to use Puppet Check to execute smoke or regression tests for your Puppet catalog.\n- **beaker** (gem): install this if you want to use Puppet Check to execute the Beaker acceptance tests during `rake`.\n- **test-kitchen** (gem): install this if you want to use Puppet Check to execute the Test Kitchen acceptance tests during `rake`.\n- **git** (pkg): install this if you want to use Puppet Check to download external module dependencies with `git` commands during RSpec Puppet testing.\n- **mercurial** (pkg): install this if you want to use Puppet Check to download external module dependencies with `hg` commands during RSpec Puppet testing.\n- **subversion** (pkg): install this if you want to use Puppet Check to download external module dependencies with `svn` commands during RSpec Puppet testing.\n\n## Contributing\nCode should pass all spec tests. New features should involve new spec tests. Adherence to Rubocop and Reek is expected where not overly onerous or where the check is of dubious cost/benefit.\n\nA [Dockerfile](Dockerfile) is provided for easy rake testing. A [Vagrantfile](Vagrantfile) is provided for easy gem building, installation, and post-installation testing.\n\nPlease consult the GitHub Project for the current development roadmap.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschuchard%2Fpuppet-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmschuchard%2Fpuppet-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschuchard%2Fpuppet-check/lists"}