Skip to content

Commit

Permalink
Add support for hex ecosystem metrics collection (dependabot#11023)
Browse files Browse the repository at this point in the history
* Add support for hex ecosystem metrics collection

* Temporarily disable language requirement

* Remove inconsistent language requirement
  • Loading branch information
amazimbe authored Dec 2, 2024
1 parent 5d96f2d commit 59effb5
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 0 deletions.
52 changes: 52 additions & 0 deletions hex/lib/dependabot/hex/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
require "dependabot/file_parsers/base"
require "dependabot/hex/file_updater/mixfile_sanitizer"
require "dependabot/hex/native_helpers"
require "dependabot/hex/language"
require "dependabot/hex/package_manager"
require "dependabot/hex/requirement"
require "dependabot/shared_helpers"
require "dependabot/errors"

# For docs, see https://hexdocs.pm/mix/Mix.Tasks.Deps.html
module Dependabot
module Hex
extend T::Sig
class FileParser < Dependabot::FileParsers::Base
extend T::Sig
require "dependabot/file_parsers/base/dependency_set"
Expand Down Expand Up @@ -44,6 +48,17 @@ def parse
dependency_set.dependencies.sort_by(&:name)
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(T::Array[T.any(T::Hash[String, String], T::Hash[String, T.untyped])]) }
Expand Down Expand Up @@ -137,6 +152,43 @@ def mixfiles
def lockfile
@lockfile ||= T.let(get_original_file("mix.lock"), T.nilable(Dependabot::DependencyFile))
end

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

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

sig { returns(String) }
def hex_version
T.must(T.must(hex_info).fetch(:hex_version))
end

sig { returns(String) }
def elixir_version
T.must(T.must(hex_info).fetch(:elixir_version))
end

sig { returns(T.nilable(T::Hash[Symbol, T.nilable(String)])) }
def hex_info
@hex_info ||= T.let(begin
version = SharedHelpers.run_shell_command("mix hex.info")
{
hex_version: version.match(/Hex: \s*(\d+\.\d+(.\d+)*)/)&.captures&.first,
elixir_version: version.match(/Elixir: \s*(\d+\.\d+(.\d+)*)/)&.captures&.first
}
end, T.nilable(T::Hash[Symbol, T.nilable(String)]))
end
end
end
end
Expand Down
21 changes: 21 additions & 0 deletions hex/lib/dependabot/hex/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/hex/version"

module Dependabot
module Hex
LANGUAGE = "elixir"

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 hex/lib/dependabot/hex/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/hex/version"

module Dependabot
module Hex
ECOSYSTEM = "hex"
PACKAGE_MANAGER = "hex"
SUPPORTED_HEX_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

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

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

sig { returns(T::Boolean) }
def unsupported?
false
end
end
end
end
28 changes: 28 additions & 0 deletions hex/spec/dependabot/hex/file_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -452,4 +452,32 @@
end
end
end

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

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

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

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

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

it "returns the correct language" do
expect(language.name).to eq "elixir"
expect(language.requirement).to be_nil
expect(language.version.to_s).to eq "1.14.4"
end
end
end
end
36 changes: 36 additions & 0 deletions hex/spec/dependabot/hex/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/hex/language"
require "dependabot/ecosystem"
require "spec_helper"

RSpec.describe Dependabot::Hex::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 eq(Dependabot::Hex::Version.new(version))
end
end

describe "#name" do
it "returns the name" do
expect(language.name).to eq(Dependabot::Hex::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
36 changes: 36 additions & 0 deletions hex/spec/dependabot/hex/package_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# typed: false
# frozen_string_literal: true

require "dependabot/hex/package_manager"
require "dependabot/ecosystem"
require "spec_helper"

RSpec.describe Dependabot::Hex::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 eq(Dependabot::Hex::Version.new(version))
end
end

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

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

describe "#supported_versions" do
it "returns supported versions" do
expect(package_manager.supported_versions).to eq(Dependabot::Hex::SUPPORTED_HEX_VERSIONS)
end
end
end

0 comments on commit 59effb5

Please sign in to comment.