diff --git a/cargo/lib/dependabot/cargo/file_parser.rb b/cargo/lib/dependabot/cargo/file_parser.rb index 59c643e2ef..9780748f10 100644 --- a/cargo/lib/dependabot/cargo/file_parser.rb +++ b/cargo/lib/dependabot/cargo/file_parser.rb @@ -11,6 +11,8 @@ require "dependabot/cargo/version" require "dependabot/errors" require "dependabot/cargo/registry_fetcher" +require "dependabot/cargo/language" +require "dependabot/cargo/package_manager" # Relevant Cargo docs can be found at: # - https://doc.rust-lang.org/cargo/reference/manifest.html @@ -42,8 +44,50 @@ def parse end end + sig { returns(Ecosystem) } + def ecosystem + @ecosystem ||= T.let(begin + Ecosystem.new( + name: ECOSYSTEM, + package_manager: package_manager, + language: language + ) + end, T.nilable(Dependabot::Ecosystem)) + end + private + sig { returns(Ecosystem::VersionManager) } + def package_manager + @package_manager ||= T.let( + PackageManager.new(T.must(cargo_version)), + T.nilable(Dependabot::Cargo::PackageManager) + ) + end + + sig { returns(T.nilable(Ecosystem::VersionManager)) } + def language + @language ||= T.let(begin + Language.new(T.must(rust_version)) + end, T.nilable(Dependabot::Cargo::Language)) + end + + sig { returns(T.nilable(String)) } + def rust_version + @rust_version ||= T.let(begin + version = SharedHelpers.run_shell_command("rustc --version") + version.match(/rustc\s*(\d+\.\d+(.\d+)*)/)&.captures&.first + end, T.nilable(String)) + end + + sig { returns(T.nilable(String)) } + def cargo_version + @cargo_version ||= T.let(begin + version = SharedHelpers.run_shell_command("cargo --version") + version.match(/cargo\s*(\d+\.\d+(.\d+)*)/)&.captures&.first + end, T.nilable(String)) + end + def check_rust_workspace_root cargo_toml = dependency_files.find { |f| f.name == "Cargo.toml" } workspace_root = parsed_file(cargo_toml).dig("package", "workspace") diff --git a/cargo/lib/dependabot/cargo/language.rb b/cargo/lib/dependabot/cargo/language.rb new file mode 100644 index 0000000000..9262d86e99 --- /dev/null +++ b/cargo/lib/dependabot/cargo/language.rb @@ -0,0 +1,24 @@ +# typed: strong +# frozen_string_literal: true + +require "sorbet-runtime" +require "dependabot/ecosystem" +require "dependabot/cargo/version" + +module Dependabot + module Cargo + LANGUAGE = "rust" + + class Language < Dependabot::Ecosystem::VersionManager + extend T::Sig + + sig { params(raw_version: String).void } + def initialize(raw_version) + super( + LANGUAGE, + Version.new(raw_version) + ) + end + end + end +end diff --git a/cargo/lib/dependabot/cargo/package_manager.rb b/cargo/lib/dependabot/cargo/package_manager.rb new file mode 100644 index 0000000000..3617b5afd0 --- /dev/null +++ b/cargo/lib/dependabot/cargo/package_manager.rb @@ -0,0 +1,41 @@ +# typed: strong +# frozen_string_literal: true + +require "sorbet-runtime" +require "dependabot/ecosystem" +require "dependabot/cargo/version" + +module Dependabot + module Cargo + ECOSYSTEM = "rust" + PACKAGE_MANAGER = "cargo" + SUPPORTED_CARGO_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version]) + + # When a version is going to be unsupported, it will be added here + DEPRECATED_CARGO_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version]) + + class PackageManager < Dependabot::Ecosystem::VersionManager + extend T::Sig + + sig { params(raw_version: String).void } + def initialize(raw_version) + super( + PACKAGE_MANAGER, + Version.new(raw_version), + DEPRECATED_CARGO_VERSIONS, + SUPPORTED_CARGO_VERSIONS + ) + end + + sig { returns(T::Boolean) } + def deprecated? + false + end + + sig { returns(T::Boolean) } + def unsupported? + false + end + end + end +end diff --git a/cargo/spec/dependabot/cargo/file_parser_spec.rb b/cargo/spec/dependabot/cargo/file_parser_spec.rb index 54feee14ed..bc64eef655 100644 --- a/cargo/spec/dependabot/cargo/file_parser_spec.rb +++ b/cargo/spec/dependabot/cargo/file_parser_spec.rb @@ -854,4 +854,32 @@ end end end + + describe "#ecosystem" do + subject(:ecosystem) { parser.ecosystem } + + it "has the correct name" do + expect(ecosystem.name).to eq "rust" + end + + describe "#package_manager" do + subject(:package_manager) { ecosystem.package_manager } + + it "returns the correct package manager" do + expect(package_manager.name).to eq "cargo" + expect(package_manager.requirement).to be_nil + expect(package_manager.version.to_s).to eq "1.82.0" + end + end + + describe "#language" do + subject(:language) { ecosystem.language } + + it "returns the correct language" do + expect(language.name).to eq "rust" + expect(language.requirement).to be_nil + expect(language.version.to_s).to eq "1.82.0" + end + end + end end diff --git a/cargo/spec/dependabot/cargo/language_spec.rb b/cargo/spec/dependabot/cargo/language_spec.rb new file mode 100644 index 0000000000..1e41d9832d --- /dev/null +++ b/cargo/spec/dependabot/cargo/language_spec.rb @@ -0,0 +1,35 @@ +# typed: false +# frozen_string_literal: true + +require "dependabot/cargo/language" +require "dependabot/ecosystem" +require "spec_helper" + +RSpec.describe Dependabot::Cargo::Language do + let(:language) { described_class.new(version) } + let(:version) { "3.0.0" } + + describe "#version" do + it "returns the version" do + expect(language.version).to eq(Dependabot::Cargo::Version.new(version)) + end + end + + describe "#name" do + it "returns the name" do + expect(language.name).to eq(Dependabot::Cargo::LANGUAGE) + end + end + + describe "#unsupported?" do + it "returns false by default" do + expect(language.unsupported?).to be false + end + end + + describe "#deprecated?" do + it "returns false by default" do + expect(language.deprecated?).to be false + end + end +end diff --git a/cargo/spec/dependabot/cargo/package_manager_spec.rb b/cargo/spec/dependabot/cargo/package_manager_spec.rb new file mode 100644 index 0000000000..426e27f235 --- /dev/null +++ b/cargo/spec/dependabot/cargo/package_manager_spec.rb @@ -0,0 +1,36 @@ +# typed: false +# frozen_string_literal: true + +require "dependabot/cargo/package_manager" +require "dependabot/ecosystem" +require "spec_helper" + +RSpec.describe Dependabot::Cargo::PackageManager do + subject(:package_manager) { described_class.new(version) } + + let(:version) { "1.12" } + + describe "#version" do + it "returns the version" do + expect(package_manager.version).to eq(Dependabot::Cargo::Version.new(version)) + end + end + + describe "#name" do + it "returns the name" do + expect(package_manager.name).to eq(Dependabot::Cargo::PACKAGE_MANAGER) + end + end + + describe "#deprecated_versions" do + it "returns deprecated versions" do + expect(package_manager.deprecated_versions).to eq(Dependabot::Cargo::DEPRECATED_CARGO_VERSIONS) + end + end + + describe "#supported_versions" do + it "returns supported versions" do + expect(package_manager.supported_versions).to eq(Dependabot::Cargo::SUPPORTED_CARGO_VERSIONS) + end + end +end