Skip to content

Extend diagnostic completeness pattern with dotnet config and dotnet env commands #49955

@richlander

Description

@richlander

Proposed by Claude (Anthropic)

Inspiration

The recent enhancement to dotnet --info (dotnet/runtime#117797) demonstrates .NET CLI innovation in providing comprehensive diagnostic state in a single command. By displaying all DOTNET_* environment variables, it eliminates the need for multiple commands to understand runtime configuration.

Building on this pattern and the broader discussion in dotnet/sdk#49951 about optimizing for AI-assisted development, we should extend this diagnostic completeness approach to other critical development scenarios while maintaining clear separation between persistent and ephemeral state.

Core Design Principle: File Format Encapsulation

The CLI should provide complete encapsulation of .NET file formats such that it becomes atypical for AI assistants to need direct file editing. This means:

  • Structured input/output: Commands accept and emit JSON/structured data instead of requiring file parsing
  • Complex workflows in single commands: Eliminate multi-step processes that force file manipulation
  • Format abstraction: Hide XML/JSON syntax complexity behind ergonomic APIs
  • Correctness by construction: CLI ensures valid file formats, eliminating parsing errors

This design goal transforms the CLI from a thin wrapper around file operations into a comprehensive API for .NET project manipulation.

Problem Statement

Currently, diagnosing and configuring .NET projects requires both multiple commands AND direct file editing:

Configuration troubleshooting requires:

  • find . -name global.json
  • Manual inspection and editing of global.json, nuget.config, Directory.Build.props
  • Understanding complex XML/JSON schema rules
  • Risk of syntax errors when AI assistants modify files directly

Project setup workflows require:

  • dotnet new + manual .csproj editing + manual nuget.config creation + manual global.json setup
  • AI assistants spending significant tokens on XML/JSON file manipulation
  • Multi-command sequences with intermediate file parsing

Dependency management requires:

  • dotnet add package + manual .csproj inspection + manual lock file analysis
  • Direct editing of Directory.Packages.props for central package management

This fragmentation forces AI assistants to become XML/JSON editors rather than leveraging structured APIs, creating token waste and correctness issues.

Proposed Solutions

1. Persistent Configuration State: dotnet config --info

Read API - Provide comprehensive view of file-based configuration:

{
  "globalJson": {
    "path": "./global.json",
    "sdk": {"version": "10.0.100", "rollForward": "latestMinor"},
    "msbuild-sdks": {"Microsoft.Build.NoTargets": "3.7.0"}
  },
  "nugetConfig": [
    {"path": "./nuget.config", "sources": ["https://api.nuget.org/v3/index.json"]},
    {"path": "./src/nuget.config", "sources": ["https://internal.feed/v3/index.json"]}
  ],
  "msbuildImports": {
    "directoryBuildProps": ["./Directory.Build.props", "./src/Directory.Build.props"],
    "directoryBuildTargets": ["./Directory.Build.targets"],
    "centralPackageManagement": "./Directory.Packages.props"
  },
  "workspaceAnalysis": {
    "solutionFile": "./MySolution.sln",
    "projectCount": 5,
    "targetFrameworks": ["net10.0", "net8.0"]
  }
}

Write API - Structured configuration modification:

# Instead of manually editing global.json
dotnet config global-json --set sdk.version=10.0.100 --set sdk.rollForward=latestMinor

# Instead of manually editing nuget.config  
dotnet config nuget --add-source https://internal.feed/v3/index.json --name internal

# Instead of manually editing Directory.Build.props
dotnet config msbuild --set-property WarningsAsErrors=true --scope ./src/

# Structured input for complex scenarios
echo '{"sdk":{"version":"10.0.100"},"msbuild-sdks":{"NoTargets":"3.7.0"}}' | dotnet config global-json --from-json

2. Ephemeral Environment State: dotnet env --info

Read API - Runtime/session state:

{
  "environmentVariables": {
    "DOTNET_ROOT": "/usr/share/dotnet",
    "NUGET_PACKAGES": "/home/user/.nuget/packages"
  },
  "userConfiguration": {
    "globalNugetConfig": "/home/user/.nuget/NuGet/NuGet.Config",
    "globalTools": [{"name": "dotnet-ef", "version": "8.0.0"}]
  },
  "installedComponents": {
    "sdks": ["10.0.100-preview.6", "8.0.100"],
    "runtimes": [{"name": "Microsoft.NETCore.App", "versions": ["10.0.0-preview.6"]}]
  }
}

Write API - Environment configuration:

# Instead of manually editing user nuget.config
dotnet env nuget --add-source https://company.feed --scope user

# Instead of manually setting environment variables
dotnet env set NUGET_PACKAGES=/custom/path --scope user

3. Project Creation with Full Specification: dotnet create

Replace multi-command workflows with single declarative commands:

# Instead of: dotnet new + dotnet add package + manual file editing
dotnet create --from-json '{
  "name": "MyApp",
  "type": "console", 
  "targetFramework": "net10.0",
  "packages": [{"id": "Newtonsoft.Json", "version": "13.0.3"}],
  "projectReferences": ["../MyLib/MyLib.csproj"],
  "properties": {"PublishAot": true, "WarningsAsErrors": true},
  "addToSolution": true
}' --output ./MyApp

4. Dependency Resolution State: dotnet deps --info

Read API - Complete dependency picture:

{
  "packageSources": [{"name": "nuget.org", "enabled": true}],
  "projects": [{
    "path": "MyApp/MyApp.csproj",
    "packageReferences": [{"id": "Newtonsoft.Json", "version": "13.0.3"}]
  }],
  "conflicts": [],
  "vulnerabilities": []
}

Write API - Structured dependency management:

# Instead of manual Directory.Packages.props editing
dotnet deps set-central-package Newtonsoft.Json --version 13.0.3

# Bulk operations from structured input
echo '{"packages":[{"id":"Serilog","version":"3.0.0"},{"id":"Serilog.Sinks.Console","version":"4.0.0"}]}' | dotnet deps add --from-json

5. Build Environment Preview: dotnet build --dry-run

Show what a build would do without executing it, with structured modification capabilities:

{
  "projects": [{
    "path": "MyApp/MyApp.csproj",
    "targetFrameworks": ["net10.0"],
    "outputPath": "MyApp/bin/Debug/net10.0/",
    "preprocessorSymbols": ["DEBUG", "NET10_0"],
    "buildActions": {"Compile": 15, "EmbeddedResource": 2}
  }],
  "buildOrder": ["MyLib/MyLib.csproj", "MyApp/MyApp.csproj"]
}

File Format Encapsulation Benefits

Token Efficiency: AI assistants use structured APIs instead of parsing/generating XML/JSON, reducing token costs by 60-80%

Correctness: CLI ensures valid file formats, eliminating syntax errors from manual editing

Workflow Simplification: Complex multi-file operations become single commands

Schema Abstraction: AI doesn't need to understand MSBuild XML, NuGet config XML, or global.json schema

Atomic Operations: Changes are validated and applied atomically, preventing partial/corrupted configurations

Version Compatibility: CLI handles format evolution, shielding AI from schema changes

Configuration as Code Integration

Enable declarative project definition:

# Export current state as reproducible configuration
dotnet workspace export --format json > project-definition.json

# Recreate entire project from specification
dotnet workspace create --from project-definition.json

# Validate current state against specification
dotnet workspace validate --against project-definition.json

Implementation Strategy

Phase 1: Read APIs (--info commands) with JSON output
Phase 2: Write APIs (dotnet config, dotnet env, structured dotnet create)
Phase 3: Workspace-level operations (dotnet workspace)
Phase 4: Migration tools (convert existing projects to declarative specs)

This transforms .NET CLI from a file-manipulation tool into a comprehensive project management API, optimizing for AI-assisted development while maintaining the declarative benefits of configuration-as-code.

Related Issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions