dependabot-nuget 0.289.0 → 0.291.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +26 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +2 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +1 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +6 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -9
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +2 -0
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +17 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +44 -5
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +19 -11
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +1 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +24 -4
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +2 -1
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -2
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +43 -18
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +13 -12
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +40 -14
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +2 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +45 -7
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +2 -2
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +0 -4
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +41 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -0
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -1
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +2 -1
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +7 -31
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +340 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +0 -12
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +55 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -6
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +785 -755
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +2 -2
  61. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +1 -1
  62. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  63. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  64. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  65. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  66. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  67. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  68. data/lib/dependabot/nuget/file_fetcher.rb +3 -3
  69. data/lib/dependabot/nuget/file_parser.rb +92 -3
  70. data/lib/dependabot/nuget/file_updater.rb +13 -13
  71. data/lib/dependabot/nuget/language.rb +82 -0
  72. data/lib/dependabot/nuget/native_helpers.rb +37 -5
  73. data/lib/dependabot/nuget/package_manager.rb +51 -0
  74. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  75. data/lib/dependabot/nuget/update_checker.rb +116 -190
  76. metadata +20 -29
  77. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  78. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  79. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  80. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -122
  81. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -277
  82. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  83. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -104
  84. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  85. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -61
  86. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  87. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -214
  88. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  89. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  90. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  91. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  92. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  93. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  94. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  95. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  96. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  97. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -1,102 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/nuget/native_discovery/native_evaluation_details"
