From ae2aef79422c90c689ebbed65a7f750f65b303d3 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 8 Aug 2025 19:48:38 +0200 Subject: [PATCH 01/19] Allow running help on/for other Taskfiles --- src/components/Generator/GeneredTaskfile/taskfile-base.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Generator/GeneredTaskfile/taskfile-base.sh b/src/components/Generator/GeneredTaskfile/taskfile-base.sh index c3f64dd..47c66fa 100644 --- a/src/components/Generator/GeneredTaskfile/taskfile-base.sh +++ b/src/components/Generator/GeneredTaskfile/taskfile-base.sh @@ -52,14 +52,16 @@ function title { echo -e "\n${BLUE}=>${RESET} $1\n" } +# shellcheck disable=SC2120 function task:help { ## Show all available tasks + TASKFILE_FILE=${1-$0} banner title "Available tasks" awk 'BEGIN {FS = " { [#][#][ ]?"} /^([a-zA-Z_-]*:?.*)(\{ )?[#][#][ ]?/ \ - {printf "\033[33m%-34s\033[0m %s\n", $1, $2}' $0 |\ + {printf "\033[33m%-34s\033[0m %s\n", $1, $2}' "$TASKFILE_FILE" |\ sed -E "s/[#]{2,}[ ]*/${RESET}/g" |\ sed -E "s/function task:*/ /g" - echo -e "\n${BLUE}Usage:${RESET} ./Taskfile ${YELLOW}${RESET} " + echo -e "\n${BLUE}Usage:${RESET} $TASKFILE_FILE ${YELLOW}${RESET} " } function task:shorthand { ## Create CLI shorthand task instead of ./Taskfile From f6f48ad140d321dacc03251c0180465b9b137c83 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 8 Aug 2025 20:57:31 +0200 Subject: [PATCH 02/19] Document subTaskfiles --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eef7334..579c434 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ Lines with only a single `#` will not appear as section in `task:help` and can b Running `./Taskfile help`, the `task:help` function is triggered. This task will list all available sections and tasks using the double `##` comments you've learned about above. Now it's clear how you can run any other task! -# Auto-completion +# Advanced +## Auto-completion Autocompletion works when you use `zsh` and `oh-my-zsh`. Create the following file in your oh-my-zsh directory `~/.oh-my-zsh/completions/_task.zsh`: @@ -82,6 +83,59 @@ _task "$@" Now after running `task shorthand`, your `task` commands will get autocompleted. +## SubTaskfiles + +Have a (mono)repo with multiple projects, a group of less-used or specialized tasks or just waaay to many tasks for a +single Taskfile? SubTaskfiles might be for you! They allow you to divide your tasks across multiple files while still +(also) calling them from a single one. + +There are two flavours, but in both cases tasks from the subTaskfile are called "via" a task in the root Taskfile, +like this: `./Taskfile foo ` + +### Full SubTaskfile + +This flavour of subTaskfile is more verbose, but can be used on its own as well. Most useful in (mono)repos where people might +be working on part as often as the whole project. + +In the main Taskfile you call the subTaskfile like any other script: +```shell +function task:foo { ## bar + ./path/to/subtaskfile/Taskfile "${@-help}" +} +``` + +The subTaskfile is just a regular Taskfile, including utilities like `task:help`, `file:ensure` and a line with `task:"${@-help}"` +at the bottom. + +### Lean SubTaskfile + +This flavour of subTaskfile cannot be called on its own, but has a lot less boilerplate. Most useful for splitting off a +group of tasks that can be logically grouped together, possibly because they are rarely used. + +In the main Taskfile: +```shell +function task:foo { ## bar + SUB_TASKFILE_DIR="./path/to/subtaskfile/" + + source "$SUB_TASKFILE_DIR/Taskfile" + + task:"${@-_help}" +} +``` + +The subTaskfile just needs to contain the tasks and sections you need, but has a few notes: +```shell +# Files in the subTaskfile's directory need to be prefixed with $SUB_TASKFILE_DIR +function task:call-script { ## Call a script + "$SUB_TASKFILE_DIR/some-script.sh" +} + +# Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` +function task:_help { ## Show all available tasks + task:help "$SUB_TASKFILE_DIR/Taskfile" +} +``` + # Credits This Taskfile setup is based on [Adrian Cooney's Taskfile](https://github.com/adriancooney/Taskfile) and is widely From 00ce5f0712c864d584df36f36aa8eba2868e6db3 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 8 Aug 2025 21:09:27 +0200 Subject: [PATCH 03/19] Clarify naming of the two types --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 579c434..dd0ae6e 100644 --- a/README.md +++ b/README.md @@ -83,34 +83,34 @@ _task "$@" Now after running `task shorthand`, your `task` commands will get autocompleted. -## SubTaskfiles +## Splitting Taskfiles Have a (mono)repo with multiple projects, a group of less-used or specialized tasks or just waaay to many tasks for a -single Taskfile? SubTaskfiles might be for you! They allow you to divide your tasks across multiple files while still -(also) calling them from a single one. +single Taskfile? Splitting your Taskfiles might be for you! This allows you to divide your tasks across multiple files +while still (also) calling them from a single one. -There are two flavours, but in both cases tasks from the subTaskfile are called "via" a task in the root Taskfile, +There are two types, but in both cases tasks from the secondary Taskfile are called "via" a task in the root Taskfile, like this: `./Taskfile foo ` -### Full SubTaskfile +### Remote Taskfile -This flavour of subTaskfile is more verbose, but can be used on its own as well. Most useful in (mono)repos where people might -be working on part as often as the whole project. +This type is more verbose, but can be used on its own as well. Most useful in (mono)repos where people might be working +in a subdirectory as often as on the project as a whole. -In the main Taskfile you call the subTaskfile like any other script: +In the main Taskfile you call the secondary like any other script: ```shell function task:foo { ## bar - ./path/to/subtaskfile/Taskfile "${@-help}" + ./path/to/secondary/Taskfile "${@-help}" } ``` -The subTaskfile is just a regular Taskfile, including utilities like `task:help`, `file:ensure` and a line with `task:"${@-help}"` -at the bottom. +The secondary is just a regular Taskfile, including utilities (semi) optional ones like `task:help`, `file:ensure` and +the required line with `task:"${@-help}"`at the bottom. -### Lean SubTaskfile +### SubTaskfile -This flavour of subTaskfile cannot be called on its own, but has a lot less boilerplate. Most useful for splitting off a -group of tasks that can be logically grouped together, possibly because they are rarely used. +This type cannot be called on its own, but has a lot less boilerplate. Most useful for splitting off a group of tasks +that can be logically grouped together, for specific tasks or because they are rarely used. In the main Taskfile: ```shell @@ -125,7 +125,7 @@ function task:foo { ## bar The subTaskfile just needs to contain the tasks and sections you need, but has a few notes: ```shell -# Files in the subTaskfile's directory need to be prefixed with $SUB_TASKFILE_DIR +# When you use files in the subTaskfile's directory, you need prefix them with $SUB_TASKFILE_DIR function task:call-script { ## Call a script "$SUB_TASKFILE_DIR/some-script.sh" } From 1717560a13c27d5a81bc604e163a5a223607d4c9 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 8 Aug 2025 23:55:07 +0200 Subject: [PATCH 04/19] Remove "Remote Taskfile" type and other findings from in-person review --- README.md | 51 +++++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index dd0ae6e..f0e186a 100644 --- a/README.md +++ b/README.md @@ -83,56 +83,47 @@ _task "$@" Now after running `task shorthand`, your `task` commands will get autocompleted. -## Splitting Taskfiles +## SubTaskfiles Have a (mono)repo with multiple projects, a group of less-used or specialized tasks or just waaay to many tasks for a -single Taskfile? Splitting your Taskfiles might be for you! This allows you to divide your tasks across multiple files -while still (also) calling them from a single one. +single Taskfile? Splitting your Taskfile might be for you! Using SubTaskfiles allows you to divide your tasks across +multiple files while still calling them from a single one. Most useful for splitting off a group of tasks that can be +logically grouped together, like for specific use-cases or because they are rarely used. -There are two types, but in both cases tasks from the secondary Taskfile are called "via" a task in the root Taskfile, -like this: `./Taskfile foo ` +Example use-cases: git-hooks, frontend- / backend-specific tasks, tasks that fix (infrequently occurring) bugs, etc. -### Remote Taskfile +SubTaskfiles can't be run directly, but are always run "via" a task in the root Taskfile, like this: +`Usage: ./Taskfile foo ` -This type is more verbose, but can be used on its own as well. Most useful in (mono)repos where people might be working -in a subdirectory as often as on the project as a whole. +### How -In the main Taskfile you call the secondary like any other script: +Put this in the root Taskfile: ```shell function task:foo { ## bar - ./path/to/secondary/Taskfile "${@-help}" -} -``` - -The secondary is just a regular Taskfile, including utilities (semi) optional ones like `task:help`, `file:ensure` and -the required line with `task:"${@-help}"`at the bottom. - -### SubTaskfile - -This type cannot be called on its own, but has a lot less boilerplate. Most useful for splitting off a group of tasks -that can be logically grouped together, for specific tasks or because they are rarely used. + SUBTASKFILE_DIR="./path/to/subtaskfile/" -In the main Taskfile: -```shell -function task:foo { ## bar - SUB_TASKFILE_DIR="./path/to/subtaskfile/" - - source "$SUB_TASKFILE_DIR/Taskfile" + source "$SUBTASKFILE_DIR/SubTaskfile" task:"${@-_help}" } + +# Optional: use proxy-tasks like this for tasks you want to run straight from the root Taskfile +function task:baz { ## Call `foo baz` directly + task:foo baz +} ``` -The subTaskfile just needs to contain the tasks and sections you need, but has a few notes: +Give SubTaskfile the filename `SubTaskfile`. It needs to contain only the tasks and sections you think useful (while +still having access to stuff like `file:ensure` from the root Taskfile!), but it has a few notes: ```shell -# When you use files in the subTaskfile's directory, you need prefix them with $SUB_TASKFILE_DIR +# When you refer to files in the subTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR function task:call-script { ## Call a script - "$SUB_TASKFILE_DIR/some-script.sh" + "$SUBTASKFILE_DIR/some-script.sh" } # Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` function task:_help { ## Show all available tasks - task:help "$SUB_TASKFILE_DIR/Taskfile" + task:help "$SUBTASKFILE_DIR/SubTaskfile" } ``` From 9e5b72f248b7216e694199099b3b70a2976a9c11 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Sat, 21 Feb 2026 00:28:35 +0100 Subject: [PATCH 05/19] General typo-fixes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f0e186a..e959953 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Taskfile ([taskfile.sh](https://taskfile.sh)) -A `./Taskfile` is a task runner in plain and easy [Bash](https://nl.wikipedia.org/wiki/Bash). It adds a list of +A `./Taskfile` is a task runner in plain and easy [Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)). It adds a list of available tasks to your project. Generate your own Taskfile at [taskfile.sh](https://taskfile.sh). @@ -14,7 +14,7 @@ Generate your own Taskfile at [taskfile.sh](https://taskfile.sh). - Very easy to use - Automate your most common tasks (updating, starting, building, etc...) - Easy to understand and maintain -- Automatically generated list of available task +- Automatically generated list of available tasks # How does it work? @@ -130,10 +130,10 @@ function task:_help { ## Show all available tasks # Credits This Taskfile setup is based on [Adrian Cooney's Taskfile](https://github.com/adriancooney/Taskfile) and is widely -adopted by [Enrise](https://enrise.com) in our modified flavour. +adopted by [Enrise](https://enrise.com) in our modified flavor. # Contributors A big thanks to all the contributors of Taskfile! -![contirubtor avatars](https://contrib.rocks/image?repo=enrise/taskfile) +![contributor avatars](https://contrib.rocks/image?repo=enrise/taskfile) From 38494cef049a95906a27c3495b44172211c0b632 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Sat, 21 Feb 2026 00:36:01 +0100 Subject: [PATCH 06/19] Misc SubTaskfile text tweaks --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e959953..19a33df 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,13 @@ Now after running `task shorthand`, your `task` commands will get autocompleted. Have a (mono)repo with multiple projects, a group of less-used or specialized tasks or just waaay to many tasks for a single Taskfile? Splitting your Taskfile might be for you! Using SubTaskfiles allows you to divide your tasks across -multiple files while still calling them from a single one. Most useful for splitting off a group of tasks that can be -logically grouped together, like for specific use-cases or because they are rarely used. +multiple files while still calling them from a single entrypoint (a familiar, regular Taskfile). Most useful for +splitting off a group of tasks that can be logically grouped together, like for specific use-cases or because they are +rarely used. Example use-cases: git-hooks, frontend- / backend-specific tasks, tasks that fix (infrequently occurring) bugs, etc. -SubTaskfiles can't be run directly, but are always run "via" a task in the root Taskfile, like this: +Tasks in SubTaskfiles are not called directly, but "via" a task in the root Taskfile, like this: `Usage: ./Taskfile foo ` ### How @@ -113,10 +114,13 @@ function task:baz { ## Call `foo baz` directly } ``` -Give SubTaskfile the filename `SubTaskfile`. It needs to contain only the tasks and sections you think useful (while +Give the SubTaskfile the filename `SubTaskfile`. It needs to contain only the tasks and sections you think useful (while still having access to stuff like `file:ensure` from the root Taskfile!), but it has a few notes: ```shell -# When you refer to files in the subTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR +#!/bin/bash +# Adding `#!/bin/bash` is optional but recommended, as it hints editors etc. what syntax highlighting to use. + +# When you refer to files in the SubTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR function task:call-script { ## Call a script "$SUBTASKFILE_DIR/some-script.sh" } From 198bb4293d785b374740e87372cd630480242995 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 27 Feb 2026 19:57:59 +0100 Subject: [PATCH 07/19] Tighten up SubTaskfile description --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 19a33df..08f37cb 100644 --- a/README.md +++ b/README.md @@ -85,20 +85,20 @@ Now after running `task shorthand`, your `task` commands will get autocompleted. ## SubTaskfiles -Have a (mono)repo with multiple projects, a group of less-used or specialized tasks or just waaay to many tasks for a -single Taskfile? Splitting your Taskfile might be for you! Using SubTaskfiles allows you to divide your tasks across -multiple files while still calling them from a single entrypoint (a familiar, regular Taskfile). Most useful for -splitting off a group of tasks that can be logically grouped together, like for specific use-cases or because they are -rarely used. +SubTaskfiles allow you to divide your tasks across multiple files while still calling them from a single entrypoint +(a familiar, regular Taskfile). -Example use-cases: git-hooks, frontend- / backend-specific tasks, tasks that fix (infrequently occurring) bugs, etc. +Use them to split off groups of tasks that can be logically grouped together, like for specific use-cases or because they are rarely +used. For example: git-hooks, frontend- / backend-specific tasks, tasks for (infrequently occurring) procedures, +CI-only tasks, etc. -Tasks in SubTaskfiles are not called directly, but "via" a task in the root Taskfile, like this: +Tasks in SubTaskfiles are never called directly, but "via" a task in the root Taskfile, like this: `Usage: ./Taskfile foo ` ### How Put this in the root Taskfile: + ```shell function task:foo { ## bar SUBTASKFILE_DIR="./path/to/subtaskfile/" @@ -114,8 +114,10 @@ function task:baz { ## Call `foo baz` directly } ``` -Give the SubTaskfile the filename `SubTaskfile`. It needs to contain only the tasks and sections you think useful (while -still having access to stuff like `file:ensure` from the root Taskfile!), but it has a few notes: +Create a file named `SubTaskfile` in a relevant location. It should only contain the tasks and sections you think useful +for that location (as utility stuff like `task:help`, `BLUE` env vars, `file:ensure`, etc. are provided by the root +Taskfile), and has a few notes: + ```shell #!/bin/bash # Adding `#!/bin/bash` is optional but recommended, as it hints editors etc. what syntax highlighting to use. From c140264279791577c9eccc519230f930e7398aea Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 20 Mar 2026 19:59:18 +0100 Subject: [PATCH 08/19] Clarify which comments in example are intended for what ie: which should be used in the final Subtaskfile and which are only clarifications in the context of the README --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 08f37cb..45029b0 100644 --- a/README.md +++ b/README.md @@ -116,18 +116,22 @@ function task:baz { ## Call `foo baz` directly Create a file named `SubTaskfile` in a relevant location. It should only contain the tasks and sections you think useful for that location (as utility stuff like `task:help`, `BLUE` env vars, `file:ensure`, etc. are provided by the root -Taskfile), and has a few notes: +Taskfile). This is a full example (with a few README specific explanations marked by ###): ```shell -#!/bin/bash -# Adding `#!/bin/bash` is optional but recommended, as it hints editors etc. what syntax highlighting to use. +#!/usr/bin/env bash +### Adding `#!/usr/bin/env bash` is optional but recommended, as it hints editors etc. what syntax highlighting to use. -# When you refer to files in the SubTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR +### When you refer to files in the SubTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR function task:call-script { ## Call a script "$SUBTASKFILE_DIR/some-script.sh" } -# Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` +# ========================================================= +# SubTaskfile helper +# ========================================================= + +### Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` function task:_help { ## Show all available tasks task:help "$SUBTASKFILE_DIR/SubTaskfile" } From 38895dd8fcbb1397b78bbd9a720563936bba99ca Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 20 Mar 2026 20:38:15 +0100 Subject: [PATCH 09/19] Show SubTaskfile calling task in SubTaskfile help output Also use env vars instead of function params to influence task:help output --- README.md | 6 ++++-- src/components/Generator/GeneredTaskfile/taskfile-base.sh | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 45029b0..50e1860 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,10 @@ Put this in the root Taskfile: ```shell function task:foo { ## bar SUBTASKFILE_DIR="./path/to/subtaskfile/" + SUBTASKFILE_TASK="foo" + TASKFILE_FILE="$SUBTASKFILE_DIR/SubTaskfile" - source "$SUBTASKFILE_DIR/SubTaskfile" + source "$TASKFILE_FILE" task:"${@-_help}" } @@ -133,7 +135,7 @@ function task:call-script { ## Call a script ### Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` function task:_help { ## Show all available tasks - task:help "$SUBTASKFILE_DIR/SubTaskfile" + task:help } ``` diff --git a/src/components/Generator/GeneredTaskfile/taskfile-base.sh b/src/components/Generator/GeneredTaskfile/taskfile-base.sh index 47c66fa..ebfa61f 100644 --- a/src/components/Generator/GeneredTaskfile/taskfile-base.sh +++ b/src/components/Generator/GeneredTaskfile/taskfile-base.sh @@ -54,14 +54,16 @@ function title { # shellcheck disable=SC2120 function task:help { ## Show all available tasks - TASKFILE_FILE=${1-$0} + TASKFILE_FILE=${TASKFILE_FILE-$0} + banner - title "Available tasks" + title "Available tasks $([[ -n "$SUBTASKFILE_TASK" ]] && echo "for ${YELLOW}$SUBTASKFILE_TASK${RESET}")" + awk 'BEGIN {FS = " { [#][#][ ]?"} /^([a-zA-Z_-]*:?.*)(\{ )?[#][#][ ]?/ \ {printf "\033[33m%-34s\033[0m %s\n", $1, $2}' "$TASKFILE_FILE" |\ sed -E "s/[#]{2,}[ ]*/${RESET}/g" |\ sed -E "s/function task:*/ /g" - echo -e "\n${BLUE}Usage:${RESET} $TASKFILE_FILE ${YELLOW}${RESET} " + echo -e "\n${BLUE}Usage:${RESET} ./Taskfile ${YELLOW}$SUBTASKFILE_TASK ${RESET} " } function task:shorthand { ## Create CLI shorthand task instead of ./Taskfile From bc0793480d5b92994596bd25420149ad69df9c56 Mon Sep 17 00:00:00 2001 From: Johan van Overbeeke Date: Fri, 20 Mar 2026 20:53:58 +0100 Subject: [PATCH 10/19] Make SubTaskfile task:_help output optional --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50e1860..c6bd9d8 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ function task:foo { ## bar source "$TASKFILE_FILE" - task:"${@-_help}" + task:"${@-help}" } # Optional: use proxy-tasks like this for tasks you want to run straight from the root Taskfile @@ -133,7 +133,7 @@ function task:call-script { ## Call a script # SubTaskfile helper # ========================================================= -### Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` +### Optional, but without this, you can only run `./Taskfile foo` to get help output function task:_help { ## Show all available tasks task:help } From 5611655bab3e92e16260a8ee67a5668ce2342320 Mon Sep 17 00:00:00 2001 From: Rick van der Staaij <6495166+rick-nu@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:55:39 +0100 Subject: [PATCH 11/19] Add SubTaskfile generator & seperate docs pages (#26) * Add subtaskfile setup in the generator * Add subtaskfile content * Style sub pages for docs * Improve colors * Finalize new design * Reset README --- dev/linting/eslint.config.mjs | 2 +- docs/auto-completion.md | 25 +++ docs/how-does-it-work.md | 39 +++++ docs/sub-taskfiles.md | 49 ++++++ package-lock.json | 165 +++++++----------- src/app/docs/auto-completion/page.tsx | 14 ++ src/app/docs/how-does-it-work/page.tsx | 14 ++ src/app/{about => docs}/page.tsx | 2 +- src/app/docs/sub-taskfiles/page.tsx | 14 ++ src/app/globals.scss | 12 +- src/components/Content/Content.tsx | 88 +++++++--- src/components/Content/content.module.scss | 59 ++++++- src/components/Desktop/Desktop.tsx | 4 +- .../Form/Checkbox/checkbox.module.css | 4 + src/components/Generator/Generator.tsx | 17 +- .../GeneredTaskfile/SaveFile/SaveFile.tsx | 5 +- .../Generator/GeneredTaskfile/SubTaskfile.tsx | 19 ++ .../GeneredTaskfile/sub-taskfile-base.sh | 17 ++ .../Generator/GeneredTaskfile/taskfile.ts | 5 + .../Generator/Settings/Settings.tsx | 2 + .../Generator/generator.module.scss | 15 ++ src/components/Window/window.module.scss | 1 + src/style/variables/_color.scss | 9 +- 23 files changed, 440 insertions(+), 141 deletions(-) create mode 100644 docs/auto-completion.md create mode 100644 docs/how-does-it-work.md create mode 100644 docs/sub-taskfiles.md create mode 100644 src/app/docs/auto-completion/page.tsx create mode 100644 src/app/docs/how-does-it-work/page.tsx rename src/app/{about => docs}/page.tsx (90%) create mode 100644 src/app/docs/sub-taskfiles/page.tsx create mode 100644 src/components/Generator/GeneredTaskfile/SubTaskfile.tsx create mode 100644 src/components/Generator/GeneredTaskfile/sub-taskfile-base.sh diff --git a/dev/linting/eslint.config.mjs b/dev/linting/eslint.config.mjs index 6f698a5..b96b125 100644 --- a/dev/linting/eslint.config.mjs +++ b/dev/linting/eslint.config.mjs @@ -63,6 +63,6 @@ export default [ }, }, { - ignores: ['.next/', 'out/'], + ignores: ['.next/', 'out/', 'next-env.d.ts'], }, ]; diff --git a/docs/auto-completion.md b/docs/auto-completion.md new file mode 100644 index 0000000..7ba3027 --- /dev/null +++ b/docs/auto-completion.md @@ -0,0 +1,25 @@ +# Auto-completion + +Autocompletion works when you use `zsh` and `oh-my-zsh`. Create the following file in your oh-my-zsh directory +`~/.oh-my-zsh/completions/_task.zsh`: + +```shell +#compdef task + +_task() { + local -a commands + local tasks=$(task comp_targets) + + while IFS= read -r line; do + if [[ -n "$line" ]]; then + commands+=("$line") + fi + done <<< "$tasks" + + _describe -t commands 'task commands' commands +} + +_task "$@" +``` + +Now after running `task shorthand`, your `task` commands will get autocompleted. diff --git a/docs/how-does-it-work.md b/docs/how-does-it-work.md new file mode 100644 index 0000000..77a0cce --- /dev/null +++ b/docs/how-does-it-work.md @@ -0,0 +1,39 @@ +# How does it work? + +Taskfiles are simple bash scripts, but an easy-to-read function format. There are some things that we need to explain +for our Taskfile setup. It all starts with a `Taskfile`. Download your `Taskfile` from +[taskfile.sh](https://taskfile.sh) and save it. Make sure the Taskfile is executable: `chmod +x ./Taskfile`. You can now +run `./Taskfile` in your terminal. + +## Tasks + +A task is defined by creating a function that starts with `task:`. This defines a task that can be triggered by running +the `./Taskfile`. Right next to the task, you should add a task definition with two hashes. This will let the +`task:help` function know that you're writing the task function definition. So an example task will look like the +following: + +```shell +function task:example { ## Show some example text + title "Example" + echo "This is an example task." +} +``` + +In a task you can call other functions, and run all tooling you desire. Now running `./Taskfile example` will execute +the new task. + +## Sections + +To group multiple tasks, sections can be created in your Taskfile. A section is created by creating a comment line with +a double hashtag like so: + +```shell +## Project section +``` + +Lines with only a single `#` will not appear as section in `task:help` and can be seen as plain comments. + +## Help command + +Running `./Taskfile help`, the `task:help` function is triggered. This task will list all available sections and tasks +using the double `##` comments you've learned about above. Now it's clear how you can run any other task! diff --git a/docs/sub-taskfiles.md b/docs/sub-taskfiles.md new file mode 100644 index 0000000..1714c51 --- /dev/null +++ b/docs/sub-taskfiles.md @@ -0,0 +1,49 @@ +# SubTaskfiles + +SubTaskfiles allow you to divide your tasks across multiple files while still calling them from a single entrypoint (a +familiar, regular Taskfile). + +Use them to split off groups of tasks that can be logically grouped together, like for specific use-cases or because +they are rarely used. For example: git-hooks, frontend- / backend-specific tasks, tasks for (infrequently occurring) +procedures, CI-only tasks, etc. + +Tasks in SubTaskfiles are never called directly, but "via" a task in the root Taskfile, like this: +`Usage: ./Taskfile foo ` + +## How + +Put this in the root Taskfile: + +```shell +function task:foo { ## bar + SUBTASKFILE_DIR="./path/to/subtaskfile/" + + source "$SUBTASKFILE_DIR/SubTaskfile" + + task:"${@-_help}" +} + +# Optional: use proxy-tasks like this for tasks you want to run straight from the root Taskfile +function task:baz { ## Call `foo baz` directly + task:foo baz +} +``` + +Create a file named `SubTaskfile` in a relevant location. It should only contain the tasks and sections you think useful +for that location (as utility stuff like `task:help`, `BLUE` env vars, `file:ensure`, etc. are provided by the root +Taskfile), and has a few notes: + +```shell +#!/bin/bash +# Adding `#!/bin/bash` is optional but recommended, as it hints editors etc. what syntax highlighting to use. + +# When you refer to files in the SubTaskfile's directory, you need prefix them with $SUBTASKFILE_DIR +function task:call-script { ## Call a script + "$SUBTASKFILE_DIR/some-script.sh" +} + +# Without this, you cannot run `./Taskfile foo` or `./Taskfile foo help` +function task:_help { ## Show all available tasks + task:help "$SUBTASKFILE_DIR/SubTaskfile" +} +``` diff --git a/package-lock.json b/package-lock.json index dac33a4..04c93b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -759,9 +759,9 @@ } }, "node_modules/@next/env": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.12.tgz", - "integrity": "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.14.tgz", + "integrity": "sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -775,9 +775,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.12.tgz", - "integrity": "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.14.tgz", + "integrity": "sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==", "cpu": [ "arm64" ], @@ -791,9 +791,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.12.tgz", - "integrity": "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.14.tgz", + "integrity": "sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==", "cpu": [ "x64" ], @@ -807,9 +807,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.12.tgz", - "integrity": "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.14.tgz", + "integrity": "sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==", "cpu": [ "arm64" ], @@ -823,9 +823,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.12.tgz", - "integrity": "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.14.tgz", + "integrity": "sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==", "cpu": [ "arm64" ], @@ -839,9 +839,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.12.tgz", - "integrity": "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.14.tgz", + "integrity": "sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==", "cpu": [ "x64" ], @@ -855,9 +855,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.12.tgz", - "integrity": "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.14.tgz", + "integrity": "sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==", "cpu": [ "x64" ], @@ -871,9 +871,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.12.tgz", - "integrity": "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.14.tgz", + "integrity": "sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==", "cpu": [ "arm64" ], @@ -887,9 +887,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.12.tgz", - "integrity": "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.14.tgz", + "integrity": "sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==", "cpu": [ "x64" ], @@ -1391,6 +1391,7 @@ "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.0", "@typescript-eslint/types": "8.56.0", @@ -1512,13 +1513,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -1723,13 +1724,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -1978,9 +1979,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "license": "MIT", "peer": true, "dependencies": { @@ -3178,6 +3179,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3590,9 +3592,9 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -3909,9 +3911,9 @@ } }, "node_modules/immutable": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", - "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", "devOptional": true, "license": "MIT" }, @@ -4676,9 +4678,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -4737,12 +4739,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "15.5.12", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", - "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "version": "15.5.14", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.14.tgz", + "integrity": "sha512-M6S+4JyRjmKic2Ssm7jHUPkE6YUJ6lv4507jprsSZLulubz0ihO2E+S4zmQK3JZ2ov81JrugukKU4Tz0ivgqqQ==", "license": "MIT", "dependencies": { - "@next/env": "15.5.12", + "@next/env": "15.5.14", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -4755,14 +4757,14 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.12", - "@next/swc-darwin-x64": "15.5.12", - "@next/swc-linux-arm64-gnu": "15.5.12", - "@next/swc-linux-arm64-musl": "15.5.12", - "@next/swc-linux-x64-gnu": "15.5.12", - "@next/swc-linux-x64-musl": "15.5.12", - "@next/swc-win32-arm64-msvc": "15.5.12", - "@next/swc-win32-x64-msvc": "15.5.12", + "@next/swc-darwin-arm64": "15.5.14", + "@next/swc-darwin-x64": "15.5.14", + "@next/swc-linux-arm64-gnu": "15.5.14", + "@next/swc-linux-arm64-musl": "15.5.14", + "@next/swc-linux-x64-gnu": "15.5.14", + "@next/swc-linux-x64-musl": "15.5.14", + "@next/swc-win32-arm64-msvc": "15.5.14", + "@next/swc-win32-x64-msvc": "15.5.14", "sharp": "^0.34.3" }, "peerDependencies": { @@ -5158,15 +5160,6 @@ ], "license": "MIT" }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/raw-loader": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", @@ -5393,26 +5386,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -5507,15 +5480,6 @@ "node": ">=10" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5985,15 +5949,14 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "engines": { diff --git a/src/app/docs/auto-completion/page.tsx b/src/app/docs/auto-completion/page.tsx new file mode 100644 index 0000000..3257ad7 --- /dev/null +++ b/src/app/docs/auto-completion/page.tsx @@ -0,0 +1,14 @@ +import { Metadata } from 'next'; +import Content from '@/components/Content'; + +import markdown from '@/../docs/auto-completion.md'; + +export const generateMetadata = (): Metadata => ({ + title: 'Auto completion • taskfile.sh', + description: + 'Quickly kick start your project by moving all your development commands to one easy to understand and maintain place.', +}); + +export default function Page() { + return ; +} diff --git a/src/app/docs/how-does-it-work/page.tsx b/src/app/docs/how-does-it-work/page.tsx new file mode 100644 index 0000000..e95dea1 --- /dev/null +++ b/src/app/docs/how-does-it-work/page.tsx @@ -0,0 +1,14 @@ +import { Metadata } from 'next'; +import Content from '@/components/Content'; + +import markdown from '@/../docs/how-does-it-work.md'; + +export const generateMetadata = (): Metadata => ({ + title: 'How does it work? • taskfile.sh', + description: + 'Quickly kick start your project by moving all your development commands to one easy to understand and maintain place.', +}); + +export default function Page() { + return ; +} diff --git a/src/app/about/page.tsx b/src/app/docs/page.tsx similarity index 90% rename from src/app/about/page.tsx rename to src/app/docs/page.tsx index 9eb34e0..2639cc0 100644 --- a/src/app/about/page.tsx +++ b/src/app/docs/page.tsx @@ -4,7 +4,7 @@ import Content from '@/components/Content'; import readme from '@/../README.md'; export const generateMetadata = (): Metadata => ({ - title: 'Information • taskfile.sh', + title: 'Documentation • taskfile.sh', description: 'Quickly kick start your project by moving all your development commands to one easy to understand and maintain place.', }); diff --git a/src/app/docs/sub-taskfiles/page.tsx b/src/app/docs/sub-taskfiles/page.tsx new file mode 100644 index 0000000..fde63a9 --- /dev/null +++ b/src/app/docs/sub-taskfiles/page.tsx @@ -0,0 +1,14 @@ +import { Metadata } from 'next'; +import Content from '@/components/Content'; + +import markdown from '@/../docs/sub-taskfiles.md'; + +export const generateMetadata = (): Metadata => ({ + title: 'Sub Taskfiles • taskfile.sh', + description: + 'Quickly kick start your project by moving all your development commands to one easy to understand and maintain place.', +}); + +export default function Page() { + return ; +} diff --git a/src/app/globals.scss b/src/app/globals.scss index a90e5f9..30eb559 100644 --- a/src/app/globals.scss +++ b/src/app/globals.scss @@ -8,12 +8,12 @@ } body { - background: #ff00cc; /* fallback for old browsers */ - background: -webkit-linear-gradient(to left, #ff00cc, #333399); /* Chrome 10-25, Safari 5.1-6 */ + background: $color-yellow-50; /* fallback for old browsers */ background: linear-gradient( - to left, - #ff00cc, - #333399 + 220deg, + $color-yellow-50, + $color-purple-50, + $color-black ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ font-family: var(--font-text), sans-serif; } @@ -25,7 +25,7 @@ pre { } a { - color: $color-blue-50; + color: $color-purple-50; text-decoration: none; } diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index 50b873b..8672f3c 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -1,35 +1,79 @@ +'use client'; + import { ReactElement } from 'react'; import styles from './content.module.scss'; import Window from '@/components/Window'; import Markdown from 'markdown-to-jsx'; import { highlighter } from '@/components/Generator/GeneredTaskfile/Highlighter'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import SaveFile from '@/components/Generator/GeneredTaskfile/SaveFile'; + +const links = [ + { href: '/docs', label: 'About Taskfile' }, + { href: '/docs/how-does-it-work', label: 'How does it work?' }, + { href: '/docs/auto-completion', label: 'Auto completion' }, + { href: '/docs/sub-taskfiles', label: 'Sub Taskfiles' }, +]; type WindowProps = { content: string; }; -const Content = ({ content }: WindowProps): ReactElement => ( -
- -
{highlighter(original.children.props.children)}
, - img: ({ alt, src }) => {alt}, - a: ({ href, props, children }) => ( - - {children} - - ), - }, - }} - > - {content} -
-
-
-); +const Content = ({ content }: WindowProps): ReactElement => { + const path = usePathname(); + + return ( +
+
+ +
+ {links.map(({ href, label }) => ( + + {label} + + ))} +
+
+
+ + ( +
+									
+									{highlighter(original.children.props.children)}
+								
+ ), + img: ({ alt, src }) => {alt}, + a: ({ href, props, children }) => { + if (href.includes('.md')) { + const target = href.replace('.md', ''); + + return ( + + {children} + + ); + } + + return ( + + {children} + + ); + }, + }, + }} + > + {content} +
+
+
+ ); +}; export default Content; diff --git a/src/components/Content/content.module.scss b/src/components/Content/content.module.scss index 83124a9..4b65658 100644 --- a/src/components/Content/content.module.scss +++ b/src/components/Content/content.module.scss @@ -1,35 +1,85 @@ @use 'mixins/from-size' as *; +@use 'variables/color' as *; .container { + display: flex; + gap: 1rem; + flex-direction: column; padding: 1rem; margin: 0 auto; width: 100%; - max-width: 54rem; + max-width: 80rem; line-height: 150%; + justify-content: start; @include from(small) { padding: 2rem; + gap: 2rem; } @include from(medium) { padding: 4rem; + gap: 4rem; + } + + @include from(large) { + flex-direction: row; + } +} + +.menu { + width: 100%; + min-height: 1rem; + + @include from(large) { + width: 20rem; + flex-shrink: 0; + flex-grow: 0; + } + + .menuWindow { + min-height: 1rem; + } +} + +.links { + display: flex; + flex-direction: column; + gap: 0.5rem; + + a { + display: block; + padding: 0.5rem 1rem; + background: #f0f0f0; + font-weight: 'semi-bold'; + border-radius: 0.5rem; + color: #000; + transition: background 0.2s; + + &:hover, + &.active { + background: $color-purple-10; + text-decoration: none; + } } } .content { display: flex; flex-direction: column; - gap: 1rem; + gap: 1.5rem; ul { padding-left: 2rem; } pre { + position: relative; padding: 1rem; font-size: 0.8rem; background: rgba(16, 0, 31, 0.87); border-radius: 0.5rem; + overflow: hidden; } code { @@ -40,6 +90,11 @@ } } +.content .preSave { + top: 1rem; +} + .image { max-width: 100%; + border-radius: 0.5rem; } diff --git a/src/components/Desktop/Desktop.tsx b/src/components/Desktop/Desktop.tsx index 568974c..fa8853f 100644 --- a/src/components/Desktop/Desktop.tsx +++ b/src/components/Desktop/Desktop.tsx @@ -22,8 +22,8 @@ const Desktop = ({ children }: DesktopProps): ReactElement => { Generate your Taskfile - - About Taskfiles + + Documentation diff --git a/src/components/Form/Checkbox/checkbox.module.css b/src/components/Form/Checkbox/checkbox.module.css index f76864b..7876e48 100644 --- a/src/components/Form/Checkbox/checkbox.module.css +++ b/src/components/Form/Checkbox/checkbox.module.css @@ -61,6 +61,10 @@ transform: translateY(-50%) scale(1); } +.checkbox input:checked + span { + background: #a1e1aa76; +} + .label { user-select: none; } diff --git a/src/components/Generator/Generator.tsx b/src/components/Generator/Generator.tsx index c0d97a8..de2e43d 100644 --- a/src/components/Generator/Generator.tsx +++ b/src/components/Generator/Generator.tsx @@ -9,6 +9,7 @@ import Settings from './Settings'; import GeneratedTaskfile from './GeneredTaskfile'; import Form from '@/components/Form'; import { Font } from './GeneredTaskfile/buildHeader'; +import SubTaskfile from '@/components/Generator/GeneredTaskfile/SubTaskfile'; export type GeneratorSettings = { project: string; @@ -17,6 +18,7 @@ export type GeneratorSettings = { developmentProxy: boolean; checkoutGitRequest: 'none' | 'github' | 'gitlab'; configureGitHooks: boolean; + subTaskfile: boolean; fileUtilities: boolean; appUtilities: boolean; }; @@ -32,14 +34,23 @@ const Generator = (): ReactElement => { }, }); + const hasSubTaskfile = form.watch('subTaskfile'); + return (
{})}> - - - +
+ + + + {hasSubTaskfile && ( + + + + )} +
); }; diff --git a/src/components/Generator/GeneredTaskfile/SaveFile/SaveFile.tsx b/src/components/Generator/GeneredTaskfile/SaveFile/SaveFile.tsx index baeb701..a85eafc 100644 --- a/src/components/Generator/GeneredTaskfile/SaveFile/SaveFile.tsx +++ b/src/components/Generator/GeneredTaskfile/SaveFile/SaveFile.tsx @@ -6,9 +6,10 @@ import styles from './save-file.module.scss'; type SaveFileProps = { content: string; + className?: string; }; -const SaveFile = ({ content }: SaveFileProps): ReactElement => { +const SaveFile = ({ content, className = '' }: SaveFileProps): ReactElement => { const [isCopied, setCopied] = useState(false); const copyToClipboard = (): void => { @@ -29,7 +30,7 @@ const SaveFile = ({ content }: SaveFileProps): ReactElement => { }; return ( -
+