7 ms·
Slightly tangential but I've worked for several companies now that use `make` as a simple command runner, and I have to say it's been a boon. Being able to dro
by Nexialist 4y ago
Slightly tangential but I've worked for several companies now that use `make` as a simple command runner, and I have to say it's been a boon.
Being able to drop into any repo at work and expect that `make init`, `make test` and `make start` will by convention always work no matter what the underlying language or technology is, has saved me a lot of time.
- ReadTheLicense 4y agoThis is standard in Node.js ecosystem and I love it. Each package has scripts in package.json that you can run with npm run [name], and some of these like start, test or build (and more) are standardized. It's really great DX.
- patrickthebold 4y agoBut it's npm, so when you switch to a java project, for example, you have different commands.
- r3trohack3r 4y agoQuite a few companies I've contracted with have lifted the pattern up into Bazel or Gnu Make - for node projects `make lint` can be a pass through. In the project repo, either work.
- txutxu 4y agoConventions are great, but that doesn't look like anything specific to make, a shell wrapper could do that: #!/bin/sh case $1 in init) ... do whatever for each project init ;; start) ... do whatever for each project start ;; test) ... do whatever for each project tests ;; *) echo "Usage: $0 init|start|test" >&2 exit 1 ;; esac In my home/personal projects I use a similar convention (clean, deploy, update, start, stop, test...), I call those little sh scripts in the root of the repo "runme". The advantage could be, maybe, no need to install make if not present, and no need to learn make stuff if you don't know it. Sometimes they don't match the usual words (deploy, start, stop, etc) but then I know that if I don't remember them, I just type ./runme and get the help. For my scenario, it's perfect because of it's simplicity.
- whateveracct 4y agomake gives you autocomplete more easily for free. One reason I use it always.
- nrclark 4y ago+1 for this, free autocomplete is the reason that I love using Make as the top-level tool, even if the actual heavy lifting is done by CMake or something.
- dymk 4y agoA shell wrapper could do that, but Makefiles are a DSL to do exactly that with less boilerplate.
- marcosdumay 4y agoAnd have a nice inbuilt graph runner if you decide one task depends on another...
- tom_ 4y agoComplete with automatic parallelization if you ask for it! And automatic KEY=VALUE command line parsing, default echoing of commands (easily silenced), default barf on subprocess failure (easily bypassed). The variable system also interacts reasonably sensibly with the environment. I've never rated Make for building C programs, but it's pretty good as a convenient cross-platform shell-agnostic task runner. There are also several minimal-dependency builds for Windows, that mean you can just add the exe to your repo and forget about it.
- marcosdumay 4y agoTo tell the truth, make sucks incredibly for building modern C programs. There are just too many targets. It's why all of them generate their makefile with some abomination. But it is still a great task runner.
- 4y ago
- shoo 4y agoI've worked on a few projects that apply this pattern of using a Makefile to define and run imperative commands. A few people develop the pattern independently, then it gets proliferated through the company as part of the boilerplate into new repositories. It's not a terrible pattern, it's just a bit strange. For many junior colleagues, this pattern is the first time they've ever encountered make -- hijacked as some kind of imperative command runner. It's quite rare to run into someone who is aware that make can be used to define rules for producing files from other files. I find it all a bit odd. Of course, no-one is born knowing about middle-aged build tools.
- arinlen 4y ago> It's quite rare to run into someone who is aware that make can be used to define rules for producing files from other files. Is it, though? That's literally what Make does as part of its happy path. GNU Make even added support for pattern rules, as this use case is so pervasive. What do you think people think make is about?
- shoo 4y agooh i agree, that's why i find the situation odd! i'm talking working on projects with people whose first encounter with make is in a project where someone else has defined a Makefile to wrap imperative actions, e.g. `make run-unit-tests`, `make deploy`. If they think about make at all, there's a good chance they think make is for performing imperative actions, and has nothing specifically to do with producing files from other files using rules and a dependency graph, or the idea of a target being a file, or a target being out of date.
- 3836293648 4y agoThis is what I do for all non-rust projects. I knew what it was supposed to do, but wow if it took me forever to figure out how to do it (the connection between rule name and file name is really poorly documented in tutorials, probably should've just read the man page)
- 4y ago
- sanderjd 4y agoThis was the nicest thing about blaze at google. I'm a big believer that having a single standard tool for things is a huge value add, regardless of what the tool is. I didn't really like blaze particularly, and I don't really like make particularly, but it's amazing to just have a single standard that everybody uses, no matter what it is.
- pornel 4y agoRust's Cargo has the same appeal. There are 90,000 libraries that support cargo build/doc/run/test without fuss.
- sneak 4y agoNo, I believe GP is advocating against language-specific tools being the standard. In the ideal world you would have a Makefile that calls cargo so "make" still works like it does identically in the js or python or golang repos.
- ahungry 4y agoyup, thats the appeal - in a multi language environment a common call, not having to futz with cargo run, npm run start, python3 -m something, etc
- pak9rabid 4y ago$ make run-dev That command (to run an Angular/nodejs dev instance has staved off carpel-tunnel syndrome for me for maybe another 5 years.
- nickjj 4y agoI did this for a while but make isn't well suited for this use case. What I ended up doing is have a shell script with a bunch of functions in it. Functions can automatically become a callable command (with a way to make private functions if you want) with pretty much no boilerplate code or arg parsing. You can even auto-generate a help menu using compgen. The benefit of this is it's just shell scripting so you can use shell features like $@ to pass args to another command and everything else the shell has to offer. I've written about this process at https://nickjanetakis.com/blog/replacing-make-with-a-shell-script-for-running-your-projects-tasks https://nickjanetakis.com/blog/replacing-make-with-a-shell-s... and an example file is here https://github.com/nickjj/docker-flask-example/blob/main/run https://github.com/nickjj/docker-flask-example/blob/main/run.
- js2 4y agoNice shell script. It’s rare to see one written so well. I’ll add you to my list of people I can still count on one hand that properly quote variables. If I had to pick one nit, and it’s a stylistic choice, you use braces around variable names where they aren’t strictly needed. I also like to add “set -u”.
- nickjj 4y agoThanks. My thought process around using braces when they're not needed is mainly around consistency. If you pick and choose when to add them then you need to make a decision every time you add a variable. I've written about that here: https://nickjanetakis.com/blog/why-you-should-put-braces-around-your-variables-when-shell-scripting https://nickjanetakis.com/blog/why-you-should-put-braces-aro... That is a good call about `set -u`, it's something I've been using more recently but I haven't added it into that script yet but thanks for the reminder, I will soon. I ended up making a post about that here: https://nickjanetakis.com/blog/prevent-unset-variables-in-your-shell-bash-scripts-with-set-nounset https://nickjanetakis.com/blog/prevent-unset-variables-in-yo... Another small thing I've been doing recently is defining options like this: set -o errexit set -o pipefail set -o nounset It's a little more explicit on what each option does. It might be just enough context to avoid having to look up what something does. Philosophy wise that's also something I've been doing semi-recently which is to use long form flags over short flags in scripts https://nickjanetakis.com/blog/when-to-use-long-word-or-short-letter-command-line-flags https://nickjanetakis.com/blog/when-to-use-long-word-or-shor....