Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2667b0f
Register MSBuild SDK resolvers during AOT startup
baronfel Jul 27, 2026
352d097
Run physical dotnet pack through Native AOT
baronfel Jul 21, 2026
ff4071e
Evaluate directive-free virtual projects in Native AOT
baronfel Jul 21, 2026
c43ab4e
Run dotnet publish through Native AOT
baronfel Jul 21, 2026
188a8aa
Run dotnet build through Native AOT
baronfel Jul 21, 2026
bcc0800
Run dotnet restore through Native AOT
baronfel Jul 21, 2026
34850e6
Run dotnet clean through Native AOT
baronfel Jul 21, 2026
3607c40
Run dotnet msbuild through Native AOT
baronfel Jul 21, 2026
da4716b
Document Native AOT MSBuild command activation
baronfel Jul 28, 2026
1784ef1
Test Native AOT project completions
baronfel Jul 28, 2026
f0a4061
Allow Native AOT dependency rollup warnings
baronfel Jul 28, 2026
b7665cd
Declare virtual project evaluation API
baronfel Aug 12, 2026
ac877d4
Adapt AOT evaluation to cached run
baronfel Aug 12, 2026
6862b8d
Build Linux AOT CLI against portable rootfs
baronfel Aug 12, 2026
1c81ff9
Use portable linker for Native AOT CLI tests
baronfel Aug 12, 2026
e70a996
Cover cross-target PublishRelease evaluation
baronfel Aug 13, 2026
aca70a5
Evaluate file directives in the Native AOT CLI
baronfel Aug 13, 2026
41f4b4e
Group Native AOT virtual project guards
baronfel Aug 13, 2026
2d48af8
Clean file-based app artifacts in Native AOT
baronfel Aug 13, 2026
baca1b2
Explain file-based app managed fallback
baronfel Aug 13, 2026
c3184e0
Document Native AOT file-based app behavior
baronfel Aug 13, 2026
729d232
Clarify file-based app AOT fallback
baronfel Aug 13, 2026
e51af4e
Bring console logger options into Native AOT
baronfel Aug 13, 2026
925e04a
Share virtual project state with Native AOT
baronfel Aug 13, 2026
987afb7
Share file app cache helpers with Native AOT
baronfel Aug 13, 2026
27ce83c
Compile simple file apps in Native AOT CLI
baronfel Aug 13, 2026
421d339
Share file app build flow with Native AOT
baronfel Aug 13, 2026
88e49b3
Remove obsolete MSBuild AOT suppressions
baronfel Aug 13, 2026
d8875c3
Minimize Native AOT command diff
baronfel Aug 13, 2026
227d16a
Make cross-target AOT publish test portable
baronfel Aug 13, 2026
8103eff
Use completed AOT build launch state
baronfel Aug 18, 2026
9945ce0
Support evaluation-only file app queries in AOT
baronfel Aug 18, 2026
31fdb25
Clarify AOT file app fallback behavior
baronfel Aug 18, 2026
b5ed222
Normalize file app MSBuild arguments
baronfel Aug 18, 2026
fb12b3d
Preserve AOT run logger arguments
baronfel Aug 18, 2026
a18b262
Minimize AOT-specific virtual build branches
baronfel Aug 18, 2026
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
4 changes: 4 additions & 0 deletions .vsts-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-arm64
env:
ROOTFS_DIR: /crossrootfs/arm64
azureLinuxCrossX64:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64@sha256:ca817af24ff68c801a3e31f16a0fbf6bb7ba57764b0aeae5be260dbc70ae25cb
env:
ROOTFS_DIR: /crossrootfs/x64

sdl:
sourceAnalysisPool:
Expand Down
5 changes: 4 additions & 1 deletion .vsts-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ resources:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-arm64
env:
ROOTFS_DIR: /crossrootfs/arm64
- container: azureLinuxCrossX64
image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64@sha256:ca817af24ff68c801a3e31f16a0fbf6bb7ba57764b0aeae5be260dbc70ae25cb
env:
ROOTFS_DIR: /crossrootfs/x64

stages:
############### BUILD STAGE ###############
Expand Down Expand Up @@ -100,4 +104,3 @@ stages:
helixTargetQueue: osx.15.amd64.open
macOSJobParameterSets:
- runtimeIdentifier: osx-x64

