Tho*_*ger 1 f# gruntjs f#-fake
我想使用FAKE自动化我的项目的构建过程,这需要我运行一个艰巨的任务.
特别是,我想创建一个在解决方案文件夹的子文件夹中运行grunt构建任务的目标.由于我缺乏F#知识,我无法将多个参数传递给Shell类的静态Exec方法.https://fsharp.github.io/FAKE/apidocs/fake-processhelper-shell.html
这是我到目前为止所得到的:
Target "RunGrunt" (fun _ ->
      let errorCode = Shell.Exec "grunt" "build" "\Frontend"
      ()
 )
此操作失败,并显示以下错误消息:
build.fsx(38,23): error FS0003: This value is not a function and cannot be applied
如果我删除最后2个参数,它可以工作,但无法在运行时找到grunt:
System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at Fake.ProcessHelper.start(Process proc) in C:\code\fake\src\app\FakeLib\ProcessHelper.fs:line 22
   at Fake.ProcessHelper.asyncShellExec@424-2.Invoke(Process _arg1) in C:\code\fake\src\app\FakeLib\ProcessHelper.fs:line 428
   at Microsoft.FSharp.Control.AsyncBuilderImpl.callA@851.Invoke(AsyncParams`1 args)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](Result`1 res)
   at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
   at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
   at FSI_0001.Build.clo@34-6.Invoke(Unit _arg5) in D:\Development\Repos\FMVEAv2\Fmvea2-frontend\build.fsx:line 36
   at Fake.TargetHelper.runSingleTarget(TargetTemplate`1 target) in C:\code\fake\src\app\FakeLib\TargetHelper.fs:line 483
Grunt包含在路径变量中.(如果从命令行调用它可以工作)
我的问题是:
如何将多个参数传递给Shell.Exec方法?
如何运行grunt,而不包括完整的路径?
这两个问题现在都解决了.
John在评论中指出使用元组样式而不是curry形式,这导致以下代码:
Shell.Exec("grunt","build","\ FrontEnd")
FAKE提供了一种在路径上查找文件的方法.http://fsharp.github.io/FAKE/apidocs/fake-processhelper.html
因此,目标定义如下所示:
Target "RunGrunt" (fun _ ->
    let grunt = tryFindFileOnPath if isUnix then "grunt" else "grunt.cmd"
    let errorCode = match grunt with
                      | Some g -> Shell.Exec(g, "build", "FrontEnd")
                      | None -> -1
    ()
)
neftedollar在关于跨平台兼容性的评论中提出了一个很好的观点:使用EnvironmentHelper确定平台并搜索grunt的正确可执行文件.