Thanks to visit codestin.com
Credit goes to github.com

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
48 changes: 48 additions & 0 deletions src/Perla/CliMiddleware.fs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,46 @@ module internal MiddlewareImpl =
return ()
}

let fableCheck (isFableInConfig: bool) : MiddlewareFn =
fun context next -> task {
let cmdName = context.ParseResult.CommandResult.Command.Name

let isFableRequired =
[ "serve"; "build"; "test" ] |> List.contains cmdName

if not isFableRequired || not isFableInConfig then
return! next.Invoke context
else
let! isFablePresent = FileSystem.CheckFableExists()

if isFablePresent then
return! next.Invoke context
else
Logger.log
"Looks like you don't have fable installed, we'll try to call [yellow]dotnet tool restore[/]."

match! FileSystem.DotNetToolRestore() with
| Ok() -> return! next.Invoke context
| Error err ->
Logger.log "dotnet tool restore failed:"
Logger.log err
Logger.log "Please try installing fable manually and try again."
context.ExitCode <- 1
return ()

}

let runDotEnv: MiddlewareFn =
fun context next -> task {
let cmdName = context.ParseResult.CommandResult.Command.Name

let runDotEnv = [ "serve"; "build"; "test" ] |> List.contains cmdName

if runDotEnv then
FileSystem.GetDotEnvFilePaths() |> Env.LoadEnvFiles

return! next.Invoke context
}

[<RequireQualifiedAccess>]
module Middleware =
Expand Down Expand Up @@ -265,3 +305,11 @@ module Middleware =
Checks.SaveTemplatesPresent
)
)

let FableCheck =
ConfigurationManager.UpdateFromFile()
let config = ConfigurationManager.CurrentConfig

InvocationMiddleware(MiddlewareImpl.fableCheck config.fable.IsSome)

let RunDotEnv = InvocationMiddleware(MiddlewareImpl.runDotEnv)
8 changes: 7 additions & 1 deletion src/Perla/CliMiddleware.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ module internal MiddlewareImpl =
val esbuildBinCheck: checks: EsbuildBinCheck -> MiddlewareFn

val templatesCheck:
templatesArePresent: (unit -> bool) * setCheck: (unit -> ObjectId) -> MiddlewareFn
templatesArePresent: (unit -> bool) * setCheck: (unit -> ObjectId) ->
MiddlewareFn

val fableCheck: isFableInConfig: bool -> MiddlewareFn

val runDotEnv: MiddlewareFn

module Middleware =
val PreviewCheck: InvocationMiddleware
val EsbuildPluginCheck: InvocationMiddleware
val SetupCheck: InvocationMiddleware
val EsbuildBinCheck: InvocationMiddleware
val TemplatesCheck: InvocationMiddleware
val FableCheck: InvocationMiddleware
val RunDotEnv: InvocationMiddleware
37 changes: 37 additions & 0 deletions src/Perla/FileSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
open System
open System.IO
open System.IO.Compression
open System.Text
open System.Text.Json.Nodes
open System.Threading
open System.Threading.Tasks
Expand Down Expand Up @@ -342,6 +343,42 @@ module FileSystem =
fsw.Filters.Add(".jsonc")
fsw

let DotNetToolRestore () : Task<Result<unit, string>> = task {
let ext = if Env.IsWindows then ".exe" else ""
let dotnet = $"dotnet{ext}"
let err = StringBuilder()

let cmd =
Cli
.Wrap(dotnet)
.WithArguments("tool restore")
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(err))

try
let! result = cmd.ExecuteAsync()

if result.ExitCode <> 0 then
return Error(err.ToString())
else
return Ok()
with ex ->
return Error $"{ex.Message}\n{err.ToString()}"
}

let CheckFableExists () : Task<bool> = task {
let ext = if Env.IsWindows then ".exe" else ""
let dotnet = $"dotnet{ext}"

let cmd = Cli.Wrap(dotnet).WithArguments("fable --version")

try
let! result = cmd.ExecuteAsync()

if result.ExitCode <> 0 then return false else return true
with ex ->
return false
}

type FileSystem =

static member PerlaConfigText
Expand Down
3 changes: 3 additions & 0 deletions src/Perla/FileSystem.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ module FileSystem =
val TplRepositoryChildTemplates:
path: string<SystemPath> -> string<SystemPath> seq

val DotNetToolRestore: unit -> Task<Result<unit, string>>
val CheckFableExists: unit -> Task<bool>

[<Class>]
type FileSystem =
static member PerlaConfigText:
Expand Down
61 changes: 11 additions & 50 deletions src/Perla/Handlers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -409,43 +409,6 @@ module Esbuild =

Task.WhenAll(cssTasks, jsTasks)

