Skip to content
Merged
  •  
  •  
  •  
10 changes: 5 additions & 5 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-latest, windows-2025-vs2026]
steps:
- uses: actions/checkout@v6

Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
run: dotnet test --project ./tests/NuGetUtility.UrlToLicenseMapping.Test/NuGetUtility.UrlToLicenseMapping.Test.csproj --configuration Release --no-restore

test_windows:
runs-on: windows-latest
runs-on: windows-2025-vs2026
strategy:
matrix:
framework: [net8.0, net472, net9.0, net10.0]
Expand All @@ -112,7 +112,7 @@ jobs:
run: msbuild -t:rebuild -restore -p:RestorePackagesConfig=true -property:Configuration=TestWindows

- name: test
uses: josepho0918/vstest-action@640704dc17dc7debcbd5f54213f39cf448d922a7
uses: josepho0918/vstest-action@d188330fa1e2f802e65637e8fed0e04e0c7f8387
with:
testAssembly: "NuGet*.Test.dll"
searchFolder: "tests/*/bin/TestWindows/${{ matrix.framework }}/"
Expand Down Expand Up @@ -231,7 +231,7 @@ jobs:
}

check_licenses_net472:
runs-on: windows-latest
runs-on: windows-2025-vs2026
strategy:
matrix:
project: [App, Tests, ProjectWithReferenceContainingLicenseExpression, ProjectWithReferenceContainingFileLicense, ProjectWithReferenceContainingWindowsSpecificPath]
Expand Down Expand Up @@ -372,7 +372,7 @@ jobs:
exit 1;
}
check_version_command_net472:
runs-on: windows-latest
runs-on: windows-2025-vs2026
steps:
- uses: actions/checkout@v6
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
build:
runs-on: windows-latest
runs-on: windows-2025-vs2026
steps:
- uses: actions/checkout@v6

Expand All @@ -33,7 +33,7 @@ jobs:
run: msbuild -t:rebuild -restore -p:RestorePackagesConfig=true -property:Configuration=Release

- name: test
uses: josepho0918/vstest-action@640704dc17dc7debcbd5f54213f39cf448d922a7
uses: josepho0918/vstest-action@d188330fa1e2f802e65637e8fed0e04e0c7f8387
with:
testAssembly: "NuGet*.Test.dll"
searchFolder: "tests/*/bin/Release/net9.0/"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ nuget-license [options]
| `-err`, `--error-only` | When set, only validation errors are shown. |
| `-include-ignored`, `--include-ignored-packages` | When set, ignored packages are included in the output. |
| `-exclude-projects`, `--exclude-projects-matching <FILE\|LIST>` | Specifies projects to exclude from analysis. You can provide either a JSON file (see [docs/exclude-projects-json.md](docs/exclude-projects-json.md)), or a semicolon-separated list (e.g., `"*Test*;Legacy*"`). Wildcards (`*`) are supported. |
| `--exclude-publish-false` | Excludes packages marked with `<Publish>false</Publish>` metadata in the project file. This also recursively excludes transitive dependencies. A package is only excluded if all paths leading to it originate from a `Publish="false"` reference (consistent with `dotnet publish` behavior). |
| `-isp`, `--include-shared-projects` | Include shared projects (`.shproj`). |
| `-f`, `--target-framework <TFM>` | Analyze for a specific Target Framework Moniker. |
| `-fo`, `--file-output <FILE>` | Write output to a file instead of console. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MyCSharp.HttpUserAgentParser" Version="3.0.28" />
<PackageReference Include="MyCSharp.HttpUserAgentParser" Version="3.1.3" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/NuGetLicense/ICommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ public interface ICommandLineOptions
public string? TargetFramework { get; }
public string? DestinationFile { get; }
public string? LicenseFileMappings { get; }
public bool ExcludePublishFalse { get; }
}
}
13 changes: 10 additions & 3 deletions src/NuGetLicense/LicenseValidationOrchestrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using NuGetUtility.ReferencedPackagesReader;
using NuGetUtility.Wrapper.HttpClientWrapper;
using NuGetUtility.Wrapper.MsBuildWrapper;
using NuGetUtility.Wrapper.NuGetWrapper.Frameworks;
using NuGetUtility.Wrapper.NuGetWrapper.Packaging.Core;
using NuGetUtility.Wrapper.NuGetWrapper.ProjectModel;
using NuGetUtility.Wrapper.NuGetWrapper.Protocol;
Expand Down Expand Up @@ -62,7 +63,12 @@ public async Task<int> ValidateAsync(ICommandLineOptions options, CancellationTo
IOutputFormatter output = _optionsParser.GetOutputFormatter(options.OutputType, options.ReturnErrorsOnly, options.IncludeIgnoredPackages);

var projectCollector = new ProjectsCollector(_solutionPersistance, _fileSystem);
var projectReader = new ReferencedPackageReader(_msBuild, new LockFileFactory(), _packagesConfigReader);
var projectReader = new ReferencedPackageReader(
_msBuild,
new LockFileFactory(),
new NuGetFrameworkUtility(),
new AssetsPackageDependencyReader(new NuGetFrameworkUtility()),
_packagesConfigReader);
var validator = new LicenseValidator.LicenseValidator(licenseMappings,
allowedLicensesArray,
licenseDownloader,
Expand All @@ -71,7 +77,7 @@ public async Task<int> ValidateAsync(ICommandLineOptions options, CancellationTo

string[] excludedProjectsArray = _optionsParser.GetExcludedProjects(options.ExcludedProjects);
IEnumerable<string> projects = (await inputFiles.SelectManyAsync(projectCollector.GetProjectsAsync)).Where(p => !Array.Exists(excludedProjectsArray, ignored => p.PathLike(ignored)));
IEnumerable<ProjectWithReferencedPackages> packagesForProject = GetPackagesPerProject(projects, projectReader, options.IncludeTransitive, options.TargetFramework, options.IncludeSharedProjects, out IReadOnlyCollection<Exception> projectReaderExceptions);
IEnumerable<ProjectWithReferencedPackages> packagesForProject = GetPackagesPerProject(projects, projectReader, options.IncludeTransitive, options.TargetFramework, options.ExcludePublishFalse, options.IncludeSharedProjects, out IReadOnlyCollection<Exception> projectReaderExceptions);
IAsyncEnumerable<ReferencedPackageWithContext> downloadedLicenseInformation =
packagesForProject.SelectMany(p => GetPackageInformations(p, overridePackageInformationArray, cancellationToken));
var results = (await validator.Validate(downloadedLicenseInformation, cancellationToken)).ToList();
Expand Down Expand Up @@ -135,6 +141,7 @@ private static IReadOnlyCollection<ProjectWithReferencedPackages> GetPackagesPer
ReferencedPackageReader reader,
bool includeTransitive,
string? targetFramework,
bool excludePublishFalse,
bool includeSharedProjects,
out IReadOnlyCollection<Exception> exceptions)
{
Expand All @@ -147,7 +154,7 @@ private static IReadOnlyCollection<ProjectWithReferencedPackages> GetPackagesPer
{
try
{
IEnumerable<PackageIdentity> installedPackages = reader.GetInstalledPackages(project, includeTransitive, targetFramework);
IEnumerable<PackageIdentity> installedPackages = reader.GetInstalledPackages(project, includeTransitive, targetFramework, excludePublishFalse);
result.Add(new ProjectWithReferencedPackages(project, installedPackages));
}
catch (Exception e)
Expand Down
4 changes: 2 additions & 2 deletions src/NuGetLicense/NuGetLicense.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="System.IO.Hashing" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="10.0.3" />
<PackageReference Include="System.IO.Hashing" Version="10.0.5" />
<PackageReference Include="System.Collections.Immutable" Version="10.0.5" />
<PackageReference Include="PolySharp" Version="1.15.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
8 changes: 4 additions & 4 deletions src/NuGetLicense/Output/Csv/CsvOutputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class CsvOutputFormatter : IOutputFormatter
private readonly bool _printErrorsOnly;
private readonly bool _skipIgnoredPackages;

public CsvOutputFormatter(bool printErrorsOnly = false, bool skipIgnoredPackages = false)
public CsvOutputFormatter(bool printErrorsOnly, bool skipIgnoredPackages)
{
_printErrorsOnly = printErrorsOnly;
_skipIgnoredPackages = skipIgnoredPackages;
Expand All @@ -38,7 +38,7 @@ await writer.WriteLineAsync(

foreach (var license in results)
{
var row = new[]
string[] row = new[]
{
EscapeCsvValue(license.PackageId),
EscapeCsvValue(license.PackageVersion.ToString()),
Expand Down Expand Up @@ -66,7 +66,7 @@ private static string EscapeCsvValue(string? value)

if (value.Contains(',') || value.Contains('"') || value.Contains('\n') || value.Contains('\r'))
{
var escaped = value!.Replace("\"", "\"\"");
string escaped = value!.Replace("\"", "\"\"");
return $"\"{escaped}\"";
}

Expand All @@ -75,7 +75,7 @@ private static string EscapeCsvValue(string? value)

private static string GetValidationErrorsString(IEnumerable<ValidationError> errors)
{
var result = string.Join("; ", errors.Select(e => EscapeCsvValue($"{e.Error} ({e.Context})")));
string result = string.Join("; ", errors.Select(e => EscapeCsvValue($"{e.Error} ({e.Context})")));
return EscapeCsvValue(result);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/NuGetLicense/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public class Program : ICommandLineOptions
[Option("-file-mapping|--licensefile-to-license-mappings", Description = "File in json format that contains a dictionary to map license files to licenses.")]
public string? LicenseFileMappings { get; set; }

[Option("--exclude-publish-false", Description = "If set, packages with <Publish>false</Publish> metadata are excluded from analysis.")]
public bool ExcludePublishFalse { get; set; }

public async Task<int> OnExecuteAsync(CommandLineApplication app, CancellationToken cancellationToken)
{
// Check if mandatory parameters are provided
Expand Down Expand Up @@ -94,6 +97,7 @@ public async Task<int> OnExecuteAsync(CommandLineApplication app, CancellationTo

return await orchestrator.ValidateAsync(this, cancellationToken);
}

private static string GetVersion() =>
typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? string.Empty;

Expand Down
10 changes: 5 additions & 5 deletions src/NuGetUtility/NuGetUtility.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;net8.0;net9.0;net10.0</TargetFrameworks>
Expand Down Expand Up @@ -35,13 +35,13 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" Version="18.0.*" />
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" Version="18.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="System.IO.Hashing" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="10.0.3" />
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" Version="18.0.*" />
<PackageReference Include="System.IO.Hashing" Version="10.0.5" />
<PackageReference Include="System.Collections.Immutable" Version="10.0.5" />
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" Version="18.*" />
<PackageReference Include="PolySharp" Version="1.15.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading