en-US/about_Whiskey_Writing_Tasks.help.txt

TOPIC
    about_Whiskey_Writing_Tasks
 
SHORT DESCRIPTION
    This help topic describes how to write your own Whiskey tasks.
 
LONG DESCRIPTION
 
    A Whiskey task is a PowerShell function that has a `Whiskey.Task` attribute:
 
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    To use your task in a whiskey.yml file, make sure the task is loaded first, then use the name from the `Whiskey.Task` attribute, e.g.
 
        Build:
        - LoadTask:
            Path: path\to\task\file.ps1
        - TASK_NAME:
            Property: Value
            Property2:
            - One
            - Two
 
    To allow users to pass values to your task, create parameters on your function. Whiskey will map the parameter names to the property names from the build YAML.
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                [string]
                $Property
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    With the above task, your task would be used in the YAML like this:
     
        - TASK_NAME:
            Property: Value
             
    With this YAML, Whiskey will pass `Value` to your function's `Property` parameter.
     
    You can get the raw parsed YAML as a hashtable by having a `TaskParameter` parameter on your function:
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                [hasthable]
                $TaskParameter
            )
 
            Set-StrictMode -Version 'Latest'
        }
         
    Named parameters are never passed in the `TaskParameter` hashtable.
 
    All values from YAML files are strings and are passed to your function as strings. If a named parameter has a specific type, PowerShell must be able to implicity convert strings to that type. Additionally, Whiskey will convert YAML booleans (`yes`, `no`, `true`, `false`, `1`, or `0`) to PowerShell booleans for any parameters whose types are `[Switch]` or `[bool]`.
     
    If you want the value of your parameter to come from a Whiskey variable, decorate the parameter with Whiskey's `Whiskey.Tasks.ParameterValueFromVariable` attribute, passing the variable expression (method/property names allowed):
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                [Whiskey.Tasks.ParameterValueFromVariable('WHISKEY_ENVIRONMENT')]
                $Environment,
                 
                [Whiskey.Tasks.ParameterValueFromVariable('WHISKEY_ENVIRONMENT.Length')]
                $Length
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    See `about_Whiskey_Variables` for a list of variables available. All environment variables are available, too.
     
    If you need to muck about with Whiskey's context (not recommended), add a `TaskContext` parameter to your function:
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                [Whiskey.Context]
                $TaskContext
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    Whiskey supports these reserved global task properties:
 
    * OnlyDuring
    * ExceptDuring
    * OnlyOnBranch
    * ExceptOnBranch
    * OnlyBy
    * ExceptBy
    * WorkingDirectory
    * IfExists
    * UnlessExists
 
    Reserved properties are never passed to your function, either as a parameter or in the parameter hashtable.
 
 
    # Validating Paths
     
    If you have a parameter that should be a path to a single file/directory, Whiskey can validate the path exists and convert it to a full path for you. To enable this, add the `Whiskey.Tasks.ValidatePath` attribute to the function parameter (or parameters) that should be resolved as paths.
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                [Whiskey.Tasks.ValidatePath()]
                [string]
                $Path
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    By default, the property can be empty and any paths that are given in YAML *must* exist. If you want to require that the user give at least one path (and fail the build if they don't), use the `Mandatory` property:
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                # The user must supply a path to a single file/directory that exists.
                [Whiskey.Tasks.ValidatePath(Mandatory)]
                [string]
                $Path
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    To support multiple paths, set the type of the parameter to `[string[]]`:
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                # The user can use wildcards that point to multiple items.
                [Whiskey.Tasks.ValidatePath(Mandatory)]
                [string[]]
                $Path
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    If the path must be to a file or directory, use the `PathType` property to specify which. The build will fail if any path in the YAML isn't of the given type.
     
        function FUNCTION_NAME
        {
            [Whiskey.Task('TASK_NAME')]
            [CmdletBinding()]
            param(
                # Must be paths to files only.
                [Whiskey.Tasks.ValidatePath(PathType='File')]
                [string[]]
                $FilePath,
                 
                # Must be paths to directories only.
                [Whiskey.Tasks.ValidatePath(PathType='Directory')]
                [string[]]
                $DirectoryPath
            )
 
            Set-StrictMode -Version 'Latest'
        }
 
    If you have more advanced needs, your task can use the `Resolve-WhiskeyTaskPath` function.
     
    # Platform
 
    If your task should only run on certain platforms/operating systems, set the `Platform` property on your task's `TaskAttribute` to the platform(s) it is restricted to. If the task runs on an unsupported platform, the build will fail. By default, tasks can run on all platforms. Supported platforms are `Windows`, `Linux`, and `MacOS`. For example, a task with this task attribute will only run on Windows:
 
        [Whiskey.Task('TASK_NAME',Platform=[Whiskey.Platform]::Windows)]
 
    To run on multiple platforms, use PowerShell's `-bor` operator:
 
        [Whiskey.Task('TASK_NAME',Platform=[Whiskey.Platform]::Windows -bor [Whiskey.Platform]::Linux)]
 
    # Aliases
 
    You can define aliases for your task name. This is useful for making your tasks more discoverable or for re-naming tasks without requiring people to update their build scripts when they upgrade. Use the `Aliases` property to define a list of aliases.
 
        [Whiskey.Task('TASK_NAME',Aliases=('OldName','AnotherOldName'))]
 
    If you want to warn when someone uses your task using an aliased name, set the `WarnWhenUsingAlias` property to `$true`.
 
        [Whiskey.Task('TASK_NAME',Aliases=('DeprecatedName'),WarnWhenUsingAlias=$true)]
 
    # Deprecating Tasks
 
    To deprecate a task, set the `Obsolete` property on its `Whiskey.Task` attribute:
 
        [Whiskey.Task('TASK_NAME',Obsolete)]
 
    When someone uses your task, Whiskey will write a warning that the task is obsolete and shouldn't be used. You can customize the message shown to users with the `ObsoleteMessage` property:
 
        [Whiskey.Task('TASK_NAME',Obsolete,ObsoleteMessage='The "TASK_NAME" task is obsolete. Please use the "NonObsoleteTask" instead.')]
 
    # Tools
 
    Whiskey can automatically install some tools for your task. The path to that tool is passed to your task in the `TaskParameter` parameter.
 
    To tell Whiskey what tools you depend on, add a `Whiskey.RequiresTool` attribute. It has two parameters: the name of the tool, and the name of the key to use in the `TaskParameter` hashtable where the path to your tool is saved.
 
    For example, given this task:
 
        function FUNCTION_NAME
        {
            [Whiskey.Task(''TASK_NAME'')]
            # The second parameter is the name of the key in the $TaskParamter hashtable where Whiskey should put the path to the Node executable it installs.
            [Whiskey.RequiresTool(''Node'',''NodePath'')]
            [CmdletBinding()]
            param(
                $TaskContext,
 
                [hashtable]
                $TaskParameter
            )
 
            $nodePath = Assert-WhiskeyNodePath -Path $TaskParameter[''NodePath''] -ErrorAction Stop
        }
 
    Whiskey will install the latest version of Node, and put the path to the Node executable in the `NodePath` key in the `TaskParameter` hasthable. You can see that the task is using `Assert-WhiskeyPath` to ensure the `NodePath` parameter points to an existing path.
 
    ## Installing a Specific Tool Version
 
    If your task requires a specific version of a tool, use the `Whiskey.RequiresTool` attribute's `Version` property:
 
        [Whiskey.RequiresTool('NodeModule::nsp', 'NspPath', Version='2.7.0')]
 
    If you want the user to be able to control what version of a tool to use, the `Whiskey.RequiresTool` attribute has a `VersionParameterName` property that should be set to a property name users can use in their whiskey.yml file to control what version of a tool to use. The default name is `Version`. For example, if your `Whiskey.RequiresTool` attribute looks like this:
 
         [Whiskey.RequiresTool('NodeModule::nsp', 'NspPath', VersionParameterName='NspVersion')]
 
    A user could use the `NspVersion` property to control what version of Node they want to use:
 
         Build:
         - TASK_NAME:
            NspVersion: 8.9.4
 
    In the example above, Whiskey would install version 8.9.4 of ths NSP node module.
 
    Whiskey supports installing:
 
    * Node
    * Node Modules
    * .NET Core SDK
    * PowerShell modules
 
    ## Node
 
    To install Node, add this to your task:
 
         [Whiskey.RequiresTool('Node','NodePath')]
 
    The `NodePath` string is the name of the key where the path to Node should be saved in the `TaskParameter` hashtable when calling your task.
 
    If the user doesn't use the version parameter to control what version of Node to use, Whiskey also looks in the user's package.json file at the `engines.node` property, e.g.
 
       {
            "engines": {
                "node": "^8.9.4"
            }
       }
 
    Node is installed to a `.node` directory in the build root. This gives every project its own version of Node to use.
 
    ## Node Modules
 
    To install a Node module, pass the name of the module (case-sensitive) to the `Whiskey.RequiresTool` attribute, prefixed with `NodeModule::`. For example,
 
        [Whiskey.Requirestool('NodeModule::nsp', 'NspPath')]
 
    would cause Whiskey to install the NSP module and send the path to its directory in the `NspPath` key of the `TaskParameter` hashtable when calling your task. The path will always be to the Node module's directory in the `node_modules` directory.
 
    Whiskey does not install these Node modules in your project's node_modules directory. It installs them to the "node_modules" directory in your project's dedicated "global" Node environment.
 
    ## .NET Core SDK
 
    To install the .NET Core SDK, add this to your task:
 
        [Whiskey.RequiresTool('DotNet','DotNetPath')]
 
    The `DotNetPath` string is the name of the key where the path to the `dotnet.exe` command should be saved in the `$TaskParameter` hashtable when calling your task.
 
    If the SDK version to install is not defined in the `whiskey.yml` file, then Whiskey will look for a .NET Core `global.json` file first in the task's working directory and then in the same directory as the `whiskey.yml` file. The `global.json` file defines the SDK version with the `sdk.version` property, e.g.
 
        {
            "sdk": {
                "version": "2.1.4"
            }
        }
 
    If no SDK version is found in the `whiskey.yml` or `global.json`, Whiskey will use the latest LTS release of the .NET Core SDK.
 
    Before installing the .NET Core SDK to the build root, Whiskey will first search for global .NET Core installs containing the desired version. If a global install is found with the correct version, that path is used and the install to the local build root is skipped.
 
    Whiskey will *always* update the `sdk.version` property within the `global.json` file found in the task working directory or the Whiskey build root with the version of the SDK that task is using. If a `global.json` file does not exist in either the working directory or build root, one is created in the build root.
 
    ## PowerShell Modules
 
    To install a PowerShell module, add this to your task:
 
        [Whiskey.RequiresTol('PowerShellModule::Whiskey','WhiskeyPath')]
 
    The `WhiskeyPath` string is the name of the key where the path to the module root should be saved in the `$TaskParameter` hashtable passed to your task.
 
    Use the `Import-WhiskeyPowerShellModule` function in your task to import the module. Pass the name (or names) of the module to the `Import-WhiskeyPowerShellModule` function's `Name` parameter.
 
    Modules are saved to a directory in working directory of the task that requires it. The exact directory is an implementation detail, and is subject to change. Use the path as passed to your task.