module Setup =
/// set esbuild, playwright and import map dependencies in parallel
/// as these are not overlapping and should save time
let EnsureDependencies (config, cancel) = task {
let! results =
[
task {
do Testing.SetupPlaywright()
return None
}
task {
do! FileSystem.SetupEsbuild(config.esbuild.version, cancel)
return None
}
task {
let! result =
Logger.spinner (
"Resolving Static dependencies and import map...",
Dependencies.GetMapAndDependencies(
[ yield! config.dependencies; yield! config.devDependencies ]
|> Seq.map (fun d -> d.AsVersionedString),
config.provider
)
)

return
result
|> Result.defaultWith (fun _ ->
(Seq.empty, FileSystem.GetImportMap()))
|> Some
}
]
|> Task.WhenAll

return results[2].Value
}

module Testing =
let RunOnce
(
Expand Down Expand Up @@ -833,16 +796,12 @@ module Handlers =


let runBuild (options: BuildOptions, cancellationToken: CancellationToken) = task {
FileSystem.GetDotEnvFilePaths() |> Env.LoadEnvFiles

ConfigurationManager.UpdateFromCliArgs(?runConfig = options.mode)
let config = ConfigurationManager.CurrentConfig

do! Fable.StartFable(config, cancellationToken)

if not <| File.Exists($"{FileSystem.EsbuildBinaryPath}") then
do! FileSystem.SetupEsbuild(config.esbuild.version, cancellationToken)

let outDir = UMX.untag config.build.outDir

try
Expand Down Expand Up @@ -944,7 +903,6 @@ module Handlers =
}

let runServe (options: ServeOptions, cancellationToken: CancellationToken) = task {
FileSystem.GetDotEnvFilePaths() |> Env.LoadEnvFiles

let cliArgs = [
match options.port with
Expand Down Expand Up @@ -988,10 +946,6 @@ module Handlers =

do! FsMonitor.FirstCompileDone true fableEvents

do! FileSystem.SetupEsbuild(config.esbuild.version, cancellationToken)

PluginRegistry.LoadPlugins(config.esbuild)

do! VirtualFileSystem.Mount(config)

let perlaChanges =
Expand Down Expand Up @@ -1038,7 +992,6 @@ module Handlers =
cancellationToken: CancellationToken
) =
task {
FileSystem.GetDotEnvFilePaths() |> Env.LoadEnvFiles

ConfigurationManager.UpdateFromCliArgs(
testingOptions = [
Expand All @@ -1065,6 +1018,7 @@ module Handlers =

let config = {
ConfigurationManager.CurrentConfig with
runConfiguration = RunConfiguration.Development
mountDirectories =
ConfigurationManager.CurrentConfig.mountDirectories
|> Map.add
Expand All @@ -1074,8 +1028,6 @@ module Handlers =

let isWatch = config.testing.watch

let! dependencies = Setup.EnsureDependencies(config, cancellationToken)

let fableEvents =
match config.testing.fable with
| Some fable -> Fable.Observe(fable, isWatch)
Expand All @@ -1091,7 +1043,6 @@ module Handlers =

do! FsMonitor.FirstCompileDone isWatch fableEvents


PluginRegistry.LoadPlugins config.esbuild

do! VirtualFileSystem.Mount config
Expand Down Expand Up @@ -1119,6 +1070,14 @@ module Handlers =

let events = Subject<TestEvent>.broadcast

let! dependencies =
Dependencies.GetMapAndDependencies(
Seq.empty,
config.provider,
config.runConfiguration
)
|> TaskResult.defaultValue (Seq.empty, FileSystem.GetImportMap())

let mutable app =
Server.GetTestingApp(
config,
Expand Down Expand Up @@ -1592,3 +1551,5 @@ module Handlers =
table.DoubleBorder() |> AnsiConsole.Write
return 0
}
return 0
}
11 changes: 9 additions & 2 deletions src/Perla/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ let main argv =
pipeline
// don't replace leading @ strings e.g. @lit-labs/task
.UseTokenReplacer(fun _ _ _ -> false)
// Check for hidden commands and if the preview directive is enabled
.AddMiddleware(Middleware.PreviewCheck)
// Setup Perla if it's not already setup
.AddMiddleware(Middleware.SetupCheck)
// Setup Esbuild in case it's not already setup
.AddMiddleware(Middleware.EsbuildBinCheck)
// Download templates if they're not already present
.AddMiddleware(Middleware.TemplatesCheck)
// Check if the esbuild plugin is present in PerlaConfiguration
.AddMiddleware(Middleware.EsbuildPluginCheck)
// Check for hidden commands and if the preview directive is enabled
.AddMiddleware(Middleware.PreviewCheck)
// Run Dotnet tool if fable is in config and not installed
.AddMiddleware(Middleware.FableCheck)
// Add .env files to the environment
.AddMiddleware(Middleware.RunDotEnv)
|> ignore)

addCommands [
Expand Down