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

Metric collection for DotNet ecosystem and languages #11096

Closed
wants to merge 11 commits into from
Closed
4 changes: 4 additions & 0 deletions .github/workflows/sorbet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ jobs:
with:
bundler-cache: true

- run: bundle exec srb --version

- run: ruby -v

- run: bundle exec tapioca gem --verify

- run: bundle exec srb tc
Expand Down
90 changes: 88 additions & 2 deletions nuget/lib/dependabot/nuget/file_parser.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# typed: strong
# frozen_string_literal: true
# typed: strict

require "dependabot/dependency"
require "dependabot/file_parsers"
require "dependabot/file_parsers/base"
require "dependabot/nuget/native_discovery/native_discovery_json_reader"
require "dependabot/nuget/native_helpers"
require "dependabot/nuget/package_manager"
require "dependabot/nuget/language"
require "sorbet-runtime"

# For details on how dotnet handles version constraints, see:
Expand All @@ -22,8 +23,33 @@ def parse
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

sig { returns(T::Array[Dependabot::Dependency]) }
def content_json
@content_json ||= T.let(begin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier, I run into issues when I changed the public interface of this class. Try moving this into the private section below.

directory = source&.directory || "/"
discovery_json_reader = Dependabot::Nuget::NativeDiscoveryJsonReader.run_discovery_in_directory(
repo_contents_path: T.must(repo_contents_path),
directory: directory,
credentials: credentials
)
discovery_json_reader.dependency_set.dependencies
end, T.nilable(T::Array[Dependabot::Dependency]))
end

sig { returns(T::Array[Dependabot::Dependency]) }
def dependencies
@dependencies ||= T.let(begin
Expand Down Expand Up @@ -53,6 +79,66 @@ def check_required_files
"No project file."
)
end

sig { returns(T.nilable(Ecosystem::VersionManager)) }
def language
# Historically new version of language is released with incremental update of
# .Net version, so we tie the language with framework version for metric collection

nomenclature = "#{language_type} #{framework_version&.first}".strip.tr(" ", "-")

Dependabot.logger.info("Detected language and framework #{nomenclature}")

case language_type

when CSharpLanguage::TYPE
CSharpLanguage.new(nomenclature)

when VBLanguage::TYPE
VBLanguage.new(nomenclature)

when FSharpLanguage::TYPE
FSharpLanguage.new(nomenclature)

when DotNet::TYPE
DotNet.new(nomenclature)

end
end

sig { returns(T.nilable(T::Array[T.nilable(String)])) }
def framework_version
# pending due to some issue with sorbet during CI tests
[]
rescue StandardError
nil
end

sig { returns(T.nilable(String)) }
def language_type
requirement_files = dependencies.flat_map do |dep|
dep.requirements.map { |r| T.let(r.fetch(:file), String) }
end.uniq

return "cs" if requirement_files.any? { |f| File.basename(f).match?(/\.csproj$/) }
return "vb" if requirement_files.any? { |f| File.basename(f).match?(/\.vbproj$/) }
return "fs" if requirement_files.any? { |f| File.basename(f).match?(/\.fsproj$/) }

# return a fallback to avoid falling to exception
"dotnet"
end

sig { returns(Ecosystem::VersionManager) }
def package_manager
NugetPackageManager.new(nuget_version)
end
Copy link
Contributor

@amazimbe amazimbe Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nuget_version could be nil so you probably need T.must(nuget_version)


sig { returns(T.nilable(String)) }
def nuget_version
SharedHelpers.run_shell_command("dotnet nuget --version").split("Command Line").last&.strip
rescue StandardError
nil
end
end
end
end
Expand Down
82 changes: 82 additions & 0 deletions nuget/lib/dependabot/nuget/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# typed: strong
# frozen_string_literal: true

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

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

sig { params(language: String, raw_version: String, requirement: T.nilable(Requirement)).void }
def initialize(language, raw_version, requirement = nil)
super(language, Version.new(raw_version), [], [], requirement)
end
end

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

LANGUAGE = "CSharp"
TYPE = "cs"

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

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

sig { params(language: String, requirement: T.nilable(Requirement)).void }
def initialize(language, requirement = nil)
super(language, Version.new(nil), [], [], requirement)
end
end

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

LANGUAGE = "VB"
TYPE = "vb"

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

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

sig { params(language: String, requirement: T.nilable(Requirement)).void }
def initialize(language, requirement = nil)
super(language, Version.new(nil), [], [], requirement)
end
end

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

LANGUAGE = "FSharp"
TYPE = "fs"

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

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

sig { params(language: String, requirement: T.nilable(Requirement)).void }
def initialize(language, requirement = nil)
super(language, Version.new(nil), [], [], requirement)
end
end

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

TYPE = "dotnet"

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

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

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

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

module Dependabot
module Nuget
ECOSYSTEM = "dotnet"

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

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

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

NAME = "nuget"

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

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

sig do
params(
raw_version: T.nilable(String)
).void
end
def initialize(raw_version)
super(
NAME,
Version.new(raw_version),
SUPPORTED_VERSIONS,
DEPRECATED_VERSIONS
)
end

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

sig { override.returns(T::Boolean) }
def unsupported?
false
end
end
end
end
Loading
Loading