They should really be using bash for this, not make. There is nothing wrong with bash scripts calling Make -- for building with DEPENDENCIES. But when you aren't doing that, just use bash (because Make is actually Make + bash to begin with).
This is dumb:
restart-frontend: ## Restart the frontend and admin apps in dev
@make stop-frontend-dev && make run-frontend-dev
@echo "Frontend app restarted"
Write it with a shell script like this:
stop-frontend-dev() {
...
}
run-frontend-dev() {
...
}
restart-front-end() {
stop-frontend-dev
run-frontend-dev
echo "Frontend app restarted"
}
build() {
make # this actually does stuff you can't do in bash.
}
"$@" # call function $1 with args $2... Can also print help here.
This is a lot cleaner. The PID stuff can be done with bash too.
This is only cleaner in your simple case. Make's power lies in dependency tracking and its declarative approach to defining those dependencies.
When you use make anyway, adding those targets there is the logical thing to do. One interface instead of two. It's even less lines of code than your proposed solution (which btw does not fail hard like make does, so a recipe for desaster).
Finally: Pretty please, sh, not bash. Almost none of the bash-scripts out there use actual bash-features and those that do can usually easily be rewritten to just rely on a plain posix shell.
Before fig, Docker build repositories often have awkward arguments to build or run a container, and that's where I first saw people using a Makefile as basically a bash script file. I copied it and since then I've used it like 100 times since, it feels a lot more easier than the above bash script approach, though for reasons I can't quite put into words right now.
It also turns out that dependencies creep up pretty often, so shortly after we started abusing the Makefile, we also started using it "right" too.
I like the ideas here, but for long-running processes like file watching, dev servers, hot reloading, etc. a better format is Procfile (https://devcenter.heroku.com/articles/procfile). The ideas from this article could be nicely applied to it.
Procfil is a format that declares a named list of processes to be run that can be controlled by tools like Foreman (http://ddollar.github.io/foreman/) and Honcho (https://pypi.python.org/pypi/honcho). The advantage is being able to start and stop them concurrently as a group, useful for things that otherwise take a tmux session or multiple windows/tabs, like dev server + file watching + live reload: they become a simple `foreman start`. Processes can also be started individually. Procfiles can also be exported to other formats, like systemd, upstart, inittab, etc.
Here's an example Procfile from a web project I've been working on. Since it uses node I went with node tools like http-server and watch, but it could just as easily use any other web server or file watcher. The way it works is it starts a web server serving public/; starts a live reload server for public/; and watches the src/ directory for changes and re-runs make. The makefile has a few rules for compiling JS and CSS from src/ to public/.
web: ./node_modules/.bin/http-server
livereload: ./node_modules/.bin/livereload public
watch: ./node_modules/.bin/watch make src
An important point of the article was to use standard tools installed everywhere and not some obscure niche tools. Please note that you yourself felt the need to explain what “Procfil” is in the first place.
> but for long-running processes like file watching, dev servers, hot reloading, etc.
I don't think anybody should use make to do that at first place. That's not what make was built for. Likewise Foreman should not be used as a build tool because it is not.
EDIT:
now i've seen the makefile in the example,I understand your comment and this is absolutely not where one wants to use make, that's just ridiculous.
>Wouldn’t it better if we could just type make, and get a list of available commands, together with their desciption?
No, Jesus Christ, please don't. Preserve default action as being to build.
Good user interface and good user experience relies on meeting expectations. This behavior breaks those expectations. What if your expectations are different, you ask? In environments where there is an established tradition I think it is rude to break with the norm unless there is a compelling reason to do so. The commandline is popular among developers, other IT professionals and power users because of how efficient it is. It is efficient because there is not all the noise, handholding and other bullsh*t. Please let us keep it that way.
Use a specific target to list other targets. I've seen some people use "make targets".
Bah. What's the harm here? It's not like you'll type make and then not be able to figure out what to do next. The problem you're trying to avoid when preserving default behavior is confusing the user, and that's not applicable here.
Instead of blindly following laws like "Always meet user expectations" we should think about things in a case-by-case basis. Your law is at best a rule of thumb.
Thanks for sharing! This is a great way to document and see documentation for main targets in Makefile.
We use Makefile in same way to execute project related tasks like deployments and run development environments. This will even further help to show main targets from a Makefile easily and pretty standard way. Will be taken into use.
You can achieve similar by writing bash scripts, but it will be mostly custom and others need to learn how to use it and extend it. Makefile gives you a standard way of writing small utilities related to all your project, and almost everybody knows how Makefile works and if not, they can learn from existing documentation.
... but I agree, breaking expectations is somewhat bad.
Also, many shells have completion for Makefiles nowadays, though, that won't get you an additional help text.
I've been using a similar self-documenting technique myself for a while now, too. Although, my version preserved the traditional part where just calling `make` starts building the program and also supported short one line descriptions and longer ones.
Slightly OT: I like how Rake handles this, which is what gave me the idea in the first place
I don't have an OS X box, but I do know that you'll need to change the `-r` to `-E` (GNU sed vs BSD sed). Recent versions of GNU sed (4.2+, I think) also accept `-E` for compatibility with BSD sed (though this is undocumented).
But then you have lost the default target of make and instead of make && make install you end up with make build && make install. That's going to break a brain or two when people try to figure out why their default MO doesn't work.
[+] [-] ArnaudRinquin|10 years ago|reply
To fix that, I created `make2tap`: https://www.npmjs.com/package/make2tap
This small utility takes a `make` output and generate a `TAP` one that you can pipe to any `TAP reporter`.
Our current `make build | make2tap | tap-format-spec` looks like: http://i.imgur.com/chs0Jf3.png
[+] [-] agumonkey|10 years ago|reply
[+] [-] chubot|10 years ago|reply
This is dumb:
Write it with a shell script like this: This is a lot cleaner. The PID stuff can be done with bash too.[+] [-] jlg23|10 years ago|reply
When you use make anyway, adding those targets there is the logical thing to do. One interface instead of two. It's even less lines of code than your proposed solution (which btw does not fail hard like make does, so a recipe for desaster).
Finally: Pretty please, sh, not bash. Almost none of the bash-scripts out there use actual bash-features and those that do can usually easily be rewritten to just rely on a plain posix shell.
[+] [-] dergachev|10 years ago|reply
It also turns out that dependencies creep up pretty often, so shortly after we started abusing the Makefile, we also started using it "right" too.
Examples: * https://github.com/dergachev/screengif/blob/master/Makefile * https://github.com/dergachev/drupal-docker-marriage/blob/mas...
[+] [-] xaduha|10 years ago|reply
[+] [-] s_kilk|10 years ago|reply
http://manuel.00null.net/
Not very useful, but it kept me amused for a weekend at least.
[+] [-] accatyyc|10 years ago|reply
[+] [-] jdp|10 years ago|reply
Procfil is a format that declares a named list of processes to be run that can be controlled by tools like Foreman (http://ddollar.github.io/foreman/) and Honcho (https://pypi.python.org/pypi/honcho). The advantage is being able to start and stop them concurrently as a group, useful for things that otherwise take a tmux session or multiple windows/tabs, like dev server + file watching + live reload: they become a simple `foreman start`. Processes can also be started individually. Procfiles can also be exported to other formats, like systemd, upstart, inittab, etc.
Here's an example Procfile from a web project I've been working on. Since it uses node I went with node tools like http-server and watch, but it could just as easily use any other web server or file watcher. The way it works is it starts a web server serving public/; starts a live reload server for public/; and watches the src/ directory for changes and re-runs make. The makefile has a few rules for compiling JS and CSS from src/ to public/.
[+] [-] tempodox|10 years ago|reply
[+] [-] aikah|10 years ago|reply
I don't think anybody should use make to do that at first place. That's not what make was built for. Likewise Foreman should not be used as a build tool because it is not.
EDIT:
now i've seen the makefile in the example,I understand your comment and this is absolutely not where one wants to use make, that's just ridiculous.
[+] [-] yxlx|10 years ago|reply
No, Jesus Christ, please don't. Preserve default action as being to build.
Good user interface and good user experience relies on meeting expectations. This behavior breaks those expectations. What if your expectations are different, you ask? In environments where there is an established tradition I think it is rude to break with the norm unless there is a compelling reason to do so. The commandline is popular among developers, other IT professionals and power users because of how efficient it is. It is efficient because there is not all the noise, handholding and other bullsh*t. Please let us keep it that way.
Use a specific target to list other targets. I've seen some people use "make targets".
[+] [-] solipsism|10 years ago|reply
Instead of blindly following laws like "Always meet user expectations" we should think about things in a case-by-case basis. Your law is at best a rule of thumb.
[+] [-] ajdlinux|10 years ago|reply
[+] [-] andrewpe|10 years ago|reply
[+] [-] gtramont|10 years ago|reply
[+] [-] mfukar|10 years ago|reply
[+] [-] terminalcommand|10 years ago|reply
I really wish dd had this type of caution. It would save me a lot of misery, preventing the loss of numerous drives.
[+] [-] jgrahamc|10 years ago|reply
[+] [-] saiki|10 years ago|reply
We use Makefile in same way to execute project related tasks like deployments and run development environments. This will even further help to show main targets from a Makefile easily and pretty standard way. Will be taken into use.
You can achieve similar by writing bash scripts, but it will be mostly custom and others need to learn how to use it and extend it. Makefile gives you a standard way of writing small utilities related to all your project, and almost everybody knows how Makefile works and if not, they can learn from existing documentation.
[+] [-] kluck|10 years ago|reply
@grep -P '^[a-zA-Z0-9_-]+:.?## .$$' $(MAKEFILE_LIST) | ...
[+] [-] m6w6|10 years ago|reply
[+] [-] to3m|10 years ago|reply
[+] [-] spoiler|10 years ago|reply
Slightly OT: I like how Rake handles this, which is what gave me the idea in the first place
[+] [-] rekado|10 years ago|reply
[+] [-] tempodox|10 years ago|reply
[+] [-] fzaninotto|10 years ago|reply
[+] [-] beaufils|10 years ago|reply
[+] [-] LukeShu|10 years ago|reply
[+] [-] ehartsuyker|10 years ago|reply
https://github.com/ehartsuyker/node-deb/blob/ede596b2c8a07f1...
[+] [-] Gratsby|10 years ago|reply