diff --git a/.gitignore b/.gitignore index 51ec6219235..6a1acc0a024 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ coverage/ spoom_data/ spoom_report.html .vs/ +# Ignore VSCode C# Dev Kit +**/.mono/**/values.xml diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs new file mode 100644 index 00000000000..0661665712d --- /dev/null +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs @@ -0,0 +1,28 @@ +namespace NuGetUpdater.Core; + +internal static class LockFileUpdater +{ + public static async Task UpdateLockFileAsync( + string repoRootPath, + string projectPath, + Logger logger) + { + var projectDirectory = Path.GetDirectoryName(projectPath); + var lockPath = Path.Combine(projectDirectory, "packages.lock.json"); + logger.Log($" Updating lock file"); + if (!File.Exists(lockPath)) + { + logger.Log($" File [{Path.GetRelativePath(repoRootPath, lockPath)}] does not exist."); + return; + } + + await MSBuildHelper.SidelineGlobalJsonAsync(projectDirectory, repoRootPath, async () => + { + var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", $"restore --force-evaluate {projectPath}", workingDirectory: projectDirectory); + if (exitCode != 0) + { + logger.Log($" Lock file update failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}"); + } + }, retainMSBuildSdks: true); + } +} diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs index 3c6e6eb27cf..c348d30a0f6 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs @@ -189,5 +189,11 @@ private async Task RunUpdaterAsync( // Some repos use a mix of packages.config and PackageReference await SdkPackageUpdater.UpdateDependencyAsync(repoRootPath, projectPath, dependencyName, previousDependencyVersion, newDependencyVersion, isTransitive, _logger); + + // Update lock file if exists + if (File.Exists(Path.Combine(Path.GetDirectoryName(projectPath), "packages.lock.json"))) + { + await LockFileUpdater.UpdateLockFileAsync(repoRootPath, projectPath, _logger); + } } } diff --git a/nuget/lib/dependabot/nuget/file_fetcher.rb b/nuget/lib/dependabot/nuget/file_fetcher.rb index c8993a8e0f6..331b0a32c04 100644 --- a/nuget/lib/dependabot/nuget/file_fetcher.rb +++ b/nuget/lib/dependabot/nuget/file_fetcher.rb @@ -52,6 +52,7 @@ def initialize(source:, credentials:, repo_contents_path: nil, options: {}) @nuget_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile])) @packages_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile])) @assembly_binding_redirect_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile])) + @packages_lock_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile])) end sig { override.returns(T::Array[DependencyFile]) } @@ -63,6 +64,7 @@ def fetch_files *packages_config_files, *assembly_binding_redirect_config_files, *nuget_config_files, + *packages_lock_files, global_json, dotnet_tools_json, packages_props @@ -266,6 +268,21 @@ def nuget_config_files @nuget_config_files end + sig { returns(T::Array[Dependabot::DependencyFile]) } + def packages_lock_files + return @packages_lock_files if @packages_lock_files + + candidate_paths = + [*project_files.map { |f| File.dirname(f.name) }, "."].uniq + + @packages_lock_files = + candidate_paths.filter_map do |dir| + file = repo_contents(dir: dir) + .find { |f| f.name.casecmp("packages.lock.json").zero? } + fetch_file_from_host(File.join(dir, file.name)) if file + end + end + sig do params( project_file: Dependabot::DependencyFile,