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

Add support for devcontainers ecosystem metrics collection #11047

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions common/lib/dependabot/ecosystem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class VersionManager
extend T::Sig
extend T::Helpers

DEFAULT_VERSION_PATTERN = /(\d+\.\d+(.\d+)*)/

abstract!
# Initialize version information for a package manager or language.
# @param name [String] the name of the package manager or language (e.g., "bundler", "ruby").
Expand Down
51 changes: 51 additions & 0 deletions devcontainers/lib/dependabot/devcontainers/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
require "dependabot/file_parsers"
require "dependabot/file_parsers/base"
require "dependabot/devcontainers/version"
require "dependabot/devcontainers/language"
require "dependabot/devcontainers/package_manager"
require "dependabot/devcontainers/file_parser/feature_dependency_parser"

module Dependabot
Expand All @@ -28,6 +30,17 @@ def parse
dependency_set.dependencies
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 { override.void }
Expand Down Expand Up @@ -55,6 +68,44 @@ def config_dependency_files
T.nilable(T::Array[Dependabot::DependencyFile])
)
end

sig { returns(Ecosystem::VersionManager) }
def package_manager
@package_manager ||= T.let(
PackageManager.new(T.must(devcontainer_version)),
T.nilable(Dependabot::Devcontainers::PackageManager)
)
end

sig { returns(T.nilable(Ecosystem::VersionManager)) }
def language
@language ||= T.let(
Language.new(T.must(node_version)),
T.nilable(Dependabot::Devcontainers::Language)
)
end

sig { returns(T.nilable(String)) }
def devcontainer_version
@devcontainer_version ||= T.let(
begin
version = SharedHelpers.run_shell_command("devcontainer --version")
version.match(Dependabot::Ecosystem::VersionManager::DEFAULT_VERSION_PATTERN)&.captures&.first
end,
T.nilable(String)
)
end

sig { returns(T.nilable(String)) }
def node_version
@node_version ||= T.let(
begin
version = SharedHelpers.run_shell_command("node --version")
version.match(Dependabot::Ecosystem::VersionManager::DEFAULT_VERSION_PATTERN)&.captures&.first
end,
T.nilable(String)
)
end
end
end
end
Expand Down
21 changes: 21 additions & 0 deletions devcontainers/lib/dependabot/devcontainers/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/ecosystem"
require "dependabot/devcontainers/version"

module Dependabot
module Devcontainers
LANGUAGE = "node"

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
41 changes: 41 additions & 0 deletions devcontainers/lib/dependabot/devcontainers/package_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# typed: strong
# frozen_string_literal: true

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

module Dependabot
module Devcontainers
ECOSYSTEM = "devcontainers"
PACKAGE_MANAGER = "devcontainers"
SUPPORTED_DEVCONTAINER_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

# When a version is going to be unsupported, it will be added here
DEPRECATED_DEVCONTAINER_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_DEVCONTAINER_VERSIONS,
SUPPORTED_DEVCONTAINER_VERSIONS
)
end

sig { returns(T::Boolean) }
def deprecated?
false
end

sig { returns(T::Boolean) }
def unsupported?
false
end
end
end
end
31 changes: 31 additions & 0 deletions devcontainers/spec/dependabot/devcontainers/file_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,35 @@
expect(dependencies).to be_empty
end
end

describe "#ecosystem" do
subject(:ecosystem) { parser.ecosystem }

let(:project_name) { "config_in_root" }
let(:directory) { "/" }

it "has the correct name" do
expect(ecosystem.name).to eq "devcontainers"
end

describe "#package_manager" do
subject(:package_manager) { ecosystem.package_manager }

it "returns the correct package manager" do
expect(package_manager.name).to eq "devcontainers"
expect(package_manager.requirement).to be_nil
expect(package_manager.version.to_s).to eq "0.72.0"
end
end

describe "#language" do
subject(:language) { ecosystem.language }

it "returns the correct language" do
expect(language.name).to eq "node"
expect(language.requirement).to be_nil
expect(language.version.to_s).to eq "18.20.5"
end
end
end
end
36 changes: 36 additions & 0 deletions devcontainers/spec/dependabot/devcontainers/language_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# typed: false
# frozen_string_literal: true

require "dependabot/devcontainers/language"
require "dependabot/ecosystem"
require "spec_helper"

RSpec.describe Dependabot::Devcontainers::Language do
subject(:language) { described_class.new(version) }

let(:version) { "1.17.3" }

describe "#version" do
it "returns the version" do
expect(language.version.to_s).to eq version
end
end

describe "#name" do
it "returns the name" do
expect(language.name).to eq(Dependabot::Devcontainers::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
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# typed: false
# frozen_string_literal: true

require "dependabot/devcontainers/package_manager"
require "dependabot/ecosystem"
require "spec_helper"

RSpec.describe Dependabot::Devcontainers::PackageManager do
subject(:package_manager) { described_class.new(version) }

let(:version) { "2.1.1" }

describe "#version" do
it "returns the version" do
expect(package_manager.version.to_s).to eq version
end
end

describe "#name" do
it "returns the name" do
expect(package_manager.name).to eq(Dependabot::Devcontainers::PACKAGE_MANAGER)
end
end

describe "#deprecated_versions" do
it "returns deprecated versions" do
expect(package_manager.deprecated_versions).to eq(Dependabot::Devcontainers::DEPRECATED_DEVCONTAINER_VERSIONS)
end
end

describe "#supported_versions" do
it "returns supported versions" do
expect(package_manager.supported_versions).to eq(Dependabot::Devcontainers::SUPPORTED_DEVCONTAINER_VERSIONS)
end
end
end
Loading