Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

## 1.0.5

### changed

* "Virtual" (in-memory) project file

## 1.0.4

### changed
Expand Down
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 12 additions & 21 deletions src/Runfs/Build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 =
Expand Down
26 changes: 26 additions & 0 deletions src/Runfs/ProjectFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,31 @@ let createProjectFileLines directives entryPointSourceFullPath artifactsPath ass
$""" <Compile Include="{escape entryPointSourceFullPath}" />"""
" </ItemGroup>"
yield! sdks |> List.map (sdkLine "Sdk.targets")

$""" <!-- Override targets which don't work with project files that are not present on disk. --> """
$""" <!-- Hopefully we can remove this once net10 has landed. --> """

$""" <Target Name="_FilterRestoreGraphProjectInputItems" """
$""" DependsOnTargets="_LoadRestoreGraphEntryPoints" """
$""" Returns="@(FilteredRestoreGraphProjectInputItems)"> """
$""" <ItemGroup> """
$""" <FilteredRestoreGraphProjectInputItems Include="@(RestoreGraphProjectInputItems)" /> """
$""" </ItemGroup> """
$""" </Target> """

$""" <Target Name="_GetAllRestoreProjectPathItems" """
$""" DependsOnTargets="_FilterRestoreGraphProjectInputItems" """
$""" Returns="@(_RestoreProjectPathItems)"> """
$""" <ItemGroup> """
$""" <_RestoreProjectPathItems Include="@(FilteredRestoreGraphProjectInputItems)" /> """
$""" </ItemGroup> """
$""" </Target> """

$""" <Target Name="_GenerateRestoreGraph" """
$""" DependsOnTargets="_FilterRestoreGraphProjectInputItems;_GetAllRestoreProjectPathItems;_GenerateRestoreGraphProjectEntry;_GenerateProjectRestoreGraph" """
$""" Returns="@(_RestoreGraphEntry)"> """
$""" <!-- Output from dependency _GenerateRestoreGraphProjectEntry and _GenerateProjectRestoreGraph --> """
$""" </Target> """

"</Project>"
]
16 changes: 8 additions & 8 deletions src/Runfs/Runfs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions src/Runfs/Runfs.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<!-- General -->
<AssemblyName>Runfs</AssemblyName>
<Version>1.0.4</Version>
<Version>1.0.5</Version>
<Description>"dotnet run app.cs" functionality for F#.</Description>
<Copyright>Copyright 2025 by Martin521</Copyright>
<Authors>Martin521 and contributors</Authors>
Expand All @@ -19,7 +19,7 @@
<PackageIcon>
</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!-- <PackageReadmeFile>README.md</PackageReadmeFile> -->
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="" />
Expand Down
2 changes: 0 additions & 2 deletions tests/Runfs.Tests/TestFiles/test1.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ printfn $"args: {args}"

// let RuntimeVersion = Environment.Version
// printfn $"Runtime version: {RuntimeVersion}"


Loading