7 changes: 5 additions & 2 deletions eng/pipelines/templates/jobs/sdk-job-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ parameters:
runTests: false
### LINUX ###
linuxJobParameterSets:
- osProperties: $(linuxOsglibcProperties)
- container: azureLinuxCrossX64
osProperties: $(linuxOsglibcProperties)
runNativeAotCliTests: true
# The x64 AOT leg runs on native x64 hardware (HostRid == TargetRid == linux-x64) so it can both
# build dotnet-aot via NativeAOT (producing the .so and its mstat/dgml size-analysis output) and
# run the *.AoT.Tests.csproj test projects.
# run the *.AoT.Tests.csproj test projects. Both x64 legs use the portable Linux rootfs so the
# shipped native library runs on every supported glibc version.
- categoryName: AOT
container: azureLinuxCrossX64
runAoTTests: true
osProperties: $(linuxOsglibcProperties)
- categoryName: ContainerBased
Expand Down
2 changes: 2 additions & 0 deletions src/Cli/dotnet-aot/AotDependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<PackageReference Include="Microsoft.Build.Framework" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Build.NuGetSdkResolver" />
<PackageReference Include="Microsoft.Build.Utilities.Core" />
<PackageReference Include="Microsoft.CodeAnalysis.BuildClient" />
<PackageReference Include="Microsoft.NET.HostModel" />
<PackageReference Include="NuGet.Configuration" />
<PackageReference Include="NuGet.Credentials" />
<PackageReference Include="NuGet.Packaging" />
Expand Down
23 changes: 22 additions & 1 deletion src/Cli/dotnet-aot/AotSourceFiles.props
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\AotRunCommand.cs" Link="Commands\Run\AotRunCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\AotRunInvocation.cs" Link="Commands\Run\AotRunInvocation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\BuildLevel.cs" Link="Commands\Run\BuildLevel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\CSharpCompilerCommand.cs" Link="Commands\Run\CSharpCompilerCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\CSharpCompilerCommand.Generated.cs" Link="Commands\Run\CSharpCompilerCommand.Generated.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\FileBasedAppSourceEditor.cs" Link="Commands\Run\FileBasedAppSourceEditor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\FileBasedAppCacheInfo.cs" Link="Commands\Run\FileBasedAppCacheInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\FileBasedAppLaunchInfo.cs" Link="Commands\Run\FileBasedAppLaunchInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\FileBasedAppRunPlan.cs" Link="Commands\Run\FileBasedAppRunPlan.cs" />
Expand Down Expand Up @@ -210,10 +213,28 @@
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Solution\Remove\SolutionRemoveCommand.cs" Link="Commands\Solution\Remove\SolutionRemoveCommand.cs" />
</ItemGroup>

<!-- Project-backed command completions. -->
<!-- MSBuild-backed commands: physical project/solution evaluation and out-of-process forwarding. -->
<ItemGroup>
<Compile Include="$(RepoRoot)src\Common\MSBuildPropertyNames.cs" Link="MSBuildPropertyNames.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\ReleasePropertyProjectLocator.cs" Link="ReleasePropertyProjectLocator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\CliCompletion.cs" Link="CliCompletion.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Extensions\ProjectInstanceExtensions.cs" Link="Extensions\ProjectInstanceExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Build\BuildCommand.cs" Link="Commands\Build\BuildCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Build\BuildCommandParser.cs" Link="Commands\Build\BuildCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Clean\CleanCommand.cs" Link="Commands\Clean\CleanCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Clean\CleanCommandParser.cs" Link="Commands\Clean\CleanCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Clean\FileBasedAppArtifacts\CleanFileBasedAppArtifactsCommand.cs" Link="Commands\Clean\FileBasedAppArtifacts\CleanFileBasedAppArtifactsCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\MSBuild\MSBuildCommand.cs" Link="Commands\MSBuild\MSBuildCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\MSBuild\MSBuildCommandParser.cs" Link="Commands\MSBuild\MSBuildCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\VirtualProjectBuildingCommand.cs" Link="Commands\Run\VirtualProjectBuildingCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Pack\PackCommand.cs" Link="Commands\Pack\PackCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Pack\PackCommandParser.cs" Link="Commands\Pack\PackCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Publish\PublishCommand.cs" Link="Commands\Publish\PublishCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Publish\PublishCommandParser.cs" Link="Commands\Publish\PublishCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Restore\RestoreCommand.cs" Link="Commands\Restore\RestoreCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Restore\RestoreCommandParser.cs" Link="Commands\Restore\RestoreCommandParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Restore\RestoringCommand.cs" Link="Commands\Restore\RestoringCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\dotnet\Commands\Run\RunFileJsonSerializerContext.cs" Link="Commands\Run\RunFileJsonSerializerContext.cs" />
</ItemGroup>

<!--
Expand Down
45 changes: 30 additions & 15 deletions src/Cli/dotnet-aot/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ bridge builds the
**full** command tree (the same `DotNetCommandDefinition` used by the managed
CLI) so that parsing and `--help` match the managed CLI exactly. Commands that
can run entirely in AOT (`--version`, `--info`, the AOT-capable `sln`
subcommands, and the narrow file-based run path described below) execute immediately and return.
subcommands, the narrow file-based run path described below, plus `build`, `clean`,
`msbuild`, `restore`, `pack`, and `publish` setup)
execute immediately and return.
Other built-in command shapes are wired with a fallback action that throws
`CommandNotAvailableInAotException`;
the bridge catches it (and any unexpected parse-time failure) and transparently
Expand All @@ -148,32 +150,45 @@ executed twice. If resolution returns no command, reuse-only implicit file-based
unchanged validated cache; other shorthand shapes defer. The native path also supports explicit
`dotnet run --file` and positional `dotnet run app.cs`.

**No-build file launch** — `AotRunCommand` handles explicit `--file` and positional
`dotnet run <path> --no-build` when the prior cache records a synthetic CSC build. Positional discovery runs natively
**File-based app run** — `AotRunCommand` handles explicit `--file` and positional
`dotnet run <path>`. For a fresh simple app, the native path uses the shared
`CSharpCompilerCommand` fast path to write the response and auxiliary files, invoke the compiler
server, create the apphost, and update the build-success cache before launching it. Apps whose
directives, global properties, implicit build files, or missing package inputs require a full
MSBuild build continue through managed fallback. `--no-build` can launch a prior synthetic CSC
build without changing the cache. Positional discovery runs natively
only when the current directory contains no project; otherwise it defers so the project receives
the path as an application argument. The native path preserves arguments after `--`, `-e`
environment variables, the architecture-specific
`DOTNET_ROOT`, working directory, Ctrl-C handling, and exit code. Project launch
profiles decorate the cached apphost; Executable profiles bypass the cache and launch their
configured command. Runs requiring compile/build work and unsupported options continue through
managed fallback.
configured command. Unsupported options continue through managed fallback.

The validated-cache launch additionally handles unchanged replayed/MSBuild caches, including package apps.
The bridge validates versions, global properties, source and tracked filesystem inputs, and the
serialized `RunProperties` contract before using its command, arguments, working directory, and
RID/framework values. Stale or ambiguous caches defer before launch. Missing launch output follows
the same process-start or apphost failure path as managed `dotnet run`.

**MSBuild evaluation infrastructure** — The Native AOT closure includes the
SDK-shipped workload and NuGet SDK resolvers and a reflection-free project evaluator
that uses MSBuild's static resolver registration APIs. SDK-relative paths
(`MSBuild.dll`, `Sdks`, `MSBuildExtensionsPath`, and the telemetry logger) come from
`SdkPaths.SdkDirectory`, not `AppContext.BaseDirectory`. This infrastructure is
available to command handlers but is not registered or invoked during Native AOT
startup yet. The shared `RestoringCommand` starts workload advertising and
vulnerability-cache maintenance in both modes. Its AOT closure reuses the existing
NuGet downloader, file-based and administrative-MSI manifest extraction, and read-only
workload records without linking workload install/repair or elevated MSI IPC.
**MSBuild evaluation and project commands** — The AOT bridge registers the
SDK-shipped workload and NuGet SDK resolvers through MSBuild's static registration APIs.
For a physical project, solution, or current directory, it forwards the command target to the
selected SDK's `MSBuild.dll` out of process. Build, pack, and publish also forward restore when
requested. Pack and publish first evaluate the project properties needed to honor `PackRelease`
or `PublishRelease`. File-based app inputs use the existing virtual-project builder in AOT,
including `#:` directives, SDK imports, and implicit files such as `Directory.Build.props`.
Simple `dotnet run` file inputs can use the direct CSC path above. File-based invocations that
require restore or full in-process MSBuild execution report the boundary and fall back to the
managed CLI. SDK-relative paths
(`MSBuild.dll`, `Sdks`,
`MSBuildExtensionsPath`, the Roslyn compiler server, and the telemetry logger) come from
`SdkPaths.SdkDirectory`, not `AppContext.BaseDirectory`. `.nuspec` inputs also defer
because they use the in-process NuGet pack engine. The shared `RestoringCommand` starts
workload advertising and vulnerability-cache maintenance in both modes. Its AOT closure
reuses the existing NuGet downloader, file-based and administrative-MSI manifest
extraction, and read-only workload records without linking workload install/repair or
elevated MSI IPC. The `dotnet clean file-based-apps` maintenance subcommand runs directly
in AOT with source-generated JSON metadata.

**Slow path** — When `DOTNET_CLI_ENABLEAOT` is disabled (`false`/`0`/`no`/`off`)
or the AOT bridge does
Expand Down
2 changes: 2 additions & 0 deletions src/Cli/dotnet-aot/NativeEntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ internal static int ExecuteCore(
}

SdkDirectory = string.IsNullOrEmpty(sdkDirectory) ? null : sdkDirectory;
// MSBuild snapshots registered resolvers on first SDK resolution, so register during startup.
MSBuildSdkResolverRegistration.Register();

// Telemetry is best-effort and must never prevent the CLI from running. Initializing
// it can fail on some layouts (e.g. the NativeAOT muxer cannot resolve the crypto
Expand Down
13 changes: 8 additions & 5 deletions src/Cli/dotnet-aot/SdkRootResolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ The authoritative integration layout is produced by the full Debug redist build:
must invoke that `dotnet.exe` from outside the repository so the repository
`global.json` cannot select the bootstrap SDK.

Focused Native AOT tests register the compiled-in resolvers explicitly and evaluate a
stock `Microsoft.NET.Sdk` project against the bootstrap SDK, proving that the workload
resolver handles the SDK's workload-locator imports through `SdkResolver.Register`
without reflective plugin loading. Command handlers do not activate this evaluator in
the shipping Native AOT entry point yet.
The Native AOT test executable also evaluates a stock `Microsoft.NET.Sdk` project
against the bootstrap SDK, proving that the workload resolver handles the SDK's
workload-locator imports through `SdkResolver.Register` without reflective plugin
loading. Command-specific tests additionally verify that `PackRelease`/`PublishRelease`
evaluation and the child MSBuild process use the versioned SDK directory. End-to-end
parity toggles `DOTNET_CLI_ENABLEAOT` on the same redist muxer; telemetry must report
`cli.runtime=aot` for physical project packing and publishing and direct-compiled file-based
apps, and `cli.runtime=managed` for `.nuspec` and full-MSBuild file-based build fallbacks.
6 changes: 6 additions & 0 deletions src/Cli/dotnet-aot/dotnet-aot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
<!-- Ignore checking for OS API compatibility as we aren't targeting just the Windows platform -->
<NoWarn>$(NoWarn);CA1416</NoWarn>

<!-- NuGet's AOT feature switch is configured in AotSourceFiles.props. NuGet.Packaging still
exposes Newtonsoft.Json-backed runtime-model APIs in the SDK resolver closure, while the
runtime dynamic assemblies also produce AOT rollups. Keep dependency rollups visible but
non-fatal; first-party IL warnings and all other warning codes remain errors. -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);IL2104;IL3053</WarningsNotAsErrors>

<!--
Enable control flow guard
https://github.com/dotnet/docs/blob/main/docs/core/deploying/native-aot/security.md#control-flow-guard
Expand Down
30 changes: 10 additions & 20 deletions src/Cli/dotnet/Commands/DotNetCommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Microsoft.DotNet.Cli.CommandFactory;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Commands;
Expand Down Expand Up @@ -48,7 +47,6 @@ private static bool TryGetBuiltInCommand(string commandName, out Func<string[],
return false;
}

