diff --git a/CHANGELOG.md b/CHANGELOG.md index 717b8e5..d59a2d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ Starting with v2.0.0, all notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## v3.0.0 - 2021-01-28 + +* Breaking: The `puppet_forge` gem now requires at least Ruby 2.4.0. +* Update `faraday` and `faraday_middleware` gem dependencies to 1.x series. +* Update optional `typhoeus` dependency to `>= 1.4` to maintain compatibility with `faraday`. + ## v2.3.4 - 2020-03-31 * Update the forge API url to `forgeapi.puppet.com` (instead of using the older puppetlabs.com domain). diff --git a/lib/puppet_forge/connection.rb b/lib/puppet_forge/connection.rb index 49f5112..bee139a 100644 --- a/lib/puppet_forge/connection.rb +++ b/lib/puppet_forge/connection.rb @@ -2,7 +2,6 @@ require 'faraday' require 'faraday_middleware' -require 'puppet_forge/middleware/symbolify_json' module PuppetForge # Provide a common mixin for adding a HTTP connection to classes. @@ -81,7 +80,7 @@ def default_connection(opts = {}) begin # Use Typhoeus if available. - Gem::Specification.find_by_name('typhoeus', '~> 1.0.1') + Gem::Specification.find_by_name('typhoeus', '~> 1.4') require 'typhoeus/adapters/faraday' adapter = :typhoeus rescue Gem::LoadError @@ -114,8 +113,7 @@ def make_connection(url, adapter_args = nil, opts = {}) end Faraday.new(url, options) do |builder| - builder.use PuppetForge::Middleware::SymbolifyJson - builder.response(:json, :content_type => /\bjson$/) + builder.response(:json, :content_type => /\bjson$/, :parser_options => { :symbolize_names => true }) builder.response(:raise_error) builder.use(:connection_failure) diff --git a/lib/puppet_forge/middleware/symbolify_json.rb b/lib/puppet_forge/middleware/symbolify_json.rb deleted file mode 100644 index 3516d35..0000000 --- a/lib/puppet_forge/middleware/symbolify_json.rb +++ /dev/null @@ -1,72 +0,0 @@ -module PuppetForge - module Middleware - - # SymbolifyJson is a Faraday Middleware that will process any response formatted as a hash - # and change all the keys into symbols (as long as they respond to the method #to_sym. - # - # This middleware makes no changes to the values of the hash. - # If the response is not a hash, no changes will be made. - class SymbolifyJson < Faraday::Middleware - - # Processes an array - # - # @return an array with any hash's keys turned into symbols if possible - def process_array(array) - array.map do |arg| - # Search any arrays and hashes for hash keys - if arg.is_a? Hash - process_hash(arg) - elsif arg.is_a? Array - process_array(arg) - else - arg - end - end - end - - # Processes a hash - # - # @return a hash with all keys turned into symbols if possible - def process_hash(hash) - - # hash.map returns an array in the format - # [ [key, value], [key2, value2], ... ] - # Hash[] converts that into a hash in the format - # { key => value, key2 => value2, ... } - Hash[hash.map do |key, val| - # Convert to a symbol if possible - if key.respond_to? :to_sym - new_key = key.to_sym - else - new_key = key - end - - # If value is a hash or array look for more hash keys inside. - if val.is_a?(Hash) - [new_key, process_hash(val)] - elsif val.is_a?(Array) - [new_key, process_array(val)] - else - [new_key, val] - end - end] - end - - def process_response(env) - if !env["body"].nil? && env["body"].is_a?(Hash) - process_hash(env.body) - else - env.body - end - end - - def call(environment) - @app.call(environment).on_complete do |env| - env.body = process_response(env) - end - end - - end - end -end - diff --git a/lib/puppet_forge/version.rb b/lib/puppet_forge/version.rb index 9054eb9..532bb7d 100644 --- a/lib/puppet_forge/version.rb +++ b/lib/puppet_forge/version.rb @@ -1,3 +1,3 @@ module PuppetForge - VERSION = '2.3.4' # Library version + VERSION = '3.0.0' # Library version end diff --git a/puppet_forge.gemspec b/puppet_forge.gemspec index 6e58396..cd40315 100644 --- a/puppet_forge.gemspec +++ b/puppet_forge.gemspec @@ -18,13 +18,13 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] - spec.required_ruby_version = '>= 1.9.3' + spec.required_ruby_version = '>= 2.4.0' - spec.add_runtime_dependency "faraday", [">= 0.9.0", "< 0.18.0", "!= 0.13.1"] - spec.add_runtime_dependency "faraday_middleware", [">= 0.9.0", "< 0.15.0"] - spec.add_dependency 'semantic_puppet', '~> 1.0' - spec.add_dependency 'minitar' - spec.add_dependency 'gettext-setup', '~> 0.11' + spec.add_runtime_dependency "faraday", "~> 1.3" + spec.add_runtime_dependency "faraday_middleware", "~> 1.0" + spec.add_dependency "semantic_puppet", "~> 1.0" + spec.add_dependency "minitar" + spec.add_dependency "gettext-setup", "~> 0.11" spec.add_development_dependency "rake" spec.add_development_dependency "rspec", "~> 3.0" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5265d51..bdea1e7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,8 +15,7 @@ module StubbingFaraday def stub_api_for(klass, base_url = "http://api.example.com") allow(klass).to receive(:conn) do Faraday.new :url => base_url do |builder| - builder.use PuppetForge::Middleware::SymbolifyJson - builder.response(:json, :content_type => /\bjson$/) + builder.response(:json, :content_type => /\bjson$/, :parser_options => { :symbolize_names => true }) builder.response(:raise_error) builder.use(:connection_failure) diff --git a/spec/unit/forge/connection_spec.rb b/spec/unit/forge/connection_spec.rb index 5a6cb05..a0a9c31 100644 --- a/spec/unit/forge/connection_spec.rb +++ b/spec/unit/forge/connection_spec.rb @@ -88,7 +88,7 @@ expect { subject.get('/error') - }.to raise_error(Faraday::ClientError, "the server responded with status 503") + }.to raise_error(Faraday::ServerError, "the server responded with status 503") end context 'when an authorization value is provided' do diff --git a/spec/unit/forge/middleware/symbolify_json_spec.rb b/spec/unit/forge/middleware/symbolify_json_spec.rb deleted file mode 100644 index df2fb2f..0000000 --- a/spec/unit/forge/middleware/symbolify_json_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'spec_helper' - -describe PuppetForge::Middleware::SymbolifyJson do - let(:basic_array) { [1, "two", 3] } - let(:basic_hash) { { "id" => 1, "data" => "x" } } - let(:symbolified_hash) { { :id => 1, :data => "x" } } - let(:internal_hash) { { :id => 2, :data => basic_hash } } - - let(:hash_with_array) { { "id" => 3, "data" => basic_array } } - let(:array_with_hash) { [1, "two", basic_hash] } - - let(:complex_array) { [array_with_hash, hash_with_array] } - let(:complex_hash) { { "id" => 4, "data" => [complex_array, basic_array], "more_data" => hash_with_array } } - let(:complex_request) { { "id" => 5, "data" => complex_hash } } - - let(:middleware) { described_class.new() } - - context "#process_array" do - it "doesn't change an array with no array or hash inside" do - processed_array = middleware.process_array(basic_array) - expect(processed_array).to eql( [1, "two", 3] ) - end - - it "changes all keys of a hash inside the array" do - processed_array = middleware.process_array(array_with_hash) - expect(processed_array).to eql( [ 1, "two", { :id => 1, :data => "x" } ] ) - end - end - - context "#process_hash" do - it "changes all keys that respond to :to_sym into Symbols and doesn't change values." do - processed_hash = middleware.process_hash(basic_hash) - expect(processed_hash).to eql( { :id => 1, :data => "x" } ) - end - - it "doesn't change keys that don't respond to :to_sym" do - processed_hash = middleware.process_hash(basic_hash.merge({ 1 => 2 })) - expect(processed_hash).to eql( { :id => 1, :data => "x", 1 => 2 } ) - end - - it "can process a hash that is already symbolified" do - processed_hash = middleware.process_hash(symbolified_hash) - expect(processed_hash).to eql( { :id => 1, :data => "x" }) - end - - it "can process a hash with a hash inside of it" do - processed_hash = middleware.process_hash(internal_hash) - expect(processed_hash).to eql( {:id => 2, :data => { :id => 1, :data => "x" } }) - end - - it "can process a hash with an array inside of it" do - processed_hash = middleware.process_hash(hash_with_array) - expect(processed_hash).to eql( { :id => 3, :data => [1, "two", 3] } ) - end - - it "can handle extensively nested arrays and hashes" do - processed_hash = middleware.process_hash(complex_request) - expect(processed_hash).to eql( { :id => 5, :data => { :id => 4 , :data=>[ [ [1, "two", { :id => 1, :data => "x" } ], { :id=>3, :data => [1, "two", 3] } ], [1, "two", 3] ], :more_data => { :id => 3, :data => [1, "two", 3] } } } ) - end - end - -end - diff --git a/spec/unit/forge/v3/metadata_spec.rb b/spec/unit/forge/v3/metadata_spec.rb index 19da0d5..02d0215 100644 --- a/spec/unit/forge/v3/metadata_spec.rb +++ b/spec/unit/forge/v3/metadata_spec.rb @@ -168,14 +168,6 @@ end - context "with a valid dependency", :pending => "dependency resolution is not yet in scope" do - let(:data) { {'dependencies' => [{'name' => 'puppetlabs-goodmodule'}] }} - - it "adds the dependency" do - expect(subject.dependencies.size).to eq(1) - end - end - context "with a invalid dependency name" do let(:data) { {'dependencies' => [{'name' => 'puppetlabsbadmodule'}] }} @@ -184,14 +176,6 @@ end end - context "with a valid dependency version range", :pending => "dependency resolution is not yet in scope" do - let(:data) { {'dependencies' => [{'name' => 'puppetlabs-badmodule', 'version_requirement' => '>= 2.0.0'}] }} - - it "adds the dependency" do - expect(subject.dependencies.size).to eq(1) - end - end - context "with a invalid version range" do let(:data) { {'dependencies' => [{'name' => 'puppetlabsbadmodule', 'version_requirement' => '>= banana'}] }} @@ -199,30 +183,6 @@ expect { subject }.to raise_error(ArgumentError) end end - - context "with duplicate dependencies", :pending => "dependency resolution is not yet in scope" do - let(:data) { {'dependencies' => [{'name' => 'puppetlabs-dupmodule', 'version_requirement' => '1.0.0'}, - {'name' => 'puppetlabs-dupmodule', 'version_requirement' => '0.0.1'}] } - } - - it "raises an exception" do - expect { subject }.to raise_error(ArgumentError) - end - end - - context "adding a duplicate dependency", :pending => "dependency resolution is not yet in scope" do - let(:data) { {'dependencies' => [{'name' => 'puppetlabs-origmodule', 'version_requirement' => '1.0.0'}] }} - - it "with a different version raises an exception" do - metadata.add_dependency('puppetlabs-origmodule', '>= 0.0.1') - expect { subject }.to raise_error(ArgumentError) - end - - it "with the same version does not add another dependency" do - metadata.add_dependency('puppetlabs-origmodule', '1.0.0') - expect(subject.dependencies.size).to eq(1) - end - end end describe '#dashed_name' do