|
| 1 | +--- |
| 2 | +title: "The Saga of Improving Windows Compatibility: Announcing Built-in Core Utilities" |
| 3 | +description: The journey of enhancing Windows support in Task. |
| 4 | +author: andreynering |
| 5 | +date: 2025-08-26 |
| 6 | +outline: deep |
| 7 | +--- |
| 8 | + |
| 9 | +# The Saga of Improving Windows Compatibility: Announcing Built-in Core Utilities |
| 10 | + |
| 11 | +<AuthorCard :author="$frontmatter.author" /> |
| 12 | + |
| 13 | +When I started Task back in 2017, one of my biggest goals was to build a task |
| 14 | +runner that would work well on all major platforms, including Windows. |
| 15 | +At the time, I was using Windows as my main platform, and it caught my attention |
| 16 | +how much of a pain it was to get a working version of Make on Windows, for |
| 17 | +example. |
| 18 | + |
| 19 | +## The very beginning |
| 20 | + |
| 21 | +The very first versions, which looked very prototyp-ish, already supported |
| 22 | +Windows, but it was falling back to Command Prompt (`cmd.exe`) to run commands |
| 23 | +if `bash` wasn't available in the system. That didn't mean you couldn't run |
| 24 | +Bash commands on Windows necessarily, because if you used Task inside Git Bash, |
| 25 | +it would expose `bash.exe` into your `$PATH`, which made possible for Task to |
| 26 | +use it. Outside of it, you would be out of luck, though, because running on |
| 27 | +Command Prompt meant that the commands wouldn't be really compatible. |
| 28 | + |
| 29 | +## Adopting a shell interpreter |
| 30 | + |
| 31 | +I didn't take too much time to discover that there was |
| 32 | +[a shell interpreter for Go that was very solid][mvdan], and I quickly adopted |
| 33 | +it to ensure we would be able to run commands with consistency across all |
| 34 | +platforms. It was fun because once adopted, I had the opportunity to |
| 35 | +[make some contributions to make it more stable][mvdan-prs], which I'm sure the |
| 36 | +author appreciated. |
| 37 | + |
| 38 | +## The lack of core utilities |
| 39 | + |
| 40 | +There was one important thing missing, though. If you needed to use any core |
| 41 | +utilities on Windows, like copying files with `cp`, moving with `mv`, creating |
| 42 | +a directory with `mkdir -p`, that likely would just fail :boom:. |
| 43 | +There were workarounds, of course. You could run `task` inside Git Bash which |
| 44 | +exposed core utils in `$PATH` for you, or you could install these core utils |
| 45 | +manually (there are a good number of alternative implementations available |
| 46 | +for download). |
| 47 | + |
| 48 | +That was still far from ideal, though. One of my biggest goals with Task is that it |
| 49 | +should "just work", even on Windows. Requiring additional setup to make |
| 50 | +things work is exactly what I wanted to avoid. |
| 51 | + |
| 52 | +## They finally arrive! |
| 53 | + |
| 54 | +And here we are, in 2025, 8 years after the initial release. We might be late, |
| 55 | +but I'm happy nonetheless. From now on, the following core utilities will be |
| 56 | +available on Windows. This is the start. We want to add more with time. |
| 57 | + |
| 58 | +* `base64` |
| 59 | +* `cat` |
| 60 | +* `chmod` |
| 61 | +* `cp` |
| 62 | +* `find` |
| 63 | +* `gzip` |
| 64 | +* `ls` |
| 65 | +* `mkdir` |
| 66 | +* `mktemp` |
| 67 | +* `mv` |
| 68 | +* `rm` |
| 69 | +* `shasum` |
| 70 | +* `tar` |
| 71 | +* `touch` |
| 72 | +* `xargs` |
| 73 | + |
| 74 | +## How we made this possible |
| 75 | + |
| 76 | +This was made possible via a collaboration with the maintainers of other Go |
| 77 | +projects. |
| 78 | + |
| 79 | +### u-root/u-root |
| 80 | + |
| 81 | +We are using the core utilities implementations in Go from the |
| 82 | +[u-root][u-root] project. It wasn't as simple as it sounds because they have |
| 83 | +originally implemented every core util as a standalone `main` package, which |
| 84 | +means we couldn't just import and use them as libraries. We had some discussion |
| 85 | +and we agreed on a common [interface][uroot-interface] and |
| 86 | +[base implementation][uroot-base]. Then, I refactored one-by-one of the core |
| 87 | +utils in the list above. This is the reason we don't have all of them: there are |
| 88 | +too many! But the good news is that we can refactor more with time and include |
| 89 | +them in Task. |
| 90 | + |
| 91 | +### mvdan/sh |
| 92 | + |
| 93 | +The other collaboration was with the maintainer of the shell interpreter. |
| 94 | +He agreed on having [an official middleware][middleware] to expose these core |
| 95 | +utilities. |
| 96 | +This means that other projects that use the shell interpreter can also benefit |
| 97 | +from this work, and as more utilities are included, those projects will benefit |
| 98 | +as well. |
| 99 | + |
| 100 | +## Can I choose whether to use them or not? |
| 101 | + |
| 102 | +Yes. We added a new environment variable called |
| 103 | +[`TASK_CORE_UTILS`][task-core-utils] to control if the Go implementations are |
| 104 | +used or not. By default, this is `true` on Windows and `false` on other |
| 105 | +platforms. You can override it like this: |
| 106 | + |
| 107 | +```bash |
| 108 | +# Enable, even on non-Windows platforms |
| 109 | +env TASK_CORE_UTILS=1 task ... |
| 110 | + |
| 111 | +# Disable, even on Windows |
| 112 | +env TASK_CORE_UTILS=0 task ... |
| 113 | +``` |
| 114 | + |
| 115 | +We'll consider making this enabled by default on all platforms in the future. |
| 116 | +In the meantime, we're still using the system core utils on non-Windows |
| 117 | +platforms to avoid regressions as the Go implementations may not be 100% |
| 118 | +compatible with the system ones. |
| 119 | + |
| 120 | +## Feedback |
| 121 | + |
| 122 | +If you have any feedback about this feature, join our [Discord server][discord] |
| 123 | +or [open an issue][gh-issue] on GitHub. |
| 124 | + |
| 125 | +Also, if Task is useful for you or your company, consider |
| 126 | +[sponsoring the project][sponsor]! |
| 127 | + |
| 128 | +[mvdan]: https://github.com/mvdan/sh |
| 129 | +[mvdan-prs]: https://github.com/mvdan/sh/pulls?q=is%3Apr+author%3Aandreynering+is%3Aclosed+sort%3Acreated-asc |
| 130 | +[u-root]: https://github.com/u-root/u-root |
| 131 | +[uroot-interface]: https://github.com/u-root/u-root/blob/main/pkg/core/command.go |
| 132 | +[uroot-base]: https://github.com/u-root/u-root/blob/main/pkg/core/base.go |
| 133 | +[middleware]: https://github.com/mvdan/sh/blob/master/moreinterp/coreutils/coreutils.go |
| 134 | +[task-core-utils]: /docs/reference/environment#task-core-utils |
| 135 | +[discord]: https://discord.com/invite/6TY36E39UK |
| 136 | +[gh-issue]: https://github.com/go-task/task/issues |
| 137 | +[sponsor]: /donate |
0 commit comments