diff --git a/.gitignore b/.gitignore index 147c70c..650022e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,24 @@ -pkg/ -Gemfile.lock -Gemfile.local +.git/ +.*.sw[op] +.metadata +.yardoc +.yardwarns +*.iml +/.bundle/ +/.idea/ +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/ +/tmp/ +/vendor/ +/convert_report.txt +/update_report.txt +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..d651650 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,41 @@ +--- +stages: + - syntax + - unit + +cache: + paths: + - vendor/bundle + +before_script: + - bundle -v + - rm Gemfile.lock || true + - gem update --system + - gem --version + - bundle -v + - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) + +parallel_spec-Ruby 2.1.9-Puppet ~> 4.0: + stage: syntax + image: ruby:2.1.9 + script: + - bundle exec rake parallel_spec + variables: + PUPPET_GEM_VERSION: '~> 4.0' + +syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop-Ruby 2.4.4-Puppet ~> 5.5: + stage: syntax + image: ruby:2.4.4 + script: + - bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop + variables: + PUPPET_GEM_VERSION: '~> 5.5' + +parallel_spec-Ruby 2.4.4-Puppet ~> 5.5: + stage: syntax + image: ruby:2.4.4 + script: + - bundle exec rake parallel_spec + variables: + PUPPET_GEM_VERSION: '~> 5.5' + diff --git a/.pdkignore b/.pdkignore new file mode 100644 index 0000000..650022e --- /dev/null +++ b/.pdkignore @@ -0,0 +1,24 @@ +.git/ +.*.sw[op] +.metadata +.yardoc +.yardwarns +*.iml +/.bundle/ +/.idea/ +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/ +/tmp/ +/vendor/ +/convert_report.txt +/update_report.txt +.DS_Store diff --git a/.rspec b/.rspec index 8c18f1a..16f9cdb 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ ---format documentation --color +--format documentation diff --git a/.rubocop.yml b/.rubocop.yml index 2433fc0..54d1597 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,548 +1,118 @@ +--- require: rubocop-rspec AllCops: - TargetRubyVersion: 1.9 + DisplayCopNames: true + TargetRubyVersion: '2.1' Include: - - ./**/*.rb + - "./**/*.rb" Exclude: - - files/**/* - - vendor/**/* - - .vendor/**/* - - pkg/**/* - - spec/fixtures/**/* - - Gemfile - - Rakefile - - Guardfile - - Vagrantfile -Lint/ConditionPosition: - Enabled: True - -Lint/ElseLayout: - Enabled: True - -Lint/UnreachableCode: - Enabled: True - -Lint/UselessComparison: - Enabled: True - -Lint/EnsureReturn: - Enabled: True - -Lint/HandleExceptions: - Enabled: True - -Lint/LiteralInCondition: - Enabled: True - -Lint/ShadowingOuterLocalVariable: - Enabled: True - -Lint/LiteralInInterpolation: - Enabled: True - -Style/HashSyntax: - Enabled: True - -Style/RedundantReturn: - Enabled: True - -Layout/EndOfLine: - Enabled: False - -Lint/AmbiguousOperator: - Enabled: True - -Lint/AssignmentInCondition: - Enabled: True - -Layout/SpaceBeforeComment: - Enabled: True - -Style/AndOr: - Enabled: True - -Style/RedundantSelf: - Enabled: True - -Metrics/BlockLength: - Enabled: False - -# Method length is not necessarily an indicator of code quality -Metrics/MethodLength: - Enabled: False - -# Module length is not necessarily an indicator of code quality -Metrics/ModuleLength: - Enabled: False - -Style/WhileUntilModifier: - Enabled: True - -Lint/AmbiguousRegexpLiteral: - Enabled: True - -Security/Eval: - Enabled: True - -Lint/BlockAlignment: - Enabled: True - -Lint/DefEndAlignment: - Enabled: True - -Lint/EndAlignment: - Enabled: True - -Lint/DeprecatedClassMethods: - Enabled: True - -Lint/Loop: - Enabled: True - -Lint/ParenthesesAsGroupedExpression: - Enabled: True - -Lint/RescueException: - Enabled: True - -Lint/StringConversionInInterpolation: - Enabled: True - -Lint/UnusedBlockArgument: - Enabled: True - -Lint/UnusedMethodArgument: - Enabled: True - -Lint/UselessAccessModifier: - Enabled: True - -Lint/UselessAssignment: - Enabled: True - -Lint/Void: - Enabled: True - -Layout/AccessModifierIndentation: - Enabled: True - -Style/AccessorMethodName: - Enabled: True - -Style/Alias: - Enabled: True - -Layout/AlignArray: - Enabled: True - -Layout/AlignHash: - Enabled: True - -Layout/AlignParameters: - Enabled: True - -Metrics/BlockNesting: - Enabled: True - -Style/AsciiComments: - Enabled: True - -Style/Attr: - Enabled: True - -Style/BracesAroundHashParameters: - Enabled: True - -Style/CaseEquality: - Enabled: True - -Layout/CaseIndentation: - Enabled: True - -Style/CharacterLiteral: - Enabled: True - -Style/ClassAndModuleCamelCase: - Enabled: True - -Style/ClassAndModuleChildren: - Enabled: False - -Style/ClassCheck: - Enabled: True - -# Class length is not necessarily an indicator of code quality -Metrics/ClassLength: - Enabled: False - -Style/ClassMethods: - Enabled: True - -Style/ClassVars: - Enabled: True - -Style/WhenThen: - Enabled: True - -Style/WordArray: - Enabled: True - -Style/UnneededPercentQ: - Enabled: True - -Layout/Tab: - Enabled: True - -Layout/SpaceBeforeSemicolon: - Enabled: True - -Layout/TrailingBlankLines: - Enabled: True - -Layout/SpaceInsideBlockBraces: - Enabled: True - -Layout/SpaceInsideBrackets: - Enabled: True - -Layout/SpaceInsideHashLiteralBraces: - Enabled: True - -Layout/SpaceInsideParens: - Enabled: True - -Layout/LeadingCommentSpace: - Enabled: True - -Layout/SpaceBeforeFirstArg: - Enabled: True - -Layout/SpaceAfterColon: - Enabled: True - -Layout/SpaceAfterComma: - Enabled: True - -Layout/SpaceAfterMethodName: - Enabled: True - -Layout/SpaceAfterNot: - Enabled: True - -Layout/SpaceAfterSemicolon: - Enabled: True - -Layout/SpaceAroundEqualsInParameterDefault: - Enabled: True - -Layout/SpaceAroundOperators: - Enabled: True - -Layout/SpaceBeforeBlockBraces: - Enabled: True - -Layout/SpaceBeforeComma: - Enabled: True - -Style/CollectionMethods: - Enabled: True - -Layout/CommentIndentation: - Enabled: True - -Style/ColonMethodCall: - Enabled: True - -Style/CommentAnnotation: - Enabled: True - -# 'Complexity' is very relative -Metrics/CyclomaticComplexity: - Enabled: False - -Style/ConstantName: - Enabled: True - -Style/Documentation: - Enabled: False - -Style/DefWithParentheses: - Enabled: True - -Style/PreferredHashMethods: - Enabled: True - -Layout/DotPosition: - EnforcedStyle: trailing - -Style/DoubleNegation: - Enabled: True - -Style/EachWithObject: - Enabled: True - -Layout/EmptyLineBetweenDefs: - Enabled: True - -Layout/IndentArray: - Enabled: True - -Layout/IndentHash: - Enabled: True - -Layout/IndentationConsistency: - Enabled: True - -Layout/IndentationWidth: - Enabled: True - -Layout/EmptyLines: - Enabled: True - -Layout/EmptyLinesAroundAccessModifier: - Enabled: True - -Style/EmptyLiteral: - Enabled: True - -# Configuration parameters: AllowURI, URISchemes. + - bin/* + - ".vendor/**/*" + - "**/Gemfile" + - "**/Rakefile" + - pkg/**/* + - spec/fixtures/**/* + - vendor/**/* + - "**/Puppetfile" + - "**/Vagrantfile" + - "**/Guardfile" Metrics/LineLength: - Enabled: False - -Style/MethodCallWithoutArgsParentheses: - Enabled: True - -Style/MethodDefParentheses: - Enabled: True - -Style/LineEndConcatenation: - Enabled: True - -Layout/TrailingWhitespace: - Enabled: True - -Style/StringLiterals: - Enabled: True - -Style/TrailingCommaInArguments: - Enabled: True - -Style/TrailingCommaInLiteral: - Enabled: True - -Style/GlobalVars: - Enabled: True - -Style/GuardClause: - Enabled: True - -Style/IfUnlessModifier: - Enabled: True - -Style/MultilineIfThen: - Enabled: True - -Style/NegatedIf: - Enabled: True - -Style/NegatedWhile: - Enabled: True - -Style/Next: - Enabled: True - -Style/SingleLineBlockParams: - Enabled: True - -Style/SingleLineMethods: - Enabled: True - -Style/SpecialGlobalVars: - Enabled: True - -Style/TrivialAccessors: - Enabled: True - -Style/UnlessElse: - Enabled: True - -Style/VariableInterpolation: - Enabled: True - -Style/VariableName: - Enabled: True - -Style/WhileUntilDo: - Enabled: True - -Style/EvenOdd: - Enabled: True - -Style/FileName: - Enabled: True - -Style/For: - Enabled: True - -Style/Lambda: - Enabled: True - -Style/MethodName: - Enabled: True - -Style/MultilineTernaryOperator: - Enabled: True - -Style/NestedTernaryOperator: - Enabled: True - -Style/NilComparison: - Enabled: True - + Description: People have wide screens, use them. + Max: 200 +RSpec/BeforeAfterAll: + Description: Beware of using after(:all) as it may cause state to leak between tests. + A necessary evil in acceptance testing. + Exclude: + - spec/acceptance/**/*.rb +RSpec/HookArgument: + Description: Prefer explicit :each argument, matching existing module's style + EnforcedStyle: each +Style/BlockDelimiters: + Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to + be consistent then. + EnforcedStyle: braces_for_chaining +Style/ClassAndModuleChildren: + Description: Compact style reduces the required amount of indentation. + EnforcedStyle: compact +Style/EmptyElse: + Description: Enforce against empty else clauses, but allow `nil` for clarity. + EnforcedStyle: empty Style/FormatString: - Enabled: True - -Style/MultilineBlockChain: - Enabled: True - -Style/Semicolon: - Enabled: True - -Style/SignalException: - Enabled: True - -Style/NonNilCheck: - Enabled: True - -Style/Not: - Enabled: True - -Style/NumericLiterals: - Enabled: True - -Style/OneLineConditional: - Enabled: True - -Style/OpMethod: - Enabled: True - -Style/ParenthesesAroundCondition: - Enabled: True - -Style/PercentLiteralDelimiters: - Enabled: True - -Style/PerlBackrefs: - Enabled: True - -Style/PredicateName: - Enabled: True - -Style/RedundantException: - Enabled: True - -Style/SelfAssignment: - Enabled: True - -Style/Proc: - Enabled: True - -Style/SymbolProc: - Enabled: False - -Style/RaiseArgs: - Enabled: True - -Style/RedundantBegin: - Enabled: True - -Style/RescueModifier: - Enabled: True - -# based on https://github.com/voxpupuli/modulesync_config/issues/168 + Description: Following the main puppet project's style, prefer the % format format. + EnforcedStyle: percent +Style/FormatStringToken: + Description: Following the main puppet project's style, prefer the simpler template + tokens over annotated ones. + EnforcedStyle: template +Style/Lambda: + Description: Prefer the keyword for easier discoverability. + EnforcedStyle: literal Style/RegexpLiteral: + Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 EnforcedStyle: percent_r - Enabled: True - -Lint/UnderscorePrefixedVariableName: - Enabled: True - -Metrics/ParameterLists: - Enabled: False - -Lint/RequireParentheses: - Enabled: True - -Style/ModuleFunction: - Enabled: True - -Lint/Debugger: - Enabled: True - -Style/IfWithSemicolon: - Enabled: True - -Style/Encoding: - Enabled: True - -Style/BlockDelimiters: - Enabled: True - -Layout/MultilineBlockLayout: - Enabled: True - -# 'Complexity' is very relative +Style/TernaryParentheses: + Description: Checks for use of parentheses around ternary conditions. Enforce parentheses + on complex expressions for better readability, but seriously consider breaking + it up. + EnforcedStyle: require_parentheses_when_complex +Style/TrailingCommaInArguments: + Description: Prefer always trailing comma on multiline argument lists. This makes + diffs, and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/TrailingCommaInLiteral: + Description: Prefer always trailing comma on multiline literals. This makes diffs, + and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/SymbolArray: + Description: Using percent style obscures symbolic intent of array's contents. + EnforcedStyle: brackets +RSpec/MessageSpies: + EnforcedStyle: receive +Style/Documentation: + Exclude: + - lib/puppet/parser/functions/**/* + - spec/**/* +Style/WordArray: + EnforcedStyle: brackets +Style/CollectionMethods: + Enabled: true +Style/MethodCalledOnDoEndBlock: + Enabled: true +Style/StringMethods: + Enabled: true +Layout/EndOfLine: + Enabled: false +Layout/IndentHeredoc: + Enabled: false Metrics/AbcSize: - Enabled: False - -# 'Complexity' is very relative + Enabled: false +Metrics/BlockLength: + Enabled: false +Metrics/ClassLength: + Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false +Metrics/MethodLength: + Enabled: false +Metrics/ModuleLength: + Enabled: false +Metrics/ParameterLists: + Enabled: false Metrics/PerceivedComplexity: - Enabled: False - -Lint/UselessAssignment: - Enabled: True - -Layout/ClosingParenthesisIndentation: - Enabled: True - -# RSpec - -RSpec/BeforeAfterAll: - Exclude: - - spec/acceptance/**/* - -# We don't use rspec in this way + Enabled: false RSpec/DescribeClass: - Enabled: False - -# Example length is not necessarily an indicator of code quality + Enabled: false RSpec/ExampleLength: - Enabled: False - -RSpec/NamedSubject: - Enabled: False - -# disabled for now since they cause a lot of issues -# these issues aren't easy to fix -RSpec/RepeatedDescription: - Enabled: False - + Enabled: false +RSpec/MessageExpectation: + Enabled: false +RSpec/MultipleExpectations: + Enabled: false RSpec/NestedGroups: - Enabled: False - -# this is broken on ruby1.9 -Layout/IndentHeredoc: - Enabled: False - -# disable Yaml safe_load. This is needed to support ruby2.0.0 development envs -Security/YAMLLoad: Enabled: false - -# This affects hiera interpolation, as well as some configs that we push. -Style/FormatStringToken: +Style/AsciiComments: Enabled: false - -# This is useful, but sometimes a little too picky about where unit tests files -# are located. -RSpec/FilePath: +Style/IfUnlessModifier: + Enabled: false +Style/SymbolProc: Enabled: false diff --git a/.travis.yml b/.travis.yml index e4e8cb2..81f77dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,35 +1,44 @@ --- sudo: false +dist: trusty language: ruby -matrix: - fast_finish: true - include: - - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.8.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.6 - env: PUPPET_GEM_VERSION="~> 4.0" - - rvm: 2.1.9 - env: PUPPET_GEM_VERSION="~> 4.0" - - rvm: 2.2 - env: PUPPET_GEM_VERSION="~> 4.0" - - rvm: 2.3.1 - env: PUPPET_GEM_VERSION="~> 4.0" - - rvm: 2.4.1 - env: PUPPET_GEM_VERSION="~> 4.0" - - rvm: 2.4.1 - env: PUPPET_GEM_VERSION="~> 5.0" CHECK="rubocop" -script: - - 'bundle exec rake spec $CHECK' -bundler_args: --without system_tests cache: bundler before_install: - bundle -v - - rm Gemfile.lock .gemfile.lock || true + - rm -f Gemfile.lock - gem update --system - - gem update bundler - gem --version - bundle -v +script: + - 'bundle exec rake $CHECK' +bundler_args: --without system_tests +rvm: + - 2.4.1 +env: + global: + - BEAKER_PUPPET_COLLECTION=puppet5 PUPPET_GEM_VERSION="~> 5.0" +matrix: + fast_finish: true + include: + - + env: CHECK="syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop" + - + env: CHECK=parallel_spec + - + env: PUPPET_GEM_VERSION="~> 4.0" CHECK=parallel_spec + rvm: 2.1.9 +branches: + only: + - master + - /^v\d/ notifications: email: false +deploy: + provider: puppetforge + user: puppet + password: + secure: "" + on: + tags: true + all_branches: true + condition: "$DEPLOY_TO_FORGE = yes" diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..29c933b --- /dev/null +++ b/.yardopts @@ -0,0 +1 @@ +--markup markdown diff --git a/Gemfile b/Gemfile index 3414850..5cda86e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,21 +1,78 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' -group :test do - gem 'puppetlabs_spec_helper', :require => false - gem 'rspec-puppet', :require => false - gem 'rspec-puppet-facts', :require => false - gem 'semantic_puppet', :require => false - gem 'rubocop', '~> 0.49.1', :require => false if RUBY_VERSION >= '2.3.0' - gem 'rubocop-rspec', '~> 1.15.0', :require => false if RUBY_VERSION >= '2.3.0' - gem 'json', '< 2.0.0', :require => false if RUBY_VERSION < '2.0.0' - gem 'json_pure', '< 2.0.0', :require => false if RUBY_VERSION < '2.0.0' +def location_for(place_or_version, fake_version = nil) + if place_or_version =~ %r{\A(git[:@][^#]*)#(.*)} + [fake_version, { git: Regexp.last_match(1), branch: Regexp.last_match(2), require: false }].compact + elsif place_or_version =~ %r{\Afile:\/\/(.*)} + ['>= 0', { path: File.expand_path(Regexp.last_match(1)), require: false }] + else + [place_or_version, { require: false }] + end end -if RUBY_VERSION < '2.0.0' - gem 'metadata-json-lint', '< 1.2.0', :require => false, :groups => [:test] -else - gem 'metadata-json-lint', :require => false, :groups => [:test] +def gem_type(place_or_version) + if place_or_version =~ %r{\Agit[:@]} + :git + elsif !place_or_version.nil? && place_or_version.start_with?('file:') + :file + else + :gem + end end -ENV['PUPPET_GEM_VERSION'].nil? ? puppetversion = '~> 4.0' : puppetversion = ENV['PUPPET_GEM_VERSION'].to_s -gem 'puppet', puppetversion, :require => false, :groups => [:test] +ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments +minor_version = ruby_version_segments[0..1].join('.') + +group :development do + gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') + gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') + gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9') + gem "json", '<= 2.0.4', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.4.4') + gem "puppet-module-posix-default-r#{minor_version}", require: false, platforms: [:ruby] + gem "puppet-module-posix-dev-r#{minor_version}", require: false, platforms: [:ruby] + gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "puppet-module-win-dev-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] +end + +puppet_version = ENV['PUPPET_GEM_VERSION'] +puppet_type = gem_type(puppet_version) +facter_version = ENV['FACTER_GEM_VERSION'] +hiera_version = ENV['HIERA_GEM_VERSION'] + +gems = {} + +gems['puppet'] = location_for(puppet_version) + +# If facter or hiera versions have been specified via the environment +# variables + +gems['facter'] = location_for(facter_version) if facter_version +gems['hiera'] = location_for(hiera_version) if hiera_version + +if Gem.win_platform? && puppet_version =~ %r{^(file:///|git://)} + # If we're using a Puppet gem on Windows which handles its own win32-xxx gem + # dependencies (>= 3.5.0), set the maximum versions (see PUP-6445). + gems['win32-dir'] = ['<= 0.4.9', require: false] + gems['win32-eventlog'] = ['<= 0.6.5', require: false] + gems['win32-process'] = ['<= 0.7.5', require: false] + gems['win32-security'] = ['<= 0.2.5', require: false] + gems['win32-service'] = ['0.8.8', require: false] +end + +gems.each do |gem_name, gem_params| + gem gem_name, *gem_params +end + +# Evaluate Gemfile.local and ~/.gemfile if they exist +extra_gemfiles = [ + "#{__FILE__}.local", + File.join(Dir.home, '.gemfile'), +] + +extra_gemfiles.each do |gemfile| + if File.file?(gemfile) && File.readable?(gemfile) + eval(File.read(gemfile), binding) + end +end +# vim: syntax=ruby diff --git a/Rakefile b/Rakefile index 14f1c24..204fb18 100644 --- a/Rakefile +++ b/Rakefile @@ -1,2 +1,75 @@ -require 'rubygems' require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-syntax/tasks/puppet-syntax' +require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? +require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any? + +def changelog_user + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = nil || JSON.load(File.read('metadata.json'))['author'] + raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator user:#{returnVal}" + returnVal +end + +def changelog_project + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = nil || JSON.load(File.read('metadata.json'))['name'] + raise "unable to find the changelog_project in .sync.yml or the name in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator project:#{returnVal}" + returnVal +end + +def changelog_future_release + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = JSON.load(File.read('metadata.json'))['version'] + raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator future_release:#{returnVal}" + returnVal +end + +PuppetLint.configuration.send('disable_relative') + +if Bundler.rubygems.find_name('github_changelog_generator').any? + GitHubChangelogGenerator::RakeTask.new :changelog do |config| + raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil? + config.user = "#{changelog_user}" + config.project = "#{changelog_project}" + config.future_release = "#{changelog_future_release}" + config.exclude_labels = ['maintenance'] + config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)." + config.add_pr_wo_labels = true + config.issues = false + config.merge_prefix = "### UNCATEGORIZED PRS; GO LABEL THEM" + config.configure_sections = { + "Changed" => { + "prefix" => "### Changed", + "labels" => ["backwards-incompatible"], + }, + "Added" => { + "prefix" => "### Added", + "labels" => ["feature", "enhancement"], + }, + "Fixed" => { + "prefix" => "### Fixed", + "labels" => ["bugfix"], + }, + } + end +else + desc 'Generate a Changelog from GitHub' + task :changelog do + raise <= Gem::Version.new('2.2.2')" +EOM + end +end + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..4a5b227 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,52 @@ +--- +version: 1.1.x.{build} +skip_commits: + message: /^\(?doc\)?.*/ +clone_depth: 10 +init: + - SET + - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0' + - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0' +environment: + matrix: + - + RUBY_VERSION: 24-x64 + CHECK: syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop + - + PUPPET_GEM_VERSION: ~> 4.0 + RUBY_VERSION: 21 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 4.0 + RUBY_VERSION: 21-x64 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 5.0 + RUBY_VERSION: 24 + CHECK: parallel_spec + - + PUPPET_GEM_VERSION: ~> 5.0 + RUBY_VERSION: 24-x64 + CHECK: parallel_spec +matrix: + fast_finish: true +install: + - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% + - bundle install --jobs 4 --retry 2 --without system_tests + - type Gemfile.lock +build: off +test_script: + - bundle exec puppet -V + - ruby -v + - gem -v + - bundle -v + - bundle exec rake %CHECK% +notifications: + - provider: Email + to: + - nobody@nowhere.com + on_build_success: false + on_build_failure: false + on_build_status_changed: false diff --git a/lib/puppet/provider/debconf/debian.rb b/lib/puppet/provider/debconf/debian.rb index c04b796..7994ddc 100644 --- a/lib/puppet/provider/debconf/debian.rb +++ b/lib/puppet/provider/debconf/debian.rb @@ -1,216 +1,215 @@ # debian.rb --- Debian provider for debconf type Puppet::Type.type(:debconf).provide(:debian) do desc 'Manage debconf database entries on Debian based systems.' confine osfamily: :debian defaultfor osfamily: :debian + # A private class to communicate with the debconf database class Debconf < IO - # A private class to communicate with the debconf database - # The regular expression used to parse the debconf-communicate output DEBCONF_COMMUNICATE = Regexp.new( '^([0-9]+)' + # error code '\s*' + # whitespace '(.*)' + # return value '\s*$' # optional trailing spaces ) def initialize(pipe) # The pipe to the debconf-communicate program @pipe = pipe end # Open communication channel with the debconf database def self.communicate(package) Puppet.debug("Debconf: open pipe to debconf-communicate for #{package}") pipe = IO.popen("/usr/bin/debconf-communicate #{package}", 'w+') raise(Puppet::Error, 'Debconf: failed to open pipe to debconf-communicate') unless pipe # Call block for pipe yield new(pipe) if block_given? # Close pipe and finish, ignore remaining output from command pipe.close_write pipe.read(nil) pipe.close_read @pipe = nil end # Send a command to the debconf-communicate pipe and collect response def send(command) Puppet.debug("Debconf: send #{command}") @pipe.puts(command) response = @pipe.gets("\n") raise(Puppet::Error, 'Debconf: debconf-communicate unexpectedly closed pipe') unless response raise(Puppet::Error, "Debconf: debconf-communicate returned (#{response})") unless DEBCONF_COMMUNICATE.match(response) # Response is devided into the return code (casted to int) and the # result text. Depending on the context the text could be an error # message or the value of an item. retcode = Regexp.last_match(1).to_i retmesg = Regexp.last_match(2) [retcode, retmesg] end # Get an item from the debconf database # Return the value of the item or nil if the item is not found def get(item) resultcode, resultmesg = send("GET #{item}") # Check for errors case resultcode when 0 then resultmesg # OK when 10 then nil # item doesn't exist else raise(Puppet::Error, "Debconf: 'GET #{item}' returned #{resultcode}: #{resultmesg}") end end # Get the seen flag for an item from the debconf database # Return a boolean true or false def seen?(item) resultcode, resultmesg = send("FGET #{item} seen") # Check for errors case resultcode when 0 then (resultmesg == 'true') when 10 then false else raise(Puppet::Error, "Debconf: 'FGET #{item} seen' returned #{resultcode}: #{resultmesg}") end end # Unregister an item in the debconf database def unregister(item) resultcode, resultmesg = send("UNREGISTER #{item}") # Check for errors raise(Puppet::Error, "Debconf: 'UNREGISTER #{item}' returned #{resultcode}: #{resultmesg}") unless resultcode.zero? @property_hash = {} end end # # The Debian debconf provider # def initialize(value = {}) super(value) @property_hash = {} end # Fetch item properties def fetch Puppet.debug("Debconf: fetch #{resource[:item]} for #{resource[:package]}") Debconf.communicate(resource[:package]) do |debconf| value = debconf.get(resource[:item]) if value Puppet.debug("Debconf: #{resource[:item]} = '#{value}'") @property_hash[:ensure] = :present @property_hash[:value] = value seen = debconf.seen?(resource[:item]) Puppet.debug("Debconf: #{resource[:item]} seen flag is '#{seen}'") @property_hash[:seen] = seen else @property_hash[:ensure] = :absent end end end # Call debconf-set-selections to store the item values def flush Puppet.debug("Debconf: calling flush #{resource[:name]}") case @property_hash[:ensure] when :present IO.popen('/usr/bin/debconf-set-selections', 'w+') do |pipe| # Store type/value if @property_hash[:value] args = [resource[:package], resource[:item]] args << resource[:type] args << resource[:value] comm = args.join(' ') Puppet.debug("Debconf: debconf-set-selections #{comm}") pipe.puts(comm) end # Store seen flag unless resource[:seen].nil? args = [resource[:package], resource[:item]] args << 'seen' args << resource[:seen].to_s comm = args.join(' ') Puppet.debug("Debconf: debconf-set-selections #{comm}") pipe.puts(comm) end # Ignore remaining output from command pipe.close_write pipe.read(nil) end when :absent Debconf.communicate(resource[:package]) do |debconf| debconf.unregister(resource[:item]) end end end def create Puppet.debug("Debconf: calling create #{resource[:name]}") @property_hash[:ensure] = resource[:ensure] @property_hash[:value] = resource[:value] @property_hash[:seen] = resource[:seen] if resource[:seen] end def destroy Puppet.debug("Debconf: calling destroy for #{resource[:name]}") @property_hash[:ensure] = :absent end def exists? Puppet.debug("Debconf: calling exists? for #{resource[:name]}") fetch if @property_hash.empty? @property_hash[:ensure] == :present end def value Puppet.debug("Debconf: calling get #{resource[:item]}") fetch if @property_hash.empty? @property_hash[:value] end def value=(val) Puppet.debug("Debconf: calling set #{resource[:item]} to #{val}") @property_hash[:item] = val end def seen Puppet.debug("Debconf: calling get seen flag of #{resource[:item]}") fetch if @property_hash.empty? @property_hash[:seen].to_s end def seen=(val) Puppet.debug("Debconf: calling set seen flag of #{resource[:item]} to #{val}") @property_hash[:seen] = val end end diff --git a/metadata.json b/metadata.json index e057ca8..801dee5 100644 --- a/metadata.json +++ b/metadata.json @@ -1,26 +1,43 @@ { "name": "stm-debconf", "version": "2.2.0", "author": "stm", "summary": "Manage debconf database items on Debian based systems.", "license": "BSD-2-Clause", "source": "https://github.com/smoeding/puppet-debconf", "project_page": "https://github.com/smoeding/puppet-debconf", "issues_url": "https://github.com/smoeding/puppet-debconf/issues", - "data_provider": null, - "tags": [ "debconf" ], + "dependencies": [ + + ], "operatingsystem_support": [ { "operatingsystem": "Debian", - "operatingsystemrelease": [ "7", "8", "9" ] + "operatingsystemrelease": [ + "7", + "8", + "9" + ] }, { "operatingsystem": "Ubuntu", - "operatingsystemrelease": [ "14.04", "16.04", "17.10" ] + "operatingsystemrelease": [ + "14.04", + "16.04", + "17.10" + ] } ], - "dependencies": [], "requirements": [ - { "name": "puppet", "version_requirement": ">= 3.0.0 < 6.0.0" } - ] + { + "name": "puppet", + "version_requirement": ">= 3.0.0 < 6.0.0" + } + ], + "tags": [ + "debconf" + ], + "pdk-version": "1.6.0", + "template-url": "https://github.com/puppetlabs/pdk-templates", + "template-ref": "heads/master-0-gc87eee3" } diff --git a/spec/default_facts.yml b/spec/default_facts.yml new file mode 100644 index 0000000..3248be5 --- /dev/null +++ b/spec/default_facts.yml @@ -0,0 +1,8 @@ +# Use default_module_facts.yml for module specific facts. +# +# Facts specified here will override the values provided by rspec-puppet-facts. +--- +concat_basedir: "/tmp" +ipaddress: "172.16.254.254" +is_pe: false +macaddress: "AA:AA:AA:AA:AA:AA" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1a7c6b7..e69d11d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,45 @@ -require 'rubygems' + require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' +begin + require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) +rescue LoadError => loaderror + warn "Could not require spec_helper_local: #{loaderror.message}" +end + include RspecPuppetFacts + +default_facts = { + puppetversion: Puppet.version, + facterversion: Facter.version, +} + +default_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')) +default_module_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')) + +if File.exist?(default_facts_path) && File.readable?(default_facts_path) + default_facts.merge!(YAML.safe_load(File.read(default_facts_path))) +end + +if File.exist?(default_module_facts_path) && File.readable?(default_module_facts_path) + default_facts.merge!(YAML.safe_load(File.read(default_module_facts_path))) +end + +RSpec.configure do |c| + c.default_facts = default_facts + c.before :each do + # set to strictest setting for testing + # by default Puppet runs at warning level + Puppet.settings[:strict] = :warning + end +end + +def ensure_module_defined(module_name) + module_name.split('::').reduce(Object) do |last_module, next_module| + last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module) + last_module.const_get(next_module) + end +end + +# 'spec_overrides' from sync.yml will appear below this line diff --git a/spec/unit/provider/debian_spec.rb b/spec/unit/provider/debian_spec.rb index e9ccdf4..2b2805d 100644 --- a/spec/unit/provider/debian_spec.rb +++ b/spec/unit/provider/debian_spec.rb @@ -1,25 +1,25 @@ require 'spec_helper' provider_class = Puppet::Type.type(:debconf).provider(:debian) describe provider_class do let(:name) { 'foo' } let(:resource) do Puppet::Type.type(:debconf).new( name: name, - provider: 'debian' + provider: 'debian', ) end let(:provider) do provider = provider_class.new provider.resource = resource provider end it 'is the default provider on :osfamily => Debian' do Facter.expects(:value).with(:osfamily).returns('Debian') - expect(described_class.default?).to be_truthy + expect(described_class).to be_default end end diff --git a/spec/unit/type/debconf_spec.rb b/spec/unit/type/debconf_spec.rb index 3af4902..7a3928d 100644 --- a/spec/unit/type/debconf_spec.rb +++ b/spec/unit/type/debconf_spec.rb @@ -1,33 +1,33 @@ require 'spec_helper' describe Puppet::Type.type(:debconf) do on_supported_os.each do |os, facts| context "on #{os}" do - before do + before(:each) do Facter.clear facts.each do |k, v| Facter.stubs(:fact).with(k).returns Facter.add(k) { setcode { v } } end end describe 'when validating attributes' do [:item, :package, :type].each do |param| it "has a #{param} parameter" do expect(described_class.attrtype(param)).to eq(:param) end end [:value].each do |prop| it "has a #{prop} property" do expect(described_class.attrtype(prop)).to eq(:property) end end end describe 'namevar validation' do it 'has :item as its namevar' do expect(described_class.key_attributes).to eq([:item]) end end end end end