From e872a6c0b8febd9f18854b9cc78c35f6324716d9 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Mon, 1 Sep 2025 17:22:19 +0200 Subject: [PATCH 1/3] avoid artifact left-overs on error --- src/Runfs/Build.fs | 22 ++++++++++++---------- src/Runfs/Runfs.fsproj | 7 +++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Runfs/Build.fs b/src/Runfs/Build.fs index 98e9d18..70cbdcb 100644 --- a/src/Runfs/Build.fs +++ b/src/Runfs/Build.fs @@ -6,7 +6,6 @@ open Microsoft.Build.Evaluation open Microsoft.Build.Execution open Microsoft.Build.Framework open Microsoft.Build.Logging -open Microsoft.Build.Locator open System open System.IO open System.Xml @@ -21,7 +20,7 @@ type Project = type MSBuildError = MSBuildError of target: string * result: string -let initMSBuild() = MSBuildLocator.RegisterDefaults() |> ignore +let initMSBuild() = Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults() |> ignore let createProject verbose projectFilePath (projectFileText: string) : Project = let verbosity = if verbose then "m" else "q" @@ -46,14 +45,17 @@ let createProject verbose projectFilePath (projectFileText: string) : Project = // let projectInstance = ProjectInstance.FromProjectRootElement(projectRoot, options) File.WriteAllText(projectFilePath, projectFileText) - let projectInstance = ProjectInstance.FromFile(projectFilePath, options) - - let parameters = BuildParameters projectCollection - parameters.Loggers <- loggers - parameters.LogTaskInputs <- false - let buildManager = BuildManager.DefaultBuildManager - buildManager.BeginBuild parameters - {buildManager = buildManager; projectInstance = projectInstance} + try + let projectInstance = ProjectInstance.FromFile(projectFilePath, options) + let parameters = BuildParameters projectCollection + parameters.Loggers <- loggers + parameters.LogTaskInputs <- false + let buildManager = BuildManager.DefaultBuildManager + buildManager.BeginBuild parameters + {buildManager = buildManager; projectInstance = projectInstance} + with ex -> + File.Delete projectFilePath + reraise() let build target project = let flags = diff --git a/src/Runfs/Runfs.fsproj b/src/Runfs/Runfs.fsproj index 9b846e1..c30bf52 100644 --- a/src/Runfs/Runfs.fsproj +++ b/src/Runfs/Runfs.fsproj @@ -36,11 +36,10 @@ + - + + \ No newline at end of file From de6a1eb12b0351637338b7bfeb8ceda379ddc67c Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Mon, 1 Sep 2025 17:24:22 +0200 Subject: [PATCH 2/3] change log --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98c0711..e6aab80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 1.0.4 + +### changed + +* Avoid artifact left-over in certain error situations + ## 1.0.3 ### changed From 602565075f8fa47c38a145e9d190688bf70a4602 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:24:47 +0200 Subject: [PATCH 3/3] virtual project file --- CHANGELOG.md | 6 +++++ README.md | 8 ++----- src/Runfs/Build.fs | 33 ++++++++++------------------ src/Runfs/ProjectFile.fs | 26 ++++++++++++++++++++++ src/Runfs/Runfs.fs | 16 +++++++------- src/Runfs/Runfs.fsproj | 4 ++-- tests/Runfs.Tests/TestFiles/test1.fs | 2 -- 7 files changed, 56 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6aab80..e15c922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 1.0.5 + +### changed + +* "Virtual" (in-memory) project file + ## 1.0.4 ### changed diff --git a/README.md b/README.md index 6dc9979..0a1028b 100644 --- a/README.md +++ b/README.md @@ -58,15 +58,11 @@ Main learnings - A small compiler change is needed to allow for the directive format. - The most important missing piece is editor support. -Open items -- I did not succeed yet in replicating the "virtual project file" approach. If I use the msbuild API's `BuildManager`, it doesn't find the sdk, probably because I am missing the right global build properties that `dotnet run` has available internally. I am not sure if there is a workaround. For now, I settled for a less nice file-based approach. Less nice because the script location must be writable. -- Not sure yet if the "compile only" shortcut can easily be replicated for F#. - ## TODOs Runfs -- investigate the open items: virtual project file, optimize the build step (cache core compile input beyond restore) -- add more tests, automate publishing, possibly Rid-package, fix case sensitivity issue in Directives.fs +- investigate if the "compile only" shortcut can be replicated for F# +- add more tests, possibly Rid-package, fix case sensitivity issue in Directives.fs - implement the #project, #source and #dll directives and `--convert` Elsewhere diff --git a/src/Runfs/Build.fs b/src/Runfs/Build.fs index 70cbdcb..dfe50b9 100644 --- a/src/Runfs/Build.fs +++ b/src/Runfs/Build.fs @@ -27,9 +27,7 @@ let createProject verbose projectFilePath (projectFileText: string) : Project = let loggerArgs = [|$"-verbosity:{verbosity}"; "-tl:off"; "NoSummary"|] let consoleLogger = TerminalLogger.CreateTerminalOrConsoleLogger loggerArgs let loggers = [|consoleLogger|] - let globalProperties = - dict [ - ] + let globalProperties = dict [] let projectCollection = new ProjectCollection( globalProperties, loggers, @@ -38,24 +36,17 @@ let createProject verbose projectFilePath (projectFileText: string) : Project = options.ProjectCollection <- projectCollection options.GlobalProperties <- globalProperties - // let reader = new StringReader(projectFileText) - // let xmlReader = XmlReader.Create reader - // let projectRoot = ProjectRootElement.Create(xmlReader, projectCollection) - // projectRoot.FullPath <- projectFilePath - // let projectInstance = ProjectInstance.FromProjectRootElement(projectRoot, options) - - File.WriteAllText(projectFilePath, projectFileText) - try - let projectInstance = ProjectInstance.FromFile(projectFilePath, options) - let parameters = BuildParameters projectCollection - parameters.Loggers <- loggers - parameters.LogTaskInputs <- false - let buildManager = BuildManager.DefaultBuildManager - buildManager.BeginBuild parameters - {buildManager = buildManager; projectInstance = projectInstance} - with ex -> - File.Delete projectFilePath - reraise() + let reader = new StringReader(projectFileText) + let xmlReader = XmlReader.Create reader + let projectRoot = ProjectRootElement.Create(xmlReader, projectCollection) + projectRoot.FullPath <- projectFilePath + let projectInstance = ProjectInstance.FromProjectRootElement(projectRoot, options) + let parameters = BuildParameters projectCollection + parameters.Loggers <- loggers + parameters.LogTaskInputs <- false + let buildManager = BuildManager.DefaultBuildManager + buildManager.BeginBuild parameters + {buildManager = buildManager; projectInstance = projectInstance} let build target project = let flags = diff --git a/src/Runfs/ProjectFile.fs b/src/Runfs/ProjectFile.fs index 8a9a415..eea9551 100644 --- a/src/Runfs/ProjectFile.fs +++ b/src/Runfs/ProjectFile.fs @@ -59,5 +59,31 @@ let createProjectFileLines directives entryPointSourceFullPath artifactsPath ass $""" """ " " yield! sdks |> List.map (sdkLine "Sdk.targets") + + $""" """ + $""" """ + + $""" """ + $""" """ + $""" """ + $""" """ + $""" """ + + $""" """ + $""" """ + $""" <_RestoreProjectPathItems Include="@(FilteredRestoreGraphProjectInputItems)" /> """ + $""" """ + $""" """ + + $""" """ + $""" """ + $""" """ + "" ] \ No newline at end of file diff --git a/src/Runfs/Runfs.fs b/src/Runfs/Runfs.fs index dffb70e..7ae69b8 100644 --- a/src/Runfs/Runfs.fs +++ b/src/Runfs/Runfs.fs @@ -107,7 +107,7 @@ let run (options, sourcePath, args) = return computeDependenciesHash (string fullSourceDir) directives } - let! dependenciesChanged, sourceChanged, noExecutable = guardAndTime "computing build level" <| fun () -> + let! needsRestore, needsBuild = guardAndTime "computing build level" <| fun () -> let dependenciesChanged = if noDependencyCheck then false @@ -118,34 +118,34 @@ let run (options, sourcePath, args) = let readPreviousSourceHash() = File.ReadAllText sourceHashPath not (File.Exists sourceHashPath && readPreviousSourceHash() = sourceHash) let noDll = not (File.Exists dllPath) - Ok (dependenciesChanged, sourceChanged, noDll) + Ok (dependenciesChanged || noDll, sourceChanged) - if dependenciesChanged || noExecutable then + if needsRestore then do! guardAndTime "creating and writing project file" <| fun () -> let projectFileLines = createProjectFileLines directives fullSourcePath artifactsDir AssemblyName File.WriteAllLines(savedProjectFilePath, projectFileLines) |> Ok - if dependenciesChanged || sourceChanged || noExecutable then + if needsRestore || needsBuild then use! project = guardAndTime "creating msbuild project instance" <| fun () -> let projectFileText = File.ReadAllText savedProjectFilePath createProject verbose virtualProjectFilePath projectFileText |> Ok - if dependenciesChanged || noExecutable then + if needsRestore then do! guardAndTime "running msbuild restore" <| fun () -> result { File.Delete dependenciesHashPath do! build "restore" project |> Result.mapError BuildError } - + do! guardAndTime "running dotnet build" <| fun () -> result { File.Delete sourceHash do! build "build" project |> Result.mapError BuildError } - if dependenciesChanged then + if needsRestore then do! guardAndTime "saving dependencies hash" <| fun () -> File.WriteAllText(dependenciesHashPath, dependenciesHash) |> Ok - if sourceChanged then + if needsBuild then do! guardAndTime "saving source hash" <| fun () -> File.WriteAllText(sourceHashPath, sourceHash) |> Ok diff --git a/src/Runfs/Runfs.fsproj b/src/Runfs/Runfs.fsproj index c30bf52..f020813 100644 --- a/src/Runfs/Runfs.fsproj +++ b/src/Runfs/Runfs.fsproj @@ -2,7 +2,7 @@ Runfs - 1.0.4 + 1.0.5 "dotnet run app.cs" functionality for F#. Copyright 2025 by Martin521 Martin521 and contributors @@ -19,7 +19,7 @@ MIT - + README.md diff --git a/tests/Runfs.Tests/TestFiles/test1.fs b/tests/Runfs.Tests/TestFiles/test1.fs index cac4644..fc3b416 100644 --- a/tests/Runfs.Tests/TestFiles/test1.fs +++ b/tests/Runfs.Tests/TestFiles/test1.fs @@ -13,5 +13,3 @@ printfn $"args: {args}" // let RuntimeVersion = Environment.Version // printfn $"Runtime version: {RuntimeVersion}" - -