5
- require "sorbet-runtime"
6
-
7
- module Dependabot
8
- module Nuget
9
- class NativeDependencyDetails
10
- extend T::Sig
11
-
12
- sig { params(json: T::Hash[String, T.untyped]).returns(NativeDependencyDetails) }
13
- def self.from_json(json)
14
- name = T.let(json.fetch("Name"), String)
15
- version = T.let(json.fetch("Version"), T.nilable(String))
16
- type = T.let(json.fetch("Type"), String)
17
- evaluation = NativeEvaluationDetails
18
- .from_json(T.let(json.fetch("EvaluationResult"), T.nilable(T::Hash[String, T.untyped])))
19
- target_frameworks = T.let(json.fetch("TargetFrameworks"), T.nilable(T::Array[String]))
20
- is_dev_dependency = T.let(json.fetch("IsDevDependency"), T::Boolean)
21
- is_direct = T.let(json.fetch("IsDirect"), T::Boolean)
22
- is_transitive = T.let(json.fetch("IsTransitive"), T::Boolean)
23
- is_override = T.let(json.fetch("IsOverride"), T::Boolean)
24
- is_update = T.let(json.fetch("IsUpdate"), T::Boolean)
25
- info_url = T.let(json.fetch("InfoUrl"), T.nilable(String))
26
-
27
- NativeDependencyDetails.new(name: name,
28
- version: version,
29
- type: type,
30
- evaluation: evaluation,
31
- target_frameworks: target_frameworks,
32
- is_dev_dependency: is_dev_dependency,
33
- is_direct: is_direct,
34
- is_transitive: is_transitive,
35
- is_override: is_override,
36
- is_update: is_update,
37
- info_url: info_url)
38
- end
39
-
40
- sig do
41
- params(name: String,
42
- version: T.nilable(String),
43
- type: String,
44
- evaluation: T.nilable(NativeEvaluationDetails),
45
- target_frameworks: T.nilable(T::Array[String]),
46
- is_dev_dependency: T::Boolean,
47
- is_direct: T::Boolean,
48
- is_transitive: T::Boolean,
49
- is_override: T::Boolean,
50
- is_update: T::Boolean,
51
- info_url: T.nilable(String)).void
52
- end
53
- def initialize(name:, version:, type:, evaluation:, target_frameworks:, is_dev_dependency:, is_direct:,
54
- is_transitive:, is_override:, is_update:, info_url:)
55
- @name = name
56
- @version = version
57
- @type = type
58
- @evaluation = evaluation
59
- @target_frameworks = target_frameworks
60
- @is_dev_dependency = is_dev_dependency
61
- @is_direct = is_direct
62
- @is_transitive = is_transitive
63
- @is_override = is_override
64
- @is_update = is_update
65
- @info_url = info_url
66
- end
67
-
68
- sig { returns(String) }
69
- attr_reader :name
70
-
71
- sig { returns(T.nilable(String)) }
72
- attr_reader :version
73
-
74
- sig { returns(String) }
75
- attr_reader :type
76
-
77
- sig { returns(T.nilable(NativeEvaluationDetails)) }
78
- attr_reader :evaluation
79
-
80
- sig { returns(T.nilable(T::Array[String])) }
81
- attr_reader :target_frameworks
82
-
83
- sig { returns(T::Boolean) }
84
- attr_reader :is_dev_dependency
85
-
86
- sig { returns(T::Boolean) }
87
- attr_reader :is_direct
88
-
89
- sig { returns(T::Boolean) }
90
- attr_reader :is_transitive
91
-
92
- sig { returns(T::Boolean) }
93
- attr_reader :is_override
94
-
95
- sig { returns(T::Boolean) }
96
- attr_reader :is_update
97
-
98
- sig { returns(T.nilable(String)) }
99
- attr_reader :info_url
100
- end
101
- end
102
- end
@@ -1,122 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/nuget/native_discovery/native_dependency_details"
5
- require "sorbet-runtime"
6
-
7
- module Dependabot
8
- module Nuget
9
- class NativeDependencyFileDiscovery
10
- extend T::Sig
11
-
12
- sig do
13
- params(json: T.nilable(T::Hash[String, T.untyped]),
14
- directory: String).returns(T.nilable(NativeDependencyFileDiscovery))
15
- end
16
- def self.from_json(json, directory)
17
- return nil if json.nil?
18
-
19
- file_path = File.join(directory, T.let(json.fetch("FilePath"), String))
20
- dependencies = T.let(json.fetch("Dependencies"), T::Array[T::Hash[String, T.untyped]]).map do |dep|
21
- NativeDependencyDetails.from_json(dep)
22
- end
23
-
24
- NativeDependencyFileDiscovery.new(file_path: file_path,
25
- dependencies: dependencies)
26
- end
27
-
28
- sig do
29
- params(file_path: String,
30
- dependencies: T::Array[NativeDependencyDetails]).void
31
- end
32
- def initialize(file_path:, dependencies:)
33
- @file_path = file_path
34
- @dependencies = dependencies
35
- end
36
-
37
- sig { returns(String) }
38
- attr_reader :file_path
39
-
40
- sig { returns(T::Array[NativeDependencyDetails]) }
41
- attr_reader :dependencies
42
-
43
- sig { overridable.returns(Dependabot::FileParsers::Base::DependencySet) }
44
- def dependency_set # rubocop:disable Metrics/PerceivedComplexity
45
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
46
-
47
- file_name = Pathname.new(file_path).cleanpath.to_path
48
- dependencies.each do |dependency|
49
- next if dependency.name.casecmp("Microsoft.NET.Sdk")&.zero?
50
-
51
- # If the version string was evaluated it must have been successfully resolved
52
- if dependency.evaluation && dependency.evaluation&.result_type != "Success"
53
- logger.warn "Dependency '#{dependency.name}' excluded due to unparsable version: #{dependency.version}"
54
- next
55
- end
56
-
57
- # Exclude any dependencies using version ranges or wildcards
58
- next if dependency.version&.include?(",") ||
59
- dependency.version&.include?("*")
60
-
61
- # Exclude any dependencies specified using interpolation
62
- next if dependency.name.include?("%(") ||
63
- dependency.version&.include?("%(")
64
-
65
- # Exclude any dependencies which reference an item type
66
- next if dependency.name.include?("@(")
67
-
68
- dependency_set << build_dependency(file_name, dependency)
69
- end
70
-
71
- dependency_set
72
- end
73
-
74
- private
75
-
76
- sig { returns(::Logger) }
77
- def logger
78
- Dependabot.logger
79
- end
80
-
81
- sig { params(file_name: String, dependency_details: NativeDependencyDetails).returns(Dependabot::Dependency) }
82
- def build_dependency(file_name, dependency_details)
83
- requirement = build_requirement(file_name, dependency_details)
84
- requirements = requirement.nil? ? [] : [requirement]
85
-
86
- version = dependency_details.version&.gsub(/[\(\)\[\]]/, "")&.strip
87
- version = nil if version&.empty?
88
-
89
- Dependency.new(
90
- name: dependency_details.name,
91
- version: version,
92
- package_manager: "nuget",
93
- requirements: requirements
94
- )
95
- end
96
-
97
- sig do
98
- params(file_name: String, dependency_details: NativeDependencyDetails)
99
- .returns(T.nilable(T::Hash[Symbol, T.untyped]))
100
- end
101
- def build_requirement(file_name, dependency_details)
102
- return if dependency_details.is_transitive
103
-
104
- version = dependency_details.version
105
- version = nil if version&.empty?
106
-
107
- requirement = {
108
- requirement: version,
109
- file: file_name,
110
- groups: [dependency_details.is_dev_dependency ? "devDependencies" : "dependencies"],
111
- source: nil
112
- }
113
-
114
- property_name = dependency_details.evaluation&.root_property_name
115
- return requirement unless property_name
116
-
117
- requirement[:metadata] = { property_name: property_name }
118
- requirement
119
- end
120
- end
121
- end
122
- end
@@ -1,277 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/dependency"
5
- require "dependabot/file_parsers/base/dependency_set"
6
- require "dependabot/nuget/cache_manager"
7
- require "dependabot/nuget/native_discovery/native_workspace_discovery"
8
- require "json"
9
- require "sorbet-runtime"
10
-
11
- module Dependabot
12
- module Nuget
13
- class NativeDiscoveryJsonReader
14
- extend T::Sig
15
-
16
- sig { returns(T::Hash[String, NativeDiscoveryJsonReader]) }
17
- def self.cache_directory_to_discovery_json_reader
18
- CacheManager.cache("cache_directory_to_discovery_json_reader")
19
- end
20
-
21
- sig { returns(T::Hash[String, NativeDiscoveryJsonReader]) }
22
- def self.cache_dependency_file_paths_to_discovery_json_reader
23
- CacheManager.cache("cache_dependency_file_paths_to_discovery_json_reader")
24
- end
25
-
26
- sig { returns(T::Hash[String, String]) }
27
- def self.cache_dependency_file_paths_to_discovery_json_path
28
- CacheManager.cache("cache_dependency_file_paths_to_discovery_json_path")
29
- end
30
-
31
- sig { void }
32
- def self.testonly_clear_caches
33
- cache_directory_to_discovery_json_reader.clear
34
- cache_dependency_file_paths_to_discovery_json_reader.clear
35
- cache_dependency_file_paths_to_discovery_json_path.clear
36
- end
37
-
38
- sig { void }
39
- def self.testonly_clear_discovery_files
40
- # this will get recreated when necessary
41
- FileUtils.rm_rf(discovery_directory)
42
- end
43
-
44
- sig { params(error_if_missing: T::Boolean).void }
45
- def self.debug_report_discovery_files(error_if_missing:)
46
- if File.exist?(discovery_map_file_path)
47
- Dependabot.logger.info("Discovery map file (#{discovery_map_file_path}) contents: " \
48
- "#{File.read(discovery_map_file_path)}")
49
- Dependabot.logger.info("Discovery files: #{Dir.glob(File.join(discovery_directory, '*'))}")
50
- elsif error_if_missing
51
- Dependabot.logger.error("discovery map file missing")
52
- end
53
- end
54
-
55
- # Runs NuGet dependency discovery in the given directory and returns a new instance of NativeDiscoveryJsonReader.
56
- # The location of the resultant JSON file is saved.
57
- sig do
58
- params(
59
- repo_contents_path: String,
60
- directory: String,
61
- credentials: T::Array[Dependabot::Credential]
62
- ).returns(NativeDiscoveryJsonReader)
63
- end
64
- def self.run_discovery_in_directory(repo_contents_path:, directory:, credentials:)
65
- # run discovery
66
- job_file_path = ENV.fetch("DEPENDABOT_JOB_PATH")
67
- discovery_json_path = discovery_file_path_from_workspace_path(directory)
68
- unless File.exist?(discovery_json_path)
69
- NativeHelpers.run_nuget_discover_tool(job_path: job_file_path,
70
- repo_root: repo_contents_path,
71
- workspace_path: directory,
72
- output_path: discovery_json_path,
73
- credentials: credentials)
74
-
75
- Dependabot.logger.info("Discovery JSON content: #{File.read(discovery_json_path)}")
76
- end
77
- load_discovery_for_directory(repo_contents_path: repo_contents_path, directory: directory)
78
- end
79
-
80
- # Loads NuGet dependency discovery for the given directory and returns a new instance of
81
- # NativeDiscoveryJsonReader and caches the resultant object.
82
- sig { params(repo_contents_path: String, directory: String).returns(NativeDiscoveryJsonReader) }
83
- def self.load_discovery_for_directory(repo_contents_path:, directory:)
84
- cache_directory_to_discovery_json_reader[directory] ||= begin
85
- discovery_json_reader = discovery_json_reader(repo_contents_path: repo_contents_path,
86
- workspace_path: directory)
87
- cache_directory_to_discovery_json_reader[directory] = discovery_json_reader
88
- dependency_file_cache_key = cache_key_from_dependency_file_paths(discovery_json_reader.dependency_file_paths)
89
- cache_dependency_file_paths_to_discovery_json_reader[dependency_file_cache_key] = discovery_json_reader
90
- discovery_file_path = discovery_file_path_from_workspace_path(directory)
91
- cache_dependency_file_paths_to_discovery_json_path[dependency_file_cache_key] = discovery_file_path
92
-
93
- discovery_json_reader
94
- end
95
- end
96
-
97
- # Retrieves the cached NativeDiscoveryJsonReader object for the given dependency file paths.
98
- sig { params(dependency_file_paths: T::Array[String]).returns(NativeDiscoveryJsonReader) }
99
- def self.load_discovery_for_dependency_file_paths(dependency_file_paths)
100
- dependency_file_cache_key = cache_key_from_dependency_file_paths(dependency_file_paths)
101
- T.must(cache_dependency_file_paths_to_discovery_json_reader[dependency_file_cache_key])
102
- end
103
-
104
- # Retrieves the cached location of the discovery JSON file for the given dependency file paths.
105
- sig { params(dependency_file_paths: T::Array[String]).returns(String) }
106
- def self.get_discovery_json_path_for_dependency_file_paths(dependency_file_paths)
107
- dependency_file_cache_key = cache_key_from_dependency_file_paths(dependency_file_paths)
108
- T.must(cache_dependency_file_paths_to_discovery_json_path[dependency_file_cache_key])
109
- end
110
-
111
- sig { params(repo_contents_path: String, dependency_file: Dependabot::DependencyFile).returns(String) }
112
- def self.dependency_file_path(repo_contents_path:, dependency_file:)
113
- dep_file_path = Pathname.new(File.join(dependency_file.directory, dependency_file.name)).cleanpath.to_path
114
- dep_file_path.delete_prefix("#{repo_contents_path}/")
115
- end
116
-
117
- sig { returns(String) }
118
- def self.discovery_map_file_path
119
- File.join(discovery_directory, "discovery_map.json")
120
- end
121
-
122
- sig { params(workspace_path: String).returns(String) }
123
- def self.discovery_file_path_from_workspace_path(workspace_path)
124
- # Given an update directory (also known as a workspace path), this function returns the path where the discovery
125
- # JSON file is located. This function is called both by methods that need to write the discovery JSON file and
126
- # by methods that need to read the discovery JSON file. This function is also called by multiple processes so
127
- # we need a way to retain the data. This is accomplished by the following steps:
128
- # 1. Check a well-known file for a mapping of workspace_path => discovery file path. If found, return it.
129
- # 2. If the path is not found, generate a new path, save it to the well-known file, and return the value.
130
- discovery_map_contents = File.exist?(discovery_map_file_path) ? File.read(discovery_map_file_path) : "{}"
131
- discovery_map = T.let(JSON.parse(discovery_map_contents), T::Hash[String, String])
132
-
133
- discovery_json_path = discovery_map[workspace_path]
134
- if discovery_json_path
135
- Dependabot.logger.info("Discovery JSON path for workspace path [#{workspace_path}] found in file " \
136
- "[#{discovery_map_file_path}] at location [#{discovery_json_path}]")
137
- return discovery_json_path
138
- end
139
-
140
- # no discovery JSON path found; generate a new one, but first find a suitable location
141
- discovery_json_counter = 1
142
- new_discovery_json_path = ""
143
- loop do
144
- new_discovery_json_path = File.join(discovery_directory, "discovery.#{discovery_json_counter}.json")
145
- break unless File.exist?(new_discovery_json_path)
146
-
147
- discovery_json_counter += 1
148
- end
149
-
150
- discovery_map[workspace_path] = new_discovery_json_path
151
-
152
- File.write(discovery_map_file_path, discovery_map.to_json)
153
- Dependabot.logger.info("Discovery JSON path for workspace path [#{workspace_path}] created for file " \
154
- "[#{discovery_map_file_path}] at location [#{new_discovery_json_path}]")
155
- new_discovery_json_path
156
- end
157
-
158
- sig { params(dependency_file_paths: T::Array[String]).returns(String) }
159
- def self.cache_key_from_dependency_file_paths(dependency_file_paths)
160
- dependency_file_paths.sort.join(",")
161
- end
162
-
163
- sig { returns(String) }
164
- def self.discovery_directory
165
- t = File.join(Dir.home, ".dependabot")
166
- FileUtils.mkdir_p(t)
167
- t
168
- end
169
-
170
- sig { params(repo_contents_path: String, workspace_path: String).returns(NativeDiscoveryJsonReader) }
171
- def self.discovery_json_reader(repo_contents_path:, workspace_path:)
172
- discovery_file_path = discovery_file_path_from_workspace_path(workspace_path)
173
- discovery_json = DependencyFile.new(
174
- name: Pathname.new(discovery_file_path).cleanpath.to_path,
175
- directory: discovery_directory,
176
- type: "file",
177
- content: File.read(discovery_file_path)
178
- )
179
- NativeDiscoveryJsonReader.new(repo_contents_path: repo_contents_path, discovery_json: discovery_json)
180
- end
181
-
182
- sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
183
- attr_reader :workspace_discovery
184
-
185
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
186
- attr_reader :dependency_set
187
-
188
- sig { returns(T::Array[String]) }
189
- attr_reader :dependency_file_paths
190
-
191
- sig { params(repo_contents_path: String, discovery_json: DependencyFile).void }
192
- def initialize(repo_contents_path:, discovery_json:)
193
- @repo_contents_path = repo_contents_path
194
- @discovery_json = discovery_json
195
- @workspace_discovery = T.let(read_workspace_discovery, T.nilable(Dependabot::Nuget::NativeWorkspaceDiscovery))
196
- @dependency_set = T.let(read_dependency_set, Dependabot::FileParsers::Base::DependencySet)
197
- @dependency_file_paths = T.let(read_dependency_file_paths, T::Array[String])
198
- end
199
-
200
- private
201
-
202
- sig { returns(String) }
203
- attr_reader :repo_contents_path
204
-
205
- sig { returns(DependencyFile) }
206
- attr_reader :discovery_json
207
-
208
- sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
209
- def read_workspace_discovery
210
- return nil unless discovery_json.content
211
-
212
- parsed_json = T.let(JSON.parse(T.must(discovery_json.content)), T::Hash[String, T.untyped])
213
- NativeWorkspaceDiscovery.from_json(parsed_json)
214
- rescue JSON::ParserError
215
- raise Dependabot::DependencyFileNotParseable, discovery_json.path
216
- end
217
-
218
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
219
- def read_dependency_set
220
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
221
- return dependency_set unless workspace_discovery
222
-
223
- workspace_result = T.must(workspace_discovery)
224
- workspace_result.projects.each do |project|
225
- dependency_set += project.dependency_set
226
- end
227
- if workspace_result.dotnet_tools_json
228
- dependency_set += T.must(workspace_result.dotnet_tools_json).dependency_set
229
- end
230
- dependency_set += T.must(workspace_result.global_json).dependency_set if workspace_result.global_json
231
-
232
- dependency_set
233
- end
234
-
235
- sig { returns(T::Array[String]) }
236
- def read_dependency_file_paths
237
- dependency_file_paths = T.let([], T::Array[T.nilable(String)])
238
- dependency_file_paths << dependency_file_path_from_repo_path("global.json") if workspace_discovery&.global_json
239
- if workspace_discovery&.dotnet_tools_json
240
- dependency_file_paths << dependency_file_path_from_repo_path(".config/dotnet-tools.json")
241
- end
242
-
243
- projects = workspace_discovery&.projects || []
244
- projects.each do |project|
245
- dependency_file_paths << dependency_file_path_from_repo_path(project.file_path)
246
- dependency_file_paths += project.imported_files.map do |f|
247
- dependency_file_path_from_project_path(project.file_path, f)
248
- end
249
- dependency_file_paths += project.additional_files.map do |f|
250
- dependency_file_path_from_project_path(project.file_path, f)
251
- end
252
- end
253
-
254
- deduped_dependency_file_paths = T.let(Set.new(dependency_file_paths.compact), T::Set[String])
255
- result = deduped_dependency_file_paths.sort
256
- result
257
- end
258
-
259
- sig { params(path_parts: String).returns(T.nilable(String)) }
260
- def dependency_file_path_from_repo_path(*path_parts)
261
- path_parts = path_parts.map { |p| p.delete_prefix("/").delete_suffix("/") }
262
- normalized_repo_path = Pathname.new(path_parts.join("/")).cleanpath.to_path.delete_prefix("/")
263
- full_path = Pathname.new(File.join(repo_contents_path, normalized_repo_path)).cleanpath.to_path
264
- return unless File.exist?(full_path)
265
-
266
- normalized_repo_path = "/#{normalized_repo_path}" unless normalized_repo_path.start_with?("/")
267
- normalized_repo_path
268
- end
269
-
270
- sig { params(project_path: String, relative_file_path: String).returns(T.nilable(String)) }
271
- def dependency_file_path_from_project_path(project_path, relative_file_path)
272
- project_directory = File.dirname(project_path)
273
- dependency_file_path_from_repo_path(project_directory, relative_file_path)
274
- end
275
- end
276
- end
277
- end
@@ -1,63 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Dependabot
7
- module Nuget
8
- class NativeEvaluationDetails
9
- extend T::Sig
10
-
11
- sig { params(json: T.nilable(T::Hash[String, T.untyped])).returns(T.nilable(NativeEvaluationDetails)) }
12
- def self.from_json(json)
13
- return nil if json.nil?
14
-
15
- result_type = T.let(json.fetch("ResultType"), String)
16
- original_value = T.let(json.fetch("OriginalValue"), String)
17
- evaluated_value = T.let(json.fetch("EvaluatedValue"), String)
18
- root_property_name = T.let(json.fetch("RootPropertyName", nil), T.nilable(String))
19
- error_message = T.let(json.fetch("ErrorMessage", nil), T.nilable(String))
20
-
21
- NativeEvaluationDetails.new(result_type: result_type,
22
- original_value: original_value,
23
- evaluated_value: evaluated_value,
24
- root_property_name: root_property_name,
25
- error_message: error_message)
26
- end
27
-
28
- sig do
29
- params(result_type: String,
30
- original_value: String,
31
- evaluated_value: String,
32
- root_property_name: T.nilable(String),
33
- error_message: T.nilable(String)).void
34
- end
35
- def initialize(result_type:,
36
- original_value:,
37
- evaluated_value:,
38
- root_property_name:,
39
- error_message:)
40
- @result_type = result_type
41
- @original_value = original_value
42
- @evaluated_value = evaluated_value
43
- @root_property_name = root_property_name
44
- @error_message = error_message
45
- end
46
-
47
- sig { returns(String) }
48
- attr_reader :result_type
49
-
50
- sig { returns(String) }
51
- attr_reader :original_value
52
-
53
- sig { returns(String) }
54
- attr_reader :evaluated_value
55
-
56
- sig { returns(T.nilable(String)) }
57
- attr_reader :root_property_name
58
-
59
- sig { returns(T.nilable(String)) }
60
- attr_reader :error_message
61
- end
62
- end
63
- end
@@ -1,104 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/nuget/native_discovery/native_dependency_details"
5
- require "dependabot/nuget/native_discovery/native_property_details"
6
- require "sorbet-runtime"
7
-
8
- module Dependabot
9
- module Nuget
10
- class NativeProjectDiscovery < NativeDependencyFileDiscovery
11
- extend T::Sig
12
-
13
- # rubocop:disable Metrics/AbcSize
14
- sig do
15
- override.params(json: T.nilable(T::Hash[String, T.untyped]),
16
- directory: String).returns(T.nilable(NativeProjectDiscovery))
17
- end
18
- def self.from_json(json, directory)
19
- return nil if json.nil?
20
-
21
- file_path = File.join(directory, T.let(json.fetch("FilePath"), String))
22
- properties = T.let(json.fetch("Properties"), T::Array[T::Hash[String, T.untyped]]).map do |prop|
23
- NativePropertyDetails.from_json(prop)
24
- end
25
- target_frameworks = T.let(json.fetch("TargetFrameworks"), T::Array[String])
26
- referenced_project_paths = T.let(json.fetch("ReferencedProjectPaths"), T::Array[String])
27
- dependencies = T.let(json.fetch("Dependencies"), T::Array[T::Hash[String, T.untyped]]).filter_map do |dep|
28
- details = NativeDependencyDetails.from_json(dep)
29
- next unless details.version # can't do anything without a version
30
-
31
- version = T.must(details.version)
32
- next unless version.length.positive? # can't do anything with an empty version
33
-
34
- next if version.include? "," # can't do anything with a range
35
-
36
- next if version.include? "*" # can't do anything with a wildcard
37
-
38
- details
39
- end
40
- imported_files = T.let(json.fetch("ImportedFiles"), T::Array[String])
41
- additional_files = T.let(json.fetch("AdditionalFiles"), T::Array[String])
42
-
43
- NativeProjectDiscovery.new(file_path: file_path,
44
- properties: properties,
45
- target_frameworks: target_frameworks,
46
- referenced_project_paths: referenced_project_paths,
47
- dependencies: dependencies,
48
- imported_files: imported_files,
49
- additional_files: additional_files)
50
- end
51
- # rubocop:enable Metrics/AbcSize
52
-
53
- sig do
54
- params(file_path: String,
55
- properties: T::Array[NativePropertyDetails],
56
- target_frameworks: T::Array[String],
57
- referenced_project_paths: T::Array[String],
58
- dependencies: T::Array[NativeDependencyDetails],
59
- imported_files: T::Array[String],
60
- additional_files: T::Array[String]).void
61
- end
62
- def initialize(file_path:,
63
- properties:,
64
- target_frameworks:,
65
- referenced_project_paths:,
66
- dependencies:,
67
- imported_files:,
68
- additional_files:)
69
- super(file_path: file_path, dependencies: dependencies)
70
- @properties = properties
71
- @target_frameworks = target_frameworks
72
- @referenced_project_paths = referenced_project_paths
73
- @imported_files = imported_files
74
- @additional_files = additional_files
75
- end
76
-
77
- sig { returns(T::Array[NativePropertyDetails]) }
78
- attr_reader :properties
79
-
80
- sig { returns(T::Array[String]) }
81
- attr_reader :target_frameworks
82
-
83
- sig { returns(T::Array[String]) }
84
- attr_reader :referenced_project_paths
85
-
86
- sig { returns(T::Array[String]) }
87
- attr_reader :imported_files
88
-
89
- sig { returns(T::Array[String]) }
90
- attr_reader :additional_files
91
-
92
- sig { override.returns(Dependabot::FileParsers::Base::DependencySet) }
93
- def dependency_set
94
- if target_frameworks.empty? && file_path.end_with?("proj")
95
- Dependabot.logger.warn("Excluding project file '#{file_path}' due to unresolvable target framework")
96
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
97
- return dependency_set
98
- end
99
-
100
- super
101
- end
102
- end
103
- end
104
- end