+
+
+
diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts
index e9c4837525..159af5e2d2 100644
--- a/website/.vitepress/config.ts
+++ b/website/.vitepress/config.ts
@@ -1,5 +1,6 @@
import { defineConfig, HeadConfig } from 'vitepress';
import githubLinksPlugin from './plugins/github-links';
+import { renderSearchContent } from './plugins/local-search';
import { readdirSync, readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
import matter from 'gray-matter';
@@ -367,6 +368,7 @@ export default defineConfig({
: {
provider: 'local',
options: {
+ _render: renderSearchContent,
detailedView: true,
miniSearch: {
searchOptions: {
diff --git a/website/.vitepress/plugins/local-search.ts b/website/.vitepress/plugins/local-search.ts
new file mode 100644
index 0000000000..2addaa89fd
--- /dev/null
+++ b/website/.vitepress/plugins/local-search.ts
@@ -0,0 +1,31 @@
+import type { MarkdownEnv, MarkdownRenderer } from 'vitepress';
+
+export function renderSearchContent(
+ src: string,
+ env: MarkdownEnv,
+ md: MarkdownRenderer
+): string {
+ let html = md.render(src, env);
+ if (env.frontmatter?.search === false) return '';
+
+ // Otherwise stripping the tags joins the language label to the first
+ // command ("shellbrew"), preventing searches for "brew install".
+ html = html.replace(/[^<]*<\/span>/g, '');
+
+ // Local search renders Markdown without mounting Vue. Include the platform
+ // label from each card's props after its heading, so searches such as Ubuntu
+ // resolve to apt rather than losing the distribution names with the markup.
+ html = html.replace(
+ /(]*\bplatform-label="([^"]*)"[^>]*>[\s\S]*?<\/h3>)/g,
+ '$1
-:::
+## Community packages {#community-maintained-package-managers}
-### [Mise](https://mise.jdx.dev/)    {#mise}
+Maintained by the community, outside the Task team's control. These packages may
+lag behind the latest release.
-Mise is a cross-platform package manager that acts as a "frontend" to a variety
-of other package managers "backends" such as `asdf`, `aqua` and `ubi`.
+
-If using Mise, we recommend using the `aqua` or `ubi` backends to install Task
-as these install directly from our GitHub releases.
+
-::: code-group
+### [Mise](https://mise.jdx.dev/) {#mise}
-```shell [aqua]
-mise use -g aqua:go-task/task@latest
-mise install
-```
+
+
+
+
+[View package](https://mise-tools.jdx.dev/tools/task)
-```shell [ubi]
-mise use -g ubi:go-task/task
-mise install
+
+
+```shell
+mise use -g task
```
-:::
+For a project-local installation, use `mise use task` instead. This adds Task to
+your project's `mise.toml`.
+
+
+
+
+
+
-### [Macports](https://macports.org)  {#macports}
+### [Macports](https://macports.org) {#macports}
-Task repository is tracked by Macports
-[[package](https://ports.macports.org/port/go-task/details/)]
-[[source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)]:
+
+
+
+
+[View package](https://ports.macports.org/port/go-task/details/)
+[Source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)
+
+
```shell
port install go-task
```
-### [pip](https://pip.pypa.io)    {#pip}
+
+
+
+
+
+
+### [pip](https://pip.pypa.io) {#pip}
+
+
+
+
+
+[View package](https://pypi.org/project/go-task-bin)
+[Source](https://github.com/Bing-su/pip-binary-factory/tree/main/task)
-Like npm, pip can be used as a cross-platform way to install Task
-[[package](https://pypi.org/project/go-task-bin)]
-[[source](https://github.com/Bing-su/pip-binary-factory/tree/main/task)]:
+
```shell
pip install go-task-bin
```
-### [Chocolatey](https://chocolatey.org)  {#chocolatey}
+
-[[package](https://community.chocolatey.org/packages/go-task)]
-[[source](https://github.com/Starz0r/ChocolateyPackagingScripts/blob/master/src/go-task_gh_build.py)]
+
+
+
+
+### [Chocolatey](https://chocolatey.org) {#chocolatey}
+
+
+
+
+
+[View package](https://community.chocolatey.org/packages/go-task)
+[Source](https://github.com/Starz0r/ChocolateyPackagingScripts/blob/master/src/go-task_gh_build.py)
+
+
```shell
choco install go-task
```
-### [Scoop](https://scoop.sh)  {#scoop}
+
+
+
+
+
+
+### [Scoop](https://scoop.sh) {#scoop}
+
+
-[[source](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)]
+
+
+[Source](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
+
+
```shell
scoop install task
```
-### Arch ([pacman](https://wiki.archlinux.org/title/Pacman))  {#arch}
+
+
+
+
+
+
+### Arch ([pacman](https://wiki.archlinux.org/title/Pacman)) {#arch}
-[[package](https://archlinux.org/packages/extra/x86_64/go-task/)]
-[[source](https://gitlab.archlinux.org/archlinux/packaging/packages/go-task)]
+
+
+
+
+[View package](https://archlinux.org/packages/extra/x86_64/go-task/)
+[Source](https://gitlab.archlinux.org/archlinux/packaging/packages/go-task)
+
+
```shell
pacman -S go-task
```
-### Fedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf))  {#fedora-community}
+
+
+
-[[package](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)]
-[[source](https://src.fedoraproject.org/rpms/golang-github-task)]
+
+
+### Fedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)) {#fedora-community}
+
+
+
+
+
+[View package](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)
+[Source](https://src.fedoraproject.org/rpms/golang-github-task)
+
+
```shell
dnf install go-task
```
-### FreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi))  {#freebsd}
+
+
+
+
+
+
+### FreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi)) {#freebsd}
+
+
-[[package](https://cgit.freebsd.org/ports/tree/devel/task)]
-[[source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)]
+
+
+[View package](https://cgit.freebsd.org/ports/tree/devel/task)
+[Source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)
+
+
```shell
pkg install task
```
-### [Nix](https://nixos.org)     {#nix}
+
+
+
+
+
+
+### [Nix](https://nixos.org) {#nix}
-[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
+
+
+
+
+[Source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
+
+
```shell
nix-env -iA nixpkgs.go-task
```
-### [pacstall](https://github.com/pacstall/pacstall)   {#pacstall}
+
+
+
-[[package](https://pacstall.dev/packages/go-task-deb)]
-[[source](https://github.com/pacstall/pacstall-programs/blob/master/packages/go-task-deb/go-task-deb.pacscript)]
+
+
+### [pacstall](https://github.com/pacstall/pacstall) {#pacstall}
+
+
+
+
+
+[View package](https://pacstall.dev/packages/go-task-deb)
+[Source](https://github.com/pacstall/pacstall-programs/blob/master/packages/go-task-deb/go-task-deb.pacscript)
+
+
```shell
pacstall -I go-task-deb
```
-### [pkgx](https://pkgx.sh)   {#pkgx}
+
+
+
+
+
+
+### [pkgx](https://pkgx.sh) {#pkgx}
+
+
+
+
-[[package](https://pkgx.dev/pkgs/taskfile.dev)]
-[[source](https://github.com/pkgxdev/pantry/blob/main/projects/taskfile.dev/package.yml)]
+[View package](https://pkgx.dev/pkgs/taskfile.dev)
+[Source](https://github.com/pkgxdev/pantry/blob/main/projects/taskfile.dev/package.yml)
+
+
```shell
pkgx task
@@ -250,75 +448,88 @@ or, if you have pkgx integration enabled:
task
```
-## Get The Binary
+
-### Binary
+
-You can download the binary from the
-[releases page on GitHub](https://github.com/go-task/task/releases) and add to
-your `$PATH`.
+## Binaries & CI {#get-the-binary}
-DEB, RPM and APK packages are also available.
+Install Task without a package manager: download a binary, use the install
+script, or add the setup action to your GitHub workflow.
-The `task_checksums.txt` file contains the SHA-256 checksum for each file.
+### Download a binary {#binary}
-### Install Script
+1. Open the [GitHub releases](https://github.com/go-task/task/releases) and
+ download the archive for your operating system and architecture.
+2. Extract `task` (`task.exe` on Windows).
+3. Move the executable to a directory on your `PATH`.
-We also have an
-[install script](https://github.com/go-task/task/blob/main/install-task.sh)
-which is very useful in scenarios like CI. Many thanks to
-[GoDownloader](https://github.com/goreleaser/godownloader) for enabling the easy
-generation of this script.
+Each release also includes DEB, RPM and APK packages, plus `task_checksums.txt`
+with SHA-256 checksums for the release files.
-By default, it installs on the `./bin` directory relative to the working
-directory:
+### Install with a script {#install-script}
-```shell
+Use the
+[install script](https://github.com/go-task/task/blob/main/install-task.sh) for
+a shell-based installation, including CI environments. It downloads a prebuilt
+binary and verifies its checksum; no Go installation is needed.
+
+By default, the script installs the latest release into `./bin`, relative to
+your current directory. Choose a different directory or pin a release:
+
+::: code-group
+
+```shell [Latest release]
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
```
-It is possible to override the installation directory with the `-b` parameter.
-On Linux, common choices are `~/.local/bin` and `~/bin` to install for the
-current user or `/usr/local/bin` to install for all users:
-
-```shell
+```shell [Custom directory]
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
```
-::: warning
+```shell [Pinned version]
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.42.1
+```
-On macOS and Windows, `~/.local/bin` and `~/bin` are not added to `$PATH` by
-default.
+```shell [Directory + version]
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1
+```
:::
-By default, it installs the latest version available. You can also specify a tag
-(available in [releases](https://github.com/go-task/task/releases)) to install a
-specific version:
+When combining options, keep the
+[release tag](https://github.com/go-task/task/releases) last.
-```shell
-sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.36.0
-```
+::: tip Make Task available in your shell
-Parameters are order specific, to set both installation directory and version:
+Add the installation directory to your `PATH` to run `task` from anywhere. With
+the default location, you can also run `./bin/task` directly.
-```shell
-sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1
-```
+On Linux, `~/.local/bin` and `~/bin` are common per-user locations;
+`/usr/local/bin` is a system-wide location and may require elevated permissions.
+Do not assume these directories are already on your `PATH`, especially on macOS
+and Windows.
+
+:::
### GitHub Actions
-We have an [official GitHub Action](https://github.com/go-task/setup-task) to
-install Task in your GitHub workflows. This repository is forked from the
-fantastic project by the Arduino team. Check out the repository for more
-examples and configuration.
+Add the [official setup action](https://github.com/go-task/setup-task) to your
+job's `steps` before running Task:
```yaml
- name: Install Task
- uses: go-task/setup-task@v1
+ uses: go-task/setup-task@v2
+
+- name: Verify Task
+ run: task --version
```
-## Build From Source
+Use the action's `version` input to pin a Task release. See the
+[action documentation](https://github.com/go-task/setup-task#usage) for examples
+and configuration.
+
+## Build from source
Ensure that you have a supported version of [Go](https://golang.org) properly
installed and setup. You can find the minimum required version of Go in the
@@ -364,7 +575,20 @@ demand before calling it.
go tool task {arguments...}
```
-## Setup completions
+## Verify installation
+
+After installing, open a terminal and check that Task is available:
+
+```shell
+task --version
+```
+
+If you installed Task with `go tool`, run `go tool task --version` instead.
+
+You're ready to [create your first Taskfile](./getting-started.md). You can also
+enable shell completions below.
+
+## Shell completions {#setup-completions}
Some installation methods will automatically install completions too, but if
this isn't working for you or your chosen method doesn't include them, you can
@@ -376,8 +600,8 @@ config:
This method loads the completion script from the currently installed version of
task every time you create a new shell. This ensures that your completions are
-always up-to-date.
-If your executable isn’t named task, set the `TASK_EXE` environment variable before running eval.
+always up-to-date. If your executable isn’t named task, set the `TASK_EXE`
+environment variable before running eval.
::: code-group
@@ -446,9 +670,10 @@ task --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/t
### Zsh customization
-The Zsh completion supports the standard `verbose` zstyle to control whether task
-descriptions are shown. By default, descriptions are displayed. To show only task
-names without descriptions, add this to your `~/.zshrc` (after the completion is loaded):
+The Zsh completion supports the standard `verbose` zstyle to control whether
+task descriptions are shown. By default, descriptions are displayed. To show
+only task names without descriptions, add this to your `~/.zshrc` (after the
+completion is loaded):
```shell
zstyle ':completion:*:*:task:*' verbose false
@@ -463,18 +688,19 @@ zstyle ':completion:*:*:task:*' show-aliases false
### Nushell caveats
-Nushell cannot source a script from stdin, so both options above write the script
-to an autoload directory. Option 1 rewrites it at every startup, which keeps it
-in sync with the installed version of Task — the refreshed completions are picked
-up by the next shell. With option 2, re-run the command after upgrading Task.
+Nushell cannot source a script from stdin, so both options above write the
+script to an autoload directory. Option 1 rewrites it at every startup, which
+keeps it in sync with the installed version of Task — the refreshed completions
+are picked up by the next shell. With option 2, re-run the command after
+upgrading Task.
The completions are attached to an `extern "task"` declaration, which Nushell
requires to be static. Three consequences are worth knowing:
-- The experimental flags (`--force-all`, `--download`, `--offline`, …) are always
- offered, even when the corresponding experiment is disabled. Their description
- is prefixed with the experiment name, and `task --experiments` lists the ones
- that are enabled.
+- The experimental flags (`--force-all`, `--download`, `--offline`, …) are
+ always offered, even when the corresponding experiment is disabled. Their
+ description is prefixed with the experiment name, and `task --experiments`
+ lists the ones that are enabled.
- Passing a value to a boolean flag with `=` does not work: Nushell forwards
`--color=false` as two arguments, so Task reads `false` as a task name. Use
`NO_COLOR=1`, or bypass the declaration with `^task --color=false`.
diff --git a/website/tests/local-search.test.mjs b/website/tests/local-search.test.mjs
new file mode 100644
index 0000000000..4ce1750feb
--- /dev/null
+++ b/website/tests/local-search.test.mjs
@@ -0,0 +1,98 @@
+import assert from 'node:assert/strict';
+import { test } from 'node:test';
+import { createMarkdownRenderer } from 'vitepress';
+import { renderSearchContent } from '../.vitepress/plugins/local-search.ts';
+
+const md = await createMarkdownRenderer(process.cwd());
+
+test('linked headings retain their text and permalink in the search index', () => {
+ const html = renderSearchContent(
+ '### [Homebrew](https://brew.sh) {#homebrew}\n\nInstall Task.\n',
+ {},
+ md
+ );
+
+ // VitePress splits sections at the first link leading to a hash. A link
+ // around Homebrew used to make the extracted title empty.
+ const heading = html.match(/