Skip to content

Implement go runner for .NET file-based apps with fast incremental rebuilds#5

Merged
kzu merged 1 commit into
mainfrom
dev/run
Jul 6, 2026
Merged

Implement go runner for .NET file-based apps with fast incremental rebuilds#5
kzu merged 1 commit into
mainfrom
dev/run

Conversation

@kzu

@kzu kzu commented Jul 6, 2026

Copy link
Copy Markdown
Member

This change turns the go global tool into a first-class launcher for .NET file-based applications (the new .cs-only project style using # directives in .NET 10+).

Behavior

  • Usage: go <file.cs> [extra args]

    • The first argument is the path to the .cs entry point.
    • Any arguments before a -- separator are passed through to dotnet publish.
    • Arguments after -- (or all if no separator) are forwarded to the published application.
  • Fast path / caching:

    • A <file>.stamp file is maintained next to the source.
    • On first/changed run: invokes dotnet publish <file.cs> while injecting go.targets via CustomAfterMicrosoftCSharpTargets + GoConfig env.
    • go.targets records inputs during CoreCompile and the final published app path after Publish.
    • BuildManager.IsUpToDate + BuildState.TryRead skips publish entirely when the cached app is newer than all inputs (mtime checks).
    • App is executed directly via ProcessRunner.
  • Components:

    • Program.cs: new ConsoleAppFramework entrypoint with caching logic.
    • GoArgs.cs: splits args at --.
    • BuildManager.cs + BuildState: stamp parsing and freshness check.
    • ProcessRunner.cs: publish + run execution.
    • go.targets: MSBuild hooks for input/app recording.
  • Tests added for arg splitting and cache logic.

  • Samples demonstrating real file-based app usage (minimal + rich showcase with #:property / #:package / #:include / #:ref).

  • Packaging, help, and dev settings updated.

Delivers a fast, script-like go file.cs experience on top of full .NET 10+ file-based programs.

…ntal rebuilds

This change turns the `go` global tool into a first-class launcher for .NET file-based
applications (the new .cs-only project style using # directives in .NET 10+).

Behavior:

- Usage: go <file.cs> [extra args]
  - The first argument is the path to the .cs entry point.
  - Any arguments before a '--' separator are passed through to 'dotnet publish'.
  - Arguments after '--' (or all arguments if no separator) are forwarded to the
    published application at runtime.

- Fast path / caching:
  - A <file>.stamp file is maintained next to the source .cs file.
  - On first run (or when inputs change), the tool invokes 'dotnet publish <file.cs>'
    while injecting custom MSBuild logic from go.targets.
  - go.targets hooks CoreCompile to record every real input source file (as 'input = ...')
    and hooks Publish to record the final published app executable path (as 'app = ...')
    into the stamp file (controlled via the GoConfig environment variable).
  - Before publishing, BuildState.TryRead + BuildManager.IsUpToDate checks whether
    the recorded app binary exists and has a newer last-write time than all the
    recorded input files. If so, publish is completely skipped.
  - The app is then launched directly via ProcessRunner.

- Implementation details:
  - Uses ConsoleAppFramework for argument parsing and help.
  - DotnetMuxer (previous change) locates the real dotnet executable.
  - ProcessRunner handles both the publish invocation (with env) and final app exec.
  - GoArgs.Split cleanly separates publish vs. app arguments at '--'.
  - Stamp parsing is robust (handles UTF8 BOM, forward vs backslashes, comments).
  - BuildManager performs mtime-based freshness checks.

- Tests:
  - GoArgsTests: separator cases (no sep, leading, trailing, normal).
  - GoBuildCacheTests: up-to-date / stale / missing app scenarios.
  - GoConfigReaderTests (BuildStateTests): parsing of multi-input stamps, BOM, paths.

- Samples:
  - samples/minimal: trivial hello.cs
  - samples/file-based-apps: rich showcase using #:property, #:package (Spectre),
    #:include, #:ref, Directory.Build.*, config files, etc. Includes launch profile
    friendly files.

- Other:
  - go.csproj updated to include and publish go.targets.
  - help.md regenerated from the new CLI.
  - launchSettings.json updated for convenient debugging against the showcase sample.

This delivers a snappy 'go file.cs' experience for modern file-based .NET programs
while correctly handling incremental compilation and argument passthrough.
@kzu

kzu commented Jul 6, 2026

Copy link
Copy Markdown
Member Author

11 passed 11 passed

🧪 Details on Ubuntu 24.04.4 LTS

from retest v1.1.0 on .NET 10.0.9 with 💜 by @devlooped

@kzu kzu merged commit aa4b11c into main Jul 6, 2026
4 checks passed
@kzu kzu deleted the dev/run branch July 6, 2026 15:00
@kzu kzu added the enhancement New feature or request label Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant