FAKE (F# Make)

repository·master·Indexed 23 days ago

https://github.com/fsprojects/fake

A cross-platform build automation system that uses F# and the .NET ecosystem to provide a typed, declarative, and extensible DSL for defining build pipelines. It features a target-based system with dependency chaining, a Vault module for securing sensitive information, Slack webhook integration, and a command-line parser via Docopt.fs.

Tokens
42.1K
Snippets
107
Records
171
Agent score
79%

What's inside FAKE

  1. What is FAKE?

    master

    FAKE (F# Make) is a cross-platform automation system primarily used for builds and releases. It leverages F# to provide a statically typed, declarative, and extensible Domain Specific Language (DSL) for automation. Because it is built on .NET, it benefits from the full .NET class library, powerful debuggers, and IDE support (syntax highlighting and code completion).

    Recommended Tooling: For the best experience, use Visual Studio Code with the Ionide extension.

  2. Format Option Descriptions

    master

    The Options: section defines the behavior of flags and arguments. Every line must start with - or -- (ignoring leading whitespace).

    Rules:

    • Arguments: To indicate an option takes an argument, place the argument name after the option (e.g., -o FILE or --output=FILE).
    • Synonyms: You can define short and long versions of the same option on one line (e.g., -i <file>, --input <file>).
    • Descriptions: Use two spaces to separate the option from its description. Using only one space may cause the parser to treat the description as the option's argument.
    • Defaults: To specify a default value, use the syntax [default: <value>] at the end of the description.

    Example:

    Options:
      -q        Quit.
      -o FILE   Output file.
      --speed=<kn>  Speed in knots [default: 10].
  3. How FAKE script caching works

    master

    Starting with version 4.0.0, FAKE automatically caches compiled assemblies for your build scripts in a hidden .fake directory. This optimization allows FAKE to start in milliseconds rather than seconds.

    Caching is managed via a crc32 key generated from the contents of the primary script and all scripts included via #load. This ensures that changes to your scripts or any loaded dependencies automatically trigger a re-compilation, removing the need for manual cache clearing.

    Important: You should add the .fake folder to your .gitignore file to avoid committing cached assemblies to your repository.

  4. Manage dependencies using Paket syntax in FAKE scripts

    master

    Modern FAKE is standalone and dependency-free, utilizing a modular system where you only load the modules you need. You can manage these dependencies using standard paket.dependencies syntax (a list of NuGet packages).

    For build scripts, you do not need to maintain a separate paket.dependencies file; you can simply place the dependency declarations at the top of your F# script, and the FAKE runner will handle the loading automatically.

  5. Understanding FAKE packages vs FAKE modules

    master

    In FAKE documentation, the terms package and module are often used interchangeably:

    • Package: Refers to the NuGet package containing the code.
    • Module: Refers to the F# module (static class) within that package.

    Typically, a single FAKE NuGet package contains a single F# module.

  6. Use the new FAKE-API

    master

    The new FAKE API moves away from globally available methods (e.g., ReadFile) in favor of namespaced, module-based calls (e.g., File.Read). This improves IDE support and code clarity.

    Key Changes:

    • Namespacing: Instead of MethodModule argument, use Module.Method argument. For example, instead of a global ReadFile, open the Fake.IO.FileSystem namespace and use File.Read.
    • Remove open Fake: The open Fake statement and its associated AutoOpen modules are obsolete. Once you have fixed all API warnings, you should remove open Fake entirely. If your build fails after removal, you may have missed an un-migrated feature or an un-warned obsolete call.
  7. Define Usage Patterns

    master

    The Usage: section (case-insensitive) defines how your program should be called. The first word after usage: is the program name.

    Supported Syntax Elements:

    • <argument> or ARGUMENT: Positional arguments.
    • -o or --option: Options. Can be boolean flags or take arguments (e.g., --opt=VAL or --opt VAL).
    • [pattern]: Optional elements (enclosed in brackets).
    • (pattern): Required elements (enclosed in parentheses).
    • pattern1 | pattern2: Mutually exclusive elements (separated by a pipe).
    • pattern...: Repeatable elements (trailing ellipsis). Results are collected into a list.
    • [options]: A shortcut to match any options defined in the Options: section.
    • - and --: Special commands. - typically represents stdin; -- separates options from positional arguments.
    • command: Any string not recognized as an option or argument is treated as a command/subcommand.

    Special Behavior:

    • If an option is matched multiple times (e.g., -vvv), the count is stored in the result (e.g., Flags(3)).
    • If the same-named option or argument is matched multiple times with values, they are collected into a list of Arguments.
  8. Understand the new FAKE API design principles

    master

    The new FAKE API design moves away from the legacy AutoOpen pattern, which previously polluted the global Fake namespace and caused naming collisions.

    Key improvements in the new design include:

    • Namespace Isolation: Modules no longer introduce generic function names into a single global namespace.
    • Structured Naming: Instead of global functions like CreateDirectory, the API uses a structured approach (e.g., Directory.Create) to provide better context and improved IDE discoverability/autocompletion.
  9. How time stamping works in SignTool

    master

    A digital signature is only valid as long as the signing certificate is valid. When a certificate expires, the signature becomes invalid.

    SignTool.timeStamp is used to extend the validity of a signature indefinitely by proving the signature was created while the certificate was still valid. You can use this function to time stamp files that have already been signed.

    SignTool.timeStamp
        "http://timestamp.example-ca.com"
        (fun o -> { o with
                        Algorithm = Some SignTool.DigestAlgorithm.SHA256 } )
        ["program.exe"; "library.dll"]
    SignTool.timeStamp
        "http://timestamp.example-ca.com"
        (fun o -> { o with
                        Algorithm = Some SignTool.DigestAlgorithm.SHA256 } )
        ["program.exe"; "library.dll"]