From 6e3b43ac9ea26f8bd6e3126636223a42888d6e1d Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Thu, 12 Oct 2017 16:12:23 -0700 Subject: [PATCH] Overhaul README (#231) - Switch to asciidoc, since it supports an auto-generated table of contents - Re-organize into sections - Document private recipes - Document windows dependencies - Document doc comments --- .gitignore | 1 + README.md => README.asc | 363 +++++++++++++++++++++++++--------------- justfile | 10 ++ src/unit.rs | 2 +- tmp/.gitignore | 1 + 5 files changed, 240 insertions(+), 137 deletions(-) rename README.md => README.asc (69%) diff --git a/.gitignore b/.gitignore index 3d3a5e48..bfe19c87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /.vagrant +/README.html diff --git a/README.md b/README.asc similarity index 69% rename from README.md rename to README.asc index bdc379a0..296ea125 100644 --- a/README.md +++ b/README.asc @@ -1,11 +1,11 @@ -just -==== += `just` +:toc: +:toc-title: - -[![crates.io version](https://img.shields.io/crates/v/just.svg)](https://crates.io/crates/just) -[![Build Status](https://travis-ci.org/casey/just.svg?branch=master)](https://travis-ci.org/casey/just) -[![Chat](https://badges.gitter.im/just-because/Lobby.svg)](https://gitter.im/just-because/Lobby) -[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/casey) +image:https://img.shields.io/crates/v/just.svg[crates.io version,link=https://crates.io/crates/just] +image:https://travis-ci.org/casey/just.svg?branch=master[build status,link=https://travis-ci.org/casey/just] +image:https://badges.gitter.im/just-because/Lobby.svg[chat on gitter,link= https://gitter.im/just-because/Lobby] +image:https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg[say thanks,link=https://saythanks.io/to/casey] `just` is a handy way to save and run commands. @@ -24,38 +24,36 @@ test TEST: build ./test --test {{TEST}} ``` -`just` produces detailed error messages and avoids `make`'s idiosyncrasies, so debugging a justfile is easier and less surprising than debugging a makefile. +`just` produces detailed error messages and avoids `make`’s idiosyncrasies, so debugging a justfile is easier and less surprising than debugging a makefile. If you need help with `just` please feel free to open an issue. Feature requests and bug reports are also always welcome! +== Installation -installation ------------- +`just` should run on any system with a reasonable `sh`. -`just` should run on any system with a reasonable `sh`. +On Windows, the `sh` provided by https://git-scm.com[git] and https://desktop.github.com[GitHub Desktop] should both work. -### prebuilts +=== Pre-built Binaries -Prebuilt binaries for Linux and macOS can be found on [the releases page](https://github.com/casey/just/releases). +Pre-built binaries for Linux, macOS, and Windows can be found on https://github.com/casey/just/releases[the releases page]. -### cargo +=== Cargo -Alternately, `just` can be installed with `cargo`, the [rust language](https://www.rust-lang.org) package manager: +`just` can also be installed with `cargo`, the https://www.rust-lang.org[rust language package manager]: -1. Install rust and cargo by following the instructions at [rustup.rs](https://www.rustup.rs) +1. Install rust and cargo by following the instructions https://www.rustup.rs[here] 2. Run `cargo install just` -3. Add `~/.cargo/bin` to your PATH +3. Add `~/.cargo/bin` to your shell's $PATH. -### alias +`rustup` may have done #3 for you. If this doesn't work, put `export PATH="$HOME/.cargo/bin:$PATH"` in your shell's configuration file -You can put `alias j=just` in your shell's config file for lightning fast command running. +== Quick Start -How do I just? --------------- -Once `just` is working, create a file called `justfile` in the root of your project and start adding recipes to it. +See xref:Installation[] for how to install `just` on your computer. Try running `just --version` to make sure that it's installed correctly. -Recipes look like this: +Once `just` is installed and working, create a file named `justfile` in the root of your project with the following contents: ```make recipe-name: @@ -63,9 +61,11 @@ recipe-name: # this is a comment another-recipe: - @echo 'Another recipe.' + @echo 'This is another recipe.' ``` +When you invoke `just` it looks for a `justfile` in the current directory and upwards, so you can invoke it from any subdirectory of your project. + Running `just` with no arguments runs the first recipe in the `justfile`: ```sh @@ -74,34 +74,14 @@ echo 'This is a recipe!' This is a recipe! ``` -When you invoke `just` it looks for a `justfile` in the current directory and upwards, so you can invoke `just` from any subdirectory of your project. - -One or more arguments specify the recipes to run: +One or more arguments specify the recipe(s) to run: ```sh $ just another-recipe Another recipe. ``` -`just` prints each command to standard error before running it, which is why `echo 'This is a recipe!'` was printed. Lines starting with `@` will not be printed which is why `echo 'Another recipe.'` was not printed. - -A recipe name may be prefixed with '@' to invert the meaning of '@' before each line: - -```make -@quiet: - echo hello - echo goodbye - @# all done! -``` - -Now only the lines starting with '@' will be echoed: - -```sh -$ j quiet -hello -goodbye -# all done! -``` +`just` prints each command to standard error before running it, which is why `echo 'This is a recipe!'` was printed. This is suppressed for lines starting with `@`, which is why `echo 'Another recipe.'` was not printed. Recipes stop running if a command fails. Here `cargo publish` will only run if `cargo test` succeeds: @@ -149,23 +129,52 @@ cc main.c foo.c bar.c -o main testing... all tests passed! ``` -If the first argument passed to `just` contains a `/`, then the following occurs: +== Features -1. The argument is split at the last `/`. -2. The part before the last `/` is treated as a directory. Just will start its search for the justfile there, instead of in the current directory. -3. The part after the last slash is treated as a normal argument, or ignored if it is empty. +=== Listing Available Recipes -This may seem a little strange, but it's useful if you wish to run a command in a justfile that is in a subdirectory. - -For example, if you are in a directory which contains a subdirectory named `foo`, which contains justfile with the recipe `build`, which is also the default recipe, the following are all equivalent: +Recipes can be listed with `just --list` : ```sh -$ (cd foo && just build) -$ just foo/build -$ just foo/ +$ just --list +Available recipes: + build + test + deploy + lint ``` -Assignment, strings, concatenation, and substitution with `{{...}}` are supported: +`just --summary` is more concise: + +```sh +$ just --summary +build test deploy lint +``` + +=== Documentation Comments + +Comments immediately preceding a recipe will appear in `just --list`: + +```make +# build stuff +build: + ./bin/build + +# test stuff +test: + ./bin/test +``` + +```sh +$ just --list +Available recipes: + build # build stuff + test # test stuff +``` + +=== Variables and Substitution + +Variables, strings, concatenation, and substitution using `{{...}}` are supported: ```make version = "0.2.7" @@ -181,27 +190,7 @@ publish: rm -rf {{tarball}} {{tardir}} ``` -`{{...}}` substitutions may need to be quoted if they contains spaces. For example, if you have the following recipe: - -```make -search QUERY: - lynx https://www.google.com/?q={{QUERY}} -``` - -And you type: - -```sh -$ just search "cat toupee" -``` - -Just will run the command `lynx https://www.google.com/?q=cat toupee`, which will get parsed by `sh` as `lynx`, `https://www.google.com/?q=cat`, and `toupee`, and not the intended `lynx` and `https://www.google.com/?q=cat toupee`. - -You can fix this by adding quotes: - -```make -search QUERY: - lynx 'https://www.google.com/?q={{QUERY}}' -``` +=== Strings Double-quoted strings support escape sequences: @@ -250,6 +239,67 @@ string! " ``` +=== Command Evaluation using Backticks + +Backticks can be used to store the result of commands: + +```make +localhost = `dumpinterfaces | cut -d: -f2 | sed 's/\/.*//' | sed 's/ //g'` + +serve: + ./serve {{localhost}} 8080 +``` + +=== Setting Variables from the Command Line + +Variables can be overridden from the command line. + +```make +os = "linux" + +test: build + ./test --test {{os}} + +build: + ./build {{os}} +``` + +```sh +$ just +./build linux +./test --test linux +``` + +Any number of arguments of the form `NAME=VALUE` can be passed before recipes: + +```sh +$ just os=plan9 +./build plan9 +./test --test plan9 +``` + +Or you can use the `--set` flag: + +```sh +$ just --set os bsd +./build bsd +./test --test bsd +``` + +=== Environment Variables + +Assignments prefixed with the `export` keyword will be exported to recipes as environment variables: + +```make +export RUST_BACKTRACE = "1" + +test: + # will print a stack trace if it crashes + cargo test +``` + +=== Recipe Parameters + Recipes may have parameters. Here recipe `build` has a parameter called `target`: ```make @@ -292,7 +342,7 @@ Testing server:unit... ./test --tests unit server ``` -The last parameter to a recipe may be variadic, indicated with a `+` before the argument name: +The last parameter of a recipe may be variadic, indicated with a `+` before the argument name: ```make backup +FILES: @@ -308,59 +358,29 @@ FAQ.md 100% 1831 1.8KB/s 00:00 GRAMMAR.md 100% 1666 1.6KB/s 00:00 ``` -Variables can be exported to recipes as environment variables: +`{{...}}` substitutions may need to be quoted if they contains spaces. For example, if you have the following recipe: ```make -export RUST_BACKTRACE = "1" - -test: - # will print a stack trace if it crashes - cargo test +search QUERY: + lynx https://www.google.com/?q={{QUERY}} ``` -Variables can also be overridden from the command line: +And you type: + +```sh +$ just search "cat toupee" +``` + +Just will run the command `lynx https://www.google.com/?q=cat toupee`, which will get parsed by `sh` as `lynx`, `https://www.google.com/?q=cat`, and `toupee`, and not the intended `lynx` and `https://www.google.com/?q=cat toupee`. + +You can fix this by adding quotes: ```make -os = "linux" - -test: build - ./test --test {{os}} - -build: - ./build {{os}} -``` - -```sh -$ just -./build linux -./test --test linux -``` - -You can pass any number of arguments of the form `NAME=VALUE` before recipes: - -```sh -$ just os=plan9 -./build plan9 -./test --test plan9 -``` - -Or you can use the `--set` flag: - -```sh -$ just --set os bsd -./build bsd -./test --test bsd -``` - -Backticks can be used to store the result of commands: - -```make -localhost = `dumpinterfaces | cut -d: -f2 | sed 's/\/.*//' | sed 's/ //g'` - -serve: - ./serve {{localhost}} 8080 +search QUERY: + lynx 'https://www.google.com/?q={{QUERY}}' ``` +=== Write Recipes in other Languages Recipes that start with a `#!` are executed as scripts, so you can write recipes in other languages: @@ -398,7 +418,9 @@ Yo from a shell script! Hello from ruby! ``` -`just` also supports a number of useful command line options for listing, dumping, and debugging recipes and variable: +=== Command Line Options + +`just` supports a number of useful command line options for listing, dumping, and debugging recipes and variable: ```sh $ just --list @@ -418,11 +440,78 @@ polyglot: python js perl sh ruby Run `just --help` to see all the options. +=== Private Recipes -miscellanea ------------ +Recipes whose name starts with a `_` are omitted from `just --list`: -### syntax highlighting +```make +test: _test-helper + ./bin/test + +_test-helper: + ./bin/super-secret-test-helper-stuff +``` + +```sh +$ just --list +Available recipes: + test +``` + +And from `just --summary`: + +```sh +$ just --summary +test +``` + +This is useful for helper recipes which are only meant to be used as dependencies of other recipes. + +=== Quiet Recipes + +A recipe name may be prefixed with '@' to invert the meaning of '@' before each line: + +```make +@quiet: + echo hello + echo goodbye + @# all done! +``` + +Now only the lines starting with '@' will be echoed: + +```sh +$ j quiet +hello +goodbye +# all done! +``` + +=== Invoking Justfiles in Other Directories + +If the first argument passed to `just` contains a `/`, then the following occurs: + +1. The argument is split at the last `/`. +2. The part before the last `/` is treated as a directory. Just will start its search for the justfile there, instead of in the current directory. +3. The part after the last slash is treated as a normal argument, or ignored if it is empty. + +This may seem a little strange, but it's useful if you wish to run a command in a justfile that is in a subdirectory. + +For example, if you are in a directory which contains a subdirectory named `foo`, which contains justfile with the recipe `build`, which is also the default recipe, the following are all equivalent: + +```sh +$ (cd foo && just build) +$ just foo/build +$ just foo/ +``` + +== Miscellanea + +=== Shell Alias + +For lightning-fast command running, put `alias j=just` in your shell's configuration file. + +=== Syntax Highlighting `justfile` syntax is close enough to `make` that you may want to tell your editor to use make syntax highlighting for just. @@ -449,15 +538,15 @@ Include the following in a `justfile` to enable syntax highlighting in vim and e Feel free to send me the commands necessary to get syntax highlighting working in your editor of choice so that I may include them here. -### justfile grammar +=== Grammar -A description of the grammar of justfiles can be found in [GRAMMAR.md](GRAMMAR.md). +A non-normative grammar of justfiles can be found in link:GRAMMAR.md[]. -### just.sh +=== just.sh -Before `just` was a bloated rust program it was a tiny shell script that called `make`. If you can't or would rather not install rust you can find the old version in [extras/just.sh](extras/just.sh). +Before `just` was a fancy rust program it was a tiny shell script that called `make`. You can find the old version in link:extras/just.sh[]. -### non-project specific justfile +=== Non-Project Specific Justfile If you want some commands to be available everwhere, put them in `~/.justfile` and add the following to your shell's initialization file: @@ -471,9 +560,11 @@ Or, if you'd rather they run in the current directory: alias .j='just --justfile ~/.justfile --working-directory .' ``` +I'm pretty sure that nobody actually uses this feature, but it's there. -further ramblings ------------------ +¯\\_(ツ)_/¯ + +== Further Ramblings I personally find it very useful to write a `justfile` for almost every project, big or small. @@ -495,7 +586,7 @@ Some ideas for recipes: Even for small, personal projects it's nice to be able to remember commands by name instead of ^Reverse searching your shell history, and it's a huge boon to be able to go into an old project written in a random language with a mysterious build system and know that all the commands you need to do whatever you need to do are in the `justfile`, and that if you type `just` something useful (or at least interesting!) will probably happen. -For ideas for recipes, check out [this project's `justfile`](justfile), or some of the `justfile`s [out in the wild](https://github.com/search?utf8=%E2%9C%93&q=filename%3Ajustfile). +For ideas for recipes, check out link:justfile[this project's `justfile`], or some of the `justfile`s https://github.com/search?utf8=%E2%9C%93&q=filename%3Ajustfile[out in the wild]. Anyways, I think that's about it for this incredibly long-winded README. diff --git a/justfile b/justfile index 6d690558..c0550acd 100644 --- a/justfile +++ b/justfile @@ -100,6 +100,16 @@ quine-text = ' } ' +render-readme: + #!/usr/bin/env ruby + require 'github/markup' + $rendered = GitHub::Markup.render("README.asc", File.read("README.asc")) + File.write('tmp/README.html', $rendered) + +watch-readme: + just render-readme + fswatch -ro README.asc | xargs -n1 -I{} just render-readme + # run all polyglot recipes polyglot: python js perl sh ruby diff --git a/src/unit.rs b/src/unit.rs index 110cdac5..de7e6952 100644 --- a/src/unit.rs +++ b/src/unit.rs @@ -1092,7 +1092,7 @@ fn readme_test() { let mut justfiles = vec![]; let mut current = None; - for line in brev::slurp("README.md").lines() { + for line in brev::slurp("README.asc").lines() { if let Some(mut justfile) = current { if line == "```" { justfiles.push(justfile); diff --git a/tmp/.gitignore b/tmp/.gitignore index 72e8ffc0..d6b7ef32 100644 --- a/tmp/.gitignore +++ b/tmp/.gitignore @@ -1 +1,2 @@ * +!.gitignore