使用F#脚本自动执行您的Dev Life

使用脚本允许您自动执行重复任务。脚本不仅可以节省时间,而且还可以降低犯错误的风险。您可以将它们视为自动清单。有很多方法可以编写脚本,但我最喜欢的方式是使用F#,因为它给了我许多处理数据输入的帮助者。此外,如果需要,我可以依赖于所有受信任的.NET功能加上一些核心包装。所以,让我们看看我们如何编写脚本,确保他们在日常生活中完成我们想要的并使用它们。

获取设置

要在计算机上编写和运行F#脚本,您需要.NET SDK.,一个具有f#sintax突出显示的编辑器 - 我推荐视觉工作室 Code.(vs代码)和离子插件. And that is it; you are ready to create your first script. Open VS Code, open a new tab, hit save and create a file with the file ending .fsx.

虽然我在这里推荐VS代码,但我已经写了很多代码视觉工作室, Mac Visual Studio骑士来自码头。这些选项没有错,如果你已经熟悉了其中一个。请不要迫害改变。但是,如果您刚刚入门,则VS代码是一个轻量级的选项来开始。

了解f#脚本

如果您正在编写F#脚本,则它将执行F#Interactive.(FSI)。让我们从下面的这个最小脚本开始:

printfn "Hello dear blog reader"

我们可以将此单衬册脚本返回到终端和(在与脚本文件的同一目录中)运行以下命令:

dotnet fsi the-name-of-your-file.fsx

该脚本将在终端上打印邮件。但是在开发时,有一种方法可以使用FSI作为REPT(Read-epg-Print-Loop)。所以在VS代码中,我们可以突出显示您的代码并点击Alt + Enter。突出显示的代码将在VS代码中执行并显示我们的问候语。同样的结果,但在开发时更方便。

写脚本

虽然这一切都很酷而且很好,但是,在某些时候看看所有.NET开发人员在某些时候都会想做的事情:粉碎该键盘对阵蒙语 - err,我的意思是删除那些obj和bin文件夹。 aka从项目中的构建输出,因为某些东西(例如,一个git rebase)制作的东西旺盛。

编写脚本时,您可以从无使用任何方法开始。开始列出给定路径中的所有目录:

Directory.EnumerateDirectories("~/TestDirectory/") |> Seq.toList

从那里开始,一步一步,构建脚本的功能。您不断通过将突出显示的部分发送到REPT来测试它。在某些时候,您将希望将代码构成为方法,以更好地概述正在发生的事情。所以要获取给定根文件夹的所有bin和obj目录路径 - 我们最终可能会有这样的东西:

let EnumerateDirectories path =
    Directory.EnumerateDirectories(path) |> Seq.toList

let isObjOrBinFolder (folderName:string) =
    folderName.EndsWith("obj", true, CultureInfo.InvariantCulture) || folderName.EndsWith("bin", true, CultureInfo.InvariantCulture)

let rec getFoldersToDelete path =
    match EnumerateDirectories path with
    | [] -> []
    | subfolders  ->
        let targetFolders = subfolders 
                            |> List.filter isObjOrBinFolder
        let targets = subfolders 
                            |> List.filter (isObjOrBinFolder >> not) 
                            |> List.collect getFoldersToDelete
                            |> List.append targetFolders
        targets

The EnumerateDirectories returns a list of directories in a path. The isObjOrBinFolder method returns true if a given folder is either named bin or obj. Finally, the getFoldersToDelete recursively iterates through every subdirectory. Collecting all the folders, we intend to delete. To remove the folders, we add an additional method:

let deleteFoldersAndSubFolders path =
    getFoldersToDelete path
    |> List.iter (fun dir -> 
        printfn "Deleting: %s" dir
        Directory.Delete dir)

What we now still need is the directory we scan for the binobj folders. Let’s say we want to give us the option to pass in the path as a parameter, and if we don’t hand in a parameter, we want to take the directory the script is invoked from:

match fsi.CommandLineArgs |> Array.skip 1 with
| [||] -> 
    deleteFoldersAndSubFolders (Directory.GetCurrentDirectory())
| directoryPaths -> 
    directoryPaths
    |> Array.iter deleteFoldersAndSubFolders

The Directory.GetCurrentDirectory() is a handy helper to provide you with the path from which your script is running from. Speaking of .NET helpers, F# offers built-in values that provide you information of the directory __SOURCE_DIRECTORY__, filename __SOURCE_FILE__和line number __LINE__. Another great helper I like to use in my scripts is #time. Placing it, e.g. at the top of your script, will tell you all kinds of information regarding CPU time and garbage collection. Note it acts as a toggle, so running #time multiple times in FSI will turn it on/off/on/off/you-get-it-by-now-right-😉.

利用尼古特的力量

While it is pretty straightforward to reference parts of the .NET SDK by using open Something.Something, it is pretty much the same when you want to reference a NuGet package. For example, let’s say you want to add Newtonsoft.JSON to our script. We could do this with the following lines:

#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json

// more codez

let movie = JsonConvert.DeserializeObject<Movie>(json)

Pretty straight forward ey? 😃 You can use the same syntax to reference local dlls. So if you have a dll locally lying around but not on NuGet, you could do something like this #r path/to/dll/theDllName.dll和then open the namespace you want to use.

善后

脚本可以是自动化一些日常任务的有趣方式,并确保没有人为错误爬行。 F#基于基于的脚本体验提供了优秀的.NET。并且能够使用Nuget包是一个显着的生产率提升。请记住,写脚本可能需要一些时间。所以你可能希望考虑益处与成本 - 如此XKCD.很高兴。然后,编写脚本可能是一个很好的乐趣和学习.NET SDK,Nuget软件包和F#的好方法。您可以找到完整的脚本 这里.

但足够的广告真实。是时候考虑您可以写的脚本以自动化您的日常开发人员生活。

Hth.

更新: