top | item 32442007

(no title)

Nexialist | 3 years 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.

discuss

order

shoo|3 years ago

I'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|3 years 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?

3836293648|3 years ago

This 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)

sanderjd|3 years ago

This 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|3 years ago

Rust's Cargo has the same appeal. There are 90,000 libraries that support cargo build/doc/run/test without fuss.

txutxu|3 years ago

Conventions 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.

dymk|3 years ago

A shell wrapper could do that, but Makefiles are a DSL to do exactly that with less boilerplate.

whateveracct|3 years ago

make gives you autocomplete more easily for free. One reason I use it always.

kazinator|3 years ago

You can make "make init" work on Windows and Unix if you work at it, out of the same Makefile.

The above won't.

ReadTheLicense|3 years ago

This 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|3 years ago

But it's npm, so when you switch to a java project, for example, you have different commands.

nickjj|3 years ago

I 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-s... and an example file is here https://github.com/nickjj/docker-flask-example/blob/main/run.

js2|3 years ago

Nice 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”.

pak9rabid|3 years 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.