From 10fa3eb5033b201fe318c206db805df176b3eea2 Mon Sep 17 00:00:00 2001 From: Mangel Maxime Date: Thu, 22 Oct 2026 14:27:35 +0200 Subject: [PATCH] perf(compiler): opt out of telemetry for dotnet build --- src/Fable.Compiler/MSBuildCrackerResolver.fs | 8 ++------ src/Fable.Compiler/ProjectCracker.fs | 6 +++++- src/Fable.Compiler/Util.fs | 15 +++++++++++++-- src/Fable.Compiler/Util.fsi | 5 +++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Fable.Compiler/MSBuildCrackerResolver.fs b/src/Fable.Compiler/MSBuildCrackerResolver.fs index 528676e673..52d95b3d3d 100644 --- a/src/Fable.Compiler/MSBuildCrackerResolver.fs +++ b/src/Fable.Compiler/MSBuildCrackerResolver.fs @@ -30,9 +30,6 @@ module private MSBuildCrackerResolver = type FullPath = string - [] - let private TelemetryOptOutVariable = "DOTNET_CLI_TELEMETRY_OPTOUT" - let private run_dotnet_msbuild (cwd: string) (fsproj: FullPath) (args: string) (defines: string list) = backgroundTask { let psi = ProcessStartInfo "dotnet" @@ -52,9 +49,8 @@ module private MSBuildCrackerResolver = // https://github.com/fable-compiler/Fable/issues/4014 psi.Environment.Add("DOTNET_NOLOGO", "1") - // The dotnet CLI blocks on sending telemetry at exit, which can take seconds on a restricted network - if not (psi.Environment.ContainsKey TelemetryOptOutVariable) then - psi.Environment.Add(TelemetryOptOutVariable, "1") + for key, value in Fable.Compiler.Util.Process.dotnetEnvVars () do + psi.Environment[key] <- value if not (List.isEmpty defines) then let definesValue = defines |> String.concat ";" diff --git a/src/Fable.Compiler/ProjectCracker.fs b/src/Fable.Compiler/ProjectCracker.fs index 9cf5b403ec..f381563ab6 100644 --- a/src/Fable.Compiler/ProjectCracker.fs +++ b/src/Fable.Compiler/ProjectCracker.fs @@ -158,7 +158,11 @@ type CrackerOptions(cliArgs: CliArgs, evaluateOnly: bool) = pendingDllBuilds[normalizedDllPath] <- Task.Run(fun () -> - Process.runSyncWithOutput projDir "dotnet" [ "build"; "-c"; cliArgs.Configuration; "--no-restore" ] + Process.runSyncWithOutputEnv + (Process.dotnetEnvVars ()) + projDir + "dotnet" + [ "build"; "-c"; cliArgs.Configuration; "--no-restore" ] ) member _.WaitForBuiltDlls() = diff --git a/src/Fable.Compiler/Util.fs b/src/Fable.Compiler/Util.fs index 9b938f5cbb..27ced7521a 100644 --- a/src/Fable.Compiler/Util.fs +++ b/src/Fable.Compiler/Util.fs @@ -474,13 +474,24 @@ module Process = let runSync (workingDir: string) (exePath: string) (args: string list) = runSyncWithEnv [] workingDir exePath args - let runSyncWithOutput workingDir exePath args = - let p = startProcess true [] workingDir exePath args + /// Environment for the `dotnet` processes Fable starts for itself, not for the user's --run commands + let dotnetEnvVars () = + // The dotnet CLI blocks on sending telemetry at exit, which can take seconds on a restricted network + if isNull (Environment.GetEnvironmentVariable "DOTNET_CLI_TELEMETRY_OPTOUT") then + [ "DOTNET_CLI_TELEMETRY_OPTOUT", "1" ] + else + [] + + let runSyncWithOutputEnv envVars workingDir exePath args = + let p = startProcess true envVars workingDir exePath args // Don't wait indefinitely to run process // This call is used to build local plugins, if the binary is used by another process this process will never end. p.WaitForExit 7000 |> ignore p.StandardOutput.ReadToEnd() + let runSyncWithOutput workingDir exePath args = + runSyncWithOutputEnv [] workingDir exePath args + [] module Async = let fold f (state: 'State) (xs: 'T seq) = diff --git a/src/Fable.Compiler/Util.fsi b/src/Fable.Compiler/Util.fsi index f856957270..4cecd1a3a4 100644 --- a/src/Fable.Compiler/Util.fsi +++ b/src/Fable.Compiler/Util.fsi @@ -94,6 +94,11 @@ module Process = val runSyncWithOutput: string -> string -> string list -> string + val runSyncWithOutputEnv: envVars: (string * string) list -> string -> string -> string list -> string + + /// Environment for the `dotnet` processes Fable starts for itself, not for the user's --run commands + val dotnetEnvVars: unit -> (string * string) list + type PathResolver = abstract TryPrecompiledOutPath: sourceDir: string * relativePath: string -> string option