From f308ce451412c0569a1c4b726f185fa4cc1a5b3e Mon Sep 17 00:00:00 2001 From: Melissa Stone Date: Fri, 18 May 2018 10:36:33 -0700 Subject: (maint) Bump pdk to 1.5.0 --- .gitignore | 1 + .gitlab-ci.yml | 75 ++++++++++++++++------------------------------------- .pdkignore | 1 + .rubocop.yml | 12 +++++++-- .sync.yml | 3 --- .travis.yml | 16 +++++------- Gemfile | 62 +++++-------------------------------------- Rakefile | 5 +++- appveyor.yml | 17 +++++------- metadata.json | 6 ++--- spec/spec_helper.rb | 6 +++++ 11 files changed, 67 insertions(+), 137 deletions(-) diff --git a/.gitignore b/.gitignore index 56efb9c..49bc2a4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,5 @@ /tmp/ /vendor/ /convert_report.txt +/update_report.txt .DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 35e4209..d651650 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,70 +1,41 @@ --- stages: - - test_2.4.1 - - test_2.1.9 + - syntax + - unit + +cache: + paths: + - vendor/bundle before_script: - bundle -v - rm Gemfile.lock || true - gem update --system - - gem update bundler - gem --version - bundle -v - - bundle install --without system_tests - -rubocop-2.4.1: - stage: test_2.4.1 - image: ruby:2.4.1 - script: - - bundle exec rake rubocop - -syntax-2.4.1: - stage: test_2.4.1 - image: ruby:2.4.1 - script: - - bundle exec rake syntax lint + - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) -metadata-2.4.1: - stage: test_2.4.1 - image: ruby:2.4.1 - script: - - bundle exec rake metadata_lint - -rspec-puppet-2.4.1: - stage: test_2.4.1 - image: ruby:2.4.1 - variables: - PUPPET_GEM_VERSION: ~> 4.0 - CHECK: spec - script: - - bundle update - - bundle exec rake $CHECK - -rubocop-2.1.9: - stage: test_2.1.9 +parallel_spec-Ruby 2.1.9-Puppet ~> 4.0: + stage: syntax image: ruby:2.1.9 script: - - bundle exec rake rubocop + - bundle exec rake parallel_spec + variables: + PUPPET_GEM_VERSION: '~> 4.0' -syntax-2.1.9: - stage: test_2.1.9 - image: ruby:2.1.9 +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 + - 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' -metadata-2.1.9: - stage: test_2.1.9 - image: ruby:2.1.9 +parallel_spec-Ruby 2.4.4-Puppet ~> 5.5: + stage: syntax + image: ruby:2.4.4 script: - - bundle exec rake metadata_lint - -rspec-puppet-2.1.9: - stage: test_2.1.9 - image: ruby:2.1.9 + - bundle exec rake parallel_spec variables: - PUPPET_GEM_VERSION: ~> 4.0 - CHECK: spec - script: - - bundle update - - bundle exec rake $CHECK + PUPPET_GEM_VERSION: '~> 5.5' diff --git a/.pdkignore b/.pdkignore index 56efb9c..49bc2a4 100644 --- a/.pdkignore +++ b/.pdkignore @@ -19,4 +19,5 @@ /tmp/ /vendor/ /convert_report.txt +/update_report.txt .DS_Store diff --git a/.rubocop.yml b/.rubocop.yml index 40a58e0..7ed6225 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,11 +8,14 @@ AllCops: Exclude: - bin/* - ".vendor/**/*" - - Gemfile - - Rakefile + - "**/Gemfile" + - "**/Rakefile" - pkg/**/* - spec/fixtures/**/* - vendor/**/* + - "**/Puppetfile" + - "**/Vagrantfile" + - "**/Guardfile" Metrics/LineLength: Description: People have wide screens, use them. Max: 200 @@ -65,6 +68,11 @@ Style/SymbolArray: EnforcedStyle: brackets RSpec/MessageSpies: EnforcedStyle: receive +Style/Documentation: + Exclude: + - lib/puppet/parser/functions/**/* +Style/WordArray: + EnforcedStyle: brackets Style/CollectionMethods: Enabled: true Style/MethodCalledOnDoEndBlock: diff --git a/.sync.yml b/.sync.yml index 00a3fb4..367f666 100644 --- a/.sync.yml +++ b/.sync.yml @@ -21,11 +21,8 @@ Gemfile: - gem: beaker-rspec from_env: BEAKER_RSPEC_VERSION ':development': - - gem: puppet-blacksmith - version: '~> 3.4' - gem: puppet-strings Rakefile: requires: - - puppet_blacksmith/rake_tasks - puppet-lint/tasks/puppet-lint diff --git a/.travis.yml b/.travis.yml index 6b1f5fb..81f77dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,8 @@ language: ruby cache: bundler before_install: - bundle -v - - rm Gemfile.lock || true + - rm -f Gemfile.lock - gem update --system - - gem update bundler - gem --version - bundle -v script: @@ -16,20 +15,17 @@ bundler_args: --without system_tests rvm: - 2.4.1 env: - - PUPPET_GEM_VERSION="~> 5.0" CHECK=spec + global: + - BEAKER_PUPPET_COLLECTION=puppet5 PUPPET_GEM_VERSION="~> 5.0" matrix: fast_finish: true include: - - env: CHECK=rubocop + env: CHECK="syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop" - - env: CHECK="syntax lint" + env: CHECK=parallel_spec - - env: CHECK=metadata_lint - - - env: CHECK=spec - - - env: PUPPET_GEM_VERSION="~> 4.0" CHECK=spec + env: PUPPET_GEM_VERSION="~> 4.0" CHECK=parallel_spec rvm: 2.1.9 branches: only: diff --git a/Gemfile b/Gemfile index bb4eff8..86e8d7f 100644 --- a/Gemfile +++ b/Gemfile @@ -28,11 +28,12 @@ group :development do 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] - gem "puppet-blacksmith", '~> 3.4', require: false + gem "puppet-blacksmith", '~> 3.4', require: false, platforms: [:ruby] gem "puppet-strings", require: false end group :system_tests do @@ -50,73 +51,24 @@ puppet_type = gem_type(puppet_version) facter_version = ENV['FACTER_GEM_VERSION'] hiera_version = ENV['HIERA_GEM_VERSION'] -def puppet_older_than?(version) - puppet_version = ENV['PUPPET_GEM_VERSION'] - !puppet_version.nil? && - Gem::Version.correct?(puppet_version) && - Gem::Requirement.new("< #{version}").satisfied_by?(Gem::Version.new(puppet_version.dup)) -end - gems = {} gems['puppet'] = location_for(puppet_version) # If facter or hiera versions have been specified via the environment -# variables, use those versions. If not, and if the puppet version is < 3.5.0, -# use known good versions of both for puppet < 3.5.0. -if facter_version - gems['facter'] = location_for(facter_version) -elsif puppet_type == :gem && puppet_older_than?('3.5.0') - gems['facter'] = ['>= 1.6.11', '<= 1.7.5', require: false] -end - -if hiera_version - gems['hiera'] = location_for(ENV['HIERA_GEM_VERSION']) -elsif puppet_type == :gem && puppet_older_than?('3.5.0') - gems['hiera'] = ['>= 1.0.0', '<= 1.3.0', require: false] -end +# variables -if Gem.win_platform? && (puppet_type != :gem || puppet_older_than?('3.5.0')) - # For Puppet gems < 3.5.0 (tested as far back as 3.0.0) on Windows - if puppet_type == :gem - gems['ffi'] = ['1.9.0', require: false] - gems['minitar'] = ['0.5.4', require: false] - gems['win32-eventlog'] = ['0.5.3', '<= 0.6.5', require: false] - gems['win32-process'] = ['0.6.5', '<= 0.7.5', require: false] - gems['win32-security'] = ['~> 0.1.2', '<= 0.2.5', require: false] - gems['win32-service'] = ['0.7.2', '<= 0.8.8', require: false] - else - gems['ffi'] = ['~> 1.9.0', require: false] - gems['minitar'] = ['~> 0.5.4', require: false] - gems['win32-eventlog'] = ['~> 0.5', '<= 0.6.5', require: false] - gems['win32-process'] = ['~> 0.6', '<= 0.7.5', require: false] - gems['win32-security'] = ['~> 0.1', '<= 0.2.5', require: false] - gems['win32-service'] = ['~> 0.7', '<= 0.8.8', require: false] - end - - gems['win32-dir'] = ['~> 0.3', '<= 0.4.9', require: false] - - if RUBY_VERSION.start_with?('1.') - gems['win32console'] = ['1.3.2', require: false] - # sys-admin was removed in Puppet 3.7.0 and doesn't compile under Ruby 2.x - gems['sys-admin'] = ['1.5.6', require: false] - end +gems['facter'] = location_for(facter_version) if facter_version +gems['hiera'] = location_for(hiera_version) if hiera_version - # Puppet < 3.7.0 requires these. - # Puppet >= 3.5.0 gem includes these as requirements. - # The following versions are tested to work with 3.0.0 <= puppet < 3.7.0. - gems['win32-api'] = ['1.4.8', require: false] - gems['win32-taskscheduler'] = ['0.2.2', require: false] - gems['windows-api'] = ['0.4.3', require: false] - gems['windows-pr'] = ['1.2.3', require: false] -elsif Gem.win_platform? +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] + gems['win32-service'] = ['0.8.8', require: false] end gems.each do |gem_name, gem_params| diff --git a/Rakefile b/Rakefile index a39cae2..ef5f698 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,7 @@ require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-syntax/tasks/puppet-syntax' -require 'puppet_blacksmith/rake_tasks' +require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.send('disable_relative') + diff --git a/appveyor.yml b/appveyor.yml index 5fd5e89..4a5b227 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,4 @@ +--- version: 1.1.x.{build} skip_commits: message: /^\(?doc\)?.*/ @@ -12,29 +13,23 @@ environment: matrix: - RUBY_VERSION: 24-x64 - CHECK: syntax lint - - - RUBY_VERSION: 24-x64 - CHECK: metadata_lint - - - RUBY_VERSION: 24-x64 - CHECK: rubocop + 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: spec + CHECK: parallel_spec - PUPPET_GEM_VERSION: ~> 4.0 RUBY_VERSION: 21-x64 - CHECK: spec + CHECK: parallel_spec - PUPPET_GEM_VERSION: ~> 5.0 RUBY_VERSION: 24 - CHECK: spec + CHECK: parallel_spec - PUPPET_GEM_VERSION: ~> 5.0 RUBY_VERSION: 24-x64 - CHECK: spec + CHECK: parallel_spec matrix: fast_finish: true install: diff --git a/metadata.json b/metadata.json index 409ae01..3c4850f 100644 --- a/metadata.json +++ b/metadata.json @@ -78,7 +78,7 @@ "version_requirement": ">= 4.7.0 < 6.0.0" } ], - "pdk-version": "1.4.1", - "template-url": "file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git", - "template-ref": "1.4.1-0-g52adbbb" + "pdk-version": "1.5.0", + "template-url": "https://github.com/puppetlabs/pdk-templates", + "template-ref": "heads/master-0-g34e3266" } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index efd225b..e117192 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ + require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' @@ -27,4 +28,9 @@ 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 -- cgit v1.2.3 From 99b8aef830b2eabaf3a217eb08da6deb12e5f8c7 Mon Sep 17 00:00:00 2001 From: Melissa Stone Date: Fri, 18 May 2018 10:41:13 -0700 Subject: (maint) Mock with rspec not mocha --- .sync.yml | 3 +++ spec/shared_behaviours/all_parsedfile_providers.rb | 2 +- spec/spec_helper.rb | 3 +++ spec/unit/type/mailalias_spec.rb | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.sync.yml b/.sync.yml index 367f666..34b1c2f 100644 --- a/.sync.yml +++ b/.sync.yml @@ -26,3 +26,6 @@ Gemfile: Rakefile: requires: - puppet-lint/tasks/puppet-lint + +spec/spec_helper.rb: + mock_with: ':rspec' diff --git a/spec/shared_behaviours/all_parsedfile_providers.rb b/spec/shared_behaviours/all_parsedfile_providers.rb index d697a14..1701fe3 100644 --- a/spec/shared_behaviours/all_parsedfile_providers.rb +++ b/spec/shared_behaviours/all_parsedfile_providers.rb @@ -5,7 +5,7 @@ shared_examples_for 'all parsedfile providers' do |provider, *files| files.flatten.each do |file| it "should rewrite #{file} reasonably unchanged" do - provider.stubs(:default_target).returns(file) + allow(provider).to receive(:default_target).and_return(file) provider.prefetch text = provider.to_file(provider.target_records(file)) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e117192..b71d71e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,6 @@ +RSpec.configure do |c| + c.mock_with :rspec +end require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' diff --git a/spec/unit/type/mailalias_spec.rb b/spec/unit/type/mailalias_spec.rb index 1fb195e..80b838c 100644 --- a/spec/unit/type/mailalias_spec.rb +++ b/spec/unit/type/mailalias_spec.rb @@ -29,13 +29,13 @@ describe Puppet::Type.type(:mailalias) do it 'tries and set the recipient when it does the sync' do expect(recipient_resource.retrieve_resource[:recipient]).to eq(:absent) - recipient_resource.property(:recipient).expects(:set).with(['yay']) + expect(recipient_resource.property(:recipient)).to receive(:set).with(['yay']) recipient_resource.property(:recipient).sync end it 'tries and set the included file when it does the sync' do expect(file_resource.retrieve_resource[:file]).to eq(:absent) - file_resource.property(:file).expects(:set).with(tmpfile_path) + expect(file_resource.property(:file)).to receive(:set).with(tmpfile_path) file_resource.property(:file).sync end -- cgit v1.2.3 From 6cd75e0f1e6169f05f4234d2cc5fc9c6c359de36 Mon Sep 17 00:00:00 2001 From: Melissa Stone Date: Fri, 18 May 2018 11:16:44 -0700 Subject: (maint) Rubocop update --- lib/puppet/provider/mailalias/aliases.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/provider/mailalias/aliases.rb b/lib/puppet/provider/mailalias/aliases.rb index c8e5e3e..7ec30b1 100644 --- a/lib/puppet/provider/mailalias/aliases.rb +++ b/lib/puppet/provider/mailalias/aliases.rb @@ -12,7 +12,7 @@ Puppet::Type.type(:mailalias).provide( text_line :comment, match: %r{^#} text_line :blank, match: %r{^\s*$} - record_line :aliases, fields: %w[name recipient], separator: %r{\s*:\s*}, block_eval: :instance do + record_line :aliases, fields: ['name', 'recipient'], separator: %r{\s*:\s*}, block_eval: :instance do def post_parse(record) if record[:recipient] record[:recipient] = record[:recipient].split(%r{\s*,\s*}).map { |d| d.gsub(%r{^['"]|['"]$}, '') } -- cgit v1.2.3 From e55b0f02e3e4ef300a5c3e96caf755f518d91c4b Mon Sep 17 00:00:00 2001 From: Melissa Stone Date: Fri, 18 May 2018 11:28:42 -0700 Subject: (maint) Update the acceptance tests Prior to this commit, the acceptance tests for mailalias were broken up in a way that was not logical. The tests had been broken up simply following the 'steps' from the previous iteration. This new structure did not work, since later steps were dependent on earlier steps. The tests could not be run in isolation. This commit changes the test set up so that we can more easily run tests in isolation and in random order. --- spec/acceptance/tests/create_spec.rb | 6 +++--- spec/acceptance/tests/destroy_spec.rb | 8 ++++---- spec/acceptance/tests/modify_spec.rb | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/spec/acceptance/tests/create_spec.rb b/spec/acceptance/tests/create_spec.rb index 82adfec..80fe8d3 100644 --- a/spec/acceptance/tests/create_spec.rb +++ b/spec/acceptance/tests/create_spec.rb @@ -16,13 +16,13 @@ RSpec.context 'Mailalias: should create an email alias' do end non_windows_agents.each do |agent| - it 'creates a mailalias with puppet' do + it 'creates a mailalias resource' do + # create a mailalias with puppet args = ['ensure=present', 'recipient="foo,bar,baz"'] on(agent, puppet_resource('mailalias', name, args)) - end - it 'verifies the alias exists' do + # verify the alias exists on(agent, 'cat /etc/aliases') do |res| assert_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias not in aliases file') end diff --git a/spec/acceptance/tests/destroy_spec.rb b/spec/acceptance/tests/destroy_spec.rb index 0f805a5..a5cb122 100644 --- a/spec/acceptance/tests/destroy_spec.rb +++ b/spec/acceptance/tests/destroy_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper_acceptance' -RSpec.context 'should delete an email alias' do +RSpec.context 'Mailalias: should delete an email alias' do name = "pl#{rand(999_999).to_i}" before(:all) do @@ -26,13 +26,13 @@ RSpec.context 'should delete an email alias' do end non_windows_agents.each do |agent| - it 'deletes the aliases database with puppet' do + it 'deletes a mailalias resource' do + # delete the aliases database with puppet args = ['ensure=absent', 'recipient="foo,bar,baz"'] on(agent, puppet_resource('mailalias', name, args)) - end - it 'verifies the alias is absent' do + # verify the alias is absent on(agent, 'cat /etc/aliases') do |res| assert_no_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias was not removed from aliases file') end diff --git a/spec/acceptance/tests/modify_spec.rb b/spec/acceptance/tests/modify_spec.rb index f4ea7bf..24903b6 100644 --- a/spec/acceptance/tests/modify_spec.rb +++ b/spec/acceptance/tests/modify_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper_acceptance' -RSpec.context 'should modify an email alias' do +RSpec.context 'Mailalias: should modify an email alias' do name = "pl#{rand(999_999).to_i}" before(:all) do non_windows_agents.each do |agent| - #------- SETUP -------# # (setup) backup alias file on(agent, 'cp /etc/aliases /tmp/aliases', acceptable_exit_codes: [0, 1]) @@ -27,13 +26,13 @@ RSpec.context 'should modify an email alias' do end non_windows_agents.each do |agent| - it 'modifies the aliases database with puppet' do + it 'modifies an existing mailalias resource' do + # modify the aliases database with puppet args = ['ensure=present', 'recipient="foo,bar,baz,blarvitz"'] on(agent, puppet_resource('mailalias', name, args)) - end - it 'verifies the updated alias is present' do + # verify the updated alias is present on(agent, 'cat /etc/aliases') do |res| assert_match(%r{#{name}:.*foo,bar,baz,blarvitz}, res.stdout, 'updated mailalias not in aliases file') end -- cgit v1.2.3 From 733bc4f4b88f3a29f66603561713fb0a18c6c947 Mon Sep 17 00:00:00 2001 From: Melissa Stone Date: Fri, 18 May 2018 11:50:25 -0700 Subject: (maint) 1.0.3 release prep --- CHANGELOG.md | 7 +++++++ metadata.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33e085f..71caca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All 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). +## [1.0.3] - 2018-05-18 +### Changed +- Update PDK to 1.5.0 +- Change mocks to use rspec rather than mocha +- Update acceptance tests to run successfully in a random order + ## [1.0.2] - 2018-04-30 ### Added - Gem dependency on puppet-blacksmith, which is required to ship to the module @@ -21,6 +27,7 @@ This is an empty release to test the release pipeline ### Summary This is the initial release of the extracted mailalias module +[1.0.3]: https://github.com/puppetlabs/puppetlabs-mailalias_core/compare/1.0.2...1.0.3 [1.0.2]: https://github.com/puppetlabs/puppetlabs-mailalias_core/compare/1.0.1...1.0.2 [1.0.1]: https://github.com/puppetlabs/puppetlabs-mailalias_core/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/puppetlabs/puppetlabs-mailalias_core/releases/tag/1.0.0 diff --git a/metadata.json b/metadata.json index 3c4850f..bec1710 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-mailalias_core", - "version": "1.0.2", + "version": "1.0.3", "author": "Puppet Labs", "summary": "Creates an email alias in the local alias database.", "license": "Apache-2.0", -- cgit v1.2.3