From c77ae2f5f6608d718d572383000d4f0ba31dbae2 Mon Sep 17 00:00:00 2001 From: kumarasantosh Date: Fri, 13 Mar 2026 08:45:17 +0530 Subject: [PATCH 1/2] packagedcode: fix gemspec version constants being stored as-is When a gemspec uses a Ruby constant for the version field like: s.version = Elasticsearch::API::VERSION s.version = Faraday::VERSION scancode was storing the constant name as the version string. These constants cannot be resolved without executing Ruby code. Add is_ruby_version_constant() to detect Ruby constant expressions (containing :: namespace separator or bare uppercase constant names) and return None for the version instead of storing an unresolvable constant string. Also fixes the download_url and api_data_url which were generating invalid URLs with the constant name embedded. Fixes #3129 Signed-off-by: kumarasantosh --- src/packagedcode/rubygems.py | 1 + src/packagedcode/spec.py | 38 +++++++++ .../elasticsearch-api.gemspec | 83 +++++++++++++++++++ .../rubygems/version-constant/excon.gemspec | 45 ++++++++++ .../rubygems/version-constant/faraday.gemspec | 1 + .../version-constant/simple-constant.gemspec | 6 ++ .../version-constant/simple-version.gemspec | 6 ++ tests/packagedcode/test_rubygems.py | 42 ++++++++++ 8 files changed, 222 insertions(+) create mode 100644 tests/packagedcode/data/rubygems/version-constant/elasticsearch-api.gemspec create mode 100644 tests/packagedcode/data/rubygems/version-constant/excon.gemspec create mode 100644 tests/packagedcode/data/rubygems/version-constant/faraday.gemspec create mode 100644 tests/packagedcode/data/rubygems/version-constant/simple-constant.gemspec create mode 100644 tests/packagedcode/data/rubygems/version-constant/simple-version.gemspec diff --git a/src/packagedcode/rubygems.py b/src/packagedcode/rubygems.py index e80295c48af..dc13b1560f9 100644 --- a/src/packagedcode/rubygems.py +++ b/src/packagedcode/rubygems.py @@ -706,6 +706,7 @@ def party_mapper(role, names=[], emails=[]): models.Party(type=models.party_person, email=email, role=role) for email in emails ) + return () def get_parties(gem_data): diff --git a/src/packagedcode/spec.py b/src/packagedcode/spec.py index 95dfdba7dd9..4c4154485fd 100644 --- a/src/packagedcode/spec.py +++ b/src/packagedcode/spec.py @@ -133,6 +133,40 @@ def get_authors(line): } +def is_ruby_version_constant(value): + """ + Return True if value looks like a Ruby constant expression + that cannot be resolved statically, such as: + Elasticsearch::API::VERSION or MyGem::VERSION + + These are dynamic values that reference Ruby constants + and cannot be determined without executing the Ruby code. + + For example: + >>> is_ruby_version_constant('Elasticsearch::API::VERSION') + True + >>> is_ruby_version_constant('MyGem::VERSION') + True + >>> is_ruby_version_constant('1.0.0') + False + >>> is_ruby_version_constant("'2.3.4'") + False + >>> is_ruby_version_constant(None) + False + """ + if not value: + return False + # Ruby constants use :: as namespace separator + if '::' in value: + return True + # A bare constant starts with uppercase and has no dots/quotes + # e.g. VERSION (unlikely but possible) + stripped = value.strip('\'"') + if stripped and stripped[0].isupper() and '.' not in stripped: + return True + return False + + def parse_spec(location, package_type): """ Return a mapping of data parsed from a podspec/gemspec/Pofile/Gemfile file @@ -151,6 +185,10 @@ def parse_spec(location, package_type): parsed = parser(line=line) if parsed: spec_data[attribute_name] = parsed + + version = spec_data.get('version') + if is_ruby_version_constant(version): + spec_data['version'] = None # description can be in single or multi-lines # There are many different ways to write description. diff --git a/tests/packagedcode/data/rubygems/version-constant/elasticsearch-api.gemspec b/tests/packagedcode/data/rubygems/version-constant/elasticsearch-api.gemspec new file mode 100644 index 00000000000..100a7d6e705 --- /dev/null +++ b/tests/packagedcode/data/rubygems/version-constant/elasticsearch-api.gemspec @@ -0,0 +1,83 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'elasticsearch/api/version' + +Gem::Specification.new do |s| + s.name = 'elasticsearch-api' + s.version = Elasticsearch::API::VERSION + s.authors = ['Karel Minarik'] + s.email = ['karel.minarik@elasticsearch.org'] + s.summary = 'Ruby API for Elasticsearch.' + s.homepage = 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/index.html' + s.license = 'Apache-2.0' + s.metadata = { + 'homepage_uri' => 'https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/index.html', + 'changelog_uri' => 'https://github.com/elastic/elasticsearch-ruby/blob/main/CHANGELOG.md', + 'source_code_uri' => 'https://github.com/elastic/elasticsearch-ruby/tree/main/elasticsearch-api', + 'bug_tracker_uri' => 'https://github.com/elastic/elasticsearch-ruby/issues' + } + s.files = `git ls-files`.split($/) + s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } + s.test_files = s.files.grep(%r{^(test|spec|features)/}) + s.require_paths = ['lib'] + + s.extra_rdoc_files = ['README.md', 'LICENSE.txt'] + s.rdoc_options = ['--charset=UTF-8'] + + s.required_ruby_version = '>= 2.5' + + s.add_dependency 'multi_json' + + s.add_development_dependency 'ansi' + s.add_development_dependency 'bundler' + s.add_development_dependency 'elasticsearch' + s.add_development_dependency 'minitest' + s.add_development_dependency 'minitest-reporters' + s.add_development_dependency 'mocha' + s.add_development_dependency 'pry' + s.add_development_dependency 'rake' + s.add_development_dependency 'shoulda-context' + s.add_development_dependency 'yard' + + # Gems for testing integrations + s.add_development_dependency 'jsonify' + s.add_development_dependency 'hashie' + # Temporary support for Ruby 2.6, since it's EOL March 2022: + if RUBY_VERSION < '2.7.0' + s.add_development_dependency 'jbuilder', '< 7.0.0' + else + s.add_development_dependency 'activesupport' + s.add_development_dependency 'jbuilder' + end + + s.add_development_dependency 'cane' + s.add_development_dependency 'escape_utils' unless defined? JRUBY_VERSION + + s.add_development_dependency 'require-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) + s.add_development_dependency 'ruby-prof' unless defined?(JRUBY_VERSION) || defined?(Rubinius) + s.add_development_dependency 'simplecov' + + s.add_development_dependency 'test-unit', '~> 2' + + s.description = <<-DESC.gsub(/^ /, '') + Ruby API for Elasticsearch. See the `elasticsearch` gem for full integration. + DESC +end diff --git a/tests/packagedcode/data/rubygems/version-constant/excon.gemspec b/tests/packagedcode/data/rubygems/version-constant/excon.gemspec new file mode 100644 index 00000000000..161eb9bc94d --- /dev/null +++ b/tests/packagedcode/data/rubygems/version-constant/excon.gemspec @@ -0,0 +1,45 @@ +$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib') +require 'excon/version' + +Gem::Specification.new do |s| + s.name = 'excon' + s.version = Excon::VERSION + s.summary = "speed, persistence, http(s)" + s.description = "EXtended http(s) CONnections" + s.authors = ["dpiddy (Dan Peterson)", "geemus (Wesley Beary)", "nextmat (Matt Sanders)"] + s.email = 'geemus@gmail.com' + s.homepage = 'https://github.com/excon/excon' + s.license = 'MIT' + s.rdoc_options = ["--charset=UTF-8"] + s.extra_rdoc_files = %w[README.md CONTRIBUTORS.md CONTRIBUTING.md] + s.files = `git ls-files -- data/* lib/*`.split("\n") + [ + "CONTRIBUTING.md", + "CONTRIBUTORS.md", + "LICENSE.md", + "README.md", + "excon.gemspec" + ] + + s.add_development_dependency('rspec', '>= 3.5.0') + s.add_development_dependency('activesupport') + s.add_development_dependency('delorean') + s.add_development_dependency('eventmachine', '>= 1.0.4') + s.add_development_dependency('open4') + s.add_development_dependency('rake') + s.add_development_dependency('rdoc') + s.add_development_dependency('shindo') + s.add_development_dependency('sinatra') + s.add_development_dependency('sinatra-contrib') + s.add_development_dependency('json', '>= 1.8.5') + s.add_development_dependency('puma') + s.add_development_dependency('webrick') + + s.metadata = { + 'homepage_uri' => 'https://github.com/excon/excon', + 'bug_tracker_uri' => 'https://github.com/excon/excon/issues', + 'changelog_uri' => 'https://github.com/excon/excon/blob/master/changelog.txt', + 'documentation_uri' => 'https://github.com/excon/excon/blob/master/README.md', + 'source_code_uri' => 'https://github.com/excon/excon', + 'wiki_uri' => 'https://github.com/excon/excon/wiki' + } +end diff --git a/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec b/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec new file mode 100644 index 00000000000..1becba2bb0a --- /dev/null +++ b/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec @@ -0,0 +1 @@ +404: Not Found \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/version-constant/simple-constant.gemspec b/tests/packagedcode/data/rubygems/version-constant/simple-constant.gemspec new file mode 100644 index 00000000000..e885a9453cd --- /dev/null +++ b/tests/packagedcode/data/rubygems/version-constant/simple-constant.gemspec @@ -0,0 +1,6 @@ +Gem::Specification.new do |s| + s.name = 'my-gem' + s.version = MyGem::VERSION + s.summary = 'A gem with a version constant' + s.license = 'MIT' +end diff --git a/tests/packagedcode/data/rubygems/version-constant/simple-version.gemspec b/tests/packagedcode/data/rubygems/version-constant/simple-version.gemspec new file mode 100644 index 00000000000..3fb26f707c7 --- /dev/null +++ b/tests/packagedcode/data/rubygems/version-constant/simple-version.gemspec @@ -0,0 +1,6 @@ +Gem::Specification.new do |s| + s.name = 'my-gem' + s.version = '1.2.3' + s.summary = 'A gem with a real version' + s.license = 'MIT' +end diff --git a/tests/packagedcode/test_rubygems.py b/tests/packagedcode/test_rubygems.py index af55f355ab7..c0e25a684ab 100644 --- a/tests/packagedcode/test_rubygems.py +++ b/tests/packagedcode/test_rubygems.py @@ -15,14 +15,56 @@ from commoncode.testcase import FileBasedTesting from packagedcode import rubygems +from packagedcode import spec from packages_test_utils import PackageTester from scancode_config import REGEN_TEST_FIXTURES +REGEN_TEST_FIXTURES = False + # TODO: Add test with https://rubygems.org/gems/pbox2d/versions/1.0.3-java # this is a multiple personality package (Java and Ruby) # see also https://rubygems.org/downloads/jaro_winkler-1.5.1-java.gem +class TestGemspecVersionConstant(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_version_constant_returns_none_for_elasticsearch(self): + test_file = self.get_test_loc('rubygems/version-constant/elasticsearch-api.gemspec') + packages = list(rubygems.GemspecHandler.parse(test_file)) + assert packages + pkg = packages[0] + assert pkg.name == 'elasticsearch-api' + assert pkg.version is None + assert 'Elasticsearch' not in str(pkg.version) + assert pkg.download_url is None + + def test_version_constant_returns_none_for_simple_constant(self): + test_file = self.get_test_loc('rubygems/version-constant/simple-constant.gemspec') + packages = list(rubygems.GemspecHandler.parse(test_file)) + assert packages + pkg = packages[0] + assert pkg.name == 'my-gem' + assert pkg.version is None + + def test_real_version_is_preserved(self): + test_file = self.get_test_loc('rubygems/version-constant/simple-version.gemspec') + packages = list(rubygems.GemspecHandler.parse(test_file)) + assert packages + pkg = packages[0] + assert pkg.name == 'my-gem' + assert pkg.version == '1.2.3' + + def test_is_ruby_version_constant_function(self): + assert spec.is_ruby_version_constant('Elasticsearch::API::VERSION') is True + assert spec.is_ruby_version_constant('MyGem::VERSION') is True + assert spec.is_ruby_version_constant('Faraday::VERSION') is True + assert spec.is_ruby_version_constant('1.0.0') is False + assert spec.is_ruby_version_constant("'2.3.4'") is False + assert spec.is_ruby_version_constant(None) is False + assert spec.is_ruby_version_constant('') is False + + class TestGemSpec(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') From f8d1c477b1d4efe080bb0db715feca258856ae1b Mon Sep 17 00:00:00 2001 From: kumarasantosh Date: Fri, 13 Mar 2026 09:01:36 +0530 Subject: [PATCH 2/2] packagedcode: add gemspec version constant coverage Signed-off-by: kumarasantosh --- .../gemspec/github.gemspec.expected.json | 12 +++--- .../oj.gemspec-package-only.expected.json | 12 +++--- .../rubygems/gemspec/oj.gemspec.expected.json | 12 +++--- .../gemspec/rubocop.gemspec.expected.json | 12 +++--- .../with_variables.gemspec.expected.json | 12 +++--- .../rubygems/version-constant/faraday.gemspec | 38 +++++++++++++++++- tests/packagedcode/test_rubygems.py | 40 +++++++++++++------ 7 files changed, 95 insertions(+), 43 deletions(-) diff --git a/tests/packagedcode/data/rubygems/gemspec/github.gemspec.expected.json b/tests/packagedcode/data/rubygems/gemspec/github.gemspec.expected.json index 51a94b6f65f..9e64c87ef14 100644 --- a/tests/packagedcode/data/rubygems/gemspec/github.gemspec.expected.json +++ b/tests/packagedcode/data/rubygems/gemspec/github.gemspec.expected.json @@ -3,7 +3,7 @@ "type": "gem", "namespace": null, "name": "github", - "version": "GitHub::VERSION", + "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Ruby", @@ -48,7 +48,7 @@ ], "keywords": [], "homepage_url": "https://github.com/defunkt/github-gem", - "download_url": "https://rubygems.org/downloads/github-GitHub::VERSION.gem", + "download_url": null, "size": null, "sha1": null, "md5": null, @@ -162,10 +162,10 @@ "extra_data": {} } ], - "repository_homepage_url": "https://rubygems.org/gems/github/versions/GitHub::VERSION", - "repository_download_url": "https://rubygems.org/downloads/github-GitHub::VERSION.gem", - "api_data_url": "https://rubygems.org/api/v2/rubygems/github/versions/GitHub::VERSION.json", + "repository_homepage_url": "https://rubygems.org/gems/github", + "repository_download_url": null, + "api_data_url": "https://rubygems.org/api/v1/versions/github.json", "datasource_id": "gemspec", - "purl": "pkg:gem/github@GitHub::VERSION" + "purl": "pkg:gem/github" } ] \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/gemspec/oj.gemspec-package-only.expected.json b/tests/packagedcode/data/rubygems/gemspec/oj.gemspec-package-only.expected.json index 41c2396b66f..2094705b872 100644 --- a/tests/packagedcode/data/rubygems/gemspec/oj.gemspec-package-only.expected.json +++ b/tests/packagedcode/data/rubygems/gemspec/oj.gemspec-package-only.expected.json @@ -3,7 +3,7 @@ "type": "gem", "namespace": null, "name": "oj", - "version": "::Oj::VERSION", + "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Ruby", @@ -27,7 +27,7 @@ ], "keywords": [], "homepage_url": "http://www.ohler.com/oj", - "download_url": "https://rubygems.org/downloads/oj-::Oj::VERSION.gem", + "download_url": null, "size": null, "sha1": null, "md5": null, @@ -97,10 +97,10 @@ "extra_data": {} } ], - "repository_homepage_url": "https://rubygems.org/gems/oj/versions/::Oj::VERSION", - "repository_download_url": "https://rubygems.org/downloads/oj-::Oj::VERSION.gem", - "api_data_url": "https://rubygems.org/api/v2/rubygems/oj/versions/::Oj::VERSION.json", + "repository_homepage_url": "https://rubygems.org/gems/oj", + "repository_download_url": null, + "api_data_url": "https://rubygems.org/api/v1/versions/oj.json", "datasource_id": "gemspec", - "purl": "pkg:gem/oj@::Oj::VERSION" + "purl": "pkg:gem/oj" } ] \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/gemspec/oj.gemspec.expected.json b/tests/packagedcode/data/rubygems/gemspec/oj.gemspec.expected.json index 41c2396b66f..2094705b872 100644 --- a/tests/packagedcode/data/rubygems/gemspec/oj.gemspec.expected.json +++ b/tests/packagedcode/data/rubygems/gemspec/oj.gemspec.expected.json @@ -3,7 +3,7 @@ "type": "gem", "namespace": null, "name": "oj", - "version": "::Oj::VERSION", + "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Ruby", @@ -27,7 +27,7 @@ ], "keywords": [], "homepage_url": "http://www.ohler.com/oj", - "download_url": "https://rubygems.org/downloads/oj-::Oj::VERSION.gem", + "download_url": null, "size": null, "sha1": null, "md5": null, @@ -97,10 +97,10 @@ "extra_data": {} } ], - "repository_homepage_url": "https://rubygems.org/gems/oj/versions/::Oj::VERSION", - "repository_download_url": "https://rubygems.org/downloads/oj-::Oj::VERSION.gem", - "api_data_url": "https://rubygems.org/api/v2/rubygems/oj/versions/::Oj::VERSION.json", + "repository_homepage_url": "https://rubygems.org/gems/oj", + "repository_download_url": null, + "api_data_url": "https://rubygems.org/api/v1/versions/oj.json", "datasource_id": "gemspec", - "purl": "pkg:gem/oj@::Oj::VERSION" + "purl": "pkg:gem/oj" } ] \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/gemspec/rubocop.gemspec.expected.json b/tests/packagedcode/data/rubygems/gemspec/rubocop.gemspec.expected.json index 0c9b94323f8..c47e41a3c7a 100644 --- a/tests/packagedcode/data/rubygems/gemspec/rubocop.gemspec.expected.json +++ b/tests/packagedcode/data/rubygems/gemspec/rubocop.gemspec.expected.json @@ -3,7 +3,7 @@ "type": "gem", "namespace": null, "name": "rubocop", - "version": "RuboCop::Version::STRING", + "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Ruby", @@ -41,7 +41,7 @@ ], "keywords": [], "homepage_url": "https://github.com/rubocop-hq/rubocop", - "download_url": "https://rubygems.org/downloads/rubocop-RuboCop::Version::STRING.gem", + "download_url": null, "size": null, "sha1": null, "md5": null, @@ -166,10 +166,10 @@ "extra_data": {} } ], - "repository_homepage_url": "https://rubygems.org/gems/rubocop/versions/RuboCop::Version::STRING", - "repository_download_url": "https://rubygems.org/downloads/rubocop-RuboCop::Version::STRING.gem", - "api_data_url": "https://rubygems.org/api/v2/rubygems/rubocop/versions/RuboCop::Version::STRING.json", + "repository_homepage_url": "https://rubygems.org/gems/rubocop", + "repository_download_url": null, + "api_data_url": "https://rubygems.org/api/v1/versions/rubocop.json", "datasource_id": "gemspec", - "purl": "pkg:gem/rubocop@RuboCop::Version::STRING" + "purl": "pkg:gem/rubocop" } ] \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/gemspec/with_variables.gemspec.expected.json b/tests/packagedcode/data/rubygems/gemspec/with_variables.gemspec.expected.json index 9d706386763..d402d106eb9 100644 --- a/tests/packagedcode/data/rubygems/gemspec/with_variables.gemspec.expected.json +++ b/tests/packagedcode/data/rubygems/gemspec/with_variables.gemspec.expected.json @@ -3,7 +3,7 @@ "type": "gem", "namespace": null, "name": "ProviderDSL::GemDescription::NAME", - "version": "ProviderDSL::GemDescription::VERSION", + "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Ruby", @@ -27,7 +27,7 @@ ], "keywords": [], "homepage_url": "ProviderDSL::GemDescription::PAGE", - "download_url": "https://rubygems.org/downloads/ProviderDSL::GemDescription::NAME-ProviderDSL::GemDescription::VERSION.gem", + "download_url": null, "size": null, "sha1": null, "md5": null, @@ -152,10 +152,10 @@ "extra_data": {} } ], - "repository_homepage_url": "https://rubygems.org/gems/ProviderDSL::GemDescription::NAME/versions/ProviderDSL::GemDescription::VERSION", - "repository_download_url": "https://rubygems.org/downloads/ProviderDSL::GemDescription::NAME-ProviderDSL::GemDescription::VERSION.gem", - "api_data_url": "https://rubygems.org/api/v2/rubygems/ProviderDSL::GemDescription::NAME/versions/ProviderDSL::GemDescription::VERSION.json", + "repository_homepage_url": "https://rubygems.org/gems/ProviderDSL::GemDescription::NAME", + "repository_download_url": null, + "api_data_url": "https://rubygems.org/api/v1/versions/ProviderDSL::GemDescription::NAME.json", "datasource_id": "gemspec", - "purl": "pkg:gem/ProviderDSL::GemDescription::NAME@ProviderDSL::GemDescription::VERSION" + "purl": "pkg:gem/ProviderDSL::GemDescription::NAME" } ] \ No newline at end of file diff --git a/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec b/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec index 1becba2bb0a..1127632356c 100644 --- a/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec +++ b/tests/packagedcode/data/rubygems/version-constant/faraday.gemspec @@ -1 +1,37 @@ -404: Not Found \ No newline at end of file +# frozen_string_literal: true + +require_relative 'lib/faraday/version' + +Gem::Specification.new do |spec| + spec.name = 'faraday' + spec.version = Faraday::VERSION + + spec.summary = 'HTTP/REST API client library.' + + spec.authors = ['@technoweenie', '@iMacTia', '@olleolleolle'] + spec.email = 'technoweenie@gmail.com' + spec.homepage = 'https://lostisland.github.io/faraday' + spec.licenses = ['MIT'] + + spec.required_ruby_version = '>= 2.6' + + # faraday-net_http is the "default adapter", but being a Faraday dependency it can't + # control which version of faraday it will be pulled from. + # To avoid releasing a major version every time there's a new Faraday API, we should + # always fix its required version to the next MINOR version. + # This way, we can release minor versions of the adapter with "breaking" changes for older versions of Faraday + # and then bump the version requirement on the next compatible version of faraday. + spec.add_dependency 'faraday-net_http', '>= 2.0', '< 3.1' + spec.add_dependency 'ruby2_keywords', '>= 0.0.4' + + # Includes `examples` and `spec` to allow external adapter gems to run Faraday unit and integration tests + spec.files = Dir['CHANGELOG.md', '{examples,lib,spec}/**/*', 'LICENSE.md', 'Rakefile', 'README.md'] + spec.require_paths = %w[lib spec/external_adapters] + spec.metadata = { + 'homepage_uri' => 'https://lostisland.github.io/faraday', + 'changelog_uri' => + "https://github.com/lostisland/faraday/releases/tag/v#{spec.version}", + 'source_code_uri' => 'https://github.com/lostisland/faraday', + 'bug_tracker_uri' => 'https://github.com/lostisland/faraday/issues' + } +end diff --git a/tests/packagedcode/test_rubygems.py b/tests/packagedcode/test_rubygems.py index c0e25a684ab..ac89125a828 100644 --- a/tests/packagedcode/test_rubygems.py +++ b/tests/packagedcode/test_rubygems.py @@ -19,8 +19,6 @@ from packages_test_utils import PackageTester from scancode_config import REGEN_TEST_FIXTURES -REGEN_TEST_FIXTURES = False - # TODO: Add test with https://rubygems.org/gems/pbox2d/versions/1.0.3-java # this is a multiple personality package (Java and Ruby) # see also https://rubygems.org/downloads/jaro_winkler-1.5.1-java.gem @@ -29,23 +27,41 @@ class TestGemspecVersionConstant(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') - def test_version_constant_returns_none_for_elasticsearch(self): - test_file = self.get_test_loc('rubygems/version-constant/elasticsearch-api.gemspec') + def _check_version_constant_package(self, test_path, expected_name): + test_file = self.get_test_loc(test_path) packages = list(rubygems.GemspecHandler.parse(test_file)) assert packages pkg = packages[0] - assert pkg.name == 'elasticsearch-api' + assert pkg.name == expected_name assert pkg.version is None - assert 'Elasticsearch' not in str(pkg.version) assert pkg.download_url is None + assert pkg.api_data_url == f'https://rubygems.org/api/v1/versions/{expected_name}.json' + return pkg + + def test_version_constant_returns_none_for_elasticsearch(self): + pkg = self._check_version_constant_package( + test_path='rubygems/version-constant/elasticsearch-api.gemspec', + expected_name='elasticsearch-api', + ) + assert 'Elasticsearch' not in str(pkg.version) + + def test_version_constant_returns_none_for_excon(self): + self._check_version_constant_package( + test_path='rubygems/version-constant/excon.gemspec', + expected_name='excon', + ) + + def test_version_constant_returns_none_for_faraday(self): + self._check_version_constant_package( + test_path='rubygems/version-constant/faraday.gemspec', + expected_name='faraday', + ) def test_version_constant_returns_none_for_simple_constant(self): - test_file = self.get_test_loc('rubygems/version-constant/simple-constant.gemspec') - packages = list(rubygems.GemspecHandler.parse(test_file)) - assert packages - pkg = packages[0] - assert pkg.name == 'my-gem' - assert pkg.version is None + self._check_version_constant_package( + test_path='rubygems/version-constant/simple-constant.gemspec', + expected_name='my-gem', + ) def test_real_version_is_preserved(self): test_file = self.get_test_loc('rubygems/version-constant/simple-version.gemspec')