pax_global_header00006660000000000000000000000064144334023640014515gustar00rootroot0000000000000052 comment=da669b02ef824bd1b09a07c0d582958f0e88032f librarian-puppet-5.0.0/000077500000000000000000000000001443340236400147755ustar00rootroot00000000000000librarian-puppet-5.0.0/.github/000077500000000000000000000000001443340236400163355ustar00rootroot00000000000000librarian-puppet-5.0.0/.github/dependabot.yml000066400000000000000000000005411443340236400211650ustar00rootroot00000000000000version: 2 updates: # raise PRs for gem updates - package-ecosystem: bundler directory: "/" schedule: interval: daily time: "13:00" open-pull-requests-limit: 10 # Maintain dependencies for GitHub Actions - package-ecosystem: github-actions directory: "/" schedule: interval: daily time: "13:00" open-pull-requests-limit: 10 librarian-puppet-5.0.0/.github/workflows/000077500000000000000000000000001443340236400203725ustar00rootroot00000000000000librarian-puppet-5.0.0/.github/workflows/release.yml000066400000000000000000000015361443340236400225420ustar00rootroot00000000000000name: Release on: push: tags: - '*' jobs: release: runs-on: ubuntu-latest if: github.repository_owner == 'voxpupuli' steps: - uses: actions/checkout@v2 - name: Install Ruby 3.0 uses: ruby/setup-ruby@v1 with: ruby-version: '3.0' - name: Build gem run: gem build *.gemspec - name: Publish gem to rubygems.org run: gem push *.gem env: GEM_HOST_API_KEY: '${{ secrets.RUBYGEMS_AUTH_TOKEN }}' - name: Setup GitHub packages access run: | mkdir -p ~/.gem echo ":github: Bearer ${{ secrets.GITHUB_TOKEN }}" >> ~/.gem/credentials chmod 0600 ~/.gem/credentials - name: Publish gem to GitHub packages run: gem push --key github --host https://rubygems.pkg.github.com/${{ github.repository_owner }} *.gem librarian-puppet-5.0.0/.github/workflows/test.yml000066400000000000000000000016561443340236400221040ustar00rootroot00000000000000name: Test on: pull_request: {} push: branches: - master jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: ruby: - "2.7" - "3.0" puppet: - "7" - "6" exclude: - puppet: "6" ruby: "3.0" name: Ruby ${{ matrix.ruby }} + Puppet ${{ matrix.puppet }} env: PUPPET_VERSION: "~> ${{ matrix.puppet }}.0" steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Show Puppet version run: bundle exec puppet --version - name: Run tests run: bundle exec rake - name: Verify gem builds run: gem build *.gemspec tests: needs: - test runs-on: ubuntu-latest name: Test suite steps: - run: echo Test suite completed librarian-puppet-5.0.0/.gitignore000066400000000000000000000000471443340236400167660ustar00rootroot00000000000000pkg/ Gemfile.lock tmp/ coverage/ *.gem librarian-puppet-5.0.0/.rspec000066400000000000000000000000371443340236400161120ustar00rootroot00000000000000--color --format documentation librarian-puppet-5.0.0/CHANGELOG.md000066400000000000000000000463511443340236400166170ustar00rootroot00000000000000# Changelog ## [v5.0.0](https://github.com/voxpupuli/librarian-puppet/tree/v5.0.0) (2023-05-24) [Full Changelog](https://github.com/voxpupuli/librarian-puppet/compare/v4.0.1...v5.0.0) **Breaking changes:** - Remove deprecated method alias [\#109](https://github.com/voxpupuli/librarian-puppet/pull/109) ([ekohl](https://github.com/ekohl)) - Remove forge.puppetlabs.com -\> forgeapi.p.c rewrite [\#108](https://github.com/voxpupuli/librarian-puppet/pull/108) ([ekohl](https://github.com/ekohl)) - Drop Modulefile support [\#106](https://github.com/voxpupuli/librarian-puppet/pull/106) ([ekohl](https://github.com/ekohl)) - Require Ruby 2.7+ [\#103](https://github.com/voxpupuli/librarian-puppet/pull/103) ([ekohl](https://github.com/ekohl)) - Default to using API v3 [\#102](https://github.com/voxpupuli/librarian-puppet/pull/102) ([ekohl](https://github.com/ekohl)) - Start assuming Puppet 3.6+ is used [\#101](https://github.com/voxpupuli/librarian-puppet/pull/101) ([ekohl](https://github.com/ekohl)) **Implemented enhancements:** - Allow puppet\_forge 4.x [\#107](https://github.com/voxpupuli/librarian-puppet/pull/107) ([ekohl](https://github.com/ekohl)) **Merged pull requests:** - CI: run on PRs and merges to master [\#105](https://github.com/voxpupuli/librarian-puppet/pull/105) ([bastelfreak](https://github.com/bastelfreak)) - Add dummy CI job we can depend on [\#104](https://github.com/voxpupuli/librarian-puppet/pull/104) ([bastelfreak](https://github.com/bastelfreak)) ## [v4.0.1](https://github.com/voxpupuli/librarian-puppet/tree/v4.0.1) (2023-04-26) [Full Changelog](https://github.com/voxpupuli/librarian-puppet/compare/v4.0.0...v4.0.1) **Fixed bugs:** - support ruby 3.2 by renaming File.exists? to File.exist? [\#98](https://github.com/voxpupuli/librarian-puppet/pull/98) ([shamil](https://github.com/shamil)) ## [v4.0.0](https://github.com/voxpupuli/librarian-puppet/tree/v4.0.0) (2023-02-22) [Full Changelog](https://github.com/voxpupuli/librarian-puppet/compare/v3.0.1...v4.0.0) **Breaking changes:** - Drop Ruby 2.4 support [\#96](https://github.com/voxpupuli/librarian-puppet/pull/96) ([evgeni](https://github.com/evgeni)) - Drop Ruby 2.3 support and switch to Github Actions [\#86](https://github.com/voxpupuli/librarian-puppet/pull/86) ([ekohl](https://github.com/ekohl)) - Drop Puppet 3/Puppet 4 and Ruby 2.0/2.1/2.2 testing [\#82](https://github.com/voxpupuli/librarian-puppet/pull/82) ([bastelfreak](https://github.com/bastelfreak)) **Implemented enhancements:** - Mark compatible with puppet\_forge 3.x [\#85](https://github.com/voxpupuli/librarian-puppet/pull/85) ([ekohl](https://github.com/ekohl)) - Add Puppet 7 support [\#84](https://github.com/voxpupuli/librarian-puppet/pull/84) ([bastelfreak](https://github.com/bastelfreak)) - Add Ruby2.5/Puppet6 to CI matrix, disable email notifications on CI runs [\#83](https://github.com/voxpupuli/librarian-puppet/pull/83) ([bastelfreak](https://github.com/bastelfreak)) **Closed issues:** - Ubuntu 22.04 Tried to create Proc without a block [\#90](https://github.com/voxpupuli/librarian-puppet/issues/90) - Unable to retrieve dependencies [\#89](https://github.com/voxpupuli/librarian-puppet/issues/89) - Domain librarian-puppet.com in GitHub About sections is for sale [\#88](https://github.com/voxpupuli/librarian-puppet/issues/88) - Bundler 2 requires Ruby 2.3 or later. Either install bundler 1 or update to a supported Ruby version [\#72](https://github.com/voxpupuli/librarian-puppet/issues/72) - "Could not resolve the dependencies." for two modules with different version requirements [\#54](https://github.com/voxpupuli/librarian-puppet/issues/54) - buffer error \(Zlib::BufError\) when installing puppetlabs-apache [\#39](https://github.com/voxpupuli/librarian-puppet/issues/39) - Faraday::SSLError [\#32](https://github.com/voxpupuli/librarian-puppet/issues/32) - Simpler github module specs [\#31](https://github.com/voxpupuli/librarian-puppet/issues/31) - -bash: librarian-puppet: command not found [\#29](https://github.com/voxpupuli/librarian-puppet/issues/29) - Error: redirection forbidden [\#28](https://github.com/voxpupuli/librarian-puppet/issues/28) - Using librarian-puppet and custom modules [\#18](https://github.com/voxpupuli/librarian-puppet/issues/18) - Failing to install activesupport-5.0.0.beta3.gem on Ruby 2.1.8. [\#6](https://github.com/voxpupuli/librarian-puppet/issues/6) - Puppetfile syntax differences - R10K vs librarian [\#5](https://github.com/voxpupuli/librarian-puppet/issues/5) **Merged pull requests:** - Actually run acceptance tests [\#92](https://github.com/voxpupuli/librarian-puppet/pull/92) ([ekohl](https://github.com/ekohl)) - Typo [\#87](https://github.com/voxpupuli/librarian-puppet/pull/87) ([sboyd-m](https://github.com/sboyd-m)) - Add --\[no-\]use-v1-api option to update command [\#75](https://github.com/voxpupuli/librarian-puppet/pull/75) ([dwminer](https://github.com/dwminer)) - Support basic auth for forge [\#69](https://github.com/voxpupuli/librarian-puppet/pull/69) ([kim-sondrup](https://github.com/kim-sondrup)) ## 3.0.1 * [PR #68](https://github.com/voxpupuli/librarian-puppet/pull/68) Specify dependent module in dependencies * [PR #80](https://github.com/voxpupuli/librarian-puppet/pull/80) Fix calling issue with open-uri ## 3.0.0 ### Breaking Changes Librarian-Puppet 3.0.0 and newer requires Ruby >= 2.0. Use version 2.2.4 if you need support for Puppet 3.7 or earlier, or Ruby 1.9 or earlier. Note that Puppet 4.10 and [newer require Ruby 2.1](https://puppet.com/docs/puppet/4.10/system_requirements.html#prerequisites) or newer. * [PR #1](https://github.com/voxpupuli/librarian/pull/1) Add support for r10k Puppetfile's opts * [PR #5](https://github.com/voxpupuli/librarian-puppet/pull/9) Update README for r10k syntax from PR #1. * [PR #8](https://github.com/voxpupuli/librarian-puppet/pull/8) Clean up tests * [PR #19](https://github.com/voxpupuli/librarian-puppet/pull/19) Fix rsync on Windows (path conversion, return code checking) and add trailing / * [Issue #20](https://github.com/voxpupuli/librarian-puppet/issues/20) Ignore Gem files * [Issue #25](https://github.com/voxpupuli/librarian-puppet/pull/25) Move to https and new forge url * Avoid deleted ripienaar-concat * [PR #59](https://github.com/voxpupuli/librarian-puppet/pull/59) Fix tests * [PR #61](https://github.com/voxpupuli/librarian-puppet/pull/61) Bring testing matrix up to date ## 2.2.3 * [Issue #1](https://github.com/voxpupuli/librarian-puppet/pull/1) Upgrade to puppet_forge 2 * [Issue #2](https://github.com/voxpupuli/librarian-puppet/pull/2) Change github user from "rodjek" to "voxpupuli" ## 2.2.1 * [Issue #311](https://github.com/rodjek/librarian-puppet/issues/311) Omit versions with a deleted_at date ## 2.2.0 * Add support for Puppet 4 * [Issue #296](https://github.com/rodjek/librarian-puppet/issues/296) Uninitialized constant Puppet::ModuleTool::ModulefileReader using Modulefiles in Puppet 4. Ignore those dependencies ## 2.1.1 * [Issue #302](https://github.com/rodjek/librarian-puppet/issues/302) Ensure path is not lost when default specfile is used * [Issue #294](https://github.com/rodjek/librarian-puppet/issues/294) Undefined variable calling Puppet version in old Puppet 2.x versions * [Issue #285](https://github.com/rodjek/librarian-puppet/issues/294) Update librarianp to allow overriding dependencies from multiple sources ## 2.1.0 * Update librarian to use the new `exclusion` syntax * [Issue #282](https://github.com/rodjek/librarian-puppet/issues/282) Merge duplicated dependencies and warn the user, no more `Cannot bounce Puppetfile.lock!` errors * [Issue #217](https://github.com/rodjek/librarian-puppet/issues/217), [Issue #244](https://github.com/rodjek/librarian-puppet/issues/244) Use librarianp 0.4.0 that no longer uses recursion to avoid `stack level too deep` errors * [Issue #277](https://github.com/rodjek/librarian-puppet/issues/277) Warn when there are two dependencies with the same module name * Use `librarianp` gem instead of `librarian`, a fork with the needed improvements and fixes. ## 2.0.1 * [Issue #272](https://github.com/rodjek/librarian-puppet/issues/272) Defined forge is not used when resolving dependencies * [Issue #150](https://github.com/rodjek/librarian-puppet/issues/150) Allow dependencies other than Puppet modules * [Issue #269](https://github.com/rodjek/librarian-puppet/issues/269) Better error message if metadata.json is bad * [Issue #264](https://github.com/rodjek/librarian-puppet/issues/264) Copying files can cause permission problems on Windows ## 2.0.0 ### Breaking Changes Librarian-Puppet 2.0.0 and newer requires Ruby >= 1.9 and uses Puppet Forge API v3. For Ruby 1.8 use 1.5.0. * Jump from 1.3.x to 2.x to leave 1.x for Ruby 1.8 compatibility * [Issue #254](https://github.com/rodjek/librarian-puppet/issues/254) Add a rsync option to prevent deleting directories * [Issue #261](https://github.com/rodjek/librarian-puppet/issues/261) Incorrect install directory is created if the organization name contains a dash * [Issue #255](https://github.com/rodjek/librarian-puppet/issues/255) Ignored forge URL when using API v3 ## 1.5.0 * Update librarian to use the new `exclusion` syntax * [Issue #282](https://github.com/rodjek/librarian-puppet/issues/282) Merge duplicated dependencies and warn the user, no more `Cannot bounce Puppetfile.lock!` errors * [Issue #217](https://github.com/rodjek/librarian-puppet/issues/217), [Issue #244](https://github.com/rodjek/librarian-puppet/issues/244) Use librarianp 0.4.0 that no longer uses recursion to avoid `stack level too deep` errors * [Issue #277](https://github.com/rodjek/librarian-puppet/issues/277) Warn when there are two dependencies with the same module name * Use `librarianp` gem instead of `librarian`, a fork with the needed improvements and fixes. ## 1.4.1 * [Issue #272](https://github.com/rodjek/librarian-puppet/issues/272) Defined forge is not used when resolving dependencies * [Issue #150](https://github.com/rodjek/librarian-puppet/issues/150) Allow dependencies other than Puppet modules * [Issue #269](https://github.com/rodjek/librarian-puppet/issues/269) Better error message if metadata.json is bad * [Issue #264](https://github.com/rodjek/librarian-puppet/issues/264) Copying files can cause permission problems on Windows ## 1.4.0 * Jump from 1.0.x to 1.4.x to keep Ruby 1.8 compatibility in the 1.x series * [Issue #254](https://github.com/rodjek/librarian-puppet/issues/254) Add a rsync option to prevent deleting directories * [Issue #261](https://github.com/rodjek/librarian-puppet/issues/261) Incorrect install directory is created if the organization name contains a dash ## 1.3.3 * [Issue #250](https://github.com/rodjek/librarian-puppet/issues/250) Fix error when module has no dependencies in `metadata.json` ## 1.3.2 * [Issue #246](https://github.com/rodjek/librarian-puppet/issues/246) Do not fail if modules have no `Modulefile` nor `metadata.json` ## 1.3.1 * Version in dependencies with `metadata.json` is ignored ## 1.3.0 * If no Puppetfile is present default to use the `metadata.json` or `Modulefile` * [Issue #235](https://github.com/rodjek/librarian-puppet/issues/235) Error when forge is not defined in `Puppetfile` * [Issue #243](https://github.com/rodjek/librarian-puppet/issues/243) Warn if `Modulefile` doesn't contain a version ## 1.2.0 * Implement `metadata` syntax for `Puppetfile` * [Issue #220](https://github.com/rodjek/librarian-puppet/issues/220) Add support for metadata.json * [Issue #242](https://github.com/rodjek/librarian-puppet/issues/242) Get organization from name correctly if name has multiple dashes ## 1.1.3 * [Issue #237](https://github.com/rodjek/librarian-puppet/issues/237) [Issue #238](https://github.com/rodjek/librarian-puppet/issues/238) Unable to use a custom v3 forge: add flags `--use-v1-api` and `--no-use-v1-api` * [Issue #239](https://github.com/rodjek/librarian-puppet/issues/239) GitHub tarball: add access_token correctly to url's which are already having query parameters * [Issue #234](https://github.com/rodjek/librarian-puppet/issues/234) Use organization-module instead of organization/module by default ## 1.1.2 * [Issue #231](https://github.com/rodjek/librarian-puppet/issues/231) Only use the `GITHUB_API_TOKEN` if it's not empty * [Issue #233](https://github.com/rodjek/librarian-puppet/issues/233) Fix version regex to match e.g. 1.99.15 * Can't pass the Puppet Forge v1 api url to clients using v3 (3.6.0+ and PE 3.2.0+) ## 1.1.1 * [Issue #227](https://github.com/rodjek/librarian-puppet/issues/227) Fix Librarian::Puppet::VERSION undefined ## 1.1.0 * [Issue #210](https://github.com/rodjek/librarian-puppet/issues/210) Use forgeapi.puppetlabs.com and API v3 * Accesing the v3 API requires Ruby 1.9 due to the puppet_forge library used ## 1.0.10 * [Issue #250](https://github.com/rodjek/librarian-puppet/issues/250) Fix error when module has no dependencies in `metadata.json` ## 1.0.9 * [Issue #246](https://github.com/rodjek/librarian-puppet/issues/246) Do not fail if modules have no `Modulefile` nor `metadata.json` ## 1.0.8 * Version in dependencies with `metadata.json` is ignored ## 1.0.7 * If no Puppetfile is present default to use the `metadata.json` or `Modulefile` * [Issue #235](https://github.com/rodjek/librarian-puppet/issues/235) Error when forge is not defined in `Puppetfile` * [Issue #243](https://github.com/rodjek/librarian-puppet/issues/243) Warn if `Modulefile` doesn't contain a version ## 1.0.6 * Implement `metadata` syntax for `Puppetfile` * [Issue #220](https://github.com/rodjek/librarian-puppet/issues/220) Add support for metadata.json * [Issue #242](https://github.com/rodjek/librarian-puppet/issues/242) Get organization from name correctly if name has multiple dashes ## 1.0.5 * [Issue #237](https://github.com/rodjek/librarian-puppet/issues/237)[Issue #238](https://github.com/rodjek/librarian-puppet/issues/238) Unable to use a custom v3 forge: add flags `--use-v1-api` and `--no-use-v1-api` * [Issue #239](https://github.com/rodjek/librarian-puppet/issues/239) GitHub tarball: add access_token correctly to url's which are already having query parameters * [Issue #234](https://github.com/rodjek/librarian-puppet/issues/234) Use organization-module instead of organization/module by default ## 1.0.4 * [Issue #231](https://github.com/rodjek/librarian-puppet/issues/231) Only use the `GITHUB_API_TOKEN` if it's not empty * [Issue #233](https://github.com/rodjek/librarian-puppet/issues/233) Fix version regex to match e.g. 1.99.15 * Can't pass the Puppet Forge v1 api url to clients using v3 (3.6.0+ and PE 3.2.0+) ## 1.0.3 * [Issue #223](https://github.com/rodjek/librarian-puppet/issues/223) `Cannot bounce Puppetfile.lock!` error when Forge modules contain duplicated dependencies ## 1.0.2 * [Issue #211](https://github.com/rodjek/librarian-puppet/issues/211) Pass the PuppetLabs Forge API v3 endpoint to `puppet module` when running on Puppet >= 3.6.0 * [Issue #198](https://github.com/rodjek/librarian-puppet/issues/198) Reduce the length of tmp dirs to avoid issues in windows * [Issue #206](https://github.com/rodjek/librarian-puppet/issues/206) githubtarball call for released versions does not consider pagination * [Issue #204](https://github.com/rodjek/librarian-puppet/issues/204) Fix regex to detect Forge API v3 url * [Issue #199](https://github.com/rodjek/librarian-puppet/issues/199) undefined method run! packaging a git source * Verify SSL certificates in github calls ## 1.0.1 * [Issue #190](https://github.com/rodjek/librarian-puppet/issues/190) Pass the PuppetLabs Forge API v3 endpoint to `puppet module` when running on Puppet Enterprise >= 3.2 * [Issue #196](https://github.com/rodjek/librarian-puppet/issues/196) Fix error in error handling when puppet is not installed ## 1.0.0 * Remove deprecation warning for github_tarball sources, some people are actually using it ## 0.9.17 * [Issue #193](https://github.com/rodjek/librarian-puppet/issues/193) Support Puppet 3.5.0 ## 0.9.16 * [Issue #181](https://github.com/rodjek/librarian-puppet/issues/181) Should use qualified module names for resolution to work correctly * Deprecate github_tarball sources * Reduce number of API calls for github_tarball sources ## 0.9.15 * [Issue #187](https://github.com/rodjek/librarian-puppet/issues/187) Fixed parallel installation issues * [Issue #185](https://github.com/rodjek/librarian-puppet/issues/185) Sanitize the gem/bundler environment before spawning (ruby 1.9+) ## 0.9.14 * [Issue #182](https://github.com/rodjek/librarian-puppet/issues/182) Sanitize the environment before spawning (ruby 1.9+) * [Issue #184](https://github.com/rodjek/librarian-puppet/issues/184) Support transitive dependencies in modules using :path * Git dependencies using modulefile syntax make librarian-puppet fail * [Issue #108](https://github.com/rodjek/librarian-puppet/issues/108) Don't fail on malformed Modulefile from a git dependency ## 0.9.13 * [Issue #176](https://github.com/rodjek/librarian-puppet/issues/176) Upgrade to librarian 0.1.2 * [Issue #179](https://github.com/rodjek/librarian-puppet/issues/179) Need to install extra gems just in case we are in ruby 1.8 * [Issue #178](https://github.com/rodjek/librarian-puppet/issues/178) Print a meaningful message if puppet gem can't be loaded for :git sources ## 0.9.12 * Remove extra dependencies from gem added when 0.9.11 was released under ruby 1.8 ## 0.9.11 * Add modulefile dsl to reuse Modulefile dependencies * Consider Puppetfile-dependencies recursively in git-source * Support changing tmp, cache and scratch paths * librarian-puppet package causes an infinite loop * Show a message if no versions are found for a module * Make download of tarballs more robust * Require open3_backport in ruby 1.8 and install if not present * Git dependencies in both Puppetfile and Modulefile cause a Cannot bounce Puppetfile.lock! error * Better sort of github tarball versions when there are mixed tags starting with and without 'v' * Fix error if a git module has a dependency without version * Fix git dependency with :path attribute * Cleaner output when no Puppetfile found * Reduce the number of API calls to the Forge * Don't sort versions as strings. Rely on the forge returning them ordered * Pass --module_repository to `puppet module install` to install from other forges * Cache forge responses and print an error if returns an invalid response * Add a User-Agent header to all requests to the GitHub API * Convert puppet version requirements to rubygems, pessimistic and ranges * Use librarian gem ## 0.9.10 * Catch GitHub API rate limit exceeded * Make Librarian::Manifest Semver 2.0.0 compatible ## 0.9.1 * Proper error message when a module that is sourced from the forge does not exist. * Added support for annotated tags as git references. * `librarian-puppet init` adds `.tmp/` to gitignore instead of `tmp/`. * Fixed syntax error in the template Puppetfile created by `librarian-puppet init`. * Checks for `lib/puppet` as well as `manifests/` when checking if the git repository is a valid module. * When a user specifies `/` as the name of a module sources from a git repository, assume the module name is actually ``. * Fixed gem description and summary in gemspec. ## 0.9.0 * Initial release \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* librarian-puppet-5.0.0/CONTRIBUTING.md000066400000000000000000000007201443340236400172250ustar00rootroot00000000000000# Librarian-puppet ## Reporting Issues Bug reports to the github issue tracker please. Please include: * Relevant `Puppetfile` and `Puppetfile.lock` files * Version of ruby, librarian-puppet, and puppet * What distro * Please run the `librarian-puppet` commands in verbose mode by using the `--verbose` flag, and include the verbose output in the bug report as well. ## How to Contribute * Pull requests please. * Bonus points for feature branches. librarian-puppet-5.0.0/Gemfile000066400000000000000000000001601443340236400162650ustar00rootroot00000000000000source 'https://rubygems.org' gemspec group :release do gem 'github_changelog_generator', require: false end librarian-puppet-5.0.0/HISTORY.md000066400000000000000000000341771443340236400164740ustar00rootroot00000000000000# Changelog ## 3.0.1 * [PR #68](https://github.com/voxpupuli/librarian-puppet/pull/68) Specify dependent module in dependencies * [PR #80](https://github.com/voxpupuli/librarian-puppet/pull/80) Fix calling issue with open-uri ## 3.0.0 ### Breaking Changes Librarian-Puppet 3.0.0 and newer requires Ruby >= 2.0. Use version 2.2.4 if you need support for Puppet 3.7 or earlier, or Ruby 1.9 or earlier. Note that Puppet 4.10 and [newer require Ruby 2.1](https://puppet.com/docs/puppet/4.10/system_requirements.html#prerequisites) or newer. * [PR #1](https://github.com/voxpupuli/librarian/pull/1) Add support for r10k Puppetfile's opts * [PR #5](https://github.com/voxpupuli/librarian-puppet/pull/9) Update README for r10k syntax from PR #1. * [PR #8](https://github.com/voxpupuli/librarian-puppet/pull/8) Clean up tests * [PR #19](https://github.com/voxpupuli/librarian-puppet/pull/19) Fix rsync on Windows (path conversion, return code checking) and add trailing / * [Issue #20](https://github.com/voxpupuli/librarian-puppet/issues/20) Ignore Gem files * [Issue #25](https://github.com/voxpupuli/librarian-puppet/pull/25) Move to https and new forge url * Avoid deleted ripienaar-concat * [PR #59](https://github.com/voxpupuli/librarian-puppet/pull/59) Fix tests * [PR #61](https://github.com/voxpupuli/librarian-puppet/pull/61) Bring testing matrix up to date ## 2.2.3 * [Issue #1](https://github.com/voxpupuli/librarian-puppet/pull/1) Upgrade to puppet_forge 2 * [Issue #2](https://github.com/voxpupuli/librarian-puppet/pull/2) Change github user from "rodjek" to "voxpupuli" ## 2.2.1 * [Issue #311](https://github.com/rodjek/librarian-puppet/issues/311) Omit versions with a deleted_at date ## 2.2.0 * Add support for Puppet 4 * [Issue #296](https://github.com/rodjek/librarian-puppet/issues/296) Uninitialized constant Puppet::ModuleTool::ModulefileReader using Modulefiles in Puppet 4. Ignore those dependencies ## 2.1.1 * [Issue #302](https://github.com/rodjek/librarian-puppet/issues/302) Ensure path is not lost when default specfile is used * [Issue #294](https://github.com/rodjek/librarian-puppet/issues/294) Undefined variable calling Puppet version in old Puppet 2.x versions * [Issue #285](https://github.com/rodjek/librarian-puppet/issues/294) Update librarianp to allow overriding dependencies from multiple sources ## 2.1.0 * Update librarian to use the new `exclusion` syntax * [Issue #282](https://github.com/rodjek/librarian-puppet/issues/282) Merge duplicated dependencies and warn the user, no more `Cannot bounce Puppetfile.lock!` errors * [Issue #217](https://github.com/rodjek/librarian-puppet/issues/217), [Issue #244](https://github.com/rodjek/librarian-puppet/issues/244) Use librarianp 0.4.0 that no longer uses recursion to avoid `stack level too deep` errors * [Issue #277](https://github.com/rodjek/librarian-puppet/issues/277) Warn when there are two dependencies with the same module name * Use `librarianp` gem instead of `librarian`, a fork with the needed improvements and fixes. ## 2.0.1 * [Issue #272](https://github.com/rodjek/librarian-puppet/issues/272) Defined forge is not used when resolving dependencies * [Issue #150](https://github.com/rodjek/librarian-puppet/issues/150) Allow dependencies other than Puppet modules * [Issue #269](https://github.com/rodjek/librarian-puppet/issues/269) Better error message if metadata.json is bad * [Issue #264](https://github.com/rodjek/librarian-puppet/issues/264) Copying files can cause permission problems on Windows ## 2.0.0 ### Breaking Changes Librarian-Puppet 2.0.0 and newer requires Ruby >= 1.9 and uses Puppet Forge API v3. For Ruby 1.8 use 1.5.0. * Jump from 1.3.x to 2.x to leave 1.x for Ruby 1.8 compatibility * [Issue #254](https://github.com/rodjek/librarian-puppet/issues/254) Add a rsync option to prevent deleting directories * [Issue #261](https://github.com/rodjek/librarian-puppet/issues/261) Incorrect install directory is created if the organization name contains a dash * [Issue #255](https://github.com/rodjek/librarian-puppet/issues/255) Ignored forge URL when using API v3 ## 1.5.0 * Update librarian to use the new `exclusion` syntax * [Issue #282](https://github.com/rodjek/librarian-puppet/issues/282) Merge duplicated dependencies and warn the user, no more `Cannot bounce Puppetfile.lock!` errors * [Issue #217](https://github.com/rodjek/librarian-puppet/issues/217), [Issue #244](https://github.com/rodjek/librarian-puppet/issues/244) Use librarianp 0.4.0 that no longer uses recursion to avoid `stack level too deep` errors * [Issue #277](https://github.com/rodjek/librarian-puppet/issues/277) Warn when there are two dependencies with the same module name * Use `librarianp` gem instead of `librarian`, a fork with the needed improvements and fixes. ## 1.4.1 * [Issue #272](https://github.com/rodjek/librarian-puppet/issues/272) Defined forge is not used when resolving dependencies * [Issue #150](https://github.com/rodjek/librarian-puppet/issues/150) Allow dependencies other than Puppet modules * [Issue #269](https://github.com/rodjek/librarian-puppet/issues/269) Better error message if metadata.json is bad * [Issue #264](https://github.com/rodjek/librarian-puppet/issues/264) Copying files can cause permission problems on Windows ## 1.4.0 * Jump from 1.0.x to 1.4.x to keep Ruby 1.8 compatibility in the 1.x series * [Issue #254](https://github.com/rodjek/librarian-puppet/issues/254) Add a rsync option to prevent deleting directories * [Issue #261](https://github.com/rodjek/librarian-puppet/issues/261) Incorrect install directory is created if the organization name contains a dash ## 1.3.3 * [Issue #250](https://github.com/rodjek/librarian-puppet/issues/250) Fix error when module has no dependencies in `metadata.json` ## 1.3.2 * [Issue #246](https://github.com/rodjek/librarian-puppet/issues/246) Do not fail if modules have no `Modulefile` nor `metadata.json` ## 1.3.1 * Version in dependencies with `metadata.json` is ignored ## 1.3.0 * If no Puppetfile is present default to use the `metadata.json` or `Modulefile` * [Issue #235](https://github.com/rodjek/librarian-puppet/issues/235) Error when forge is not defined in `Puppetfile` * [Issue #243](https://github.com/rodjek/librarian-puppet/issues/243) Warn if `Modulefile` doesn't contain a version ## 1.2.0 * Implement `metadata` syntax for `Puppetfile` * [Issue #220](https://github.com/rodjek/librarian-puppet/issues/220) Add support for metadata.json * [Issue #242](https://github.com/rodjek/librarian-puppet/issues/242) Get organization from name correctly if name has multiple dashes ## 1.1.3 * [Issue #237](https://github.com/rodjek/librarian-puppet/issues/237) [Issue #238](https://github.com/rodjek/librarian-puppet/issues/238) Unable to use a custom v3 forge: add flags `--use-v1-api` and `--no-use-v1-api` * [Issue #239](https://github.com/rodjek/librarian-puppet/issues/239) GitHub tarball: add access_token correctly to url's which are already having query parameters * [Issue #234](https://github.com/rodjek/librarian-puppet/issues/234) Use organization-module instead of organization/module by default ## 1.1.2 * [Issue #231](https://github.com/rodjek/librarian-puppet/issues/231) Only use the `GITHUB_API_TOKEN` if it's not empty * [Issue #233](https://github.com/rodjek/librarian-puppet/issues/233) Fix version regex to match e.g. 1.99.15 * Can't pass the Puppet Forge v1 api url to clients using v3 (3.6.0+ and PE 3.2.0+) ## 1.1.1 * [Issue #227](https://github.com/rodjek/librarian-puppet/issues/227) Fix Librarian::Puppet::VERSION undefined ## 1.1.0 * [Issue #210](https://github.com/rodjek/librarian-puppet/issues/210) Use forgeapi.puppetlabs.com and API v3 * Accesing the v3 API requires Ruby 1.9 due to the puppet_forge library used ## 1.0.10 * [Issue #250](https://github.com/rodjek/librarian-puppet/issues/250) Fix error when module has no dependencies in `metadata.json` ## 1.0.9 * [Issue #246](https://github.com/rodjek/librarian-puppet/issues/246) Do not fail if modules have no `Modulefile` nor `metadata.json` ## 1.0.8 * Version in dependencies with `metadata.json` is ignored ## 1.0.7 * If no Puppetfile is present default to use the `metadata.json` or `Modulefile` * [Issue #235](https://github.com/rodjek/librarian-puppet/issues/235) Error when forge is not defined in `Puppetfile` * [Issue #243](https://github.com/rodjek/librarian-puppet/issues/243) Warn if `Modulefile` doesn't contain a version ## 1.0.6 * Implement `metadata` syntax for `Puppetfile` * [Issue #220](https://github.com/rodjek/librarian-puppet/issues/220) Add support for metadata.json * [Issue #242](https://github.com/rodjek/librarian-puppet/issues/242) Get organization from name correctly if name has multiple dashes ## 1.0.5 * [Issue #237](https://github.com/rodjek/librarian-puppet/issues/237)[Issue #238](https://github.com/rodjek/librarian-puppet/issues/238) Unable to use a custom v3 forge: add flags `--use-v1-api` and `--no-use-v1-api` * [Issue #239](https://github.com/rodjek/librarian-puppet/issues/239) GitHub tarball: add access_token correctly to url's which are already having query parameters * [Issue #234](https://github.com/rodjek/librarian-puppet/issues/234) Use organization-module instead of organization/module by default ## 1.0.4 * [Issue #231](https://github.com/rodjek/librarian-puppet/issues/231) Only use the `GITHUB_API_TOKEN` if it's not empty * [Issue #233](https://github.com/rodjek/librarian-puppet/issues/233) Fix version regex to match e.g. 1.99.15 * Can't pass the Puppet Forge v1 api url to clients using v3 (3.6.0+ and PE 3.2.0+) ## 1.0.3 * [Issue #223](https://github.com/rodjek/librarian-puppet/issues/223) `Cannot bounce Puppetfile.lock!` error when Forge modules contain duplicated dependencies ## 1.0.2 * [Issue #211](https://github.com/rodjek/librarian-puppet/issues/211) Pass the PuppetLabs Forge API v3 endpoint to `puppet module` when running on Puppet >= 3.6.0 * [Issue #198](https://github.com/rodjek/librarian-puppet/issues/198) Reduce the length of tmp dirs to avoid issues in windows * [Issue #206](https://github.com/rodjek/librarian-puppet/issues/206) githubtarball call for released versions does not consider pagination * [Issue #204](https://github.com/rodjek/librarian-puppet/issues/204) Fix regex to detect Forge API v3 url * [Issue #199](https://github.com/rodjek/librarian-puppet/issues/199) undefined method run! packaging a git source * Verify SSL certificates in github calls ## 1.0.1 * [Issue #190](https://github.com/rodjek/librarian-puppet/issues/190) Pass the PuppetLabs Forge API v3 endpoint to `puppet module` when running on Puppet Enterprise >= 3.2 * [Issue #196](https://github.com/rodjek/librarian-puppet/issues/196) Fix error in error handling when puppet is not installed ## 1.0.0 * Remove deprecation warning for github_tarball sources, some people are actually using it ## 0.9.17 * [Issue #193](https://github.com/rodjek/librarian-puppet/issues/193) Support Puppet 3.5.0 ## 0.9.16 * [Issue #181](https://github.com/rodjek/librarian-puppet/issues/181) Should use qualified module names for resolution to work correctly * Deprecate github_tarball sources * Reduce number of API calls for github_tarball sources ## 0.9.15 * [Issue #187](https://github.com/rodjek/librarian-puppet/issues/187) Fixed parallel installation issues * [Issue #185](https://github.com/rodjek/librarian-puppet/issues/185) Sanitize the gem/bundler environment before spawning (ruby 1.9+) ## 0.9.14 * [Issue #182](https://github.com/rodjek/librarian-puppet/issues/182) Sanitize the environment before spawning (ruby 1.9+) * [Issue #184](https://github.com/rodjek/librarian-puppet/issues/184) Support transitive dependencies in modules using :path * Git dependencies using modulefile syntax make librarian-puppet fail * [Issue #108](https://github.com/rodjek/librarian-puppet/issues/108) Don't fail on malformed Modulefile from a git dependency ## 0.9.13 * [Issue #176](https://github.com/rodjek/librarian-puppet/issues/176) Upgrade to librarian 0.1.2 * [Issue #179](https://github.com/rodjek/librarian-puppet/issues/179) Need to install extra gems just in case we are in ruby 1.8 * [Issue #178](https://github.com/rodjek/librarian-puppet/issues/178) Print a meaningful message if puppet gem can't be loaded for :git sources ## 0.9.12 * Remove extra dependencies from gem added when 0.9.11 was released under ruby 1.8 ## 0.9.11 * Add modulefile dsl to reuse Modulefile dependencies * Consider Puppetfile-dependencies recursively in git-source * Support changing tmp, cache and scratch paths * librarian-puppet package causes an infinite loop * Show a message if no versions are found for a module * Make download of tarballs more robust * Require open3_backport in ruby 1.8 and install if not present * Git dependencies in both Puppetfile and Modulefile cause a Cannot bounce Puppetfile.lock! error * Better sort of github tarball versions when there are mixed tags starting with and without 'v' * Fix error if a git module has a dependency without version * Fix git dependency with :path attribute * Cleaner output when no Puppetfile found * Reduce the number of API calls to the Forge * Don't sort versions as strings. Rely on the forge returning them ordered * Pass --module_repository to `puppet module install` to install from other forges * Cache forge responses and print an error if returns an invalid response * Add a User-Agent header to all requests to the GitHub API * Convert puppet version requirements to rubygems, pessimistic and ranges * Use librarian gem ## 0.9.10 * Catch GitHub API rate limit exceeded * Make Librarian::Manifest Semver 2.0.0 compatible ## 0.9.1 * Proper error message when a module that is sourced from the forge does not exist. * Added support for annotated tags as git references. * `librarian-puppet init` adds `.tmp/` to gitignore instead of `tmp/`. * Fixed syntax error in the template Puppetfile created by `librarian-puppet init`. * Checks for `lib/puppet` as well as `manifests/` when checking if the git repository is a valid module. * When a user specifies `/` as the name of a module sources from a git repository, assume the module name is actually ``. * Fixed gem description and summary in gemspec. ## 0.9.0 * Initial release librarian-puppet-5.0.0/LICENSE000066400000000000000000000020761443340236400160070ustar00rootroot00000000000000Copyright (c) 2012-2014 Tim Sharpe, Carlos Sanchez and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. librarian-puppet-5.0.0/README.md000066400000000000000000000327111443340236400162600ustar00rootroot00000000000000# Librarian-puppet [![License](https://img.shields.io/github/license/voxpupuli/librarian-puppet.svg)](https://github.com/voxpupuli/librarian-puppet/blob/master/LICENSE) [![Test](https://github.com/voxpupuli/librarian-puppet/actions/workflows/test.yml/badge.svg)](https://github.com/voxpupuli/librarian-puppet/actions/workflows/test.yml) [![Release](https://github.com/voxpupuli/librarian-puppet/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/librarian-puppet/actions/workflows/release.yml) [![RubyGem Version](https://img.shields.io/gem/v/librarian-puppet.svg)](https://rubygems.org/gems/librarian-puppet) [![RubyGem Downloads](https://img.shields.io/gem/dt/librarian-puppet.svg)](https://rubygems.org/gems/librarian-puppet) [![Donated by Tim Sharpe](https://img.shields.io/badge/donated%20by-Tim%20Sharpe-fb7047.svg)](#transfer-notice) ## Introduction Librarian-puppet is a bundler for your puppet infrastructure. You can use librarian-puppet to manage the puppet modules your infrastructure depends on, whether the modules come from the [Puppet Forge](https://forge.puppet.com/), Git repositories or just a path. * Librarian-puppet can reuse the dependencies listed in your `Modulefile` or `metadata.json` * Forge modules can be installed from [Puppetlabs Forge](https://forge.puppet.com/) or an internal Forge such as [Pulp](http://www.pulpproject.org/) * Git modules can be installed from a branch, tag or specific commit, optionally using a path inside the repository * Modules can be installed from GitHub using tarballs, without needing Git installed * Modules can be installed from a filesystem path * Module dependencies are resolved transitively without needing to list all the modules explicitly Librarian-puppet manages your `modules/` directory for you based on your `Puppetfile`. Your `Puppetfile` becomes the authoritative source for what modules you require and at what version, tag or branch. Once using Librarian-puppet you should not modify the contents of your `modules` directory. The individual modules' repos should be updated, tagged with a new release and the version bumped in your Puppetfile. It is based on [Librarian](https://github.com/applicationsonline/librarian), a framework for writing bundlers, which are tools that resolve, fetch, install, and isolate a project's dependencies. ## Versions Librarian-Puppet 5.0.0 and newer requires Ruby >= 2.7 and Puppet >= 6. Use version 4.0.1 if you need support for Puppet 6 or Ruby 2.6 or earlier. Librarian-Puppet 4.0.0 and newer requires Ruby >= 2.5 and Puppet >= 5. Use version 3.0.1 is you need support for Puppet 3 or Puppet 4, or Ruby 2.4 or earlier. Librarian-Puppet 3.0.0 and newer requires Ruby >= 2.0. Use version 2.2.4 if you need support for Puppet 3.7 or earlier, or Ruby 1.9 or earlier. Note that [Puppet 4.10 and newer require Ruby 2.1](https://puppet.com/docs/puppet/4.10/system_requirements.html#prerequisites) or newer. Librarian-Puppet 2.0.0 and newer requires Ruby >= 1.9 and uses Puppet Forge API v3. For Ruby 1.8 use 1.5.0. See the [Changelog](CHANGELOG.md) for more details. ## The Puppetfile Every Puppet repository that uses Librarian-puppet may have a file named `Puppetfile`, `metadata.json` or `Modulefile` in the root directory of that repository. The full specification for which modules your puppet infrastructure repository depends goes in here. ### Simple usage If no Puppetfile is present, `librarian-puppet` will download all the dependencies listed in your `metadata.json` or `Modulefile` from the Puppet Forge, as if the Puppetfile contained forge "https://forgeapi.puppetlabs.com" metadata ### Example Puppetfile forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs-razor' mod 'puppetlabs-ntp', "0.0.3" mod 'puppetlabs-apt', :git => "git://github.com/puppetlabs/puppetlabs-apt.git" mod 'puppetlabs-stdlib', :git => "git://github.com/puppetlabs/puppetlabs-stdlib.git" mod 'puppetlabs-apache', '0.6.0', :github_tarball => 'puppetlabs/puppetlabs-apache' mod 'acme-mymodule', :path => './some_folder' exclusion 'acme-bad_module' ### Recursive module dependency resolution When fetching a module all dependencies specified in its `Modulefile`, `metadata.json` and `Puppetfile` will be resolved and installed. ### Puppetfile Breakdown forge "https://forgeapi.puppetlabs.com" This declares that we want to use the official Puppet Labs Forge as our default source when pulling down modules. If you run your own local forge, you may want to change this. metadata Download all the dependencies listed in your `metadata.json` or `Modulefile` from the Puppet Forge. mod 'puppetlabs-razor' Pull in the latest version of the Puppet Labs Razor module from the default source. mod 'puppetlabs-ntp', "0.0.3" Pull in version 0.0.3 of the Puppet Labs NTP module from the default source. mod 'puppetlabs-apt', :git => "git://github.com/puppetlabs/puppetlabs-apt.git" Our puppet infrastructure repository depends on the `apt` module from the Puppet Labs GitHub repos and checks out the `master` branch. mod 'puppetlabs-apt', :git => "git://github.com/puppetlabs/puppetlabs-apt.git", :ref => '0.0.3' Our puppet infrastructure repository depends on the `apt` module from the Puppet Labs GitHub repos and checks out a tag of `0.0.3`. mod 'puppetlabs-apt', :git => "git://github.com/puppetlabs/puppetlabs-apt.git", :ref => 'feature/master/dans_refactor' Our puppet infrastructure repository depends on the `apt` module from the Puppet Labs GitHub repos and checks out the `dans_refactor` branch. When using a Git source, we do not have to use a `:ref =>`. If we do not, then librarian-puppet will assume we meant the `master` branch. If we use a `:ref =>`, we can use anything that Git will recognize as a ref. This includes any branch name, tag name, SHA, or SHA unique prefix. If we use a branch, we can later ask Librarian-puppet to update the module by fetching the most recent version of the module from that same branch. Note that Librarian-puppet recognizes the [r10k Puppetfile's](https://github.com/puppetlabs/r10k/blob/master/doc/puppetfile.mkd) additional options, `:tag`, `:commit`, and `:branch`, but only as aliases for `:ref`. That is, there is no implementation of r10k's optimizations around fetching these different types of git objects. The Git source also supports a `:path =>` option. If we use the path option, Librarian-puppet will navigate down into the Git repository and only use the specified subdirectory. Some people have the habit of having a single repository with many modules in it. If we need a module from such a repository, we can use the `:path =>` option here to help Librarian-puppet drill down and find the module subdirectory. mod 'puppetlabs-apt', :git => "git://github.com/fake/puppet-modules.git", :path => "modules/apt" Our puppet infrastructure repository depends on the `apt` module, which we have stored as a directory under our `puppet-modules` git repos. mod 'puppetlabs-apache', '0.6.0', :github_tarball => 'puppetlabs/puppetlabs-apache' Our puppet infrastructure repository depends on the `puppetlabs-apache` module, to be downloaded from GitHub tarball. mod 'acme-mymodule', :path => './some_folder' Our puppet infrastructure repository depends on the `acme-mymodule` module, which is already in the filesystem. exclusion 'acme-bad_module' Exclude the module `acme-bad_module` from resolution and installation. ## How to Use Install librarian-puppet: $ gem install librarian-puppet Prepare your puppet infrastructure repository: $ cd ~/path/to/puppet-inf-repos $ (git) rm -rf modules $ librarian-puppet init Librarian-puppet takes over your `modules/` directory, and will always reinstall (if missing) the modules listed the `Puppetfile.lock` into your `modules/` directory, therefore you do not need your `modules/` directory to be tracked in Git. Librarian-puppet uses a `.tmp/` directory for tempfiles and caches. You should not track this directory in Git. Running `librarian-puppet init` will create a skeleton Puppetfile for you as well as adding `tmp/` and `modules/` to your `.gitignore`. $ librarian-puppet install [--clean] [--verbose] This command looks at each `mod` declaration and fetches the module from the source specified. This command writes the complete resolution into `Puppetfile.lock` and then copies all of the fetched modules into your `modules/` directory, overwriting whatever was there before. Librarian-puppet support both v1 and v3 of the Puppet Forge API. Specify a specific API version when installing modules: $ librarian-puppet install --use-v1-api # use the v1 API $ librarian-puppet install --no-use-v1-api # use the v3 API; this is the default Get an overview of your `Puppetfile.lock` with: $ librarian-puppet show Inspect the details of specific resolved dependencies with: $ librarian-puppet show NAME1 [NAME2, ...] Find out which dependencies are outdated and may be updated: $ librarian-puppet outdated [--verbose] Update the version of a dependency: $ librarian-puppet update apt [--verbose] $ git diff Puppetfile.lock $ git add Puppetfile.lock $ git commit -m "bumped the version of apt up to 0.0.4." ## Configuration Configuration comes from three sources with the following highest-to-lowest precedence: * The local config (`./.librarian/puppet/config`) * The environment * The global config (`~/.librarian/puppet/config`) You can inspect the final configuration with: $ librarian-puppet config You can find out where a particular key is set with: $ librarian-puppet config KEY You can set a key at the global level with: $ librarian-puppet config KEY VALUE --global And remove it with: $ librarian-puppet config KEY --global --delete You can set a key at the local level with: $ librarian-puppet config KEY VALUE --local And remove it with: $ librarian-puppet config KEY --local --delete You cannot set or delete environment-level config keys with the CLI. Configuration set at either the global or local level will affect subsequent invocations of `librarian-puppet`. Configurations set at the environment level are not saved and will not affect subsequent invocations of `librarian-puppet`. You can pass a config at the environment level by taking the original config key and transforming it: replace hyphens (`-`) with underscores (`_`) and periods (`.`) with doubled underscores (`__`), uppercase, and finally prefix with `LIBRARIAN_PUPPET_`. For example, to pass a config in the environment for the key `part-one.part-two`, set the environment variable `LIBRARIAN_PUPPET_PART_ONE__PART_TWO`. Configuration affects how various commands operate. * The `path` config sets the directory to install to. If a relative path, it is relative to the directory containing the `Puppetfile`. The equivalent environment variable is `LIBRARIAN_PUPPET_PATH`. * The `tmp` config sets the cache directory for librarian. If a relative path, it is relative to the directory containing the `Puppetfile`. The equivalent environment variable is `LIBRARIAN_PUPPET_TMP`. Configuration can be set by passing specific options to other commands. * The `path` config can be set at the local level by passing the `--path` option to the `install` command. It can be unset at the local level by passing the `--no-path` option to the `install` command. Note that if this is set at the environment or global level then, even if `--no-path` is given as an option, the environment or global config will be used. ## Rsync Option The default convergence strategy between the cache and the module directory is to execute an `rm -r` on the module directory and just `cp -r` from the cache. This causes the module to be removed from the module path every time librarian puppet updates, regardless of whether the content has changed. This can cause some problems in environments with lots of change. The problem arises when the module directory gets removed while Puppet is trying to read files inside it. The `puppet master` process will lose its CWD and the catalog will fail to compile. To avoid this, you can use `rsync` to implement a more conservative convergence strategy. This will use `rsync` with the `-avz` and `--delete` flags instead of a `rm -r` and `cp -r`. To use this feature, just set the `rsync` configuration setting to `true`. $ librarian-puppet config rsync true --global Alternatively, using an environment variable: LIBRARIAN_PUPPET_RSYNC='true' Note that the directories will still be purged if you run librarian-puppet with the --clean or --destructive flags. ## How to Contribute * Pull requests please. * Bonus points for feature branches. ## Reporting Issues Bug reports to the github issue tracker please. Please include: * Relevant `Puppetfile` and `Puppetfile.lock` files * Version of ruby, librarian-puppet, and puppet * What distro * Please run the `librarian-puppet` commands in verbose mode by using the `--verbose` flag, and include the verbose output in the bug report as well. ## Transfer Notice This plugin was originally authored by [Tim Sharpe](https://github.com/rodjek). The maintainer preferred that [Vox Pupuli](https://voxpupuli.org/) take ownership of the module for future improvement and maintenance. Existing pull requests and issues were transferred, please fork and continue to contribute [here](https://github.com/voxpupuli/librarian-puppet). ## License Please see the [LICENSE](https://github.com/voxpupuli/librarian-puppet/blob/master/LICENSE) file. librarian-puppet-5.0.0/Rakefile000066400000000000000000000025431443340236400164460ustar00rootroot00000000000000require 'bundler/setup' require 'cucumber/rake/task' require 'rspec/core/rake_task' require 'bundler/gem_tasks' require 'rake/testtask' require 'rake/clean' CLEAN.include('pkg/', 'tmp/') CLOBBER.include('Gemfile.lock') RSpec::Core::RakeTask.new Cucumber::Rake::Task.new(:features) Rake::TestTask.new do |test| test.pattern = 'test/**/*_test.rb' test.verbose = true end task :default => [:test, :spec, :features] desc "Bump version to the next minor" task :bump do path = 'lib/librarian/puppet/version.rb' version_file = File.read(path) version = version_file.match(/VERSION = "(.*)"/)[1] v = Gem::Version.new("#{version}.0") new_version = v.bump.to_s version_file = version_file.gsub(/VERSION = ".*"/, "VERSION = \"#{new_version}\"") File.open(path, "w") {|file| file.puts version_file} sh "git add #{path}" sh "git commit -m \"Bump version to #{new_version}\"" end begin require 'rubygems' require 'github_changelog_generator/task' rescue LoadError else GitHubChangelogGenerator::RakeTask.new :changelog do |config| config.exclude_labels = %w{duplicate question invalid wontfix wont-fix skip-changelog} config.user = 'voxpupuli' config.project = 'librarian-puppet' config.since_tag = 'v3.0.1' gem_version = Gem::Specification.load("#{config.project}.gemspec").version config.future_release = "v#{gem_version}" end end librarian-puppet-5.0.0/bin/000077500000000000000000000000001443340236400155455ustar00rootroot00000000000000librarian-puppet-5.0.0/bin/librarian-puppet000077500000000000000000000002471443340236400207540ustar00rootroot00000000000000#!/usr/bin/env ruby lib = File.expand_path('../../lib', __FILE__) $:.unshift(lib) unless $:.include?(lib) require 'librarian/puppet/cli' Librarian::Puppet::Cli.bin! librarian-puppet-5.0.0/features/000077500000000000000000000000001443340236400166135ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/000077500000000000000000000000001443340236400204315ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/dependency_without_version/000077500000000000000000000000001443340236400260775ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/dependency_without_version/manifests/000077500000000000000000000000001443340236400300705ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/dependency_without_version/manifests/init.pp000066400000000000000000000000161443340236400313710ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/dependency_without_version/metadata.json000066400000000000000000000002271443340236400305530ustar00rootroot00000000000000{ "name": "librarian-test", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [ { "name": "puppetlabs/stdlib" } ] } librarian-puppet-5.0.0/features/examples/duplicated_dependencies/000077500000000000000000000000001443340236400252555ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/duplicated_dependencies/Puppetfile000066400000000000000000000000621443340236400273130ustar00rootroot00000000000000forge 'https://forgeapi.puppetlabs.com' metadata librarian-puppet-5.0.0/features/examples/duplicated_dependencies/manifests/000077500000000000000000000000001443340236400272465ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/duplicated_dependencies/manifests/init.pp000066400000000000000000000000161443340236400305470ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/duplicated_dependencies/metadata.json000066400000000000000000000004431443340236400277310ustar00rootroot00000000000000{ "name": "librarian-duplicated_dependencies", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [ { "name": "ripienaar-concat", "version_requirement": ">= 0" }, { "name": "puppetlabs-concat", "version_requirement": "1.2.0" } ] } librarian-puppet-5.0.0/features/examples/duplicated_dependencies_transitive/000077500000000000000000000000001443340236400275255ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/duplicated_dependencies_transitive/Puppetfile000066400000000000000000000003161443340236400315650ustar00rootroot00000000000000forge 'https://forgeapi.puppetlabs.com' metadata mod 'librarian-duplicated_dependencies', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/duplicated_dependencies' librarian-puppet-5.0.0/features/examples/duplicated_dependencies_transitive/manifests/000077500000000000000000000000001443340236400315165ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/duplicated_dependencies_transitive/manifests/init.pp000066400000000000000000000000161443340236400330170ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/duplicated_dependencies_transitive/metadata.json000066400000000000000000000002041443340236400321740ustar00rootroot00000000000000{ "name": "librarian-duplicated_dependencies_transitive", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [] } librarian-puppet-5.0.0/features/examples/metadata_syntax/000077500000000000000000000000001443340236400236175ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/metadata_syntax/Puppetfile000066400000000000000000000000621443340236400256550ustar00rootroot00000000000000forge 'https://forgeapi.puppetlabs.com' metadata librarian-puppet-5.0.0/features/examples/metadata_syntax/manifests/000077500000000000000000000000001443340236400256105ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/metadata_syntax/manifests/init.pp000066400000000000000000000000161443340236400271110ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/metadata_syntax/metadata.json000066400000000000000000000033761443340236400263030ustar00rootroot00000000000000{ "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ "4", "5", "6" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ "4", "5", "6" ] }, { "operatingsystem": "OracleLinux", "operatingsystemrelease": [ "4", "5", "6" ] }, { "operatingsystem": "Scientific", "operatingsystemrelease": [ "4", "5", "6" ] }, { "operatingsystem": "SLES", "operatingsystemrelease": [ "11 SP1" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "10.04", "12.04" ] }, { "operatingsystem": "Solaris", "operatingsystemrelease": [ "10", "11" ] }, { "operatingsystem": "Windows", "operatingsystemrelease": [ "Server 2003", "Server 2003 R2", "Server 2008", "Server 2008 R2", "Server 2012", "Server 2012 R2", "7", "8" ] }, { "operatingsystem": "AIX", "operatingsystemrelease": [ "5.3", "6.1", "7.1" ] } ], "requirements": [ { "name": "pe", "version_requirement": "3.2.x" }, { "name": "puppet", "version_requirement": ">=2.7.20 <4.0.0" } ], "name": "librarian-metadata_syntax", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [ { "name": "maestrodev/test", "version_requirement": ">= 0.0.1" } ] } librarian-puppet-5.0.0/features/examples/path_dependencies/000077500000000000000000000000001443340236400240735ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/path_dependencies/Puppetfile000066400000000000000000000000761443340236400261360ustar00rootroot00000000000000mod 'librarian/test', :path => '../../features/examples/test' librarian-puppet-5.0.0/features/examples/path_dependencies/manifests/000077500000000000000000000000001443340236400260645ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/path_dependencies/manifests/init.pp000066400000000000000000000000161443340236400273650ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/path_dependencies/metadata.json000066400000000000000000000002111443340236400265400ustar00rootroot00000000000000{ "name": "librarian-path_dependencies", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [], "requirements": [] } librarian-puppet-5.0.0/features/examples/test/000077500000000000000000000000001443340236400214105ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/test/manifests/000077500000000000000000000000001443340236400234015ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/test/manifests/init.pp000066400000000000000000000000161443340236400247020ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/test/metadata.json000066400000000000000000000002741443340236400240660ustar00rootroot00000000000000{ "name": "librarian-test", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 0" } ] } librarian-puppet-5.0.0/features/examples/with_puppetfile/000077500000000000000000000000001443340236400236415ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/with_puppetfile/Puppetfile000066400000000000000000000001651443340236400257030ustar00rootroot00000000000000mod 'librarian/test', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/test' librarian-puppet-5.0.0/features/examples/with_puppetfile/manifests/000077500000000000000000000000001443340236400256325ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/with_puppetfile/manifests/init.pp000066400000000000000000000000161443340236400271330ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/with_puppetfile/metadata.json000066400000000000000000000001611443340236400263120ustar00rootroot00000000000000{ "name": "librarian-with_puppetfile", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [] } librarian-puppet-5.0.0/features/examples/with_puppetfile_and_metadata_json/000077500000000000000000000000001443340236400273545ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/with_puppetfile_and_metadata_json/Puppetfile000066400000000000000000000000771443340236400314200ustar00rootroot00000000000000forge 'https://forgeapi.puppetlabs.com' mod 'maestrodev/test' librarian-puppet-5.0.0/features/examples/with_puppetfile_and_metadata_json/manifests/000077500000000000000000000000001443340236400313455ustar00rootroot00000000000000librarian-puppet-5.0.0/features/examples/with_puppetfile_and_metadata_json/manifests/init.pp000066400000000000000000000000161443340236400326460ustar00rootroot00000000000000class test {} librarian-puppet-5.0.0/features/examples/with_puppetfile_and_metadata_json/metadata.json000066400000000000000000000003271443340236400320310ustar00rootroot00000000000000{ "name": "librarian-with_puppetfile_and_metadata_json", "version": "0.0.1", "license": "Apache 2.0", "dependencies": [ { "name": "maestrodev/test", "version_requirement": ">= 0" } ] } librarian-puppet-5.0.0/features/help.feature000066400000000000000000000006411443340236400211210ustar00rootroot00000000000000Feature: displays help if no subcommand is passed In order to get started using librarian-puppet A user should be able to run librarian-puppet without any subcommands or options Then the exit status should be 0 And a useful help screen should be displayed Scenario: App defaults to help subcommand When I successfully run `librarian-puppet` And the output should contain "librarian-puppet version" librarian-puppet-5.0.0/features/init.feature000066400000000000000000000006521443340236400211360ustar00rootroot00000000000000Feature: init subcommand should generate a Puppetfile In order to start using librarian-puppet in a project A project will need a Puppetfile. If a user runs "librarian-puppet init" Then the exit status should be 0 And a file named "Puppetfile" should exist Scenario: init subcommand should generate a Puppetfile When I successfully run `librarian-puppet init` Then a file named "Puppetfile" should exist librarian-puppet-5.0.0/features/install.feature000066400000000000000000000127001443340236400216360ustar00rootroot00000000000000Feature: cli/install In order to be worth anything Puppet librarian needs to install modules properly Scenario: Running install with no Puppetfile nor metadata.json Given there is no Puppetfile When I run `librarian-puppet install` Then the output should match /^Metadata file does not exist: .*metadata.json$/ And the exit status should be 1 Scenario: Running install with bad metadata.json Given a file named "metadata.json" with: """ """ When I run `librarian-puppet install` Then the output should match /^Unable to parse json file .*metadata.json: .*$/ And the exit status should be 1 Scenario: Install a module transitive dependency from git and forge should be deterministic Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.6.0' mod 'librarian/test', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/test' """ When I successfully run `librarian-puppet install --verbose` And the file "modules/stdlib/metadata.json" should match /"version": "4\.6\.0"/ And the output should not match /Executing puppet module install for puppetlabs.stdlib/ Scenario: Install duplicated dependencies from git and forge, last one wins Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" metadata mod 'puppetlabs-stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.6.0' """ And a file named "metadata.json" with: """ { "name": "random name", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 0" } ] } """ When I successfully run `librarian-puppet install --verbose` And the file "modules/stdlib/metadata.json" should match /"version": "4\.6\.0"/ And the output should not match /Executing puppet module install for puppetlabs.stdlib/ Scenario: Installing two modules with same name and using exclusions Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'librarian-duplicated_dependencies', :path => '../../features/examples/duplicated_dependencies' exclusion 'ripienaar-concat' """ When I successfully run `librarian-puppet install --verbose` And the file "modules/concat/metadata.json" should match /"name": "puppetlabs-concat"/ And the output should contain "Excluding dependency ripienaar-concat from" Scenario: Installing two modules with same name and using exclusions, apply transitively Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'librarian-duplicated_dependencies_transitive', :path => '../../features/examples/duplicated_dependencies_transitive' """ When PENDING I run `librarian-puppet install --verbose` Then the exit status should be 0 And the file "modules/concat/metadata.json" should match /"name": "puppetlabs-concat"/ Scenario: Install a module with the rsync configuration using the --clean flag Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'maestrodev/test' """ And a file named ".librarian/puppet/config" with: """ --- LIBRARIAN_PUPPET_RSYNC: 'true' """ When I successfully run `librarian-puppet config` And the output should contain "rsync: true" When I successfully run `librarian-puppet install` And a directory named "modules/test" should exist And the file "modules/test" should have an inode and ctime When I successfully run `librarian-puppet install --clean` And a directory named "modules/test" should exist And the file "modules/test" should not have the same inode or ctime as before Scenario: Install a module with the rsync configuration using the --destructive flag Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'maestrodev/test' """ And a file named ".librarian/puppet/config" with: """ --- LIBRARIAN_PUPPET_RSYNC: 'true' """ When I successfully run `librarian-puppet config` And the output should contain "rsync: true" When I successfully run `librarian-puppet install` And a directory named "modules/test" should exist And the file "modules/test" should have an inode and ctime Given I wait for 1 second When I successfully run `librarian-puppet install --destructive` And a directory named "modules/test" should exist And the file "modules/test" should not have the same inode or ctime as before Scenario: Install a module with the rsync configuration Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'maestrodev/test' """ And a file named ".librarian/puppet/config" with: """ --- LIBRARIAN_PUPPET_RSYNC: 'true' """ When I successfully run `librarian-puppet config` And the output should contain "rsync: true" When I successfully run `librarian-puppet install` And a directory named "modules/test" should exist And the file "modules/test" should have an inode and ctime Given I wait for 1 second When I successfully run `librarian-puppet install` And a directory named "modules/test" should exist And the file "modules/test" should have the same inode and ctime as before librarian-puppet-5.0.0/features/install/000077500000000000000000000000001443340236400202615ustar00rootroot00000000000000librarian-puppet-5.0.0/features/install/forge.feature000066400000000000000000000217451443340236400227510ustar00rootroot00000000000000Feature: cli/install/forge Puppet librarian needs to install modules from the Puppet Forge Scenario: Installing a module and its dependencies Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/ntp' """ When I successfully run `librarian-puppet install` And the file "modules/ntp/metadata.json" should match /"name": "puppetlabs-ntp"/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Running install with no Puppetfile and metadata.json Given there is no Puppetfile And a file named "metadata.json" with: """ { "name": "random name", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": "4.1.0" } ] } """ When I successfully run `librarian-puppet install` And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Installing a module without forge Given a file named "Puppetfile" with: """ mod 'puppetlabs/stdlib', '4.1.0' """ When I run `librarian-puppet install` Then the exit status should be 1 And the output should contain "forge entry is not defined in Puppetfile" Scenario: Installing an exact version of a module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apt', '0.0.4' """ When I successfully run `librarian-puppet install` And the file "modules/apt/Modulefile" should match /name *'puppetlabs-apt'/ And the file "modules/apt/Modulefile" should match /version *'0\.0\.4'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ # Puppet Module tool does not support spaces # https://github.com/rodjek/librarian-puppet/issues/201 # https://tickets.puppetlabs.com/browse/PUP-2278 @spaces Scenario: Installing a module in a path with spaces Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', '4.1.0' """ When PENDING I run `librarian-puppet install` Then the exit status should be 0 And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Installing a module with invalid versions in the forge Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apache', '7.0.0' # compatible with stdlib 8 mod 'puppetlabs/postgresql', '7.4.0' # incompatible with stdlib 8 """ # Default timeout is 15 seconds but this is too short in most cases When I successfully run `librarian-puppet install --verbose` for up to 30 seconds And the file "modules/apache/metadata.json" should match /"name": "puppetlabs-apache"/ And the file "modules/apache/metadata.json" should match /"version": "7\.0\.0"/ And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ And the file "modules/postgresql/metadata.json" should match /"version": "7\.4\.0"/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the file "modules/stdlib/metadata.json" should match /"version": "7\.1\.0"/ Scenario: Installing a module with several constraints Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apt', '>=1.0.0', '<1.0.1' """ When I successfully run `librarian-puppet install` And the file "modules/apt/Modulefile" should match /name *'puppetlabs-apt'/ And the file "modules/apt/Modulefile" should match /version *'1\.0\.0'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Changing the path Given a directory named "puppet" And a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/ntp', '3.0.3' """ When I run `librarian-puppet install --path puppet/modules` And I run `librarian-puppet config` Then the exit status should be 0 And the output from "librarian-puppet config" should contain "path: puppet/modules" And the file "puppet/modules/ntp/Modulefile" should match /name *'puppetlabs-ntp'/ And the file "puppet/modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Handle range version numbers Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/postgresql', '7.4.1' mod 'puppetlabs/apt', '< 8.4.0' """ When I successfully run `librarian-puppet install` And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ And the file "modules/postgresql/metadata.json" should match /"version": "7\.4\.1"/ And the file "modules/apt/metadata.json" should match /"name": "puppetlabs-apt"/ And the file "modules/apt/metadata.json" should match /"version": "8\.3\.0"/ Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/postgresql', :git => 'https://github.com/puppetlabs/puppet-postgresql', :ref => 'v7.5.0' """ When I successfully run `librarian-puppet install` And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ And the file "modules/postgresql/metadata.json" should match /"version": "7\.5\.0"/ And the file "modules/apt/metadata.json" should match /"name": "puppetlabs-apt"/ And the file "modules/apt/metadata.json" should not match /"version": "8\.3\.0"/ Scenario: Installing a module that does not exist Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/xxxxx' """ When I run `librarian-puppet install` Then the exit status should be 1 And the output should match: """ Unable to find module 'puppetlabs-xxxxx' on https://forgeapi.puppetlabs.com """ Scenario: Install a module with conflicts Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apache', '0.6.0' mod 'puppetlabs/stdlib', '<2.2.1' """ When I run `librarian-puppet install` Then the exit status should be 1 And the output should contain "Could not resolve the dependencies" Scenario: Install a module from the Forge with dependencies without version Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'sbadia/gitlab', '0.1.0' """ When I successfully run `librarian-puppet install` And the file "modules/gitlab/Modulefile" should match /version *'0\.1\.0'/ Scenario: Source dependencies from metadata.json Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" metadata """ And a file named "metadata.json" with: """ { "name": "random name", "dependencies": [ { "name": "puppetlabs/postgresql", "version_requirement": "4.0.0" } ] } """ When I successfully run `librarian-puppet install` And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ Scenario: Installing a module with duplicated dependencies Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'pdxcat/collectd', '2.1.0' """ When I successfully run `librarian-puppet install` And the file "modules/collectd/Modulefile" should match /name *'pdxcat-collectd'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Installing two modules with same name, alphabetical order wins Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'theforeman-dhcp', '4.0.0' mod 'puppet-dhcp', '2.0.0' """ When I successfully run `librarian-puppet install --verbose` And the file "modules/dhcp/metadata.json" should match /"name": "theforeman-dhcp"/ And the output should contain "Dependency on module 'dhcp' is fullfilled by multiple modules and only one will be used" @other-forge Scenario: Installing from another forge with local reference should not try to download anything from the official forge Given a file named "Puppetfile" with: """ forge "http://127.0.0.1:8080" mod 'tester/tester', :path => './tester-tester' """ And a file named "tester-tester/metadata.json" with: """ { "name": "tester-tester", "version": "0.1.0", "author": "Basilio Vera", "summary": "Just our own test", "license": "MIT", "dependencies": [ { "name": "puppetlabs/inifile" } ] } """ When I run `librarian-puppet install --verbose` And the output should not contain "puppetlabs.com" And the output should not contain "puppet.com" And the output should contain "Resolving puppetlabs-inifile (>= 0) " librarian-puppet-5.0.0/features/install/git.feature000066400000000000000000000162761443340236400224350ustar00rootroot00000000000000Feature: cli/install/git Puppet librarian needs to install modules from git repositories Scenario: Installing a module from git Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apache', :git => 'https://github.com/puppetlabs/puppetlabs-apache.git', :ref => '1.4.0' mod 'puppetlabs/stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.6.0' """ When I successfully run `librarian-puppet install` And the file "modules/apache/metadata.json" should match /"name": "puppetlabs-apache"/ And the file "modules/apache/metadata.json" should match /"version": "1\.4\.0"/ And the git revision of module "apache" should be "e4ec6d4985fdb23e26c809e0d5786823d0689f90" And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the file "modules/stdlib/metadata.json" should match /"version": "4\.6\.0"/ And the git revision of module "stdlib" should be "73474b00b5ae3cbccec6cd0711311d6450139e51" @spaces Scenario: Installing a module in a path with spaces Given a file named "Puppetfile" with: """ mod 'puppetlabs/stdlib', '4.6.0', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.6.0' """ When I successfully run `librarian-puppet install` And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Installing a module with invalid versions in git Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod "apache", :git => "https://github.com/puppetlabs/puppetlabs-apache.git", :ref => "1.4.0" """ When I successfully run `librarian-puppet install` And the file "modules/apache/metadata.json" should match /"name": "puppetlabs-apache"/ And the file "modules/apache/metadata.json" should match /"version": "1\.4\.0"/ Scenario: Switching a module from forge to git Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/postgresql', '7.4.1' """ When I successfully run `librarian-puppet install` And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ And the file "modules/postgresql/metadata.json" should match /"version": "7\.4\.1"/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ When I overwrite "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/postgresql', :git => 'https://github.com/puppetlabs/puppetlabs-postgresql.git', :ref => 'v7.5.0' """ And I run `librarian-puppet install` Then the exit status should be 0 And the file "modules/postgresql/metadata.json" should match /"name": "puppetlabs-postgresql"/ And the file "modules/postgresql/metadata.json" should match /"version": "7\.5\.0"/ And the file "modules/postgresql/.git/HEAD" should match /0a2cb69ccbbb0a55d42c5da33d44b0eaf33f9546/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ Scenario: Install a module with dependencies specified in metadata.json Given a file named "Puppetfile" with: """ mod 'puppetlabs-apt', :git => 'https://github.com/puppetlabs/puppetlabs-apt.git', :ref => '1.5.2' """ When I successfully run `librarian-puppet install` And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the file "modules/apt/metadata.json" should match /"name": "puppetlabs-apt"/ Scenario: Install a module with dependencies specified in a Puppetfile Given a file named "Puppetfile" with: """ mod 'librarian/with_puppetfile', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/with_puppetfile' """ When I successfully run `librarian-puppet install` And the file "modules/with_puppetfile/metadata.json" should match /"name": "librarian-with_puppetfile"/ And the file "modules/test/metadata.json" should match /"name": "librarian-test"/ Scenario: Install a module with dependencies specified in a Puppetfile and metadata.json Given a file named "Puppetfile" with: """ mod 'librarian/with_puppetfile', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/with_puppetfile_and_metadata_json' """ When I successfully run `librarian-puppet install` And the file "modules/with_puppetfile/metadata.json" should match /"name": "librarian-with_puppetfile_and_metadata_json"/ And the file "modules/test/metadata.json" should match /"name": "maestrodev-test"/ Scenario: Running install without metadata.json Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.6.0' """ When I successfully run `librarian-puppet install` Scenario: Running install with metadata.json without dependencies Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/sqlite', :git => 'https://github.com/puppetlabs/puppetlabs-sqlite.git', :ref => '84a0a6' """ When I successfully run `librarian-puppet install` Scenario: Install a module using metadata syntax Given a file named "Puppetfile" with: """ mod 'librarian/metadata_syntax', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/metadata_syntax' """ When I successfully run `librarian-puppet install` And the file "modules/metadata_syntax/metadata.json" should match /"name": "librarian-metadata_syntax"/ And the file "modules/test/metadata.json" should match /"name": "maestrodev-test"/ Scenario: Install a module from git and using path Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'librarian-test', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/test' """ When I successfully run `librarian-puppet install` And the file "modules/test/metadata.json" should match /"version": "0\.0\.1"/ And a file named "modules/stdlib/metadata.json" should exist Scenario: Install a module from git without version Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'test', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/dependency_without_version' """ When I successfully run `librarian-puppet install` And the file "modules/test/metadata.json" should match /"version": "0\.0\.1"/ And a file named "modules/stdlib/metadata.json" should exist Scenario: Install from Puppetfile with duplicated entries Given a file named "Puppetfile" with: """ mod 'puppetlabs-stdlib', :git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => 'main' mod 'puppetlabs-stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => 'main' """ When I successfully run `librarian-puppet install` And the output should contain "Dependency 'puppetlabs-stdlib' duplicated for module, merging" librarian-puppet-5.0.0/features/install/github_tarball.feature000066400000000000000000000026611443340236400246260ustar00rootroot00000000000000Feature: cli/install/github_tarball Puppet librarian needs to install tarballed modules from github repositories @github Scenario: Installing a module from github tarballs Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apache', '0.6.0', :github_tarball => 'puppetlabs/puppetlabs-apache' mod 'puppetlabs/stdlib', '2.3.0', :github_tarball => 'puppetlabs/puppetlabs-stdlib' """ When I successfully run `librarian-puppet install --verbose` And the output should contain "Downloading 'puppetlabs/puppetlabs-stdlib' """ When I successfully run `librarian-puppet install` And the file "modules/stdlib/Modulefile" should match /name *'puppetlabs-stdlib'/ librarian-puppet-5.0.0/features/install/path.feature000066400000000000000000000046631443340236400226030ustar00rootroot00000000000000Feature: cli/install/path Puppet librarian needs to install modules from local paths Scenario: Install a module with dependencies specified in a Puppetfile Given a file named "Puppetfile" with: """ mod 'librarian/with_puppetfile', :path => '../../features/examples/with_puppetfile' """ When I successfully run `librarian-puppet install` And the file "modules/with_puppetfile/metadata.json" should match /"name": "librarian-with_puppetfile"/ And the file "modules/test/metadata.json" should match /"name": "librarian-test"/ Scenario: Install a module with recursive path dependencies Given a file named "Puppetfile" with: """ mod 'librarian/path_dependencies', :path => '../../features/examples/path_dependencies' """ When I successfully run `librarian-puppet install` And the file "modules/path_dependencies/metadata.json" should match /"name": "librarian-path_dependencies"/ And the file "modules/test/metadata.json" should match /"name": "librarian-test"/ And a file named "modules/stdlib/metadata.json" should exist Scenario: Install a module with dependencies specified in a Puppetfile and metadata.json Given a file named "Puppetfile" with: """ mod 'librarian/with_puppetfile', :path => '../../features/examples/with_puppetfile_and_metadata_json' """ When I successfully run `librarian-puppet install` And the file "modules/with_puppetfile/metadata.json" should match /"name": "librarian-with_puppetfile_and_metadata_json"/ And the file "modules/test/metadata.json" should match /"name": "maestrodev-test"/ Scenario: Install a module from path without version Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'test', :path => '../../features/examples/dependency_without_version' """ When I successfully run `librarian-puppet install` And the file "modules/test/metadata.json" should match /"version": "0\.0\.1"/ And a file named "modules/stdlib/metadata.json" should exist @spaces Scenario: Installing a module in a path with spaces Given a file named "Puppetfile" with: """ mod 'librarian/test', :path => '../../features/examples/test' mod 'puppetlabs/stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib', :ref => 'main' """ When I successfully run `librarian-puppet install` And the file "modules/test/metadata.json" should match /"name": "librarian-test"/ librarian-puppet-5.0.0/features/outdated.feature000066400000000000000000000027611443340236400220070ustar00rootroot00000000000000Feature: cli/outdated Puppet librarian needs to print outdated modules Scenario: Running outdated with forge modules Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', '>=3.1.x' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) DEPENDENCIES puppetlabs/stdlib (~> 3.0) """ When I successfully run `librarian-puppet outdated` And the output should match: """ ^puppetlabs-stdlib \(3\.1\.0 -> [\.\d]+\)$ """ Scenario: Running outdated with git modules Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'test', :git => 'https://github.com/voxpupuli/librarian-puppet.git', :path => 'features/examples/test' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) GIT remote: https://github.com/voxpupuli/librarian-puppet.git path: features/examples/test ref: master sha: 10fdf98190a7a22e479628b3616f17f48a857e81 specs: test (0.0.1) puppetlabs/stdlib (>= 0) DEPENDENCIES test (>= 0) """ When I successfully run `librarian-puppet outdated` And PENDING the output should match: # """ # ^puppetlabs-stdlib \(3\.1\.0 -> [\.\d]+\)$ # ^test .*$ # """ librarian-puppet-5.0.0/features/package.feature000066400000000000000000000040571443340236400215710ustar00rootroot00000000000000Feature: cli/package Puppet librarian needs to package modules Scenario: Packaging a forge module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apt', '1.4.0' mod 'puppetlabs/stdlib', '4.1.0' """ When I successfully run `librarian-puppet package --verbose` And the file "modules/apt/Modulefile" should match /name *'puppetlabs-apt'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the following files should exist: | vendor/puppet/cache/puppetlabs-apt-1.4.0.tar.gz | | vendor/puppet/cache/puppetlabs-stdlib-4.1.0.tar.gz | Scenario: Packaging a git module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apt', '1.5.0', :git => 'https://github.com/puppetlabs/puppetlabs-apt.git', :ref => '1.5.0' mod 'puppetlabs/stdlib', '4.1.0' """ When I successfully run `librarian-puppet package --verbose` And the file "modules/apt/Modulefile" should match /name *'puppetlabs-apt'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the following files should exist: | vendor/puppet/source/e5657a61b9ac0dd3c00002c777b0d3c615bb98a5.tar.gz | | vendor/puppet/cache/puppetlabs-stdlib-4.1.0.tar.gz | @github Scenario: Packaging a github tarball module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/apt', '1.4.0', :github_tarball => 'puppetlabs/puppetlabs-apt' mod 'puppetlabs/stdlib', '4.1.0' """ When I successfully run `librarian-puppet package --verbose` And the file "modules/apt/Modulefile" should match /name *'puppetlabs-apt'/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the following files should exist: | vendor/puppet/cache/puppetlabs-puppetlabs-apt-1.4.0.tar.gz | | vendor/puppet/cache/puppetlabs-stdlib-4.1.0.tar.gz | librarian-puppet-5.0.0/features/step_definitions/000077500000000000000000000000001443340236400221615ustar00rootroot00000000000000librarian-puppet-5.0.0/features/step_definitions/convergence_steps.rb000066400000000000000000000024141443340236400262230ustar00rootroot00000000000000Then /^the file "([^"]*)" should have an inode and ctime$/ do |file| cd('.') do stat = File.stat(File.expand_path(file)) @before_inode = { 'ino' => stat.ino, 'ctime' => stat.ctime } expect(@before_inode['ino']).not_to eq nil expect(@before_inode['ctime']).not_to eq nil end end Then /^the file "([^"]*)" should have the same inode and ctime as before$/ do |file| cd('.') do stat = File.stat(File.expand_path(file)) expect(stat.ino).to eq @before_inode['ino'] expect(stat.ctime).to eq @before_inode['ctime'] end end Then /^the file "([^"]*)" should not have the same inode or ctime as before$/ do |file| cd('.') do stat = File.stat(File.expand_path(file)) begin expect(stat.ino).not_to eq @before_inode['ino'] rescue RSpec::Expectations::ExpectationNotMetError expect(stat.ctime).not_to eq @before_inode['ctime'] end end end Then /^the git revision of module "([^"]*)" should be "([0-9a-f]*)"$/ do |module_name, rev| cd("modules/#{module_name}") do cmd = "git rev-parse HEAD" run_command_and_stop(cmd) expect(last_command_started.output.strip).to eq(rev) end end Given /^I wait for (\d+) seconds?$/ do |n| sleep(n.to_i) end librarian-puppet-5.0.0/features/support/000077500000000000000000000000001443340236400203275ustar00rootroot00000000000000librarian-puppet-5.0.0/features/support/env.rb000066400000000000000000000006661443340236400214540ustar00rootroot00000000000000require 'aruba/cucumber' require 'fileutils' Before do @aruba_timeout_seconds = 120 end Before('@spaces') do @dirs = ["tmp/aruba with spaces"] @dirs.each {|dir| FileUtils.rm_rf dir} end Given /^PENDING/ do pending end Given(/^there is no Puppetfile$/) do in_current_directory do fail "Puppetfile exists at #{File.expand_path('Puppetfile')}" if (File.exist?('Puppetfile')) end end ENV['LIBRARIAN_PUPPET_TMP'] = '.tmp' librarian-puppet-5.0.0/features/update.feature000066400000000000000000000215531443340236400214600ustar00rootroot00000000000000Feature: cli/update Puppet librarian needs to update modules properly Scenario: Updating a module with no Puppetfile and with metadata.json Given a file named "metadata.json" with: """ { "name": "random name", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": "3.1.x" } ] } """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) DEPENDENCIES puppetlabs/stdlib (~> 3.0) """ When I successfully run `librarian-puppet update puppetlabs/stdlib` And the file "Puppetfile" should not exist And the file "Puppetfile.lock" should match /puppetlabs.stdlib \(3\.1\.1\)/ And the file "modules/stdlib/Modulefile" should match /name *'puppetlabs-stdlib'/ And the file "modules/stdlib/Modulefile" should match /version *'3\.1\.1'/ Scenario: Updating a module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', '3.1.x' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) DEPENDENCIES puppetlabs/stdlib (~> 3.0) """ When I successfully run `librarian-puppet update puppetlabs-stdlib` And the file "Puppetfile.lock" should match /puppetlabs.stdlib \(3\.1\.1\)/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the file "modules/stdlib/Modulefile" should match /version *'3\.1\.1'/ Scenario: Updating a module using organization/module Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', '3.1.x' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) DEPENDENCIES puppetlabs/stdlib (~> 3.0) """ When I successfully run `librarian-puppet update --verbose puppetlabs/stdlib` And the file "Puppetfile.lock" should match /puppetlabs.stdlib \(3\.1\.1\)/ And the file "modules/stdlib/metadata.json" should match /"name": "puppetlabs-stdlib"/ And the file "modules/stdlib/Modulefile" should match /version *'3\.1\.1'/ Scenario: Updating a module from git with a branch ref Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod "theforeman-dns", :git => "https://github.com/theforeman/puppet-dns.git", :ref => "4.1-stable" """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs-concat (2.2.1) puppetlabs-stdlib (>= 4.2.0, < 5.0.0) puppetlabs-stdlib (4.25.1) GIT remote: https://github.com/theforeman/puppet-dns.git ref: 4.1-stable sha: 29150008f81c0be6de4d8913f60b9e014c3f398e specs: theforeman-dns (4.1.0) puppetlabs-concat (>= 1.0.0, < 3.0.0) puppetlabs-stdlib (>= 4.13.1, < 5.0.0) DEPENDENCIES theforeman-dns (>= 0) """ When I successfully run `librarian-puppet install` And the git revision of module "dns" should be "29150008f81c0be6de4d8913f60b9e014c3f398e" When I successfully run `librarian-puppet update` And the git revision of module "dns" should be "e530ae8b1f0d85b37a69e779d1de51d054ecc9f1" Scenario: Updating a module with invalid versions in git Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod "apache", :git => "https://github.com/puppetlabs/puppetlabs-apache.git", :ref => "0.5.0-rc1" """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/firewall (0.0.4) puppetlabs/stdlib (3.2.0) GIT remote: https://github.com/puppetlabs/puppetlabs-apache.git ref: 0.5.0-rc1 sha: 94ebca3aaaf2144a7b9ce7ca6a13837ec48a7e2a specs: apache () puppetlabs/firewall (>= 0.0.4) puppetlabs/stdlib (>= 2.2.1) DEPENDENCIES apache (>= 0) """ When I successfully run `librarian-puppet update apache` And the file "Puppetfile.lock" should match /sha: d81999533af54a6fe510575d3b143308184a5005/ And the file "modules/apache/Modulefile" should match /name *'puppetlabs-apache'/ And the file "modules/apache/Modulefile" should match /version *'0\.5\.0-rc1'/ Scenario: Updating a module that is not in the Puppetfile Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'puppetlabs/stdlib', '3.1.x' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs/stdlib (3.1.0) DEPENDENCIES puppetlabs/stdlib (~> 3.0) """ When I run `librarian-puppet update stdlib` Then the exit status should be 1 And the output should contain "Unable to find module stdlib" Scenario: Updating a module to a .10 release to ensure versions are correctly ordered Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'maestrodev/test' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: maestrodev/test (1.0.2) DEPENDENCIES maestrodev/test (>= 0) """ When I successfully run `librarian-puppet update --verbose` And the file "Puppetfile.lock" should match /maestrodev.test \(1\.0\.[1-9][0-9]\)/ And the file "modules/test/Modulefile" should contain "name 'maestrodev-test'" And the file "modules/test/Modulefile" should match /version '1\.0\.[1-9][0-9]'/ Scenario: Updating a forge module with the rsync configuration Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod 'maestrodev/test' """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: maestrodev/test (1.0.2) DEPENDENCIES maestrodev/test (>= 0) """ And a file named ".librarian/puppet/config" with: """ --- LIBRARIAN_PUPPET_RSYNC: 'true' """ When I successfully run `librarian-puppet config` And the output should contain "rsync: true" When I successfully run `librarian-puppet update --verbose` And a directory named "modules/test" should exist And the file "modules/test" should have an inode and ctime When I successfully run `librarian-puppet update --verbose` And a directory named "modules/test" should exist And the file "modules/test" should have the same inode and ctime as before Scenario: Updating a git module with the rsync configuration Given a file named "Puppetfile" with: """ forge "https://forgeapi.puppetlabs.com" mod "theforeman-dns", :git => "https://github.com/theforeman/puppet-dns.git", :ref => "4.1-stable" """ And a file named "Puppetfile.lock" with: """ FORGE remote: https://forgeapi.puppetlabs.com specs: puppetlabs-concat (2.2.1) puppetlabs-stdlib (>= 4.2.0, < 5.0.0) puppetlabs-stdlib (4.25.1) GIT remote: https://github.com/theforeman/puppet-dns.git ref: 4.1-stable sha: 29150008f81c0be6de4d8913f60b9e014c3f398e specs: theforeman-dns (4.1.0) puppetlabs-concat (>= 1.0.0, < 3.0.0) puppetlabs-stdlib (>= 4.13.1, < 5.0.0) DEPENDENCIES theforeman-dns (>= 0) """ And a file named ".librarian/puppet/config" with: """ --- LIBRARIAN_PUPPET_RSYNC: 'true' """ When I successfully run `librarian-puppet config` And the output should contain "rsync: true" When I successfully run `librarian-puppet install` And the file "Puppetfile.lock" should contain "29150008f81c0be6de4d8913f60b9e014c3f398e" And the git revision of module "dns" should be "29150008f81c0be6de4d8913f60b9e014c3f398e" And a directory named "modules/dns" should exist When I successfully run `librarian-puppet update --verbose` And a directory named "modules/dns" should exist And the file "modules/dns" should have an inode and ctime And the file "Puppetfile.lock" should contain "e530ae8b1f0d85b37a69e779d1de51d054ecc9f1" And the git revision of module "dns" should be "e530ae8b1f0d85b37a69e779d1de51d054ecc9f1" When I successfully run `librarian-puppet update --verbose` And a directory named "modules/dns" should exist And the file "modules/dns" should have the same inode and ctime as before And the file "Puppetfile.lock" should contain "e530ae8b1f0d85b37a69e779d1de51d054ecc9f1" And the git revision of module "dns" should be "e530ae8b1f0d85b37a69e779d1de51d054ecc9f1" librarian-puppet-5.0.0/features/version.feature000066400000000000000000000002341443340236400216540ustar00rootroot00000000000000Feature: cli/version Scenario: Getting the version When I successfully run `librarian-puppet version` And the output should contain "librarian-" librarian-puppet-5.0.0/lib/000077500000000000000000000000001443340236400155435ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/000077500000000000000000000000001443340236400175065ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet.rb000066400000000000000000000003011443340236400213420ustar00rootroot00000000000000require 'librarian' require 'fileutils' require 'librarian/puppet/extension' require 'librarian/puppet/version' require 'librarian/action/install' module Librarian module Puppet end end librarian-puppet-5.0.0/lib/librarian/puppet/000077500000000000000000000000001443340236400210235ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/action.rb000066400000000000000000000001241443340236400226220ustar00rootroot00000000000000require "librarian/puppet/action/install" require "librarian/puppet/action/resolve" librarian-puppet-5.0.0/lib/librarian/puppet/action/000077500000000000000000000000001443340236400223005ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/action/install.rb000066400000000000000000000010411443340236400242670ustar00rootroot00000000000000require 'librarian/action/install' module Librarian module Puppet module Action class Install < Librarian::Action::Install private def create_install_path install_path.rmtree if install_path.exist? && destructive? install_path.mkpath end def destructive? environment.config_db.local['destructive'] == 'true' end def check_specfile # don't fail if Puppetfile doesn't exist as we'll use metadata.json end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/action/resolve.rb000066400000000000000000000012641443340236400243070ustar00rootroot00000000000000require 'librarian/action/resolve' require 'librarian/puppet/resolver' module Librarian module Puppet module Action class Resolve < Librarian::Action::Resolve include Librarian::Puppet::Util def run super manifests = environment.lock.manifests.select{ |m| m.name } dupes = manifests.group_by{ |m| module_name(m.name) }.select { |k, v| v.size > 1 } dupes.each do |k,v| warn("Dependency on module '#{k}' is fullfilled by multiple modules and only one will be used: #{v.map{|m|m.name}}") end end def resolver Resolver.new(environment) end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/cli.rb000066400000000000000000000072611443340236400221250ustar00rootroot00000000000000require 'librarian/helpers' require 'librarian/cli' require 'librarian/puppet' require 'librarian/puppet/action' module Librarian module Puppet class Cli < Librarian::Cli include Librarian::Puppet::Util module Particularity def root_module Puppet end end include Particularity extend Particularity source_root Pathname.new(__FILE__).dirname.join("templates") def init copy_file environment.specfile_name if File.exist? ".gitignore" gitignore = File.read('.gitignore').split("\n") else gitignore = [] end gitignore << ".tmp/" unless gitignore.include? ".tmp/" gitignore << "modules/" unless gitignore.include? "modules/" File.open(".gitignore", 'w') do |f| f.puts gitignore.join("\n") end end desc "install", "Resolves and installs all of the dependencies you specify." option "quiet", :type => :boolean, :default => false option "verbose", :type => :boolean, :default => false option "line-numbers", :type => :boolean, :default => false option "clean", :type => :boolean, :default => false option "strip-dot-git", :type => :boolean option "path", :type => :string option "destructive", :type => :boolean, :default => false option "local", :type => :boolean, :default => false option "use-v1-api", :type => :boolean, :default => false def install ensure! clean! if options["clean"] unless options["destructive"].nil? environment.config_db.local['destructive'] = options['destructive'].to_s end if options.include?("strip-dot-git") strip_dot_git_val = options["strip-dot-git"] ? "1" : nil environment.config_db.local["install.strip-dot-git"] = strip_dot_git_val end if options.include?("path") environment.config_db.local["path"] = options["path"] end environment.config_db.local['use-v1-api'] = options['use-v1-api'] ? '1' : nil environment.config_db.local['mode'] = options['local'] ? 'local' : nil resolve! debug { "Install: dependencies resolved"} install! end desc "update", "Updates and installs the dependencies you specify." option "verbose", :type => :boolean, :default => false option "line-numbers", :type => :boolean, :default => false option "use-v1-api", :type => :boolean, :default => false def update(*names) environment.config_db.local['use-v1-api'] = options['use-v1-api'] ? '1' : nil warn("Usage of module/name is deprecated, use module-name") if names.any? {|n| n.include?("/")} # replace / to - in the module names super(*names.map{|n| normalize_name(n)}) end desc "package", "Cache the puppet modules in vendor/puppet/cache." option "quiet", :type => :boolean, :default => false option "verbose", :type => :boolean, :default => false option "line-numbers", :type => :boolean, :default => false option "clean", :type => :boolean, :default => false option "strip-dot-git", :type => :boolean option "path", :type => :string option "destructive", :type => :boolean, :default => false def package environment.vendor! install end def version say "librarian-puppet v#{Librarian::Puppet::VERSION}" end private # override the actions to use our own def install!(options = { }) Action::Install.new(environment, options).run end def resolve!(options = { }) Action::Resolve.new(environment, options).run end end end end librarian-puppet-5.0.0/lib/librarian/puppet/dependency.rb000066400000000000000000000011701443340236400234650ustar00rootroot00000000000000module Librarian module Puppet class Dependency < Librarian::Dependency include Librarian::Puppet::Util attr_accessor :parent private :parent= def initialize(name, requirement, source, parent = nil) # Issue #235 fail if forge source is not defined raise Error, "forge entry is not defined in Puppetfile" if source.instance_of?(Array) && source.empty? self.parent = parent super(normalize_name(name), requirement, source) end def to_s "#{name} (#{requirement}) <#{source}> (from #{parent.nil? ? '' : parent})" end end end end librarian-puppet-5.0.0/lib/librarian/puppet/dsl.rb000066400000000000000000000057541443340236400221450ustar00rootroot00000000000000require 'librarian/dsl' require 'librarian/dsl/target' require 'librarian/puppet/source' require 'librarian/puppet/dependency' module Librarian module Puppet class Dsl < Librarian::Dsl FORGE_URL = "https://forgeapi.puppetlabs.com" dependency :mod source :forge => Source::Forge source :git => Source::Git source :path => Source::Path source :github_tarball => Source::GitHubTarball def default_specfile Proc.new do forge FORGE_URL metadata end end def self.dependency_type Librarian::Puppet::Dependency end def post_process_target(target) # save the default forge defined default_forge = target.sources.select {|s| s.is_a? Librarian::Puppet::Source::Forge}.first Librarian::Puppet::Source::Forge.default = default_forge || Librarian::Puppet::Source::Forge.from_lock_options(environment, :remote => FORGE_URL) end def receiver(target) Receiver.new(target) end def run(specfile = nil, sources = []) specfile, sources = nil, specfile if specfile.kind_of?(Array) && sources.empty? Target.new(self).tap do |target| target.precache_sources(sources) debug_named_source_cache("Pre-Cached Sources", target) specfile ||= Proc.new if block_given? if specfile.kind_of?(Pathname) and !File.exist?(specfile) debug { "Specfile #{specfile} not found, using defaults" } unless specfile.nil? receiver(target).run(specfile, &default_specfile) else receiver(target).run(specfile) end post_process_target(target) debug_named_source_cache("Post-Cached Sources", target) end.to_spec end class Target < Librarian::Dsl::Target def dependency(name, *args) options = args.last.is_a?(Hash) ? args.pop : {} source = source_from_options(options) || @source dep = dependency_type.new(name, args, source, 'Puppetfile') @dependencies << dep end end class Receiver < Librarian::Dsl::Receiver attr_reader :specfile, :working_path # save the specfile and call librarian def run(specfile = nil) @working_path = specfile.kind_of?(Pathname) ? specfile.parent : Pathname.new(Dir.pwd) @specfile = specfile super end # implement the 'metadata' syntax for Puppetfile def metadata f = working_path.join('metadata.json') unless File.exist?(f) raise Error, "Metadata file does not exist: #{f}" end begin json = JSON.parse(File.read(f)) rescue JSON::ParserError => e raise Error, "Unable to parse json file #{f}: #{e}" end dependencyList = json['dependencies'] dependencyList.each do |d| mod(d['name'], d['version_requirement']) end end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/environment.rb000066400000000000000000000022401443340236400237120ustar00rootroot00000000000000require "librarian/environment" require "librarian/puppet/dsl" require "librarian/puppet/source" require "librarian/puppet/lockfile" module Librarian module Puppet class Environment < Librarian::Environment def adapter_name "puppet" end def lockfile Lockfile.new(self, lockfile_path) end def ephemeral_lockfile Lockfile.new(self, nil) end def tmp_path part = config_db["tmp"] || ".tmp" project_path.join(part) end def install_path part = config_db["path"] || "modules" project_path.join(part) end def vendor_path project_path.join('vendor/puppet') end def vendor_cache vendor_path.join('cache') end def vendor_source vendor_path.join('source') end def vendor! vendor_cache.mkpath unless vendor_cache.exist? vendor_source.mkpath unless vendor_source.exist? end def vendor? vendor_path.exist? end def local? config_db['mode'] == 'local' end def use_v1_api config_db['use-v1-api'] end end end end librarian-puppet-5.0.0/lib/librarian/puppet/extension.rb000066400000000000000000000002301443340236400233570ustar00rootroot00000000000000require 'librarian/puppet/environment' require 'librarian/action/base' module Librarian module Puppet extend self extend Librarian end end librarian-puppet-5.0.0/lib/librarian/puppet/lockfile.rb000066400000000000000000000053111443340236400231400ustar00rootroot00000000000000# Extend Lockfile to normalize module names from acme/mod to acme-mod module Librarian module Puppet class Lockfile < Librarian::Lockfile # Extend the parser to normalize module names in old .lock files, converting / to - class Parser < Librarian::Lockfile::Parser include Librarian::Puppet::Util def extract_and_parse_sources(lines) sources = super sources.each do |source| source[:manifests] = Hash[source[:manifests].map do |name,manifest| [normalize_name(name), manifest] end] end sources end def extract_and_parse_dependencies(lines, manifests_index) # when looking up in manifests_index normalize the name beforehand class << manifests_index include Librarian::Puppet::Util alias_method :old_lookup, :[] define_method(:[]) { |k| self.old_lookup(normalize_name(k)) } end dependencies = [] while lines.first =~ /^ {2}([\w\-\/]+)(?: \((.*)\))?$/ lines.shift name, requirement = $1, $2.split(/,\s*/) dependencies << environment.dsl_class.dependency_type.new(name, requirement, manifests_index[name].source, 'lockfile') end dependencies end def compile_placeholder_manifests(sources_ast) manifests = {} sources_ast.each do |source_ast| source_type = source_ast[:type] source = source_type.from_lock_options(environment, source_ast[:options]) source_ast[:manifests].each do |manifest_name, manifest_ast| manifests[manifest_name] = ManifestPlaceholder.new( source, manifest_name, manifest_ast[:version], manifest_ast[:dependencies].map do |k, v| environment.dsl_class.dependency_type.new(k, v, nil, manifest_name) end ) end end manifests end def compile(sources_ast) manifests = compile_placeholder_manifests(sources_ast) manifests = manifests.map do |name, manifest| dependencies = manifest.dependencies.map do |d| environment.dsl_class.dependency_type.new(d.name, d.requirement, manifests[d.name].source, name) end real = Manifest.new(manifest.source, manifest.name) real.version = manifest.version real.dependencies = manifest.dependencies real end ManifestSet.sort(manifests) end end def load(string) Parser.new(environment).parse(string) end end end end librarian-puppet-5.0.0/lib/librarian/puppet/resolver.rb000066400000000000000000000011061443340236400232070ustar00rootroot00000000000000require 'librarian/resolver' module Librarian module Puppet class Resolver < Librarian::Resolver class Implementation < Librarian::Resolver::Implementation def sourced_dependency_for(dependency) return dependency if dependency.source source = dependency_source_map[dependency.name] || default_source dependency.class.new(dependency.name, dependency.requirement, source, dependency.parent) end end def implementation(spec) Implementation.new(self, spec, :cyclic => cyclic) end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source.rb000066400000000000000000000002451443340236400226510ustar00rootroot00000000000000require 'librarian/puppet/source/path' require 'librarian/puppet/source/git' require 'librarian/puppet/source/forge' require 'librarian/puppet/source/githubtarball' librarian-puppet-5.0.0/lib/librarian/puppet/source/000077500000000000000000000000001443340236400223235ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/source/forge.rb000066400000000000000000000072171443340236400237610ustar00rootroot00000000000000require 'uri' require 'librarian/puppet/util' require 'librarian/puppet/source/forge/repo_v1' require 'librarian/puppet/source/forge/repo_v3' module Librarian module Puppet module Source class Forge include Librarian::Puppet::Util class << self LOCK_NAME = 'FORGE' def default=(source) @@default = source end def default @@default end def lock_name LOCK_NAME end def from_lock_options(environment, options) new(environment, options[:remote], options.reject { |k, v| k == :remote }) end def from_spec_args(environment, uri, options) recognised_options = [] unrecognised_options = options.keys - recognised_options unless unrecognised_options.empty? raise Error, "unrecognised options: #{unrecognised_options.join(", ")}" end new(environment, uri, options) end end attr_accessor :environment private :environment= attr_reader :uri def initialize(environment, uri, options = {}) self.environment = environment @uri = URI::parse(uri) @cache_path = nil end def to_s clean_uri(uri).to_s end def ==(other) other && self.class == other.class && self.uri == other.uri end alias :eql? :== def hash self.to_s.hash end def to_spec_args [clean_uri(uri).to_s, {}] end def to_lock_options {:remote => uri.to_s} end def pinned? false end def unpin! end def install!(manifest) manifest.source == self or raise ArgumentError debug { "Installing #{manifest}" } name = manifest.name version = manifest.version install_path = install_path(name) repo = repo(name) repo.install_version! version, install_path end def manifest(name, version, dependencies) manifest = Manifest.new(self, name) manifest.version = version manifest.dependencies = dependencies manifest end def cache_path @cache_path ||= begin dir = "#{uri.host}#{uri.path}".gsub(/[^0-9a-z\-_]/i, '_') environment.cache_path.join("source/puppet/forge/#{dir}") end end def install_path(name) environment.install_path.join(module_name(name)) end def fetch_version(name, version_uri) versions = repo(name).versions if versions.include? version_uri version_uri else versions.first end end def fetch_dependencies(name, version, version_uri) repo(name).dependencies(version).map do |k, v| v = Librarian::Dependency::Requirement.new(v).to_gem_requirement Dependency.new(k, v, nil, name) end end def manifests(name) repo(name).manifests end private def repo(name) @repo ||= {} unless @repo[name] # If we are using the official Forge then use API v3, otherwise use the preferred api # as defined by the CLI option use_v1_api if !environment.use_v1_api @repo[name] = RepoV3.new(self, name) else @repo[name] = RepoV1.new(self, name) end end @repo[name] end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/forge/000077500000000000000000000000001443340236400234255ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/source/forge/repo.rb000066400000000000000000000077631443340236400247340ustar00rootroot00000000000000require 'json' require 'open-uri' require 'librarian/puppet/util' require 'librarian/puppet/source/repo' module Librarian module Puppet module Source class Forge class Repo < Librarian::Puppet::Source::Repo include Librarian::Puppet::Util def versions return @versions if @versions @versions = get_versions if @versions.empty? info { "No versions found for module #{name}" } else debug { " Module #{name} found versions: #{@versions.join(", ")}" } end @versions end # fetch list of versions ordered for newer to older def get_versions # implement in subclasses end # return map with dependencies in the form {module_name => version,...} # version: Librarian::Manifest::Version def dependencies(version) # implement in subclasses end # return the url for a specific version tarball # version: Librarian::Manifest::Version def url(name, version) # implement in subclasses end def manifests versions.map do |version| Manifest.new(source, name, version) end end def install_version!(version, install_path) if environment.local? && !vendored?(name, version) raise Error, "Could not find a local copy of #{name} at #{version}." end if environment.vendor? vendor_cache(name, version) unless vendored?(name, version) end cache_version_unpacked! version if install_path.exist? && rsync? != true install_path.rmtree end unpacked_path = version_unpacked_cache_path(version).join(module_name(name)) unless unpacked_path.exist? raise Error, "#{unpacked_path} does not exist, something went wrong. Try removing it manually" else cp_r(unpacked_path, install_path) end end def cache_version_unpacked!(version) path = version_unpacked_cache_path(version) return if path.directory? path.mkpath target = vendored?(name, version) ? vendored_path(name, version).to_s : name module_repository = source.uri.to_s command = %W{puppet module install --version #{version} --target-dir} command.push(*[path.to_s, "--module_repository", module_repository, "--modulepath", path.to_s, "--module_working_dir", path.to_s, "--ignore-dependencies", target]) debug { "Executing puppet module install for #{name} #{version}: #{command.join(" ").gsub(module_repository, source.to_s)}" } begin Librarian::Posix.run!(command) rescue Posix::CommandFailure => e # Rollback the directory if the puppet module had an error begin path.unlink rescue => u debug("Unable to rollback path #{path}: #{u}") end tar = Dir[File.join(path.to_s, "**/*.tar.gz")] msg = "" if e.message =~ /Unexpected EOF in archive/ and !tar.empty? file = tar.first msg = " (looks like an incomplete download of #{file})" end raise Error, "Error executing puppet module install#{msg}. Check that this command succeeds:\n#{command.join(" ")}\nError:\n#{e.message}" end end def vendor_cache(name, version) url = url(name, version) path = vendored_path(name, version).to_s debug { "Downloading #{url} into #{path}"} environment.vendor! File.open(path, 'wb') do |f| URI.open(url, 'rb') do |input| f.write(input.read) end end end end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/forge/repo_v1.rb000066400000000000000000000065621443340236400253360ustar00rootroot00000000000000require 'json' require 'open-uri' require 'librarian/puppet/source/forge/repo' module Librarian module Puppet module Source class Forge class RepoV1 < Librarian::Puppet::Source::Forge::Repo def initialize(source, name) super(source, name) # API returned data for this module including all versions and dependencies, indexed by module name # from https://forge.puppetlabs.com/api/v1/releases.json?module=#{name} @api_data = nil # API returned data for this module and a specific version, indexed by version # from https://forge.puppetlabs.com/api/v1/releases.json?module=#{name}&version=#{version} @api_version_data = {} end def get_versions api_data(name).map { |r| r['version'] }.reverse end def dependencies(version) api_version_data(name, version)['dependencies'] end def url(name, version) info = api_version_data(name, version) "#{source}#{info[name].first['file']}" end private # convert organization/modulename to organization-modulename def normalize_dependencies(data) return nil if data.nil? # convert organization/modulename to organization-modulename data.keys.each do |m| if m =~ %r{.*/.*} data[normalize_name(m)] = data[m] data.delete(m) end end data end # get and cache the API data for a specific module with all its versions and dependencies def api_data(module_name) return @api_data[module_name] if @api_data # call API and cache data @api_data = normalize_dependencies(api_call(module_name)) if @api_data.nil? raise Error, "Unable to find module '#{name}' on #{source}" end @api_data[module_name] end # get and cache the API data for a specific module and version def api_version_data(module_name, version) # if we already got all the versions, find in cached data return @api_data[module_name].detect{|x| x['version'] == version.to_s} if @api_data # otherwise call the api for this version if not cached already @api_version_data[version] = normalize_dependencies(api_call(name, version)) if @api_version_data[version].nil? @api_version_data[version] end def api_call(module_name, version=nil) url = source.uri.clone url.path += "#{'/' if url.path.empty? or url.path[-1] != '/'}api/v1/releases.json" url.query = "module=#{module_name.sub('-','/')}" # v1 API expects "organization/module" url.query += "&version=#{version}" unless version.nil? debug { "Querying Forge API for module #{name}#{" and version #{version}" unless version.nil?}: #{url}" } begin data = URI.open(url) {|f| f.read} JSON.parse(data) rescue OpenURI::HTTPError => e case e.io.status[0].to_i when 404,410 nil else raise e, "Error requesting #{url}: #{e.to_s}" end end end end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/forge/repo_v3.rb000066400000000000000000000036771443340236400253440ustar00rootroot00000000000000require 'librarian/puppet/source/forge/repo' require 'puppet_forge' require 'librarian/puppet/version' module Librarian module Puppet module Source class Forge class RepoV3 < Librarian::Puppet::Source::Forge::Repo PuppetForge.user_agent = "librarian-puppet/#{Librarian::Puppet::VERSION}" def initialize(source, name) PuppetForge.host = source.uri.clone super(source, name) end def get_versions get_module.releases.select{|r| r.deleted_at.nil?}.map{|r| r.version} end def dependencies(version) array = get_release(version).metadata[:dependencies].map{|d| [d[:name], d[:version_requirement]]} Hash[*array.flatten(1)] end def url(name, version) if name == "#{get_module().owner.username}/#{get_module().name}" release = get_release(version) else # should never get here as we use one repo object for each module (to be changed in the future) debug { "Looking up url for #{name}@#{version}" } release = PuppetForge::V3::Release.find("#{name}-#{version}") end "#{source}#{release.file_uri}" end private def get_module begin @module ||= PuppetForge::V3::Module.find(name) rescue Faraday::ResourceNotFound => e raise(Error, "Unable to find module '#{name}' on #{source}") end @module end def get_release(version) release = get_module.releases.find{|r| r.version == version.to_s} if release.nil? versions = get_module.releases.map{|r| r.version} raise Error, "Unable to find version '#{version}' for module '#{name}' on #{source} amongst #{versions}" end release end end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/git.rb000066400000000000000000000035601443340236400234370ustar00rootroot00000000000000require 'librarian/source/git' require 'librarian/puppet/source/local' module Librarian module Source class Git class Repository def hash_from(remote, reference) branch_names = remote_branch_names[remote] if branch_names.include?(reference) reference = "#{remote}/#{reference}" end command = %W(rev-parse #{reference}^{commit} --quiet) run!(command, :chdir => true).strip end end end end module Puppet module Source class Git < Librarian::Source::Git include Local include Librarian::Puppet::Util def cache! return vendor_checkout! if vendor_cached? if environment.local? raise Error, "Could not find a local copy of #{uri}#{" at #{sha}" unless sha.nil?}." end begin super rescue Librarian::Posix::CommandFailure => e raise Error, "Could not checkout #{uri}#{" at #{sha}" unless sha.nil?}: #{e}" end cache_in_vendor(repository.path) if environment.vendor? end private def vendor_tar environment.vendor_source.join("#{sha}.tar") end def vendor_tgz environment.vendor_source.join("#{sha}.tar.gz") end def vendor_cached? vendor_tgz.exist? end def vendor_checkout! repository.path.rmtree if repository.path.exist? repository.path.mkpath Librarian::Posix.run!(%W{tar xzf #{vendor_tgz}}, :chdir => repository.path.to_s) repository_cached! end def cache_in_vendor(tmp_path) Librarian::Posix.run!(%W{git archive -o #{vendor_tar} #{sha}}, :chdir => tmp_path.to_s) Librarian::Posix.run!(%W{gzip #{vendor_tar}}, :chdir => tmp_path.to_s) end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/githubtarball.rb000066400000000000000000000056731443340236400255070ustar00rootroot00000000000000require 'uri' require 'librarian/puppet/util' require 'librarian/puppet/source/githubtarball/repo' module Librarian module Puppet module Source class GitHubTarball include Librarian::Puppet::Util class << self LOCK_NAME = 'GITHUBTARBALL' def lock_name LOCK_NAME end def from_lock_options(environment, options) new(environment, options[:remote], options.reject { |k, v| k == :remote }) end def from_spec_args(environment, uri, options) recognised_options = [] unrecognised_options = options.keys - recognised_options unless unrecognised_options.empty? raise Error, "unrecognised options: #{unrecognised_options.join(", ")}" end new(environment, uri, options) end end attr_accessor :environment private :environment= attr_reader :uri def initialize(environment, uri, options = {}) self.environment = environment @uri = URI::parse(uri) @cache_path = nil end def to_s clean_uri(uri).to_s end def ==(other) other && self.class == other.class && self.uri == other.uri end alias :eql? :== def hash self.to_s.hash end def to_spec_args [clean_uri(uri).to_s, {}] end def to_lock_options {:remote => clean_uri(uri).to_s} end def pinned? false end def unpin! end def install!(manifest) manifest.source == self or raise ArgumentError debug { "Installing #{manifest}" } name = manifest.name version = manifest.version install_path = install_path(name) repo = repo(name) repo.install_version! version, install_path end def manifest(name, version, dependencies) manifest = Manifest.new(self, name) manifest.version = version manifest.dependencies = dependencies manifest end def cache_path @cache_path ||= begin environment.cache_path.join("source/puppet/githubtarball/#{uri.host}#{uri.path}") end end def install_path(name) environment.install_path.join(module_name(name)) end def fetch_version(name, version_uri) versions = repo(name).versions if versions.include? version_uri version_uri else versions.first end end def fetch_dependencies(name, version, version_uri) {} end def manifests(name) repo(name).manifests end private def repo(name) @repo ||= {} @repo[name] ||= Repo.new(self, name) end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/githubtarball/000077500000000000000000000000001443340236400251475ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/source/githubtarball/repo.rb000066400000000000000000000127721443340236400264520ustar00rootroot00000000000000require 'uri' require 'net/https' require 'open-uri' require 'json' require 'librarian/puppet/version' require 'librarian/puppet/source/repo' module Librarian module Puppet module Source class GitHubTarball class Repo < Librarian::Puppet::Source::Repo include Librarian::Puppet::Util TOKEN_KEY = 'GITHUB_API_TOKEN' def versions return @versions if @versions data = api_call("/repos/#{source.uri}/tags") if data.nil? raise Error, "Unable to find module '#{source.uri}' on https://github.com" end all_versions = data.map { |r| r['name'].gsub(/^v/, '') }.sort.reverse all_versions.delete_if do |version| version !~ /\A\d+\.\d+(\.\d+.*)?\z/ end @versions = all_versions.compact debug { " Module #{name} found versions: #{@versions.join(", ")}" } @versions end def manifests versions.map do |version| Manifest.new(source, name, version) end end def install_version!(version, install_path) if environment.local? && !vendored?(vendored_name, version) raise Error, "Could not find a local copy of #{source.uri} at #{version}." end vendor_cache(source.uri.to_s, version) unless vendored?(vendored_name, version) cache_version_unpacked! version if install_path.exist? && rsync? != true install_path.rmtree end unpacked_path = version_unpacked_cache_path(version).children.first cp_r(unpacked_path, install_path) end def cache_version_unpacked!(version) path = version_unpacked_cache_path(version) return if path.directory? path.mkpath target = vendored?(vendored_name, version) ? vendored_path(vendored_name, version) : name Librarian::Posix.run!(%W{tar xzf #{target} -C #{path}}) end def vendor_cache(name, version) clean_up_old_cached_versions(vendored_name(name)) url = "https://api.github.com/repos/#{name}/tarball/#{version}" add_api_token_to_url(url) environment.vendor! File.open(vendored_path(vendored_name(name), version).to_s, 'wb') do |f| begin debug { "Downloading <#{url}> to <#{f.path}>" } URI.open(url, "User-Agent" => "librarian-puppet v#{Librarian::Puppet::VERSION}") do |res| while buffer = res.read(8192) f.write(buffer) end end rescue OpenURI::HTTPError => e raise e, "Error requesting <#{url}>: #{e.to_s}" end end end def clean_up_old_cached_versions(name) Dir["#{environment.vendor_cache}/#{name}*.tar.gz"].each do |old_version| FileUtils.rm old_version end end def token_key_value ENV[TOKEN_KEY] end def token_key_nil? token_key_value.nil? || token_key_value.empty? end def add_api_token_to_url url if token_key_nil? debug { "#{TOKEN_KEY} environment value is empty or missing" } elsif url.include? "?" url << "&access_token=#{ENV[TOKEN_KEY]}" else url << "?access_token=#{ENV[TOKEN_KEY]}" end url end private def api_call(path) tags = [] url = "https://api.github.com#{path}?page=1&per_page=100" while true do debug { " Module #{name} getting tags at: #{url}" } add_api_token_to_url(url) response = http_get(url, :headers => { "User-Agent" => "librarian-puppet v#{Librarian::Puppet::VERSION}" }) code, data = response.code.to_i, response.body if code == 200 tags.concat JSON.parse(data) else begin message = JSON.parse(data)['message'] if code == 403 && message && message.include?('API rate limit exceeded') raise Error, message + " -- increase limit by authenticating via #{TOKEN_KEY}=your-token" elsif message raise Error, "Error fetching #{url}: [#{code}] #{message}" end rescue JSON::ParserError # response does not return json end raise Error, "Error fetching #{url}: [#{code}] #{response.body}" end # next page break if response["link"].nil? next_link = response["link"].split(",").select{|l| l.match /rel=.*next.*/} break if next_link.empty? url = next_link.first.match(/<(.*)>/)[1] end return tags end def http_get(url, options) uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri.request_uri) options[:headers].each { |k, v| request.add_field k, v } http.request(request) end def vendored_name(name = source.uri.to_s) name.sub('/','-') end end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/local.rb000066400000000000000000000066321443340236400237510ustar00rootroot00000000000000require 'librarian/puppet/util' module Librarian module Puppet module Source module Local include Librarian::Puppet::Util def install!(manifest) manifest.source == self or raise ArgumentError debug { "Installing #{manifest}" } name, version = manifest.name, manifest.version found_path = found_path(name) raise Error, "Path for #{name} doesn't contain a puppet module" if found_path.nil? unless name.include? '/' or name.include? '-' warn { "Invalid module name '#{name}', you should qualify it with 'ORGANIZATION-#{name}' for resolution to work correctly" } end install_path = environment.install_path.join(module_name(name)) if install_path.exist? && rsync? != true debug { "Deleting #{relative_path_to(install_path)}" } install_path.rmtree end install_perform_step_copy!(found_path, install_path) end def fetch_version(name, extra) cache! found_path = found_path(name) module_version end def fetch_dependencies(name, version, extra) dependencies = Set.new if specfile? spec = environment.dsl(Pathname(specfile)) dependencies.merge spec.dependencies end parsed_metadata['dependencies'].each do |d| gem_requirement = Librarian::Dependency::Requirement.new(d['version_requirement']).to_gem_requirement new_dependency = Dependency.new(d['name'], gem_requirement, forge_source, name) dependencies << new_dependency end dependencies end def forge_source Forge.default end private # Naming this method 'version' causes an exception to be raised. def module_version if parsed_metadata['version'] parsed_metadata['version'] else warn { "Module #{to_s} does not have version, defaulting to 0.0.1" } '0.0.1' end end def parsed_metadata if @metadata.nil? @metadata = if metadata? begin JSON.parse(File.read(metadata)) rescue JSON::ParserError => e raise Error, "Unable to parse json file #{metadata}: #{e}" end else {} end @metadata['dependencies'] ||= [] end @metadata end def metadata File.join(filesystem_path, 'metadata.json') end def metadata? File.exist?(metadata) end def specfile File.join(filesystem_path, environment.specfile_name) end def specfile? File.exist?(specfile) end def install_perform_step_copy!(found_path, install_path) debug { "Copying #{relative_path_to(found_path)} to #{relative_path_to(install_path)}" } cp_r(found_path, install_path) end def manifest?(name, path) return true if path.join('manifests').exist? return true if path.join('lib').join('puppet').exist? return true if path.join('lib').join('facter').exist? debug { "Could not find manifests, lib/puppet or lib/facter under #{path}, maybe it is not a puppet module" } true end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/path.rb000066400000000000000000000003311443340236400236010ustar00rootroot00000000000000require 'librarian/source/path' require 'librarian/puppet/source/local' module Librarian module Puppet module Source class Path < Librarian::Source::Path include Local end end end end librarian-puppet-5.0.0/lib/librarian/puppet/source/repo.rb000066400000000000000000000014521443340236400236170ustar00rootroot00000000000000# parent class for githubtarball and forge source Repos module Librarian module Puppet module Source class Repo attr_accessor :source, :name private :source=, :name= def initialize(source, name) self.source = source self.name = name end def environment source.environment end def cache_path @cache_path ||= source.cache_path.join(name) end def version_unpacked_cache_path(version) cache_path.join(version.to_s) end def vendored?(name, version) vendored_path(name, version).exist? end def vendored_path(name, version) environment.vendor_cache.join("#{name}-#{version}.tar.gz") end end end end end librarian-puppet-5.0.0/lib/librarian/puppet/templates/000077500000000000000000000000001443340236400230215ustar00rootroot00000000000000librarian-puppet-5.0.0/lib/librarian/puppet/templates/Puppetfile000066400000000000000000000010751443340236400250640ustar00rootroot00000000000000#!/usr/bin/env ruby #^syntax detection forge "https://forgeapi.puppetlabs.com" # use dependencies defined in metadata.json metadata # A module from the Puppet Forge # mod 'puppetlabs-stdlib' # A module from git # mod 'puppetlabs-ntp', # :git => 'git://github.com/puppetlabs/puppetlabs-ntp.git' # A module from a git branch/tag # mod 'puppetlabs-apt', # :git => 'https://github.com/puppetlabs/puppetlabs-apt.git', # :ref => '1.4.x' # A module from Github pre-packaged tarball # mod 'puppetlabs-apache', '0.6.0', :github_tarball => 'puppetlabs/puppetlabs-apache' librarian-puppet-5.0.0/lib/librarian/puppet/util.rb000066400000000000000000000046251443340236400223340ustar00rootroot00000000000000require 'rsync' module Librarian module Puppet module Util def debug(*args, &block) environment.logger.debug(*args, &block) end def info(*args, &block) environment.logger.info(*args, &block) end def warn(*args, &block) environment.logger.warn(*args, &block) end def rsync? environment.config_db.local['rsync'] == 'true' end # workaround Issue #173 FileUtils.cp_r will fail if there is a symlink that points to a missing file # or when the symlink is copied before the target file when preserve is true # see also https://tickets.opscode.com/browse/CHEF-833 # # If the rsync configuration parameter is set, use rsync instead of FileUtils def cp_r(src, dest) if rsync? if Gem.win_platform? src_clean = "#{src}".gsub(/^([a-z])\:/i,'/cygdrive/\1') dest_clean = "#{dest}".gsub(/^([a-z])\:/i,'/cygdrive/\1') else src_clean = src dest_clean = dest end debug { "Copying #{src_clean}/ to #{dest_clean}/ with rsync -avz --delete" } result = Rsync.run(File.join(src_clean, "/"), File.join(dest_clean, "/"), ['-avz', '--delete']) if result.success? debug { "Rsync from #{src_clean}/ to #{dest_clean}/ successful" } else msg = "Failed to rsync from #{src_clean}/ to #{dest_clean}/: " + result.error raise Error, msg end else begin FileUtils.cp_r(src, dest, :preserve => true) rescue Errno::ENOENT, Errno::EACCES debug { "Failed to copy from #{src} to #{dest} preserving file types, trying again without preserving them" } FileUtils.rm_rf(dest) FileUtils.cp_r(src, dest) end end end # Remove user and password from a URI object def clean_uri(uri) new_uri = uri.clone new_uri.user = nil new_uri.password = nil new_uri end # normalize module name to use organization-module instead of organization/module def normalize_name(name) name.sub('/','-') end # get the module name from organization-module def module_name(name) # module name can't have dashes, so let's assume it is everything after the last dash name.rpartition('-').last end end end end librarian-puppet-5.0.0/lib/librarian/puppet/version.rb000066400000000000000000000001011443340236400230250ustar00rootroot00000000000000module Librarian module Puppet VERSION = "5.0.0" end end librarian-puppet-5.0.0/librarian-puppet.gemspec000066400000000000000000000025501443340236400216220ustar00rootroot00000000000000$:.push File.expand_path("../lib", __FILE__) require 'librarian/puppet/version' Gem::Specification.new do |s| s.name = 'librarian-puppet' s.version = Librarian::Puppet::VERSION s.platform = Gem::Platform::RUBY s.authors = ['Tim Sharpe', 'Carlos Sanchez'] s.license = 'MIT' s.email = ['tim@sharpe.id.au', 'carlos@apache.org'] s.homepage = 'https://github.com/voxpupuli/librarian-puppet' s.summary = 'Bundler for your Puppet modules' s.description = 'Simplify deployment of your Puppet infrastructure by automatically pulling in modules from the forge and git repositories with a single command.' s.required_ruby_version = '>= 2.7', '< 4' s.files = [ '.gitignore', 'LICENSE', 'README.md', ] + Dir['{bin,lib}/**/*'] s.executables = ['librarian-puppet'] s.add_dependency "librarianp", ">=0.6.3" s.add_dependency "rsync" s.add_dependency "puppet_forge", ">= 2.1", '< 5' s.add_development_dependency "rake" s.add_development_dependency "rspec" s.add_development_dependency "cucumber", "<9.0.0" s.add_development_dependency "aruba", ">= 1.0", "< 3" s.add_development_dependency "puppet", ENV["PUPPET_VERSION"] s.add_development_dependency "minitest", "~> 5" s.add_development_dependency "mocha", "<2.0.0" s.add_development_dependency "simplecov", ">= 0.9.0" s.add_development_dependency "concurrent-ruby", "< 1.2" end librarian-puppet-5.0.0/spec/000077500000000000000000000000001443340236400157275ustar00rootroot00000000000000librarian-puppet-5.0.0/spec/action/000077500000000000000000000000001443340236400172045ustar00rootroot00000000000000librarian-puppet-5.0.0/spec/action/resolve_spec.rb000066400000000000000000000021051443340236400222200ustar00rootroot00000000000000require 'spec_helper' require_relative '../../lib/librarian/puppet/action/resolve' require 'librarian/ui' require 'thor' describe 'Librarian::Puppet::Action::Resolve' do let(:path) { File.expand_path("../../../features/examples/test", __FILE__) } let(:environment) { Librarian::Puppet::Environment.new(:project_path => path) } before do # run with DEBUG=true envvar to get debug output environment.ui = Librarian::UI::Shell.new(Thor::Shell::Basic.new) end describe '#run' do it 'should resolve dependencies' do Librarian::Puppet::Action::Resolve.new(environment, :force => true).run resolution = environment.lock.manifests.map { |m| {:name => m.name, :version => m.version.to_s, :source => m.source.to_s} } expect(resolution.size).to eq(1) expect(resolution.first[:name]).to eq("puppetlabs-stdlib") expect(resolution.first[:source]).to eq("https://forgeapi.puppetlabs.com") expect(resolution.first[:version]).to match(/\d+\.\d+\.\d+/) end end after do File.delete('features/examples/test/Puppetfile.lock') end end librarian-puppet-5.0.0/spec/receiver_spec.rb000066400000000000000000000022171443340236400210740ustar00rootroot00000000000000require 'spec_helper' describe 'Librarian::Puppet::Dsl::Receiver' do let(:dsl) { Librarian::Puppet::Dsl.new({}) } let(:target) { Librarian::Dsl::Target.new(dsl) } let(:receiver) { Librarian::Puppet::Dsl::Receiver.new(target) } let(:environment) { Librarian::Puppet::Environment.new(:project_path => '/tmp/tmp_module') } describe '#run' do it 'should get working_dir from pwd when specfile is nil' do receiver.run(nil) {} expect(receiver.working_path).to eq(Pathname.new(Dir.pwd)) end it 'should get working_dir from pwd with default specfile' do receiver.run(dsl.default_specfile) {} expect(receiver.working_path).to eq(Pathname.new(Dir.pwd)) end it 'should get working_dir from given path' do receiver.run(Pathname.new('/tmp/tmp_module/Puppetfile')) {} expect(receiver.working_path).to eq(Pathname.new('/tmp/tmp_module')) end it 'test receiver run' do error_message = 'Metadata file does not exist: '+File.join(environment.project_path, 'metadata.json') expect{environment.dsl(environment.specfile.path, [])}.to raise_error(Librarian::Error,error_message) end end end librarian-puppet-5.0.0/spec/source/000077500000000000000000000000001443340236400172275ustar00rootroot00000000000000librarian-puppet-5.0.0/spec/source/forge_spec.rb000066400000000000000000000011761443340236400216750ustar00rootroot00000000000000require "librarian/puppet/source/forge" require "librarian/puppet/environment" require 'librarian/puppet/extension' include Librarian::Puppet::Source describe Forge do let(:environment) { Librarian::Puppet::Environment.new } let(:uri) { "https://forgeapi.puppetlabs.com" } subject { Forge.new(environment, uri) } describe "#manifests" do let(:manifests) { [] } before do expect_any_instance_of(Librarian::Puppet::Source::Forge::RepoV3).to receive(:get_versions).at_least(:once) { manifests } end it "should return the manifests" do expect(subject.manifests("x")).to eq(manifests) end end end librarian-puppet-5.0.0/spec/spec_helper.rb000066400000000000000000000001441443340236400205440ustar00rootroot00000000000000require 'simplecov' SimpleCov.start require 'rubygems' require 'rspec' require 'librarian/puppet' librarian-puppet-5.0.0/spec/util_spec.rb000066400000000000000000000005601443340236400202440ustar00rootroot00000000000000require 'spec_helper' describe Librarian::Puppet::Util do subject { Class.new { include Librarian::Puppet::Util }.new } it 'should get organization name' do expect(subject.module_name('puppetlabs-xy')).to eq('xy') end it 'should get organization name when org contains dashes' do expect(subject.module_name('puppet-labs-xy')).to eq('xy') end end librarian-puppet-5.0.0/test/000077500000000000000000000000001443340236400157545ustar00rootroot00000000000000librarian-puppet-5.0.0/test/librarian/000077500000000000000000000000001443340236400177175ustar00rootroot00000000000000librarian-puppet-5.0.0/test/librarian/puppet/000077500000000000000000000000001443340236400212345ustar00rootroot00000000000000librarian-puppet-5.0.0/test/librarian/puppet/source/000077500000000000000000000000001443340236400225345ustar00rootroot00000000000000librarian-puppet-5.0.0/test/librarian/puppet/source/githubtarball_test.rb000066400000000000000000000055611443340236400267530ustar00rootroot00000000000000require File.expand_path("../../../../test_helper", __FILE__) require "librarian/puppet/source/githubtarball" describe Librarian::Puppet::Source::GitHubTarball::Repo do def assert_exact_error(klass, message) yield rescue Exception => e e.class.must_equal klass e.message.must_equal message else raise "No exception was raised!" end class FakeResponse attr_accessor :code,:body def initialize(code,body) @code = code @body = body end def [](key) nil end end describe "#api_call" do let(:environment) { Librarian::Puppet::Environment.new } let(:source) { Librarian::Puppet::Source::GitHubTarball.new(environment, "foo") } let(:repo) { Librarian::Puppet::Source::GitHubTarball::Repo.new(source, "bar") } let(:headers) { {'User-Agent' => "librarian-puppet v#{Librarian::Puppet::VERSION}"} } let(:url) { "https://api.github.com/foo?page=1&per_page=100" } let(:url_with_token) { "https://api.github.com/foo?page=1&per_page=100&access_token=bar" } ENV['GITHUB_API_TOKEN'] = '' it "succeeds" do response = [] repo.expects(:http_get).with(url, {:headers => headers}).returns(FakeResponse.new(200, JSON.dump(response))) repo.send(:api_call, "/foo").must_equal(response) end it "adds GITHUB_API_TOKEN if present" do ENV['GITHUB_API_TOKEN'] = 'bar' response = [] repo.expects(:http_get).with(url_with_token, {:headers => headers}).returns(FakeResponse.new(200, JSON.dump(response))) repo.send(:api_call, "/foo").must_equal(response) ENV['GITHUB_API_TOKEN'] = '' end it "fails when we hit api limit" do response = {"message" => "Oh boy! API rate limit exceeded!!!"} repo.expects(:http_get).with(url, {:headers => headers}).returns(FakeResponse.new(403, JSON.dump(response))) message = "Oh boy! API rate limit exceeded!!! -- increase limit by authenticating via GITHUB_API_TOKEN=your-token" assert_exact_error Librarian::Error, message do repo.send(:api_call, "/foo") end end it "fails with unknown error message" do repo.expects(:http_get).with(url, {:headers => headers}).returns(FakeResponse.new(403, "")) assert_exact_error Librarian::Error, "Error fetching #{url}: [403] " do repo.send(:api_call, "/foo") end end it "fails with html" do repo.expects(:http_get).with(url, {:headers => headers}).returns(FakeResponse.new(403, "Oh boy!")) assert_exact_error Librarian::Error, "Error fetching #{url}: [403] Oh boy!" do repo.send(:api_call, "/foo") end end it "fails with unknown code" do repo.expects(:http_get).with(url, {:headers => headers}).returns(FakeResponse.new(500, "")) assert_exact_error Librarian::Error, "Error fetching #{url}: [500] " do repo.send(:api_call, "/foo") end end end end librarian-puppet-5.0.0/test/test_helper.rb000066400000000000000000000002421443340236400206150ustar00rootroot00000000000000require 'bundler/setup' require 'minitest/autorun' require 'minitest/spec' require 'mocha/setup' $LOAD_PATH << "vendor/librarian/lib" require 'librarian/puppet'