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

feat: Set TFM manually #155

Merged
merged 4 commits into from
Jul 8, 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
12 changes: 9 additions & 3 deletions mdsource/cli-readme.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Dotnet tool for updating package reference and dotnet-tools.json.

The tool will try to stick to package versions that is supported by the projects target framework.
The tool will try to stick to package versions that is supported by the projects target framework moniker.

See [UpdatR](#updatr) for SDK.

Expand All @@ -17,13 +17,13 @@ See [UpdatR](#updatr) for SDK.

### Basic Usage

To update all `*.csproj` and `dotnet-tools.json` recursivly:
To update all `*.csproj` and `dotnet-tools.json` recursively:

```
> update
```

If you only want to update the `*.csproj` and `dotnet-tools.json` that is part of a solution you can specifiy the solution directly:
If you only want to update the `*.csproj` and `dotnet-tools.json` that is part of a solution you can specify the solution directly:

```
> update path/to/solution.sln
Expand Down Expand Up @@ -59,6 +59,12 @@ If you don't want to update a package or packages you can exclude them:
> update --exclude-package Microsoft.* --exclude-package Newtonsoft.*
```

If UpdatR fails to find the correct lowest TFM to support, for example for projects that supports multiple TFM's, then it's possible to set the TFM manually:

```
> update --tfm net6.0
```

### As part of CI/CD

You can get the output as a markdown by setting a path for the output:
Expand Down
1 change: 1 addition & 0 deletions src/Build/docs/release-notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Pass lowest TFM that should be supported as an argument
5 changes: 3 additions & 2 deletions src/UpdatR/Domain/Csproj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ public static Csproj Create(string path)
public ProjectWithPackages? UpdatePackages(
IDictionary<string, NuGetPackage?> packages,
bool dryRun,
ILogger logger
ILogger logger,
NuGetFramework? tfm = null
)
{
var project = new ProjectWithPackages(Path);
Expand Down Expand Up @@ -116,7 +117,7 @@ ILogger logger
CheckForDeprecationAndVulnerabilities(project, packageId, metadata);
}

if (!package.TryGetLatestComparedTo(version, TargetFramework, out var updateTo))
if (!package.TryGetLatestComparedTo(version, tfm ?? TargetFramework, out var updateTo))
{
CheckForDeprecationAndVulnerabilities(
project,
Expand Down
26 changes: 24 additions & 2 deletions src/UpdatR/Updater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Extensions.Logging;
using NuGet.Configuration;
using NuGet.Credentials;
using NuGet.Frameworks;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using UpdatR.Domain;
Expand All @@ -27,16 +28,20 @@ public Updater(ILogger<Updater>? logger = null)
/// <param name="packages">Packages to update. Supports * as wildcard. If <see langword="null"/> or empty then all packages, except <paramref name="excludePackages"/>, will be updated.</param>
/// <param name="dryRun">Do not save any changes.</param>
/// <param name="interactive">Interaction with user is possible.</param>
/// <param name="targetFrameworkMoniker">Lowest Target Framework Moniker to support.</param>
/// <returns><see cref="Summary"/></returns>
/// <exception cref="ArgumentException"></exception>
public async Task<Summary> UpdateAsync(
string? path = null,
string[]? excludePackages = null,
string[]? packages = null,
bool dryRun = false,
bool interactive = false
bool interactive = false,
string? targetFrameworkMoniker = null
)
{
var tfm = ParseTFM(targetFrameworkMoniker);

path ??= Directory.GetCurrentDirectory();

var shouldIncludePackage = CreateSearch(packages, treatNullOrEmptyAs: true);
Expand All @@ -62,7 +67,7 @@ public async Task<Summary> UpdateAsync(

foreach (var csproj in dir.Csprojs ?? Array.Empty<Csproj>())
{
var project = csproj.UpdatePackages(nugetPackages, dryRun, _logger);
var project = csproj.UpdatePackages(nugetPackages, dryRun, _logger, tfm);

if (project is not null)
{
Expand All @@ -83,6 +88,23 @@ public async Task<Summary> UpdateAsync(
return Summary.Create(result);
}

private static NuGetFramework? ParseTFM(string? targetFrameworkMoniker)
{
var tfm = string.IsNullOrWhiteSpace(targetFrameworkMoniker)
? null
: NuGetFramework.Parse(targetFrameworkMoniker);

if (tfm == NuGetFramework.UnsupportedFramework)
{
throw new ArgumentException(
$"'{targetFrameworkMoniker}' is not a supported TFM.",
nameof(targetFrameworkMoniker)
);
}

return tfm;
}

private static Func<string, bool> CreateSearch(string[]? strs, bool treatNullOrEmptyAs)
{
if (strs is null || strs.Length == 0)
Expand Down
11 changes: 7 additions & 4 deletions src/dotnet-updatr/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ internal static partial class Program
/// <summary>
/// Update all packages in solution or project(s).
/// </summary>
/// <param name="args">Path to solution or project(s). Defaults to current folder. Target can be a specific file or folder. If target is a folder then all *.csproj-files and dontet-config.json-files will be processed.</param>
/// <param name="args">Path to solution or project(s). Defaults to current folder. Target can be a specific file or folder. If target is a folder then all *.csproj-files and dotnet-config.json-files will be processed.</param>
/// <param name="package">Package to update. Supports * as wildcard. Will update all unless specified.</param>
/// <param name="excludePackage">Package to exlude. Supports * as wildcard.</param>
/// <param name="excludePackage">Package to exclude. Supports * as wildcard.</param>
/// <param name="output">Defaults to "output.md". Explicitly set to fileName.txt to generate plain text instead of markdown.</param>
/// <param name="title">Outputs title to path.</param>
/// <param name="description">Outputs description to path.</param>
/// <param name="verbosity">Log level.</param>
/// <param name="dryRun">Do not save any changes.</param>
/// <param name="browser">Open summary in browser.</param>
/// <param name="interactive">Interaction with user is possible.</param>
/// <param name="tfm">Lowest TFM to support.</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
internal static async Task Main(
Expand All @@ -38,7 +39,8 @@ internal static async Task Main(
LogLevel verbosity = LogLevel.Warning,
bool dryRun = false,
bool browser = false,
bool interactive = false
bool interactive = false,
string? tfm = null
)
{
var sw = Stopwatch.StartNew();
Expand All @@ -63,7 +65,8 @@ internal static async Task Main(
excludePackages: excludePackage,
packages: package,
dryRun,
interactive
interactive,
tfm
);

var outputStr = TextFormatter.PlainText(summary);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[
[]

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.1" />
</ItemGroup>
</Project>

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.1" />
</ItemGroup>
</Project>
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
[
{
PackageId: Dummy,
Updates: [
{
Item1: 0.0.1,
Item2: 0.0.2,
Item3: Dummy.App.csproj
}
]
}
]

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.1" />
</ItemGroup>
</Project>

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.2" />
</ItemGroup>
</Project>
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
[
{
PackageId: Dummy,
Updates: [
{
Item1: 0.0.1,
Item2: 0.0.2,
Item3: Dummy.App.csproj
}
]
}
]

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.1" />
</ItemGroup>
</Project>

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dummy" Version="0.0.2" />
</ItemGroup>
</Project>
]
42 changes: 41 additions & 1 deletion tests/UpdatR.IntegrationTests/UpdaterTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System;
using System.Diagnostics.CodeAnalysis;
using static UpdatR.IntegrationTests.FileCreationUtils;

namespace UpdatR.IntegrationTests;
Expand Down Expand Up @@ -89,6 +90,45 @@ async IAsyncEnumerable<object> GetVerifyObjects()
}
}

[Theory]
[InlineData("net5.0")] // Unsupported in 0.0.2
[InlineData("net6.0")] // Current TFM
[InlineData("net7.0")] // Future TFM
public async Task Given_TFM_When_UnsupportedInNewerVersions_Then_DoNothing(string tfm)
{
// Arrange
var temp = Path.Combine(
Paths.Temporary.Root,
nameof(Given_TFM_When_UnsupportedInNewerVersions_Then_DoNothing)
);
var tempCsproj = Path.Combine(temp, "Dummy.App.csproj");
var tempNuget = Path.Combine(temp, "nuget.config");

Directory.CreateDirectory(temp);

var csprojOriginal = await CreateTempCsprojAsync(
tempCsproj,
new KeyValuePair<string, string>("Dummy", "0.0.1")
);

CreateNuGetConfig(tempNuget);

var update = new Updater();

// Act
var summary = await update.UpdateAsync(tempCsproj, targetFrameworkMoniker: tfm);

// Assert
await Verify(GetVerifyObjects()).UseParameters(tfm);

async IAsyncEnumerable<object> GetVerifyObjects()
{
yield return summary.UpdatedPackages;
yield return csprojOriginal;
yield return await File.ReadAllTextAsync(tempCsproj);
}
}

[Theory]
[InlineData("0.0.1")]
[InlineData("0.0.2")]
Expand Down