Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables python ecosystem metric collection #10986

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions python/lib/dependabot/python/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
require "dependabot/shared_helpers"
require "dependabot/python/requirement"
require "dependabot/errors"
require "dependabot/python/language"
require "dependabot/python/native_helpers"
require "dependabot/python/name_normaliser"
require "dependabot/python/pip_compile_file_matcher"
require "dependabot/python/language_version_manager"
require "dependabot/python/package_manager"

module Dependabot
module Python
Expand Down Expand Up @@ -48,8 +51,62 @@ def parse
dependency_set.dependencies
end

sig { returns(Ecosystem) }
def ecosystem
@ecosystem ||= T.let(
Ecosystem.new(
name: ECOSYSTEM,
package_manager: package_manager,
language: language
),
T.nilable(Ecosystem)
)
end

private

def language_version_manager
@language_version_manager ||=
LanguageVersionManager.new(
python_requirement_parser: python_requirement_parser
)
end

def python_requirement_parser
@python_requirement_parser ||=
FileParser::PythonRequirementParser.new(
dependency_files: dependency_files
)
end

sig { returns(Ecosystem::VersionManager) }
def package_manager
@package_manager ||= PackageManager.new(python_raw_version, package_manager_requirement)
sachin-sandhu marked this conversation as resolved.
Show resolved Hide resolved
end

def package_manager_requirement
nil
end
sachin-sandhu marked this conversation as resolved.
Show resolved Hide resolved

sig { returns(String) }
def python_raw_version
language_version_manager.python_version
end

sig { returns(T.nilable(Ecosystem::VersionManager)) }
def language
return @language if defined?(@language)

return nil if package_manager.unsupported?

Language.new(python_raw_version, language_requirement)
end

def language_requirement
# will be implemented in subsequent PRs as this needs more work
nil
end
sachin-sandhu marked this conversation as resolved.
Show resolved Hide resolved

def requirement_files
dependency_files.select { |f| f.name.end_with?(".txt", ".in") }
end
Expand Down
21 changes: 21 additions & 0 deletions python/lib/dependabot/python/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# typed: strong
# frozen_string_literal: true

require "sorbet-runtime"
require "dependabot/python/version"
require "dependabot/ecosystem"

module Dependabot
module Python
LANGUAGE = "python"

class Language < Dependabot::Ecosystem::VersionManager
extend T::Sig

sig { params(raw_version: String, requirement: T.nilable(Requirement)).void }
def initialize(raw_version, requirement = nil)
super(LANGUAGE, Version.new(raw_version), [], [], requirement)
end
end
end
end
39 changes: 39 additions & 0 deletions python/lib/dependabot/python/package_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# typed: strong
# frozen_string_literal: true

require "sorbet-runtime"
require "dependabot/python/version"
require "dependabot/ecosystem"
require "dependabot/python/requirement"

module Dependabot
module Python
ECOSYSTEM = "Python"
PACKAGE_MANAGER = "Python"
sachin-sandhu marked this conversation as resolved.
Show resolved Hide resolved

# Keep versions in ascending order
SUPPORTED_PYTHON_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

DEPRECATED_PYTHON_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

class PackageManager < Dependabot::Ecosystem::VersionManager
extend T::Sig

sig do
params(
raw_version: String,
requirement: T.nilable(Requirement)
).void
end
def initialize(raw_version, requirement = nil)
super(
PACKAGE_MANAGER,
Version.new(raw_version),
DEPRECATED_PYTHON_VERSIONS,
SUPPORTED_PYTHON_VERSIONS,
requirement,
)
end
end
end
end
81 changes: 81 additions & 0 deletions python/spec/dependabot/python/package_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# typed: false
# frozen_string_literal: true

require "dependabot/python/package_manager"
require "dependabot/ecosystem"
require "spec_helper"

RSpec.describe Dependabot::Python::PackageManager do
let(:package_manager) { described_class.new(version, requirement) }
let(:requirement) { nil }

describe "#initialize" do
context "when version is a String" do
let(:version) { "3.11.2" }

it "sets the version correctly" do
expect(package_manager.version).to eq(Dependabot::Python::Version.new(version))
end

it "sets the name correctly" do
expect(package_manager.name).to eq(Dependabot::Python::PACKAGE_MANAGER)
end
end

context "when version is a Dependabot::Python::Version" do
let(:version) { "2" }

it "sets the version correctly" do
expect(package_manager.version).to eq(version)
end

it "sets the name correctly" do
expect(package_manager.name).to eq(Dependabot::Python::PACKAGE_MANAGER)
end
end

context "when a requirement is provided" do
let(:version) { "2.1" }
let(:requirement) { Dependabot::Python::Requirement.new(">= 1.12.0, ~> 2.3.0") }

it "sets the requirement correctly" do
expect(package_manager.requirement.to_s).to eq(">= 1.12.0, ~> 2.3.0")
end

it "calculates the correct min_version" do
expect(package_manager.requirement.min_version).to eq(Dependabot::Version.new("2.3.0"))
end

it "calculates the correct max_version" do
expect(package_manager.requirement.max_version).to eq(Dependabot::Version.new("2.4.0"))
end
end

context "when a single minimum constraint is provided" do
let(:version) { "2.1" }
let(:requirement) { Dependabot::Python::Requirement.new(">= 1.5") }

it "sets the requirement correctly" do
expect(package_manager.requirement.to_s).to eq(">= 1.5")
end

it "calculates the correct min_version" do
expect(package_manager.requirement.min_version).to eq(Dependabot::Version.new("1.5"))
end

it "returns nil for max_version" do
expect(package_manager.requirement.max_version).to be_nil
end
end
end

describe "#raise_if_unsupported!" do
context "when version is supported" do
let(:version) { "2.1" }

it "does not raise an error" do
expect { package_manager.raise_if_unsupported! }.not_to raise_error
end
end
end
end
Loading