23 ms·
Taskfile: A Modern Alternative to Makefile
- arcanemachiner 3y agoHow does this compare with `just`[0]? I've never written a Makefile but I'm a big fan of `just`. [0] https://github.com/casey/just https://github.com/casey/just
- KRAKRISMOTT 3y agoTaskfile looks heavily inspired by terraform and other "cloud native tooling (read: lots of yaml)
- diimdeep 3y agohorrible
- thiht 3y agoBecause Makefiles are so clean and legible. Taskfiles have the benefit of being very explicit and easy to understand.
- stowaway1256 3y agoYep, `just` is much more truthful to the bare bones `make` legacy while `task` offers a bit more structured approach coming from inclusion of yaml as a specification language and many convenience things like handling env, run directories etc. I have worked with `just` for quite a bit but this looks very good honestly and I will consider switching.
- SahAssar 3y agoTerraforms native language is HCL, in most terraform setups I see very little yaml. Maybe you're thinking of k8s and all of its related tooling?
- jen20 3y agoIndeed it doesn't even support YAML, except by the bad faith argument that it supports the subset of YAML which is JSON.
- haarts 3y agoI, too, use just a lot in a very off handed way. My memory isn't great and I just toss commands in a projects justfile which I occasionally need. Yes, a readme would work to a degree too, but a justfile is runnable code. That beats dead documentation everytime.
- armitron 3y agoWhenever I read "modern alternative", it's nearly always certain that the older tech is superior on multiple fronts: Better documented, better designed and architected (taking more use-cases / edge-cases into account), composable, easier to debug, fewer dependencies.
- fncslothouber 3y agoand usually also far less bloated
- ginko 3y agoJust from reading the title i figured their idea of 'modern' was using something like yaml or json.
- kristiandupont 3y agoHow Yaml of all things became so popular is a mystery to me. I am guessing the primary selling point is that it's sort of human readable similar to Markdown but even that (in fact, especially that) falls short when a configuration is more than just 5 lines, in my opinion. Trying to figure out which bullet this sub-bullet belongs to by holding my finger on the screen while scrolling is not an improved experience. And don't even get me started on the clever type system.
- sangnoir 3y ago> Trying to figure out which bullet this sub-bullet belongs to by holding my finger on the screen while scrolling is not an improved experience I don't see this as any worse than figuring out where nested parentheses are closed: tooling helps. I'm almost certain there's a whitespace plugin equivalent of Rainbow Parentheses for your IDE/editor of choice
- kristiandupont 3y agoYes, tooling helps, though I am not always in my IDE. And I agree that it shouldn't be worse than, say, JSON, but for one reason or another my brain seems to struggle with it just a bit more. It certainly does not seem like an improvement, which I feel is implied.
- mixmastamyk 3y agoIndentation guide are available on most editors.
- taspeotis 3y agoYelling At My Laptop
- trallnag 3y agoTaskfile is not an alternative to Makefile. It is first and foremost an alternative to PHONY targets in a Makefile.
- Macha 3y agoWhich rounds to approximately all non C/C++ makefile usage
- crabbone 3y agoI have coworkers who use this. They tried to make me use this too. I failed to see the point. It offers no benefits of a build system, no benefits of existing automation tools, comes with "bespoke" syntax and requires installing an extra program to run it. I have never tested it enough to discover things it does wrong, but given how new and not exactly popular this tool is, I bet there are lots of things it doesn't do right... So, I have no idea why would anyone want this tool... beside just using one extra infra tool to appear as if you know something others don't (and that's exactly the kind of people who use it at my workplace).
- trabant00 3y agoBecause Make is too stable and well documented, because it's just one tool and not 3, because it isn't written in Go and because you don't have to scratch you head at another YAML hell. Because 47 years of proven track record is nothing compared to "modern". Need I go on?
- thiht 3y agoIf you think there’s nothing to fix with make, you’re severely mistaken. The differences between GNU Make and BSD Make are for me a big reason to be extra careful when using it. Make also relies a lot on cleverness so it comes with lots of idiosyncrasies (like having to add .PHONY to all the targets not representing files, which in itself proves Make was not thought to be used like we use it). Some basic conventions we use today are also hard to do correctly with a Makefile (using dotenv files for example) I used Task on a new project and the explicitness of it all was a breath of fresh air. I mean which is clearer between: BINARY = ./foo GO_FILES = $(shell find . -type f -name '*.go') # Rebuild BINARY only if GO_FILES have been modified $(BINARY): $(GO_FILES) go build -o $@ .PHONY: build build: $(BINARY) and env: BINARY: ./foo tasks: build: cmds: - go build -o $BINARY sources: - **/*.go generates: - $BINARY ?
- morelisp 3y agoWhat if you use `embed`? Why rebuild the binary if you've only touched test files? Make at least theoretically gives you tools to deal with these (but between Make and Go they're quite hard to use), but Task gives you no chance.
- Pesthuf 3y agoI think I'd rather just keep using make .phony targets. The last thing I want is more yaml.
- choeger 3y agoSo what does make (the took is not called Makefile, btw) "wrong". Where could one improve on it? 1. Syntax. Makefiles aren't parseable and have some at least unexpected syntactic properties. 2. Dependency detection: AFAIK any make will always use a timestamp and the precision varies a lot. A checksum or at least guaranteed resolution would be great. Also, you can't depend on directories. 3. Dynamics (this is going to be contested): Changing dependencies and tasks at runtime is possible with GNU make, but not ideal. Taskfile improves on problem 1 but probably worsens everything else.
- feffe 3y ago- Multiple out file dependencies are also difficult to describe in make (GNU Make). There's a dedicated section for how to solve it in the manual[^1] but it's a crutch. - Taking environment variables into account as a dependency (they may affect Makefile logic and also code generation by tools that interpret them). [^1]: https://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html https://www.gnu.org/software/automake/manual/html_node/Multi...
- morelisp 3y agoMultiple outfile dependencies (aka "grouped targets") can be specified in GNU Make via `&:` since 4.3.
- silisili 3y agoIt's a shame, IMO, that make hasn't really evolved. I've been at a few places that insist on still using them. They mostly work fine, but having PHONY littered everywhere gets a bit annoying. I don't think a successor can exist. Makefiles seem like the last of a dying breed - not because make is bad, but because there are better ways to accomplish this already. The market for people who've outgrown Makefiles but haven't embraced the alternatives has to be pretty small...
- amno 3y agoWhy do you think they haven't evolved? Latest versions give you access to Guile scheme as an extension language, not to mention that they extended over time for quite a bit. But it is all backwards compatible so old makefiles still run.
- morelisp 3y agoMake has no way to opt into lots of greybeard "best practices" by default, and the syntax is still difficult to deal with. I want to keep the solver, which is pretty good. I want to keep the idea of targets, rules, recipes, which is what tools like Taskfile throw out that makes them not very attractive to me. I even want to keep a good chunk of the syntax for specifying these. But Make needs some kind of way to invoke it that switches off all the dumb shit. - parse any reasonable whitespace indentation, for chrissake - -r by default, or some way to opt into relevant sets of rules (e.g. `import "c"` to get CC, CFLAGS, %.o, etc.) - Separate def syntax and namespacing for proper file-generating rules vs. phony rules, no more .PHONY or fake dependencies; also move stuff like .INTERMEDIATE or .PRECIOUS to the rule def. - .DELETE_ON_ERROR, .ONESHELL by default, probably others I forgot - better semantics for double-colon rules; once you know what the phony rules are you can make them operate in this mode by default and give better syntax for pre/post hooks, priorities, run-on-failure, etc. - something solving the same problem as but less dumb than .SECONDEXPANSION (guile helps somewhat here but give me some help for the most common cases) - stamp files implemented by some out-of-tree cache, they're just an optimization and I'd rather lose them now and then and have to rebuild, than have to keep adding them to every other tool's ignore lists. As well as some actually new features to help manage targets without local inputs, e.g. smarter connectors for fetching dependencies from network resources.
- raverbashing 3y agoOk cool, let's see what this is about > Taskfile is just a dialect of YAML format with a specific syntax I imagined that. Ok bye Just write a js or python script. Or even a shell script Makefile syntax is bad but frankly YAML was a bad idea. (slightly less than XML sure)
- account-5 3y agoIf I had the choice of yaml and XML I'd probably choose XML.
- mrweasel 3y agoI can understand people not wanting to write Makefile and most of them just ends up being .phony and a bunch of shell code in many cases. Taskfile might be great for many use cases, but yes, why not just write a shell script. Almost every time I use a CI system, I end up falling back to just having it run a shell script, rather than relying on many of the build in features, because they are almost always a bit contrived. The same can be said for Makefile replacements, they try to predict what people need, and in the end it ends up being a fancy way of running a script.
- trallnag 3y agoYou don't have to choose one. M approach is to keep most "tasks" in separate script files and use Task (or just, or make, or doit, or...) to call and glue them together.
- stephenr 3y agoXML is verbose. That’s the problem. YAML is ridiculously complex, with a bunch of surprising behaviour. I would take XML over YAML any day.
- raverbashing 3y agoBasic XML is fine, maybe a bit verbose But when you start getting into why are some things properties, or values, XSD or what not, then no. Nobody has time for those thick XML books
- BiteCode_dev 3y agoSorry for the plug, but I can't help myself everytime I read about task managers to notice you have to learn yet another DSL. DSL are the plague of our field, for one that is useful like SQL, you have a hundred that turn your life into hell. Make's DSL is already full of gotchas, but templated YAML based DSL are just insanity. They have so many footguns, and so little flexibility and ability to be debugged. After trying a lot of task runners and builders, I finally settled on doit: https://www.bitecode.dev/p/doit-the-goodest-python-task-runner https://www.bitecode.dev/p/doit-the-goodest-python-task-runn... - It makes the simple things simple, and the hard things possible. - It scales up (you get targets, dependencies, manual scripting, etc), but it also scales down (you can define a simple list of shell commands to run and that's it). - Instead of a DSL, you have regular Python. Which for all it's faults, is an excellent scripting language. It has great tooling support, and comes with a debugger. - To avoid people abusing the expressiveness of Python, the default syntax to create tasks encourages a declarative style. I've been using doit for years, and every single project I introduced it to was improved by it. Of course, it comes with it's own problems (non python dev can dislike having to install that, and it doesn't yet provide a stand alone executable), but the ROI is way better than the alternatives I tried.
- emptysongglass 3y agoFor Pythonistas or people interested in Python, I can't plug the commenter's newsletter enough: it is an absolute treasure trove of good advice for new and old users of Python. They did a whole series on the right way to install and use Python [1]. If you follow their advice you'll never struggle with any of the problems people complain of encountering with Python. [1] https://www.bitecode.dev/p/installing-python-the-bare-minimum https://www.bitecode.dev/p/installing-python-the-bare-minimu...
- BiteCode_dev 3y agoCheers :)
- rewmie 3y ago> DSL are the plague of our field, for one that is useful like SQL, you have a hundred that turn your life into hell. The same can be said about using general purpose programming languages to specify stuff declaratively, but instead of implementation the problems happen in each and every single use of it. It only takes a single user that either does not comply with standards or feels they are particularly clever to mess everything for everyone.
- endgame 3y ago> Taskfile is just a dialect of YAML format with a specific syntax One of the few formats in common use that's actually worse than Makefile, plus you need to go and find another binary to run the thing.
- erik_seaberg 3y agoSeems less file-centric than gmake. You have to repeat filenames in task commands, and depend on tasks by name rather than depending on generated files.
- robbywashere_ 3y agoI use autoenv and a `./scripts` directory. So my .env file just “includes” (automatically via autoenv) what’s in my scripts directory along with setting any environment variables when I’m jumping around my shell. Therefore I can just write a function like “dbup” or “devstart” and have those locally aliased to whatever they summon in the current project
- trallnag 3y agoThat's basically what I use Taskfile for. And ensuring that things are always executed starting in the root of the repository.
- amno 3y agoI don't understand this argument: "it's 47 years old" as a bad thing. If something has been around that long, does it not mean it is proof tested? The syntax of Taskfile looks more verbose to me than Makefile, which is basically a shell script in disguise. To note also is that you praise Devenv because of it being based on Guix (Guile scheme), while you ditch Makefile which also embeds Guile scheme as the extension language (in latest versions). Also to note, the opening argument, writing Readme files on how to build and use the software, has nothing to do with Makefiles at all. You could write a simple skeleton codegen that generates a Readme file skeleton or a template with those steps autogenerated in any language preferred, shell included, and run it as a Makefile target.
- emptysongglass 3y agodevenv.sh uses Nix, not Guile.
- amno 3y agoI thought Nix used as Guix Guile under the hoos, but looked up now, and they seem to use custom language, in which case is it even worse. I should have looked up that before the hand, my bad there, I appologize. Op complained about that make requires a bunch of extra tools to get running, and suggests another bunch of extra tools, as well as of make DSL which is more or less shell on steroids, but suggests a mix of two different languages instead, and does not even seem to be aware he can use Guile Scheme to extend Make.
- tjoff 3y agoThat is not the argument though. The argument is: After being unhappy with Makefile for years now As to why being unhappy is probably not because it haven't been proof tested. I get your sentiment but feel the remark is out of place. I thought the rationale for picking other tools was straightforward and motivated. Though the simplicity of make has been lost and I'm not sure the overhead is worth it. I wouldn't want to be the one introducing taskenv, direnv and derenv to a project.
- deleted 3y ago
- prabhu-yu 3y agoScons using Pure Python Lang. No more DSL. https://scons.org/ https://scons.org/ It has cache facility to speed up re-builds. scons --implicit-cache I heard people say, Scons is slow, but it need not be if we use cache facility. Some people say Meson (https://mesonbuild.com/ https://mesonbuild.com/) would be its successor, but I use scons for building my C/Python files. (ex: Python to .mpy files, asciidoc to pdf, html etc)
- ginko 3y agoI used to swear by scons but it really collapses under its own weight when projects become larger. At my work we used it for a fairly large source tree and no-change incremental builds would take a good minute for scons to figure out there's nothing to do. These days we use something based on google blueprint which generates ninja build files.
- high_priest 3y agoHere I found an opinionated, but still very descriptive comparison of build tools the authors of SCons have experienced. https://github.com/SCons/scons/wiki/FromMakeToScons https://github.com/SCons/scons/wiki/FromMakeToScons
- deleted 3y ago[deleted]
- gorgoiler 3y agoThe command line entry points for your tooling need to be in the same language environment as everything else. If your module in app/constants.py defines PORT which app/server.py serves and app/client.py connects to, how do you drop that same constant into your Makefile or docker-compose.yaml? For me, literally everything including my docker, docker-compose, caddy, nginx, and of course the application code and all auxiliary scripts are presented as Python modules to solve this exact problem.
- deleted 3y ago[deleted]
- lf-non 3y agoWe use this to trigger local tasks (like build, codegen, db migrations etc.) in our monorepo. We moved to it because our npm scripts were getting messier in absense of task dependencies, lack of multiline support, comments in json etc. Being an easy to use cross platform binary that can be managed through asdf made adoption very easy. We have few colleagues working on react-native who use windows, and it is easy to support them because it uses mvdan/sh for script execution. Being able to organize tasks into multiple module specific taskfiles which can be merged (with auto-prefixing) into the top level taskfile is quite nice. The support for watch mode, timestamp checking, environment propagation with built in dotfile support are all nice features that we found very handy. It would have been nicer if it used hcl but I can live with yaml. I am glad that it doesn't use a real programming language - it makes it easy to look at a task in isolation (we have hundreds) and figure out what it depends on and what it does. It is easy to be dismissive of such tools when glancing at the homepage, but it is one of those tools that grow on you when you give it a chance. The author has also been addressing a lot of common pain points over the years for which we are thankful - it is nice to be able to trigger tasks from any subdir (similar to npm run ...) and the new editor integration is quite too. I see people saying that you can do all that this tool does using a few simple scripts. But these scripts only start off as simple, once you need a watch mode, cross platform support, timestamp change detection, selective argument propagation, need to exec dependencies in right directories etc. they tend to get buggier and messier.
- jbverschoor 3y agoNaming isn’t consistent with what make does and why it’s called Makefile. Makefile is for make, which “makes files”. You don’t “task files” *file in general is wrong. Of course it’s a file
- tannhaeuser 3y agoThere are weirder choices in the realm of build tools, such as CMakeLists.txt.
- colonwqbang 3y agoThe article doesn't sell the tool very well. The flaws of make are well known, let's see some example of how this new tool outshines make? To me it looks like something very similar to make but with a different (slightly verbose) syntax.
- _jplc 3y agoCorrection: > Taskfile: It’s PHONY Makefile in Yaml
- rakoo 3y agoI wanted to see what was wrong with Makefile and how Taskfile solved the issue, but the post doesn't explain; it's more a tutorial on how to use Taskfile. If the author reads this, I think we'd love to know what's wrong with make. Also, a lot of those look like artificial complexity over a shell script sourcing another one containing only variables export, and running the required scripts.
- thiht 3y agoIf you don't know what's wrong with make, just use make. But it probably means you probably don't USE make. If your Makefiles look like this: build: go build -o dist/app You might as well just use make, it's fine. It's less fine when you want to avoid rebuilding if sources didn't change, or if you want to use environment variables, maybe from a dotenv file, or if you want to do conditions (like adding a debug flag to a build command if a make variable is set), or if you need to use make incantations (hoping they'll work with both BSD Make and GNU Make), then a Taskfile might help solving some issues, including legibility.
- rakoo 3y agoI don't use make, so I wanted to see what was wrong with it, and the author's argument is that it's old. Not very convincing. Your description starts to be more interesting, and I feel like mk (the successor of make from the Plan 9 people: https://plan9.io/sys/doc/mk.html https://plan9.io/sys/doc/mk.html) might address those, but again, I don't have a need for it.
- pablo1 3y agoTaskfile is great! I used it to write a NixOS deployment tool [1] which I have been using ever since [1] https://github.com/pinpox/lollypops https://github.com/pinpox/lollypops
- TeeWEE 3y agoMake is ubiquitous, it’s simple. Everybody knows it. That’s the reason to use it. Just add a makefile to your repo and anybody is able it get started. I would have no clue what todo with a project in the structure proposed. Note: I just makefiles as an entry point to the underlying build tool such as gradle or npm or go build
- thiht 3y agoOne day after writing a complex Makefile and getting frustrated because 1) it was hard to read and reason about because of make weird syntax, 2) it didn't run on CI because it uses GNU Make instead of BSD Make on my MacBook, I thought of writing a "modern" alternative: I wanted it easy to read, write, parse and use, so I'd use YAML. You guys all shit on YAML because it's extremely badly used by, say, Helm charts, but it's a good markup language in itself. StrictYAML is anyway. So I started writing a toy Makefile in YAML with these requirements: I need to run a command, with variables, it needs to depend on another command, and shouldn't run if the "output" file is already present and newer than the "source" files. So something like this: env: APPNAME: app clean: run: rm -rf ./dist build: depends: - clean input: - **/*.go run: - go build -o dist/$APPNAME output: - dist/$APPNAME At this point I realized I had written exactly the same things proposed by Taskfile (which I heard of but thought "meh it sucks, Makefiles are great). So yeah, Taskfiles are just Makefiles with a sane syntax and better tooling (JSON schema, auto generated doc, real default target...). I have no idea why the comments are so hostile towards it, because clearly Makefiles are not perfect (it's even a pretty bad format)
- inferiorhuman 3y agoit didn't run on CI because it uses GNU Make instead of BSD Make on my MacBook What? $ /usr/bin/make --version GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i386-apple-darwin11.3.0
- thiht 3y agoMy memories must fail me, I thought it was a BSD make vs GNU make issue but probably not! Maybe a version issue between the bundled make binaries on each platform, I don't remember the details to be honest
- hitchstory 3y agoI'm the creator of StrictYAML and honestly, I would love to see something like this built with it. I hate make and I dont like the idea of using non-typesafe YAML to build this (which presumably this tool does, since it's done in golang). I've been using a "standardized" bash script with a huge case statement as a justfile/this/makefile replacement but it's not ideal.
- FullGarden_S 3y agoLooking good. But no thanks, I'm sticking to my awesome tup.
- JonChesterfield 3y agoInstead of a DSL backed by some external tool, it's possible to write build scripts in a normal programming language. You only really need to implement "spawn process and give it these arguments" and "this depends on that" to reproduce most of C++ build scripts. I've gone with lua and libuv because the concurrency model is so trivial. Each process spawn goes in a coroutine, stderr and stdout go into lua strings, use yield when the process is still running. However that comes with pretty minimal linting or error detection on the input, so maybe use some other language if you want that. Or rephrasing, instead of a DSL for describing a graph and transforms to apply to the nodes, you can use a library in your favourite language instead. You might like that more than debugging cmake.
- rgrmrts 3y agoRake[0] is still the best ‘make-like’ build tool/task runner I’ve used for general purpose stuff. The syntax is nice and it’s just Ruby which is a delight. I briefly used Mage (similar, but Go) and it was fine too. [0]: https://github.com/ruby/rake https://github.com/ruby/rake
- nunez 3y agoI use Makefiles and native Bash in 2023 because both come on just about any system that will build and package my software. Also, I disagree with Make being a bad task runner. In fact, I find it quite versatile. The fact that it is not a DSL with a meta programming language or, in the case of Taskfile, a YAML document that gets convoluted quickly (see also: Ansible) is a feature IMO.
- devduderino 3y agoTaskfile is a wonderful little tool. Used with an alias it can be a wonderful way to manage scripts. I use mine as a sort of global bookmark for shell commands I can't be bothered to memorize all the params for. Handling env files is also a huge help.
- c-hendricks 3y agoMy task runner is bash. After 15 years I've yet to find a system it's not installed on. Bonus: you write your shell commands in a file that's aware of what's correct/incorrect.
- inopinatus 3y agoHeartening to realise that that my venerable and slightly moth-eaten ThinkGeek t-shirt (ca.2001) emblazoned with "Go away or I will replace you with a very small shell script" remains relevant today.
- deviantintegral 3y agoWe’ve been using Task for our (Drupal) web projects for a few years now and are really pleased with it. Why not Make? We actually used that on a few projects previously, but found it challenging to use with both our teams and with typical tools used in the PHP and JavaScript stack. 1. Most of our newer hires have never used Make before, or anything like it. It seems to have fallen out of many curriculums in favour of other build tools, presumably due to decreasing focus on C / C++ in fundamental computer science classes. The idea that a build tool is inherently files based is a completely foreign concept. 2. File-based dependency tracking being the exception, and not the rule, simply works better with the majority of the types of tasks we run. Those include building docker containers, pulling down CMS databases for local development, and running CLI tasks like database migrations. 3. For those tasks that can be tracked with files, Task supports both timestamps and hashes. One big win of Task over other tools is that it ships it’s own built-in sh shell. If you have tasks that run on a host and not in a container, it significantly reduces your host dependencies. Being a typical single-binary go app makes deployments easy too. I’ll also say the maintainers have been very responsive to our few bug reports and feature requests, and responsive to our contributions too. The worst part is yes, it’s another YAML DSL to learn. And personally, I wish Make had gained more traction in the web and docker world. But given all of the above, the trade offs of switching to Task have been worth it for us.