
## Custom `Hog/Do` commands
The `Hog/Do` script now supports the ability to add custom commands.
This allows you to extend the functionality of `Hog/Do` with your own scripts, which can be useful for automating specific tasks or integrating with other tools. These scripts will have full access to all the functions available in `Hog.tcl`, so you can use them to interact with your projects, files, and the Hog environment in general.



 ### Defining custom commands
Commands are defined by placing `.tcl` files in the `hog-commands` directory at the root of your repository. For example:

```
hog-commands/
├── my-command.tcl
└── another-command.tcl
```



Hog will source all the `.tcl` files in this directory at startup to discover the available commands. Each command is defined by setting the `::hog_command` variable in the `.tcl` file, using the following format:


```tcl
set ::hog_command {
  NAME  {name}

  DESCRIPTION {description}

  OPTIONS { njobs.arg }

  CUSTOM_OPTIONS {
    {custom_opt  "custom_opt description"}
  }

  SCRIPT {puts "Hello World"}

}
```

:::{warning}
Hog sources all the `.tcl` files in the `hog-commands` directory at startup to discover the available commands. If there are any syntax errors in these files, it may cause issues with the startup of `Hog/Do`. Anything outside of the `set ::hog_command{}` block will also be ran and may cause problems. Make sure your command scripts are properly formatted to avoid any problems.
:::

### Available fields for custom commands
You can customize the command by filling in the following fields:

- `NAME` (***Required***): The name of the command, which will be used to invoke it from the command line.

- `SCRIPT` (***Required***): The Tcl script that will be executed when the command is invoked. This can be any valid Tcl code, and will have access to all the functions and variables available in `Hog.tcl`.

- `DESCRIPTION`: A brief description of what the command does, which will be displayed in the help message.

- `OPTIONS`: A list of hog-options that the command accepts. These are defined in the `Hog/Tcl/launch.tcl` script. Simply specify the option name to add it to your command. For a full list of available hog-options and how they are used, see `launch.tcl`. You can access these options in your script with `[dict get $list_of_options <option_name>]`.

- `CUSTOM_OPTIONS`: A list of custom options that the command accepts. Options should be formatted in the same way as Tcl's `cmdline::getoptions` command (See [cmdline::getoptions](https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/cmdline/cmdline.md#subsection2)). You can access these options in your script with `[dict get $list_of_options <custom_option_name>]`.

- `IDE`:  Specifies whether the command will run in the IDE. Expects the same format as `hog.conf`. For example, if set to `vivado 2023.2`, the command will run inside the Vivado 2023.2 IDE, giving you access to all the vivado commands.  If not specified, the command will run in the same environment as `Hog/Do`.

- `NO_EXIT`: Default is `0`. If set to `1`, the command will not exit after execution, allowing you to build custom hog flows by modifying the variables in `launch.tcl`.

### Example

Inside `Hog/Template/hog-commands`, you will find two example commands. `example_command.tcl` contains a simple command that utilizes TCLSH to print "Hello World" to the console. We will look at a slightly more complex command, `timing_closure_command.tcl`. This command will create (and optionally launch) every combination of synthesis and implementation strategies for the current project.

We begin by defining the name and description of the command:

```tcl
set ::hog_command {
  NAME  {close_timing}

  DESCRIPTION "Creates runs for all possible combinations of synthesis and implementation strategies \
  in the current project, launches them (optionally), and monitors them for timing closure."
```

Since this command will be utilizing vivado commands, we specify the IDE field to run the command in the vivado IDE.

```tcl
  IDE {vivado 2023.2}
```


We then define which built in hog options to use, as well as our own custom options with:
```tcl
  OPTIONS {njobs.arg}

  CUSTOM_OPTIONS {
    {proj.arg "" "if set, open project with this name before creating runs."}
    {run         "if set, run the created implementation runs after creation."}
    {monitor     "if set, monitor runs."}
    {timeout.arg 0 "monitor timeout in minutes."}
    {force       "if set, force reset of all synth/impl runs."}
    {keep_going  "if set, continue running after finding timing clean run."}
  }

```

Finally, we define our main script logic within the `SCRIPT` field. We can write any valid Tcl code here, and access any hog-defined functions and variables. For example,
we can access the options defined above with `[dict get $list_of_options <option_name>]`.

```tcl
  SCRIPT {
    ...

    set project_name [dict get $list_of_options proj]
    set run_flag     [dict get $list_of_options run]
    set jobs         [dict get $list_of_options njobs]
    set monitor_flag [dict get $list_of_options monitor]
    set timeout_min  [dict get $list_of_options timeout]
    set force_flag   [dict get $list_of_options force]
    set keep_going   [dict get $list_of_options keep_going]

    ...
  }
```

The rest of the script contains the logic for creating the runs, launching them, and monitoring them for timing closure.


Now, when we run `./Hog/Do HELP`, we will see our new command listed in the help message:

```
$ ./Hog/Do HELP
...

Custom commands:
   - CLOSE_TIMING: Creates runs for all possible combinations of synthesis and implementation strategies  in the current project, launches them (optionally), and monitors them for timing closure.
```

and running `./Hog/Do CLOSE_TIMING HELP` will show us the options we can use with our command:

```
$ ./Hog/Do CLOSE_TIMING HELP
...
Available options:
  -njobs.arg <argument>
    Number of jobs. Default: 4 (default: 4)
  -proj.arg <argument>
     if set, open project with this name before creating runs.
  -run
     if set, run the created implementation runs after creation.
  -monitor
     if set, monitor runs.
  -timeout.arg <argument>
    monitor timeout in minutes. (default: 0)
  -force
     if set, force reset of all synth/impl runs.
  -keep_going
     if set, continue running after finding timing clean run.
```

We can now invoke the command with any combination of the options defined above. For example, `./Hog/Do CLOSE_TIMING -proj my_project -run -monitor -njobs 8` will open the project named `my_project`, create and run all combinations of synthesis and implementation strategies, and monitor them for timing closure.