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}"
-
-