`--file=*.sln` selects the projects a solution holds rather than scanning
the solution itself. `.slnx`, the XML solution format that replaces `.sln`
from Visual Studio 17.14 / .NET 9 onwards, was not recognised: it fell
through to package-manager detection and failed with "could not detect
package manager".
Customers converting `.sln` to `.slnx` as part of a .NET 9/10 upgrade hit
this and their pipelines break. CMPA-766.
Project paths are read out of the XML rather than with a new XML
dependency, and comments are stripped first so a commented-out project
isn't scanned.
`.sln` folder resolution is untouched. The two formats disagree about a
project path written with a trailing separator — `.slnx` allows it to name
the project's directory, while a `.sln` ASP.NET Website entry has always
resolved to the directory above — so each format keeps its own rule and
a test pins the `.sln` one.
Two deliberate, disclosed side-effects on `.sln`:
- the extension is now matched case-insensitively, so `--file=App.SLN` is
expanded where it previously fell through to manifest detection;
- the unsupported-combination message names the extension in lower case,
matching the message cli-extension-os-flows produces for the same
rejection.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Pull Request Submission Checklist
What does this PR do?
Makes
--file=*.slnxwork the way--file=*.slnalready does.--file=*.slnis a target selector, not a manifest: the CLI parses the solution, keeps the projects whose folders hold a supported manifest, deletes--file, and rewrites argv as if the user had passed those folders. It sits between one.csprojand--all-projects..slnx— the XML solution format the .NET SDK reads from 9.0.200 and creates by default from .NET 10 — was not recognised at all. It fell through to package-manager detection and failed with "could not detect package manager". Customers converting.sln→.slnxas part of a .NET 9/10 upgrade hit this and their pipelines break.Ticket: CMPA-766.
Where should the reviewer start?
src/lib/sln/index.ts. Three things worth a careful look:dotnet sln migrateoutput, including a directory name containing&..slnfolder resolution is deliberately untouched. The two formats disagree about a project path written with a trailing separator: in.slnxit names a folder, while a.slnASP.NET Website entry (..\..\WebSites\Site1\) has always resolved to the folder above. An earlier revision of this PR shared one code path and silently changed which folder a.slnscan covers — that would have added projects onmonitorand vulns ontestfor existing users. Each format now has its own rule andsln-website-project/mySolution.slnpins the.slnone.solutionExtension()replacespath.extnameso a file named only.slnxreaches the right parser, and so the unsupported-combination message matches the onecli-extension-os-flowsproduces for the same rejection.Two deliberate, disclosed side-effects on
.sln, both arguably fixes but both behaviour changes:--file=App.SLNis expanded where it previously fell through to manifest detection;file=*.SLNX→file=*.slnx).How should this be manually tested?
Automated coverage:
test/jest/unit/lib/sln.spec.ts(28 tests — parsing, XML entity decoding including numeric character references, single-quoted attributes, empty solutions, path resolution relative to the solution, and the.slnregression above), plus acceptance tests intest/jest/acceptance/cli-args.spec.tsandtest/jest/acceptance/snyk-sbom/nuget-options.spec.ts.What's the product update that needs to be communicated to CLI users?
--filenow accepts.slnxsolution files as well as.sln, onsnyk test,snyk monitorandsnyk sbom. No feature flag or enablement needed.Docs are not updated by this PR and are the only shipped surface still saying
.slnonly —help/is authored in GitBook, sohelp/cli-commands/{test,monitor,sbom}.mdneed the--file=<filename>.slnsections retitled and a minimum CLI version added. Worth noting the demand evidence includes an account that has not adopted.slnxbecause the documented support matrix says we don't support it, so the docs change carries most of the customer value here.Risk assessment: Medium
Low in what it adds (
.slnxwas previously a hard failure, so there is no behaviour to regress), medium in where it sits:src/lib/sln/is on the hot path for every--file=*.slnscan across all ecosystems, not just .NET. The two disclosed.slnside-effects above are the whole of the risk; the trailing-separator regression is fixed and pinned by a test.Related PRs
The same gap in the two extensions, for reviewers tracing the whole feature:
--file=*.slnx + --project-name.slnxresolution in the unified .NET resolverThis PR should land first. The unified resolver hands a solution it cannot fully claim back to the legacy CLI, which needs this change to understand
.slnx.🤖 Generated with Claude Code