#if !CLI_AOT
internal static CommandBase CreateVirtualOrPhysicalCommand(
System.CommandLine.Command commandDefinition,
Argument<string[]> catchAllUserInputArgument,
Expand All @@ -64,23 +62,16 @@ internal static CommandBase CreateVirtualOrPhysicalCommand(
var forwardedArgs = parseResult.OptionValuesToBeForwarded(commandDefinition);
if (nonLoggerArgs is [{ } arg] && VirtualProjectBuilder.IsValidEntryPointPath(arg))
{
if (RuntimeFeature.IsDynamicCodeSupported)
{
var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments([.. forwardedArgs, .. loggerArgs],
[
.. optionsToUseWhenParsingMSBuildFlags,
CommonOptions.CreateGetPropertyOption(),
CommonOptions.CreateGetItemOption(),
CommonOptions.CreateGetTargetResultOption(),
CommonOptions.CreateGetResultOutputFileOption(),
]);
msbuildArgs = transformer?.Invoke(msbuildArgs, nonLoggerArgs) ?? msbuildArgs;
return createVirtualCommand(msbuildArgs, Path.GetFullPath(arg));
}
else
{
throw new PlatformNotSupportedException("Dynamic code generation is not supported on this platform.");
}
var msbuildArgs = MSBuildArgs.AnalyzeMSBuildArguments([.. forwardedArgs, .. loggerArgs],
[
.. optionsToUseWhenParsingMSBuildFlags,
CommonOptions.CreateGetPropertyOption(),
CommonOptions.CreateGetItemOption(),
CommonOptions.CreateGetTargetResultOption(),
CommonOptions.CreateGetResultOutputFileOption(),
]);
msbuildArgs = transformer?.Invoke(msbuildArgs, nonLoggerArgs) ?? msbuildArgs;
return createVirtualCommand(msbuildArgs, Path.GetFullPath(arg));
}
else
{
Expand Down Expand Up @@ -138,5 +129,4 @@ private static IEnumerable<string> RemoveFirst(IEnumerable<string> args, string
yield return arg;
}
}
#endif
}
16 changes: 12 additions & 4 deletions src/Cli/dotnet/Commands/Pack/PackCommand.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if !CLI_AOT
using System.Collections.ObjectModel;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.Diagnostics.CodeAnalysis;
#endif
using System.CommandLine;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Commands.Restore;
using Microsoft.DotNet.Cli.Commands.Run;
using Microsoft.DotNet.Cli.Extensions;
using Microsoft.DotNet.Cli.NuGetPackageDownloader;
using Microsoft.DotNet.Cli.Utils;
#if !CLI_AOT
using Microsoft.DotNet.Cli.NuGetPackageDownloader;
using NuGet.Commands;
using NuGet.Common;
#endif

namespace Microsoft.DotNet.Cli.Commands.Pack;

[RequiresDynamicCode("Uses MSBuild Object Model types, which are not AOT-safe")]
public class PackCommand(
MSBuildArgs msbuildArgs,
bool noRestore,
Expand Down Expand Up @@ -74,6 +76,7 @@ public static CommandBase FromParseResult(ParseResult parseResult, string? msbui
});
}

#if !CLI_AOT
private static LogLevel MappingVerbosityToNugetLogLevel(VerbosityOptions? verbosity)
{
return verbosity switch
Expand Down Expand Up @@ -132,6 +135,7 @@ public static int RunPackCommand(ParseResult parseResult)
return 1;
return 0;
}
#endif

public static int Run(ParseResult parseResult)
{
Expand All @@ -144,7 +148,11 @@ public static int Run(ParseResult parseResult)

if (args.Count > 0 && Path.GetExtension(args[0]).Equals(".nuspec", StringComparison.OrdinalIgnoreCase))
{
#if CLI_AOT
throw new CommandNotAvailableInAotException();
#else
return RunPackCommand(parseResult);
#endif
}

// Fallback to MSBuild-based packing
Expand Down
2 changes: 0 additions & 2 deletions src/Cli/dotnet/Commands/Pack/PackCommandParser.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using Microsoft.DotNet.Cli.CommandLine;

namespace Microsoft.DotNet.Cli.Commands.Pack;

internal static class PackCommandParser
{
[RequiresDynamicCode("Uses MSBuild Object Model types, which are not AOT-safe")]
public static void ConfigureCommand(PackCommandDefinition command)
{
command.ConfigurationOption.AddCompletions(CliCompletion.ConfigurationsFromProjectFileOrDefaults);
Expand Down
Loading
Loading