just について
just はプロジェクト固有の開発コマンドを管理するタスクランナーです。justfile でタスクを定義でき、パラメータ化とタスク連鎖をサポートし、複数のプラットフォームで動作します。
主な機能
- 01justfile でプロジェクトタスクを定義し、シンプルなコマンドで実行
- 02利用可能なタスクをリストアップまたはタスク定義を確認
- 03複数のタスクを組み合わせて複雑な開発ワークフローを構築
活用シーン
- 01プロジェクトのビルド、テスト、デプロイコマンドを標準化
- 02OS に関係なく開発者に一貫したタスクインターフェースを提供
- 03反復的な開発作業を再利用可能なタスクに自動化
インストール
OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。
インストール後にjust --versionを実行して確認します。
コマンド例
よく使うコマンドを使う順に並べています。
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
just
just は、プロジェクト固有のコマンドを保存して実行するための便利なツールです。
この README は書籍としても公開されています。 書籍は最新リリースを反映している一方、 GitHub 上の README は最新の master を反映しています。
(中文文档在 这里, 快看过来!)
レシピと呼ばれるコマンドは、make に着想を得た構文を使い、
justfile というファイルに保存します。

その後、just RECIPE で実行できます。
$ just test-all
cc *.c -o main
./test --all
Yay, all your tests passed!
just には便利な機能が豊富にあり、make と比べて多くの改善が加えられています。
-
justはビルドシステムではなくコマンドランナーなので、makeの複雑さや独特な仕様の多くを避けられます。.PHONYレシピは必要ありません。 -
Linux、macOS、Windows、その他の一般的な Unix 系 OS を、追加の依存関係なしでサポートしています。 (ただし、システムに
shがない場合は、別のシェルを選ぶ必要があります。) -
エラーは具体的で分かりやすく、構文エラーはソースの該当箇所とともに報告されます。
-
justには豊富な式言語と、多数の組み込み関数があります。 -
可能な限り、エラーは静的に解決されます。不明なレシピや循環依存は、実行前に報告されます。
-
justは.envファイルを読み込むため、環境変数を簡単に設定できます。 -
レシピはコマンドラインから一覧表示できます。
-
コマンドライン補完スクリプトは、 主なシェルのほとんどで利用できます。
-
レシピは、Python や Node.js などの任意の言語で記述できます。
-
justは、justfileがあるディレクトリだけでなく、任意のサブディレクトリから呼び出せます。 -
さらに多くの機能があります。
just についてサポートが必要な場合は、気軽に issue を作成するか、
Discord でご連絡ください。機能リクエストやバグ報告も
いつでも歓迎します。
インストール
Just は、お好みのパッケージマネージャーを使うか、
ビルド済みバイナリをダウンロードするか、
cargo install just でソースからビルドしてインストールできます。
前提条件
just は、Linux、macOS、BSD 系 OS を含む、一般的な sh を備えたシステムで動作します。
Windows
Windows では、just は
Git for Windows、
GitHub Desktop、または
Cygwin が提供する sh を使って動作します。インストール後、just を実行するシェルの
PATH から sh を利用できる必要があります。
sh をインストールしたくない場合は、shell 設定を使って任意のシェルを指定できます。
PowerShell の場合:
# use PowerShell instead of sh:
set shell := ["powershell.exe", "-c"]
hello:
Write-Host "Hello, world!"
…または cmd.exe の場合:
# use cmd.exe instead of sh:
set shell := ["cmd.exe", "/c"]
list:
dir
コマンドライン引数を使ってシェルを設定することもできます。たとえば、PowerShell を使うには、--shell powershell.exe --shell-arg -c を指定して just を起動します。
(PowerShell は Windows 7 SP1 および Windows Server 2008 R2 SP1 以降で既定でインストールされており、cmd.exe はかなり扱いにくいため、ほとんどの Windows ユーザーには PowerShell をおすすめします。)
パッケージ
クロスプラットフォーム
| パッケージマネージャー | パッケージ | コマンド |
|---|---|---|
| arkade | just | arkade get just |
| asdf | just |
asdf plugin add justasdf install just <version>
|
| Cargo | just | cargo install just |
| Cargo Binstall | just | cargo binstall just |
| Conda | just | conda install -c conda-forge just |
| Homebrew | just | brew install just |
| Nix | just | nix-env -iA nixpkgs.just |
| npm | rust-just | npm install -g rust-just |
| pipx | rust-just | pipx install rust-just |
| Snap | just | snap install --edge --classic just |
| Spack | just | spack install just |
| uv | rust-just | uv tool install rust-just |
| Operating System | Package Manager | Package | Command |
|---|---|---|---|
| FreeBSD | pkg | just | pkg install just |
| OpenBSD | pkg_* | just | pkg_add just |
Linux
| Operating System | Package Manager | Package | Command |
|---|---|---|---|
| Alpine | apk-tools | just | apk add just |
| Arch | pacman | just | pacman -S just |
| Debian 13 and Ubuntu 24.04 derivatives | apt | just | apt install just |
| Fedora | DNF | just | dnf install just |
| Gentoo | Portage | dev-build/just |
emerge -av dev-build/just
|
| NixOS | Nix | just | nix-env -iA nixos.just |
| openSUSE | Zypper | just | zypper in just |
| Solus | eopkg | just | eopkg install just |
| Void | XBPS | just | xbps-install -S just |
Windows
| パッケージマネージャー | パッケージ | コマンド |
|---|---|---|
| Chocolatey | just | choco install just |
| Scoop | just | scoop install just |
| Windows Package Manager | Casey/Just | winget install --id Casey.Just --exact |
macOS
| パッケージマネージャー | パッケージ | コマンド |
|---|---|---|
| MacPorts | just | port install just |
ビルド済みバイナリ
Linux、macOS、Windows 向けのビルド済みバイナリは、 リリースページから入手できます。
Linux、macOS、Windows では、次のコマンドで最新リリースをダウンロードできます。DEST は、just を配置するディレクトリに置き換えてください。
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to DEST
たとえば、just を ~/bin にインストールするには、次のようにします。
# create ~/bin
mkdir -p ~/bin
# download and extract just to ~/bin/just
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/bin
# add `~/bin` to the paths that your shell searches for executables
# this line should be added to your shell's initialization file,
# e.g. `~/.bashrc` or `~/.zshrc`
export PATH="$PATH:$HOME/bin"
# just should now be executable
just --help
install.sh は、GitHub Actions 上や、多数のマシンが同じ IP アドレスを共有するその他の環境では失敗する場合があります。install.sh は、インストールする just の最新バージョンを特定するために GitHub API を呼び出しますが、これらの API 呼び出しには IP ごとのレート制限があります。このような状況で install.sh の信頼性を高めるには、--tag を指定してインストールするタグを指定してください。
レート制限を回避するもう 1 つの方法は、環境変数 GITHUB_TOKEN として GitHub 認証トークンを install.sh に渡し、リクエストを認証できるようにすることです。
リリースには、ビルド済みバイナリアーカイブの整合性の検証に使用できる SHA256SUM ファイルが含まれています。
リリースを検証するには、ビルド済みバイナリアーカイブと SHA256SUM ファイルをダウンロードし、次のコマンドを実行します。
shasum --algorithm 256 --ignore-missing --check SHA256SUMS
GitHub Actions
GitHub Actions には、いくつかの方法で just をインストールできます。
GitHub Actions の macOS ランナーにプリインストールされているパッケージマネージャーを使う場合は brew install just を、Windows の場合は choco install just を実行します。
extractions/setup-just を使用する場合:
- uses: extractions/setup-just@v3
with:
just-version: 1.5.0 # optional semver specification, otherwise latest
または、taiki-e/install-action を使用する場合:
- uses: taiki-e/install-action@just
Docker
just は、
GitHub Container Registry から Docker イメージとして入手できます。
just を Docker イメージにコピーするには、Dockerfile に次の行を追加します。
COPY --from=ghcr.io/casey/just:latest /just /usr/local/bin/
コピー後は、docker build の一部として just を使用することもできます。
RUN just
リリース RSS フィード
just のリリース情報を配信する RSS フィードは、
こちらで利用できます。
Node.js のインストール
just-install を使うと、Node.js アプリケーションでの just のインストールを自動化できます。
just は、npm スクリプトに代わる優れた、より堅牢な選択肢です。Node.js アプリケーションの依存関係に just を含める場合、just-install は npm install コマンドの一環として、プラットフォーム固有のバイナリをローカルにインストールします。これにより、前述のいずれかの方法で各開発者が個別に just をインストールする必要がなくなります。インストール後は、npm スクリプト内または npx で just コマンドを使用できます。プロジェクトのセットアップをできるだけ簡単にしたいチームに最適です。
詳しくは、just-install README ファイルをご覧ください。
Nix Flake
just リポジトリには、nix flake を定義する
flake.nix が含まれており、別の flake の入力として just を使用できます。
{
inputs = {
just.url = "github:casey/just";
}
outputs = {self, nixpkgs, just}: {
}
}
後方互換性
バージョン 1.0 のリリースに伴い、just は後方互換性と安定性を強く重視しています。
今後のリリースでは、既存の justfile が動作しなくなったり、コマンドラインインターフェースの動作中の呼び出しが破損したりするような、後方互換性のない変更は導入されません。
ただし、明らかなバグを修正することは妨げられません。たとえ、その動作に依存する justfile が動かなくなる可能性があっても同様です。
just 2.0 がリリースされることはありません。望ましい後方互換性のない変更は、justfile ごとにオプトイン方式で提供されるため、ユーザーは都合のよいときに移行できます。
まだ安定化の準備が整っていない機能には不安定であることが明記され、いつでも変更または削除される可能性があります。不安定な機能を使用すると、デフォルトではエラーが発生します。--unstable フラグ、set unstable、または環境変数 JUST_UNSTABLE に false、0、空文字列以外の値を設定することで、このエラーを抑制できます。
必要な Just の最小バージョンの指定
特定のバージョンが必要な just の機能を使う場合、minimum-version1.55.0 設定を使用して、それより古いバージョンの just を使うとエラーになるようにできます。
set minimum-version := '1.55.0'
just が自身のバージョンより新しい最小バージョンを検出すると、必要なバージョンを示すエラーメッセージを出力します。これは、そうしなければ表示されたであろう分かりにくいエラーメッセージよりも役立つはずです。
minimum-version 設定は、justfile の先頭に配置し、その設定が制限する新機能を使用する前に記述する必要があります。
レクサーを前方互換性のない形で変更する機能では、依然として分かりにくいエラーメッセージが表示されます。最小バージョンのチェックは、レクサーの実行後に動くパーサーで実装されているためです。
エディターのサポート
justfile の構文は make に十分近いため、エディターで just に make の構文強調表示を使うよう設定するとよいでしょう。
Vim と Neovim
pbnj のおかげで、Vim バージョン 9.1.1042 以降と Neovim バージョン 0.11 以降では、Justfile の構文強調表示が標準でサポートされています。
vim-just
vim-just プラグインは、justfile の構文強調表示を提供します。
Plug など、お好みのパッケージマネージャーを使ってインストールしてください。
call plug#begin()
Plug 'NoahTheDuke/vim-just'
call plug#end()
または、Vim に組み込まれているパッケージサポートを使います。
mkdir -p ~/.vim/pack/vendor/start
cd ~/.vim/pack/vendor/start
git clone https://github.com/NoahTheDuke/vim-just.git
tree-sitter-just
tree-sitter-just は、Neovim 用の Nvim Treesitter プラグインです。
Emacs
just-mode は、justfile の構文ハイライトと自動インデントを提供します。MELPA では just-mode として利用できます。
justl は、レシピを実行したり一覧表示したりするコマンドを提供します。
ファイルごとに make モードを有効にするには、個々の justfile に次の内容を追加できます。
# Local Variables:
# mode: makefile
# End:
Visual Studio Code
VS Code 用の拡張機能はこちらから入手できます。
メンテナンスされていない VS Code 拡張機能には、 skellock/vscode-just と sclu1034/vscode-just があります。
JetBrains IDE
linux_china による JetBrains IDE 用プラグインは こちらから入手できます。
Kakoune
TeddyDD のおかげで、Kakoune は標準で justfile の構文ハイライトに対応しています。
Helix
Helix は、バージョン 23.05 以降、標準で justfile の構文ハイライトに対応しています。
Sublime Text
nk9 による、just の構文やその他のツールに対応した Just パッケージは、PackageControl から入手できます。
Micro
tomodachi94 のおかげで、Micro は標準で Justfile の構文ハイライトに対応しています。
Zed
jackTabsCode による zed-just 拡張機能は、Zed 拡張機能ページから入手できます。
その他のエディター
お使いのエディターで構文ハイライトを有効にするために必要なコマンドをぜひお知らせください。こちらに掲載させていただきます。
Language Server Protocol
just-lsp は、Language Server Protocol の実装を提供し、定義へのジャンプ、インライン診断、コード補完などの機能を実現します。
Model Context Protocol
just-mcp は、
model context protocol
アダプターを提供し、LLM が justfiles の内容を参照してレシピを実行できるようにします。
クイックスタート
お使いのコンピューターに just をインストールする方法については、インストールのセクションを参照してください。just --version を実行して、正しくインストールされていることを確認してください。
構文の概要については、 このチートシートを確認してください。
just のインストールと動作確認が完了したら、プロジェクトのルートに justfile という名前のファイルを作成し、次の内容を記述します。
recipe-name:
echo 'This is a recipe!'
# this is a comment
another-recipe:
@echo 'This is another recipe.'
just を呼び出すと、現在のディレクトリとその上位のディレクトリから justfile という名前のファイルを検索するため、プロジェクト内の任意のサブディレクトリから呼び出せます。
justfile の検索では大文字と小文字が区別されないため、Justfile、JUSTFILE、JuStFiLe など、どのような大文字・小文字の組み合わせでも動作します。また、justfile を隠したい場合に備えて、just は .justfile という名前のファイルも検索します。
デフォルトでは、引数なしで just を実行すると、justfile 内の最初のレシピが実行されます。
$ just
echo 'This is a recipe!'
This is a recipe!
1つ以上の引数を指定すると、実行するレシピを指定できます。
$ just another-recipe
This is another recipe.
just は各コマンドを実行前に標準エラー出力へ表示します。そのため、echo 'This is a recipe!' が表示されました。@ で始まる行ではこの表示が抑制されるため、echo 'This is another recipe.' は表示されませんでした。
コマンドが失敗すると、レシピの実行は停止します。ここでは、cargo test が成功した場合にのみ cargo publish が実行されます。
publish:
cargo test
# tests passed, time to publish!
cargo publish
レシピはほかのレシピに依存できます。ここでは、test レシピが build レシピに依存しているため、test の前に build が実行されます。
build:
cc main.c foo.c bar.c -o main
test: build
./test
sloc:
@echo "`wc -l *.c` lines of code"
$ just test
cc main.c foo.c bar.c -o main
./test
testing… all tests passed!
依存関係のないレシピは、コマンドラインで指定された順に実行されます。
$ just build sloc
cc main.c foo.c bar.c -o main
1337 lines of code
依存先は、依存するレシピより後に指定されていても、必ず先に実行されます。
$ just test build
cc main.c foo.c bar.c -o main
./test
testing… all tests passed!
レシピはサブモジュール内のレシピに依存することもできます。
mod foo
baz: foo::bar
例
さまざまな justfile が、
examples ディレクトリや
GitHubにあります。
レシピ
デフォルトレシピ
レシピを指定せずに just を呼び出すと、[default] 属性が付いたレシピが実行されます。その属性が付いたレシピがない場合は、justfile 内の最初のレシピが実行されます。
このレシピには、テストの実行など、プロジェクトで最も頻繁に実行されるコマンドを指定できます。
test:
cargo test
依存関係を使って、デフォルトで複数のレシピを実行することもできます。
default: lint build test
build:
echo Building…
test:
echo Testing…
lint:
echo Linting…
デフォルトレシピに適したものがない場合は、default-list1.52.0 を使って、利用可能なレシピを一覧表示できます。
set default-list := true
レシピのパラメーター
レシピにはパラメーターを設定できます。次のレシピ build には、
target というパラメーターがあります。
build target:
@echo 'Building {{target}}…'
cd {{target}} && make
コマンドラインで引数を渡すには、レシピ名の後に指定します。
$ just build my-awesome-project
Building my-awesome-project…
cd my-awesome-project && make
依存先に引数を渡すには、依存先を引数とともに括弧で囲みます。
default: (build "main")
build target:
@echo 'Building {{target}}…'
cd {{target}} && make
依存先には、変数を引数として渡すこともできます。
target := "main"
_build version:
@echo 'Building {{version}}…'
cd {{version}} && make
build: (_build target)
コマンドの引数を依存先に渡すには、依存先を引数とともに括弧で囲みます。
build target:
@echo "Building {{target}}…"
push target: (build target)
@echo 'Pushing {{target}}…'
パラメーターにはデフォルト値を設定できます。
default := 'all'
test target tests=default:
@echo 'Testing {{target}}:{{tests}}…'
./test --tests {{tests}} {{target}}
デフォルト値が設定されたパラメーターは省略できます。
$ just test server
Testing server:all…
./test --tests all server
または、値を指定することもできます。
$ just test server unit
Testing server:unit…
./test --tests unit server
デフォルト値には任意の式を指定できますが、+、&&、||、または / 演算子を含む式は括弧で囲む必要があります。
arch := "wasm"
test triple=(arch + "-unknown-unknown") input=(arch / "input.dat"):
./test {{triple}}
レシピの最後のパラメーターには可変長パラメーターを指定できます。引数名の前に + または * を付けます。
backup +FILES:
scp {{FILES}} [email protected]:
+ を前に付けた可変長パラメーターは、_1 つ以上_の引数を受け取り、空白で区切った引数を含む文字列に展開されます。
$ just backup FAQ.md GRAMMAR.md
scp FAQ.md GRAMMAR.md [email protected]:
FAQ.md 100% 1831 1.8KB/s 00:00
GRAMMAR.md 100% 1666 1.6KB/s 00:00
* を前に付けた可変長パラメーターは、_0 個以上_の引数を受け取り、空白で区切った引数を含む文字列に展開されます。引数がない場合は空文字列に展開されます。
commit MESSAGE *FLAGS:
git commit {{FLAGS}} -m "{{MESSAGE}}"
可変長パラメーターにもデフォルト値を設定できます。コマンドラインで渡された引数がデフォルト値より優先されます。
test +FLAGS='-q':
cargo test {{FLAGS}}
可変長パラメーターが受け取れる引数の数は、リストを有効にしたうえで、[arg(ARG, min=MIN)] および [arg(ARG, max=MAX)] 属性1.56.0を使って制限できます。
set unstable
set lists
[arg('FILES', min='2', max='4')]
backup +FILES:
scp {{FILES}} [email protected]:
min と max はデフォルト値にも適用されます。
{{…}} の置換結果に空白が含まれる場合は、引用符で囲む必要があります。たとえば、次のレシピがあるとします。
search QUERY:
lynx https://www.google.com/?q={{QUERY}}
そして、次のように入力します。
$ just search "cat toupee"
just はコマンド lynx https://www.google.com/?q=cat toupee を実行します。これは sh によって lynx、https://www.google.com/?q=cat、toupee と解析されます。意図した lynx と https://www.google.com/?q=cat toupee にはなりません。
引用符を追加すれば解決できます。
search QUERY:
lynx 'https://www.google.com/?q={{QUERY}}'
$ を前に付けたパラメーターは、環境変数としてエクスポートされます。
foo $bar:
echo $bar
[arg("name", pattern=PATTERN)] 属性1.45.0を使うと、パラメーターの値が正規表現パターンに一致するよう制約できます。
[arg('n', pattern='\d+')]
double n:
echo $(({{n}} * 2))
pattern の値には const 式1.55.0を指定できます。
パターンの先頭には ^ が、末尾には $ が追加されるため、引数全体の値が一致する必要があります。
| 演算子を使うと、パターンを複数の選択肢に制約できます。
[arg('flag', pattern='--help|--version')]
info flag:
just {{flag}}
正規表現には Rust の regex クレートが使われます。使用例については、構文のドキュメントを参照してください。
レシピの使用方法は、--usage サブコマンド1.46.0で表示できます。
$ just --usage foo
Usage: just foo [OPTIONS] bar
Arguments:
bar
[arg(ARG, help=HELP)] 属性を使うと、引数にヘルプ文字列を追加できます。
[arg("bar", help="hello")]
foo bar:
help の値には const 式1.55.0を指定できます。
$ just --usage foo
Usage: just foo bar
Arguments:
bar hello
レシピのフラグとオプション
レシピのパラメーターは、デフォルトでは位置引数です。
この justfile では:
@foo bar:
echo bar={{bar}}
パラメーター bar は位置引数です:
$ just foo hello
bar=hello
[arg(ARG, long=OPTION)]1.46.0 属性を使うと、パラメーターをロングオプションにできます。
この justfile では:
[arg("bar", long="bar")]
foo bar:
パラメーター bar は --bar オプションで指定します:
$ just foo --bar hello
bar=hello
オプションは --name=value 構文でも渡せます:
$ just foo --bar=hello
bar=hello
long の値は省略できます。その場合、オプション名はデフォルトでパラメーター名になります。次の justfile では、bar を --bar で渡せます:
[arg("bar", long)]
foo bar:
[arg(ARG, short=OPTION)]1.46.0 属性を使うと、パラメーターをショートオプションにできます。
この justfile では:
[arg("bar", short="b")]
foo bar:
パラメーター bar は -b オプションで指定します:
$ just foo -b hello
bar=hello
short の値は省略できます。その場合、オプションはデフォルトでパラメーター名の最初の文字になります。次の justfile では、bar を -b で渡せます:
[arg("bar", short)]
foo bar:
パラメーターにロングオプションとショートオプションの両方がある場合、どちらを使っても渡せます。
複数のショートオプションを組み合わせることもできます1.55.0。たとえば、-abc は -a -b -c と同じです。値を取るショートオプションは最後に指定できます。たとえば、-abcd VALUE のように指定します。
可変長の * および + パラメーターはオプションにすることができ、その場合、オプションは繰り返し指定でき、指定するたびに値が1つ追加されます:
[arg('file', long)]
backup +file:
scp {{file}} [email protected]:
$ just backup --file FAQ.md --file GRAMMAR.md
scp FAQ.md GRAMMAR.md [email protected]:
位置引数の可変長パラメーターと同様に、+ オプションは少なくとも1回渡す必要がありますが、* オプションは省略できます。
[arg(ARG, value=VALUE, …)]1.46.0 属性を long または short と併用すると、値を取らないフラグとしてパラメーターを指定できます。VALUE には式を指定できます1.54.0。
この justfile では:
[arg("bar", long="bar", value="hello")]
foo bar:
パラメーター bar は --bar オプションで指定しますが、値は受け取らず、代わりに [arg] 属性で指定された値を受け取ります:
$ just foo --bar
bar=hello
これは、危険なコマンドで --force のようなフラグを常に必須にする場合に便利です。
パラメーターにデフォルト値がある場合、フラグは省略可能です:
[arg("bar", long="bar", value="hello")]
foo bar="goodbye":
呼び出し時に渡さない場合は、デフォルト値が割り当てられます:
$ just foo
bar=goodbye
そのオプションを定義していないレシピに --help または -h を渡すと、レシピのヘルプ文字列が表示され、実行は停止しますmaster。
引数の分割を避ける
この justfile があるとします:
foo argument:
touch {{argument}}
次のコマンドは、some と argument.txt という2つのファイルを作成します:
$ just foo "some argument.txt"
ユーザーのシェルは "some argument.txt" を1つの引数として解析しますが、just が touch {{argument}} を touch some argument.txt に置き換えると、引用符は保持されず、touch は2つの引数を受け取ります。
これを避ける方法はいくつかあります。引用符で囲む方法、位置引数を使う方法、エクスポートされた引数を使う方法です。
引用符で囲む
{{argument}} の展開を引用符で囲むことができます:
foo argument:
touch '{{argument}}'
これにより、たとえば {{argument}} と書いた場合に、実行前に変数名の誤記を just が検出できる機能は維持されます。ただし、argument の値にシングルクォートが含まれている場合は、期待どおりに動作しません。
位置引数
positional-arguments 設定を使うと、すべての引数が位置引数として渡され、$1、$2、…、$@ でアクセスできます。これらを二重引用符で囲むと、シェルによるさらなる分割を避けられます:
set positional-arguments
foo argument:
touch "$1"
たとえば $1 の代わりに $2 と入力した場合など、誤記を just が検出できなくなりますが、二重引用符を含む値も含め、argument のあらゆる値で動作します。
エクスポートされた引数
export 設定を有効にすると、すべての引数がエクスポートされます:
set export
foo argument:
touch "$argument"
または、引数の前に $ を付けると、個別にエクスポートできます:
foo $argument:
touch "$argument"
たとえば $argument と入力した場合など、誤記を just が検出できなくなりますが、二重引用符を含む値も含め、argument のあらゆる値で動作します。
位置引数
positional-arguments が true の場合、レシピの引数はコマンドに位置引数として渡されます。シェルのレシピでは、引数 $0 はレシピ名になります。
たとえば、次のレシピを実行すると:
set positional-arguments
@foo bar:
echo $0
echo $1
次の出力が生成されます:
$ just foo hello
foo
hello
bash や zsh など、sh 互換のシェルでは、$@ はレシピに渡された位置引数を1番目から展開します。"$@" のように二重引用符で囲むと、空白を含む引数も二重引用符で囲まれた場合と同様に渡されます。つまり、"$@" は "$1" "$2"…と同等です。位置パラメーターがない場合、"$@" と $@ は何も展開しません(つまり、取り除かれます)。
次のレシピの例では、引数を1行ずつ出力します:
set positional-arguments
@test *args='':
bash -c 'while (( "$#" )); do echo - $1; shift; done' -- "$@"
_2つ_の引数を指定して実行すると:
$ just test foo "bar baz"
- foo
- bar baz
位置引数は、[positional-arguments] 属性1.29.0を使ってレシピごとに有効にすることもできます:
[positional-arguments]
@foo bar:
echo $0
echo $1
PowerShell は位置引数を他のシェルと同じ方法では処理しないため、位置引数を有効にすると、PowerShell を使うレシピが動作しなくなる可能性があります。
PowerShell 7.4 以降を使っている場合は、-CommandWithArgs フラグを指定すると、位置引数が期待どおりに動作します:
set shell := ['pwsh.exe', '-CommandWithArgs']
set positional-arguments
print-args a b c:
Write-Output @($args[1..($args.Count - 1)])
依存関係
依存関係は、それに依存するレシピより先に実行されます:
a: b
@echo A
b:
@echo B
$ just a
B
A
just の1回の呼び出しでは、引数が同じレシピは、コマンドラインで何回指定されていても、また依存関係として何回指定されていても、1回だけ実行されます:
a:
@echo A
b: a
@echo B
c: a
@echo C
$ just a a a a a
A
$ just b c
A
B
C
何らかのセットアップを行うレシピに、複数のレシピが依存することがあります。その場合、それらのレシピを実行しても、セットアップは1回だけ実行されます:
build:
cc main.c
test-foo: build
./a.out --test foo
test-bar: build
./a.out --test bar
$ just test-foo test-bar
cc main.c
./a.out --test foo
./a.out --test bar
1回の実行でレシピがスキップされるのは、同じ引数を受け取る場合に限られます:
build:
cc main.c
test TEST: build
./a.out --test {{TEST}}
$ just test foo test bar
cc main.c
./a.out --test foo
./a.out --test bar
レシピの最後に別のレシピを実行する
レシピの通常の依存関係は、レシピの開始前に必ず実行されます。つまり、依存される側のレシピは、依存する側のレシピより先に実行されます。このような依存関係は「先行依存関係」と呼ばれます。
レシピには後続依存関係も指定できます。後続依存関係はレシピの直後に実行され、&& で指定します:
a:
echo 'A!'
b: a && c d
echo 'B!'
c:
echo 'C!'
d:
echo 'D!'
…b を実行すると、次のように出力されます:
$ just b
echo 'A!'
A!
echo 'B!'
B!
echo 'C!'
C!
echo 'D!'
D!
レシピの途中で別のレシピを実行する
just は別のレシピの途中でレシピを実行する機能をサポートしていませんが、レシピの途中で just を再帰的に呼び出すことはできます。次の justfile を使うと:
a:
echo 'A!'
b: a
echo 'B start!'
just c
echo 'B end!'
c:
echo 'C!'
…b を実行すると、次のように出力されます:
$ just b
echo 'A!'
A!
echo 'B start!'
B start!
echo 'C!'
C!
echo 'B end!'
B end!
ただし、レシピ c は just をまったく新しく呼び出して実行されるため、制限があります。割り当ては再計算され、依存関係が2回実行される場合があり、コマンドライン引数は子の just プロセスに引き継がれません。
並列実行
[parallel] 属性を使うと、依存関係を並列実行できます。
次の justfile では、main を実行すると foo、bar、baz が並列に実行されます:
[parallel]
main: foo bar baz
foo:
sleep 1
bar:
sleep 1
baz:
sleep 1
同時に実行するレシピの数は、--jobs オプション1.56.0で制限できます。num_jobs() 関数はジョブ数を返し、--jobs が指定されていない場合は空のリストを返します。
レシピの行を並行して実行するには、GNU parallel を使用できます:
parallel:
#!/usr/bin/env -S parallel --shebang --ungroup --jobs {{ num_cpus() }}
echo task 1 start; sleep 3; echo task 1 done
echo task 2 start; sleep 3; echo task 2 done
echo task 3 start; sleep 3; echo task 3 done
echo task 4 start; sleep 3; echo task 4 done
ドキュメントコメント
レシピの直前にあるコメントは、just --list に表示されます:
# build stuff
build:
./bin/build
# test stuff
test:
./bin/test
$ just --list
Available recipes:
build # build stuff
test # test stuff
[doc] 属性を使うと、レシピのドキュメントコメントを設定したり、非表示にしたりできます:
# This comment won't appear
[doc('Build stuff')]
build:
./bin/build
# This one won't either
[doc]
test:
./bin/test
$ just --list
Available recipes:
build # Build stuff
test
[doc] の値には定数式を指定できます1.56.0。
グループ
レシピとモジュールには、1つ以上のグループ名を付けることができます:
[group('lint')]
js-lint:
echo 'Running JS linter…'
[group('rust recipes')]
[group('lint')]
rust-lint:
echo 'Running Rust linter…'
[group('lint')]
cpp-lint:
echo 'Running C++ linter…'
# not in any group
email-everyone:
echo 'Sending mass email…'
レシピはグループごとに表示されます:
$ just --list
Available recipes:
email-everyone # not in any group
[lint]
cpp-lint
js-lint
rust-lint
[rust recipes]
rust-lint
just --list --unsorted を実行すると、各グループ内で justfile の記述順にレシピが表示されます:
$ just --list --unsorted
Available recipes:
(no group)
email-everyone # not in any group
[lint]
js-lint
rust-lint
cpp-lint
[rust recipes]
rust-lint
--groups を使うとグループを表示できます:
$ just --groups
Recipe groups:
lint
rust recipes
just --groups --unsorted を使うと、justfile の記述順にグループを表示できます。
エイリアス
エイリアスを使うと、コマンドラインで別の名前を指定してレシピを実行できます。
alias b := build
build:
echo 'Building!'
$ just b
echo 'Building!'
Building!
エイリアスの対象には、サブモジュール内のレシピを指定できます。
mod foo
alias baz := foo::bar
または、モジュール1.55.0を指定できます。
mod frontend
alias f := frontend
$ just f build
プライベートレシピ
名前が_で始まるレシピとエイリアスは、just --listには表示されません。
test: _test-helper
./bin/test
_test-helper:
./bin/super-secret-test-helper-stuff
$ just --list
Available recipes:
test
just --summaryにも表示されません。
$ just --summary
test
名前を変更せずにレシピやエイリアスを非表示にするには、[private]属性1.10.0も使用できます。
[private]
foo:
[private]
alias b := bar
bar:
$ just --list
Available recipes:
bar
これは、他のレシピの依存関係としてのみ使用するヘルパーレシピに便利です。
アイテムの有効化と無効化
[android]、[dragonfly]、[freebsd]、[linux]、[macos]、[netbsd]、[openbsd]、[unix]、[windows]属性は条件付き属性です。デフォルトでは、アイテムは常に有効です。1つ以上の条件付き属性が付いたアイテムは、それらの条件付き属性のいずれかが有効な場合にのみ有効になります。
条件付き属性は当初レシピにのみ適用されていましたが、現在はすべてのトップレベルアイテムにも適用できます1.56.0。
これを使うと、実行するオペレーティングシステムに応じて動作を変えるjustfileを記述できます。このjustfileのrunレシピは、オペレーティングシステムに応じて異なるCコンパイラーを使用してmain.cをコンパイルし、そのコンパイラーに適した名前で出力バイナリを作成して実行します。
[unix]
run:
cc main.c
./a.out
[windows]
run:
cl main.c
main.exe
同様に、現在のオペレーティングシステムに応じて設定を切り替えることもできます。
[unix]
set shell := ['sh', '-cu']
[windows]
set shell := ['cmd', '/c']
レシピ名の重複を許可する
allow-duplicate-recipesがtrueに設定されている場合、同じ名前のレシピを複数定義してもエラーにならず、最後の定義が使用されます。デフォルトはfalseです。
set allow-duplicate-recipes
@foo:
echo foo
@foo:
echo bar
$ just foo
bar
式
変数と代入
モジュールレベルの変数は、:=を使って値を代入することで作成できます。
foo := "hello"
bar := "world"
baz:
echo {{ foo + " " + bar }}
モジュール内のすべての変数を表示できます。
$ just --evaluate
bar := "world"
foo := "hello"
または、単一の変数の値を表示できます。
$ just --evaluate foo
hello
サブモジュールへのパスを指定すると、サブモジュール内のすべての変数、またはサブモジュール内の単一の変数を表示できます1.49.0。
$ just --evaluate bob::bar
x := "world"
y := "hello"
$ just --evaluate bob::bar::y
hello
エクスポートされる変数の形式は、--evaluate-format1.49.0で制御できます。
$ just --evaluate --evaluate-format shell
bar="world"
foo="hello"
デフォルトの形式は--evaluate-format justです。
$ just --evaluate --evaluate-format just
bar := "world"
foo := "hello"
変数名の重複を許可する
allow-duplicate-variablesがtrueに設定されている場合、同じ名前の変数を複数定義してもエラーにならず、最後の定義が使用されます。デフォルトはfalseです。
set allow-duplicate-variables
a := "foo"
a := "bar"
@foo:
echo {{a}}
$ just foo
bar
遅延評価
lazy設定1.47.0を有効にすると、評価器は未使用の変数を評価しません。justfileに、評価コストは高いものの、特定の場合にしか使用しない変数が含まれている場合に便利です。
次のjustfileでは、barのみを実行する場合、tokenは評価されません。
set lazy
token := `expensive-script-to-get-credentials`
foo:
curl -H "Authorization: Bearer {{ token }}" https://example.com/foo
bar:
cargo test
エクスポートされた変数がいつ使用されるかをjustで判断できないため、exportを使った代入と、set exportが設定されたモジュール内の代入は常に評価されます。
式と置換
式ではさまざまな演算子や関数呼び出しをサポートしており、代入、レシピ引数のデフォルト値、レシピ本体内の{{…}}置換で使用できます。
tmpdir := `mktemp -d`
version := "0.2.7"
tardir := tmpdir / "awesomesauce-" + version
tarball := tardir + ".tar.gz"
config := quote(config_dir() / ".project-config")
publish:
rm -f {{tarball}}
mkdir {{tardir}}
cp README.md *.c {{ config }} {{tardir}}
tar zcvf {{tarball}} {{tardir}}
scp {{tarball}} [email protected]:release/
rm -rf {{tarball}} {{tardir}}
連結
+演算子は、左辺の引数と右辺の引数を連結した値を返します。
foobar := 'foo' + 'bar'
論理演算子
論理演算子&&と||を使うと、Pythonのandやorと同様に値を合成できます1.37.0。偽の値は空のリスト[]のみで、空文字列''を含む、それ以外の値はすべて真です。
これらの演算子を使うにはset lists1.53.0が必要です。この機能は現在、不安定な状態です。
&&演算子は、左辺の引数が偽の場合は空のリストを返し、真の場合は右辺の引数を返します。
foo := [] && 'goodbye' # []
bar := 'hello' && 'goodbye' # 'goodbye'
||演算子は、左辺の引数が真の場合はその値を返し、偽の場合は右辺の引数を返します。
foo := [] || 'goodbye' # 'goodbye'
bar := 'hello' || 'goodbye' # 'hello'
パスの結合
/ 演算子を使うと、2 つの文字列をスラッシュで結合できます。
foo := "a" / "b"
$ just --evaluate foo
a/b
すでにスラッシュがある場合でも、/ が追加されることに注意してください。
foo := "a/"
bar := foo / "b"
$ just --evaluate bar
a//b
絶対パスも構築できます1.5.0。
foo := / "b"
$ just --evaluate foo
/b
/ 演算子は、Windows でも / 文字を使用します。そのため、ユニバーサル命名規則(UNC)を使用するパス、つまり \\ で始まるパスには、/ 演算子を使わないでください。UNC パスではスラッシュがサポートされていないためです。
{{ のエスケープ
{{ を含むレシピを記述するには、{{{{ を使用します。
braces:
echo 'I {{{{LOVE}} curly braces!'
(対応する }} がない場合は無視されるため、エスケープする必要はありません。)
別の方法として、エスケープしたいテキスト全体を補間の中に入れることができます。
braces:
echo '{{'I {{LOVE}} curly braces!'}}'
さらに、{{ "{{" }} を使用する方法もあります。
braces:
echo 'I {{ "{{" }}LOVE}} curly braces!'
文字列
'single'、"double"、および '''triple''' で囲んだ文字列リテラルがサポートされています。レシピ本文とは異なり、文字列内では {{…}} の補間はサポートされていません。
ダブルクォートで囲んだ文字列では、エスケープシーケンスがサポートされています。
carriage-return := "\r"
double-quote := "\""
newline := "\n"
no-newline := "\
"
slash := "\\"
tab := "\t"
unicode-codepoint := "\u{1F916}"
$ just --evaluate
"arriage-return := "
double-quote := """
newline := "
"
no-newline := ""
slash := "\"
tab := " "
unicode-codepoint := "🤖"
Unicode 文字エスケープシーケンス \u{…}1.36.0 では、最大 6 桁の 16 進数を指定できます。
文字列には改行を含めることができます。
single := '
hello
'
double := "
goodbye
"
シングルクォートで囲んだ文字列では、エスケープシーケンスは認識されません。
escapes := '\t\n\r\"\\'
$ just --evaluate
escapes := "\t\n\r\"\\"
シングルクォートまたはダブルクォートを 3 つ並べて区切ることで、インデント付きのシングルクォート文字列とダブルクォート文字列の両方を使用できます。インデント付き文字列の各行から、先頭の改行と、空行以外のすべての行に共通する先頭の空白が取り除かれます。
# this string will evaluate to `foo\nbar\n`
x := '''
foo
bar
'''
# this string will evaluate to `abc\n wuv\nxyz\n`
y := """
abc
wuv
xyz
"""
インデントなしの文字列と同様に、インデント付きのダブルクォート文字列ではエスケープシーケンスが処理され、インデント付きのシングルクォート文字列ではエスケープシーケンスが無視されます。エスケープシーケンスの処理は、インデントの削除後に行われます。インデント削除のアルゴリズムでは、エスケープシーケンスによって生成される空白や改行は考慮されません。
シェル展開される文字列
x を接頭辞に持つ文字列は、シェル展開されます1.27.0。
foobar := x'~/$FOO/${BAR}'
| 値 | 置換後 |
|---|---|
$VAR | 環境変数 VAR の値 |
${VAR} | 環境変数 VAR の値 |
${VAR:-DEFAULT} | 環境変数 VAR の値。VAR が設定されていない場合は DEFAULT |
先頭の ~ | 現在のユーザーのホームディレクトリへのパス |
先頭の ~USER | USER のホームディレクトリへのパス |
この展開はコンパイル時に行われるため、.env ファイル内の変数やエクスポートされた just 変数は使用できません。ただし、シェル展開される文字列は、just 変数や .env ファイルに依存できない設定やインポートパスなどの場所で使用できます。
フォーマット文字列
f を接頭辞に持つ文字列は、フォーマット文字列です1.44.0。
name := "world"
message := f'Hello, {{name}}!'
フォーマット文字列には、式を含む {{…}} で区切られた補間を含めることができます。フォーマット文字列は、文字列の断片と評価された式を連結した文字列に評価されます。
フォーマット文字列にリテラルの {{ を含めるには、{{{{ を使用します。
foo := f'I {{{{LOVE} curly braces!'
リスト
lists 設定1.53.0では、文字列のリストを値として使用できます。
現在、この機能は不安定であり、後方互換性のない形で変更される予定です。この
セクションでは、set lists が有効な場合の動作の変更点について説明します。
多くの組み込み関数でリストをどのように扱うべきかは、まだ決まっていません。
リストを受け取れるよう更新された関数については、このセクションで説明します。
それ以外の関数でリストを使用するとエラーになります。join_list() 関数を使用すると、
リストをスペース区切りの文字列に変換し、未更新の関数で使用できます。組み込み関数で
リストをどのように扱うべきか、またリスト全般についてのフィードバックを歓迎します!
お気軽に issue を作成するか、
set lists tracking issue にコメントを残してください。
可変長レシピパラメーターは、スペース区切りの単一の文字列ではなく、文字列のリストになります。
リストリテラルは [a, b, c] と記述します。リストには文字列のみを含めることができ、
他のリストは含められないため、リストリテラルの引数はフラット化されます。たとえば、
[["a", "b"], [], "c"] は ["a", "b", "c"] と評価されます。
レシピ内および f 文字列内の補間では、リストはスペースで結合されて
単一の文字列になります。
依存関係に渡す各引数は、ちょうど1つのパラメーターに割り当てられます。また、 可変長の依存関係に余分な引数を渡すとエラーになります。
*(recipe *argument) を使用すると、リストの各要素について依存関係を1回ずつ呼び出せます。
引数が空のリストの場合、パラメーターはデフォルト値に評価されます。
デフォルト値のない * 以外のパラメーターに空のリストを渡すとエラーになります。
if の else は省略できます。その場合、条件が偽なら if は [] に評価されます。
assert(condition, message) および [confirm(message)] のメッセージ値は、
表示用にスペースで結合されます。
+ 演算子と / 演算子は、文字列とリストを組み合わせます。文字列と空でないリストを
組み合わせると、文字列とリストの各要素を連結した結果になります。同じ長さの2つのリストを
組み合わせると、両方のオペランドの対応する要素を連結した値を含むリストになります。
長さの異なる2つのリストを組み合わせるとエラーになります。
++ 演算子はリストを連結します。
ブール値
正規のブール値 true は文字列 "true"、正規のブール値 false は空のリスト [] です。
'' を含め、空のリスト以外のすべての値は truthy です。
if または assert() の条件には任意の式を指定でき、その式は truthy かどうか評価されます。
比較演算子 ==、!=、=~、!~ は、if と assert() だけでなくどこでも使用でき、
"true" または [] に評価されます。
value =~ regexes は、value のいずれかの要素が regexes のいずれかの正規表現に一致する場合、
真になります。value または regexes が空の場合は偽になります。
value !~ regexes は、value のどの要素も regexes のどの正規表現にも一致しない場合、
真になります。value または regexes が空の場合も真になります。
値は ! で否定できます。!expression は、expression が [] の場合は "true" に評価され、
それ以外の場合は [] に評価されます。
設定
script-interpreter、shell、windows-shell の設定では、リストリテラルと同様に要素がフラット化されます。
positional-arguments が設定されている場合、リスト引数はスペースで結合されます。ただし、可変個引数の場合は、要素ごとに1つの位置引数として渡されます。
--dotenv-filename オプションと --dotenv-path オプションは複数回指定できます。また、dotenv-filename と dotenv-path の設定にはリストを指定でき、その場合は複数の環境ファイルを読み込めます。dotenv-path の値が最初に検索されます。見つからない場合は、現在のディレクトリで dotenv-filename に指定された名前を検索し、その後、親ディレクトリを順に検索します。いずれかのファイルが含まれる最初のディレクトリで検索を停止し、そのディレクトリ内で一致したすべてのファイルを読み込みます。複数の環境ファイルを読み込む場合、リスト内で後にあるファイルの変数が、前にあるファイルの変数より優先されます。
set dotenv-command の値の各要素はコマンドとして実行されます。リスト内で後にあるコマンドの変数が、前にあるコマンドの変数より優先されます。
属性
[arg(flag)] 属性を指定すると、コマンドラインで値を取らないフラグになります。たとえば、[arg('foo', long, flag)] を指定した場合、--foo が渡されると foo は "true" になり、渡されない場合は [] になります。フラグパラメーターにはデフォルト値を指定できません。
[arg(multiple)] 属性を指定すると、オプションまたはフラグを複数回渡し、渡された値のリストをパラメーターに割り当てられます。flag または value=VALUE と組み合わせた場合、フラグが指定されるたびに、それぞれ "true" または VALUE が繰り返し追加されます。
[arg(min=MIN)] 属性と [arg(max=MAX)] 属性1.56.0を使用して、オプションまたはフラグが受け取れる値の数を制限できます。
[arg(help)] の値にはリストを指定できます。その場合、ヘルプ文字列はリストの要素をスペースで結合したものになります。リストが空の場合、その引数にはヘルプ文字列がありません。
[arg(pattern)] の値にはリストを指定できます。その場合、リスト内のいずれかのパターンに一致すれば、その引数は受け入れられます。値が空のリストの場合、任意の引数が受け入れられます。たとえば、[arg('foo', pattern=['--help', '--version'])] を指定した場合、foo には --help または --version を指定できます。
[env(variable, value)] で value が [] の場合、variable は設定されません。それ以外の場合は、value をスペースで結合した値が設定されます。
関数
absolute_path()- リストの各要素に個別に適用されます。append()- リストの各要素に個別に適用され、要素を空白で分割しません。assert(condition, message)-conditionと評価されます。bool(value)valueを正規の真偽値に変換します。valueが""、"0"、"false"、または[]の場合は[]を返し、"1"または"true"の場合は"true"を返します。それ以外の値はエラーになります。引数や環境変数として渡された真偽値の解析に使用できます。env(keys, default)keysに指定された環境変数を順番に確認し、最初に設定されている値を返します。いずれも設定されていない場合はdefaultを返します。defaultが省略されている場合はエラーになります。is_dependency()- 正規の真偽値を返します。join_list(value, separator)-valueを単一の文字列に結合します。要素はseparatorで結合されます。separatorが省略されている場合は、単一の空白で結合されます。len(value)-valueの要素数を返します。path_exists()- 正規の真偽値を返します。prepend()- リストの各要素に個別に適用され、要素を空白で分割しません。quote()- リストの各要素に個別に適用されます。semver_matches()- 正規の真偽値を返します。show(value)-valueを、そのリテラル表現を含む文字列に変換します。空のリストと複数要素のリストには、たとえば"[]"や"["foo", "bar"]"のように角括弧が使われますが、単一要素のリストには使われません(例:"foo")。split(string, separator)-separatorが現れるたびにstringを分割し、リストにします。separatorが省略されている場合は、先頭と末尾の空白を削除したうえで、空白でstringを分割します。which()- 実行可能ファイルが見つからない場合、空のリストを返します。
例
リストの各要素は個別に quote() されます。
set unstable
set lists
@foo *args:
printf '%s\n' {{ quote(args) }}
$ just foo bar 'baz bob'
bar
baz bob
quote(args) の戻り値は 'bar' 'baz bob' です。set lists がない場合は 'bar baz bob' になります。
可変個の位置引数:
set unstable
set lists
set positional-arguments
foo *args: (bar args 'bob') (baz args)
@bar first second:
echo first=$1
echo second=$2
@baz *args:
echo '$1='$1
echo '$2='$2
$ just foo one two
first=one two
second=bob
$1=one
$2=two
マップされた依存関係は、スター付き引数の各要素に対して1回ずつ呼び出されます。並列実行するには [parallel] を指定します。
set unstable
set lists
[parallel]
build target *platform: *(compile target *platform)
@compile target platform:
echo compiling {{ target }} for {{ platform }}…
$ just build x86 foo bar
compiling foo for x86…
compiling bar for x86…
オプションのデフォルト値には、正規の偽値 [] を使うことを推奨します。
set unstable
set lists
[arg('bar', long)]
foo bar=[]:
条件式
if/else 式は、2つの式が同じ値に評価されるかどうかに応じて、異なる分岐を評価します。
foo := if "2" == "2" { "Good!" } else { "1984" }
bar:
@echo "{{foo}}"
$ just bar
Good!
等しくないかどうかをテストすることもできます。
foo := if "hello" != "goodbye" { "xyz" } else { "abc" }
bar:
@echo {{foo}}
$ just bar
xyz
正規表現との照合もできます。
foo := if "hello" =~ 'hel+o' { "match" } else { "mismatch" }
bar:
@echo {{foo}}
$ just bar
match
正規表現には regex クレートが使われており、構文は docs.rsに記載されています。正規表現ではバックスラッシュのエスケープシーケンスをよく使うため、バックスラッシュがそのまま正規表現パーサーに渡される、シングルクォートの文字列リテラルを使うことを検討してください。
条件式は短絡評価されるため、どちらか一方の分岐のみが評価されます。これを利用すると、実行すべきでないときにバッククォート式が実行されないようにできます。
foo := if env_var("RELEASE") == "true" { `get-something-from-release-database` } else { "dummy-value" }
レシピ内でも条件式を使用できます。
bar foo:
echo {{ if foo == "bar" { "hello" } else { "goodbye" } }}
複数の条件式を連結できます。
foo := if "hello" == "goodbye" {
"xyz"
} else if "a" == "a" {
"abc"
} else {
"123"
}
bar:
@echo {{foo}}
$ just bar
abc
バッククォートによるコマンド評価
バッククォートを使うと、コマンドの結果を保存できます。
localhost := `dumpinterfaces | cut -d: -f2 | sed 's/\/.*//' | sed 's/ //g'`
serve:
./serve {{localhost}} 8080
3つのバッククォートで囲まれたインデント付きバッククォートは、インデント付き文字列と同じ方法でインデントが削除されます。
# This backtick evaluates the command `echo foo\necho bar\n`, which produces the value `foo\nbar\n`.
stuff := ```
echo foo
echo bar
```
インデントの削除について詳しくは、文字列のセクションを参照してください。
バッククォートは #! で始めることはできません。この構文は将来のアップグレード用に予約されています。
shell(…) 関数は、より汎用的な外部コマンドの呼び出し方法を提供します。変数の内容をコマンドとして実行したり、コマンドに引数を渡したりできます。
エラーによる実行の停止
error 関数を使って実行を停止できます。例:
foo := if "hello" == "goodbye" {
"xyz"
} else if "a" == "b" {
"abc"
} else {
error("123")
}
実行すると、次のエラーが発生します。
error: Call to function `error` failed: 123
|
16 | error("123")
組み込み関数
just は、式、レシピ本体の {{…}} 置換、代入、デフォルトのパラメーター値で使用できる組み込み関数を多数提供しています。
_directory で終わる関数は、すべて _dir に短縮できます。そのため、home_directory() は home_dir() と書くこともできます。また、invocation_directory_native() は invocation_dir_native() に短縮できます。
ユーザー定義関数
新しい関数を定義できます1.49.0:
set unstable
hello(name) := f"Hello, {{ name }}!"
foo:
echo '{{ hello("World") }}'
ユーザー定義関数は、現在不安定な機能です。
関数から同じモジュール内の代入を参照できます:
set unstable
base := "foo"
join(extension) := base + "." + extension
create:
touch {{ join("c") }}
touch {{ join("html") }}
touch {{ join("txt") }}
実行
シジル
シェルレシピのコマンドには、シジル -、@、? を任意に組み合わせて前置できます。
@ シジルは、コマンドのエコーを切り替えます:
foo:
@echo "This line won't be echoed!"
echo "This line will be echoed!"
@bar:
@echo "This line will be echoed!"
echo "This line won't be echoed!"
- シジルを付けると、コマンドがゼロ以外の終了ステータスを返しても、レシピの実行が続行されます:
# execution will continue, even if bar doesn't exist
foo:
-rmdir bar
mkdir bar
echo 'so much good stuff' > bar/stuff.txt
? シジル1.47.0を付けると、コマンドがステータスコード 1 で終了した場合、現在のレシピの実行は停止します。ただし、ほかのレシピの実行は続行されます。終了ステータス 0 の場合、現在のレシピの実行は通常どおり続行されます。ほかのすべての終了コードは予約済みであり、今後の just のバージョンで意味が与えられる可能性があるため、使用しないでください。
guards 設定が未設定または false の場合、? シジルは無視され、コマンドの一部として扱われます。
set guards
@foo: bar
echo FOO
@bar:
?[[ -f baz ]]
echo BAR
$ just foo
FOO
$ touch baz
$ just foo
BAR
FOO
クワイエットレシピ
レシピ名の前に @ を付けると、各行の前に付ける @ の意味が反転します:
@quiet:
echo hello
echo goodbye
@# all done!
これで、@ で始まる行だけがエコーされます:
$ just quiet
hello
goodbye
# all done!
set quiet を設定すると、justfile 内のすべてのレシピをクワイエットにできます:
set quiet
foo:
echo "This is quiet"
@foo2:
echo "This is also quiet"
[no-quiet] 属性を指定すると、この設定が上書きされます:
set quiet
foo:
echo "This is quiet"
[no-quiet]
foo2:
echo "This is not quiet"
シバンレシピは、デフォルトでクワイエットです:
foo:
#!/usr/bin/env bash
echo 'Foo!'
$ just foo
Foo!
シバンレシピ名に @ を追加すると、実行前に just がレシピを表示するようになります:
@bar:
#!/usr/bin/env bash
echo 'Bar!'
$ just bar
#!/usr/bin/env bash
echo 'Bar!'
Bar!
通常、レシピの行が失敗すると、just はエラーメッセージを表示します。個々のレシピに [no-exit-message]1.7.0 属性を付けるか、モジュール全体に set no-exit-message1.39.0 を設定すると、これらのエラーメッセージを抑制できます。ツールをラップするレシピで特に役立つ場合があります:
git *args:
@git {{args}}
$ just git status
fatal: not a git repository (or any of the parent directories): .git
error: Recipe `git` failed on line 2 with exit code 128
ツールがゼロ以外のコードで終了したときに、終了エラーメッセージを抑制するには、この属性を追加します:
[no-exit-message]
git *args:
@git {{args}}
$ just git status
fatal: not a git repository (or any of the parent directories): .git
シバンレシピ
#! で始まるレシピはシバンレシピと呼ばれ、レシピ本体をファイルに保存して実行します。これにより、さまざまな言語でレシピを記述できます:
polyglot: python js perl sh ruby nu
python:
#!/usr/bin/env python3
print('Hello from python!')
js:
#!/usr/bin/env node
console.log('Greetings from JavaScript!')
perl:
#!/usr/bin/env perl
print "Larry Wall says Hi!\n";
sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
nu:
#!/usr/bin/env nu
let hello = 'Hola'
echo $"($hello) from a nushell script!"
ruby:
#!/usr/bin/env ruby
puts "Hello from ruby!"
$ just polyglot
Hello from python!
Greetings from JavaScript!
Larry Wall says Hi!
Yo from a shell script!
Hola from a nushell script!
Hello from ruby!
Linux や macOS を含む Unix 系オペレーティングシステムでは、シバンレシピはレシピ本体を一時ディレクトリ内のファイルに保存し、そのファイルに実行権限を付与してから実行します。その後、OS がシバン行をコマンドラインとして解析し、ファイルのパスを含めてコマンドを実行します。たとえば、レシピが #!/usr/bin/env bash で始まる場合、OS が実行する最終的なコマンドは /usr/bin/env bash /tmp/PATH_TO_SAVED_RECIPE_BODY のようになります。
シバン行の分割方法はオペレーティングシステムによって異なります。引数付きのコマンドを渡す場合、-S フラグを使って env に明示的に分割させる必要がある場合があります:
run:
#!/usr/bin/env -S bash -x
ls
Windows はシバン行をサポートしていません。Windows では、just がシバン行をコマンドと引数に分割し、レシピ本体をファイルに保存してから、分割したコマンドと引数を呼び出します。その際、保存したレシピ本体のパスを最後の引数として追加します。たとえば、Windows でレシピが #! py で始まる場合、OS が実行する最終的なコマンドは py C:\Temp\PATH_TO_SAVED_RECIPE_BODY のようになります。
スクリプトレシピ
[script(COMMAND)]1.32.0属性を持つレシピは、COMMANDで解釈されるスクリプトとして実行されます。これにより、Windowsでのcygpathの使用、/usr/bin/envの使用が必要になること、Unix OS間でシバン行の分割に一貫性がないこと、ファイルを実行できる一時ディレクトリが必要になることなど、シバンレシピに関するいくつかの問題を回避できます。
空の[script]属性を持つレシピは、set script-interpreter := […]1.33.0の値で実行されます。デフォルトはsh -euで、set shellの値は使用されません。
レシピの本文は評価された後、一時ディレクトリ内のディスクに書き込まれ、そのパスを引数としてCOMMANDに渡すことで実行されます。
set default-script := true1.52.0を設定すると、[shell]属性1.52.0で上書きされない限り、レシピはシェルレシピではなくスクリプトレシピがデフォルトになります。
スクリプトレシピとシバンレシピの一時ファイル
スクリプトレシピとシバンレシピはどちらも、実行するためにレシピの本文を一時ファイルに書き込みます。スクリプトレシピは、そのファイルをコマンドに渡して実行します。一方、シバンレシピはファイルを直接実行します。一時ファイルを含むファイルシステムがnoexecでマウントされている場合、またはその他の理由で実行できない場合、シバンレシピの実行は失敗します。
justが一時ファイルを書き込むディレクトリは、優先度の高い順に、次のいずれかの方法で設定できます。
-
--tempdirコマンドラインオプションまたはJUST_TEMPDIR環境変数を使って、グローバルに設定します1.41.0。 -
tempdir設定を使って、モジュールごとに設定します。 -
Linuxでは、
XDG_RUNTIME_DIR環境変数を使って、グローバルに設定します。 -
いずれも設定されていない場合は、std::env::temp_dirが返すディレクトリが使用されます。
より安全な Bash シバンレシピ
bashのシバンレシピを書く場合は、set -euxo pipefailの追加を検討してください。
foo:
#!/usr/bin/env bash
set -euxo pipefail
hello='Yo'
echo "$hello from Bash!"
必須ではありませんが、set -euxo pipefailを設定すると、いくつかの便利な機能が有効になり、bashのシバンレシピを通常のシェルjustレシピに近い動作にできます。
-
set -eを設定すると、コマンドが失敗した場合にbashが終了します。 -
set -uを設定すると、未定義の変数がある場合にbashが終了します。 -
set -xを設定すると、実行前にスクリプトの各行がbashによって表示されます。 -
set -o pipefailを設定すると、パイプライン内のコマンドが失敗した場合にbashが終了します。これはbash固有の機能のため、通常のシェルjustレシピでは有効になりません。
これらを組み合わせることで、シェルスクリプトでよくある落とし穴を数多く回避できます。
Windowsでのシバンレシピの実行
Windowsでは、/を含むシバンインタープリターのパスは、Cygwinに付属するユーティリティcygpathを使って、Unix形式のパスからWindows形式のパスに変換されます。
たとえば、Windowsで次のレシピを実行する場合:
echo:
#!/bin/sh
echo "Hello!"
インタープリターのパス/bin/shは、実行前にcygpathを使ってWindows形式のパスに変換されます。
インタープリターのパスに/が含まれていない場合、変換せずに実行されます。これは、cygpathを利用できない場合や、インタープリターにWindows形式のパスを渡したい場合に便利です。
インデント
レシピの行はスペースまたはタブでインデントできますが、両方を混在させることはできません。1つのレシピ内のすべての行で同じ種類のインデントを使用する必要がありますが、同じjustfile内のレシピごとに異なる種類のインデントを使用できます。
各レシピはrecipe-nameから少なくとも1段階インデントする必要がありますが、それ以降はさらにインデントできます。
次のjustfileでは、スペースでインデントしたレシピを·で、タブでインデントしたレシピを→で表しています。
[windows]
set shell := ["pwsh", "-NoLogo", "-NoProfileLoadTime", "-Command"]
set ignore-comments
list-space directory:
··#!pwsh
··foreach ($item in $(Get-ChildItem {{directory}} )) {
····echo $item.Name
··}
··echo ""
# indentation nesting works even when newlines are escaped
list-tab directory:
→ @foreach ($item in $(Get-ChildItem {{directory}} )) { \
→ → echo $item.Name \
→ }
→ @echo ""
PS > just list-space ~
Desktop
Documents
Downloads
PS > just list-tab ~
Desktop
Documents
Downloads
複数行の構文
先頭にシバンがないレシピは、行ごとに評価して実行されるため、複数行の構文はおそらく意図したとおりに動作しません。
たとえば、次の justfile では:
conditional:
if true; then
echo 'True!'
fi
conditional レシピの2行目の先頭に余分な空白があるため、解析エラーが発生します。
$ just conditional
error: Recipe line has extra leading whitespace
|
3 | echo 'True!'
| ^^^^^^^^^^^^^^^^
これを回避するには、条件式を1行で記述するか、スラッシュで改行をエスケープするか、レシピにシバンを追加します。参考として、複数行の構文の例をいくつか示します。
if 文
conditional:
if true; then echo 'True!'; fi
conditional:
if true; then \
echo 'True!'; \
fi
conditional:
#!/usr/bin/env sh
if true; then
echo 'True!'
fi
for ループ
for:
for file in `ls .`; do echo $file; done
for:
for file in `ls .`; do \
echo $file; \
done
for:
#!/usr/bin/env sh
for file in `ls .`; do
echo $file
done
while ループ
while:
while `server-is-dead`; do ping -c 1 server; done
while:
while `server-is-dead`; do \
ping -c 1 server; \
done
while:
#!/usr/bin/env sh
while `server-is-dead`; do
ping -c 1 server
done
レシピ本体の外
括弧で囲まれた式は複数行にまたがることができます。
abc := ('a' +
'b'
+ 'c')
abc2 := (
'a' +
'b' +
'c'
)
foo param=('foo'
+ 'bar'
):
echo {{param}}
bar: (foo
'Foo'
)
echo 'Bar!'
バックスラッシュで終わる行は、空白でつないだかのように次の行へ続きます1.15.0。
a := 'foo' + \
'bar'
foo param1 \
param2='foo' \
*varparam='': dep1 \
(dep2 'foo')
echo {{param1}} {{param2}} {{varparam}}
dep1: \
# this comment is not part of the recipe body
echo 'dep1'
dep2 \
param:
echo 'Dependency with parameter {{param}}'
バックスラッシュによる行継続は、補間でも使用できます。バックスラッシュの次の行はインデントする必要があります。
recipe:
echo '{{ \
"This interpolation " + \
"has a lot of text." \
}}'
echo 'back to recipe body'
レシピ内での変数の設定
レシピの行は just ではなくシェルによって解釈されるため、レシピの途中で just 変数を設定することはできません。
foo:
x := "hello" # This doesn't work!
echo {{x}}
シェル変数は使用できますが、別の問題があります。レシピの各行は新しいシェルインスタンスで実行されるため、ある行で設定した変数は次の行には引き継がれません。
foo:
x=hello && echo $x # This works!
y=bye
echo $y # This doesn't, `y` is undefined here!
これを回避する最善の方法は、シバン付きレシピを使うことです。シバン付きレシピの本体はスクリプトとして抽出されて実行されるため、1つのシェルインスタンスで全体が実行されます。
foo:
#!/usr/bin/env bash
set -euxo pipefail
x=hello
echo $x
シェルの設定
シェルレシピのシェルを設定する方法はいくつかあります。レシピが #! シバンで始まらない場合、シェルレシピがデフォルトで使用されます。優先順位は高いものから順に次のとおりです。
--shellおよび--shell-argコマンドラインオプション。どちらかを指定すると、justは現在の justfile の設定を無視します。set windows-shell := [...](非推奨)set windows-powershell(非推奨)set shell := [...]
Windowsで異なるシェルを使用するには、set shell とともに [windows] 属性および [unix] 属性を使います。
シェル
shell 設定は、レシピの行およびバッククォートの実行に使用するコマンドを指定します。シバン付きレシピには影響しません。デフォルトのシェルは sh -cu です。
# use python3 to execute recipe lines and backticks
set shell := ["python3", "-c"]
# use print to capture result of evaluation
foos := `print("foo" * 4)`
foo:
print("Snake snake snake snake.")
print("{{foos}}")
just は実行するコマンドを引数として渡します。多くのシェルでは、最初の引数を評価させるために、追加のフラグ(多くの場合 -c)が必要です。
Windowsのシェル
just はWindowsではデフォルトで sh を使用します。Windowsで別のシェルを使うには、shell 設定に [windows] 属性を使用します。
[windows]
set shell := ["powershell.exe", "-NoLogo", "-Command"]
hello:
Write-Host "Hello, world!"
すべてのプラットフォームでPowerShellを使用するjustfileについては、 powershell.justを参照してください。
Python 3
set shell := ["python3", "-c"]
Bash
set shell := ["bash", "-uc"]
Z Shell
set shell := ["zsh", "-uc"]
Fish
set shell := ["fish", "-c"]
Nushell
set shell := ["nu", "-c"]
デフォルトのテーブルモードを light に変更する場合:
set shell := ['nu', '-m', 'light', '-c']
NushellはRustで書かれており、Windows/macOSおよびLinuxをクロスプラットフォームでサポートしています。
環境変数
環境変数の取得と設定
just 変数のエクスポート
export キーワードを前置した代入は、環境変数としてレシピにエクスポートされます。
export RUST_BACKTRACE := "1"
test:
# will print a stack trace if it crashes
cargo test
$ を前置したパラメーターは、環境変数としてエクスポートされます。
test $RUST_BACKTRACE="1":
# will print a stack trace if it crashes
cargo test
[env(NAME, VALUE)] 属性を使用して、特定のレシピに環境変数をエクスポートすることもできます。
[env("RUST_BACKTRACE", "1")]
test:
# will print a stack trace if it crashes
cargo test
エクスポートされた変数とパラメーターは、同じスコープ内のバッククォートにはエクスポートされません。
export WORLD := "world"
# This backtick will fail with "WORLD: unbound variable"
BAR := `echo hello $WORLD`
# Running `just a foo` will fail with "A: unbound variable"
a $A $B=`echo $A`:
echo $A $B
export が設定されている場合、すべての just 変数が環境変数としてエクスポートされます。
環境変数のエクスポート解除
unexport キーワードを使うと、環境変数のエクスポートを解除できます1.29.0。
unexport FOO
@foo:
echo $FOO
$ export FOO=bar
$ just foo
sh: FOO: unbound variable
環境から環境変数を取得する
環境の環境変数は、レシピに自動的に渡されます。
print_home_folder:
@echo "HOME is: '${HOME}'"
$ just
HOME is: '/home/myuser'
環境変数から just 変数を設定する
env() 関数を使って、環境変数を just 変数に引き継ぐことができます。
environment-variablesを参照してください。
Dotenv の設定
dotenv-load、dotenv-filename、dotenv-override、dotenv-path、
または dotenv-required のいずれかが設定されている場合、just はファイルから環境変数を読み込もうとします。
dotenv-path が設定されている場合、just は指定されたパスにあるファイルを探します。このパスは絶対パスでも、作業ディレクトリからの相対パスでもかまいません。
コマンドラインオプション --dotenv-path(短縮形 -E)を使うと、実行時に dotenv-path を設定または上書きできます。
dotenv-filename が設定されている場合、just は作業ディレクトリおよびそのすべての親ディレクトリを基準に、指定されたパスにあるファイルを探します。
コマンドラインオプション --dotenv-filename(短縮形 -F)を使うと、実行時に dotenv-filename を設定または上書きできます。
dotenv-filename が設定されておらず、dotenv-load または dotenv-required が設定されている場合、just は作業ディレクトリおよびそのすべての親ディレクトリを基準に、.env という名前のファイルを探します。
dotenv-filename と dotenv-path は似ていますが、dotenv-path は作業ディレクトリからの相対パスとしてのみ確認されるのに対し、dotenv-filename は作業ディレクトリおよびそのすべての親ディレクトリを基準に確認されます。
dotenv-required が設定されていない限り、環境ファイルが見つからなくてもエラーにはなりません。
読み込まれた変数は just 変数ではなく環境変数なので、レシピやバッククォート内では $VARIABLE_NAME を使ってアクセスする必要があります。
dotenv-override が設定されている場合、環境ファイルの変数が既存の環境変数を上書きします。
dotenv-command が設定されている場合、just は設定された shell でそのコマンドを実行し、標準出力を環境ファイルとして読み込みます。
これは、シークレットマネージャーやボールトからシークレットを取得する際に便利です。
set dotenv-command := 'sops -d .enc.env'
コマンドラインオプション --dotenv-command を使うと、実行時に dotenv-command を設定または上書きできます。また、複数回指定できます。各値はコマンドとして実行され、後のコマンドの変数が前のコマンドの変数より優先されます。
たとえば、.env ファイルに次の内容が含まれている場合:
# a comment, will be ignored
DATABASE_ADDRESS=localhost:6379
SERVER_PORT=1337
そして、justfile に次の内容が含まれている場合:
set dotenv-load
serve:
@echo "Starting server with database $DATABASE_ADDRESS on port $SERVER_PORT…"
./server --database $DATABASE_ADDRESS --port $SERVER_PORT
just serve を実行すると、次のように出力されます:
$ just serve
Starting server with database localhost:6379 on port 1337…
./server --database $DATABASE_ADDRESS --port $SERVER_PORT
親モジュールで読み込まれた環境ファイルの変数は、サブモジュールに継承されます。
環境ファイルはサブモジュールでも読み込まれ1.49.0、親モジュールの環境ファイルで定義された変数を上書きすることがあります。
エクスポート
export 設定を有効にすると、すべての just 変数が環境変数としてエクスポートされます。デフォルトは false です。
set export
a := "hello"
@foo b:
echo $a
echo $b
$ just foo goodbye
hello
goodbye
レシピ間で環境変数を共有する
各レシピの各行は新しいシェルで実行されるため、レシピ間で環境変数を共有することはできません。
Python 仮想環境の使用
Python の venv のように、動作させるために環境変数の読み込みが必要なツールもあり、just での使用が難しい場合があります。回避策として、仮想環境のバイナリを直接実行できます。
venv:
[ -d foo ] || python3 -m venv foo
run: venv
./foo/bin/python3 main.py
作業ディレクトリ
デフォルトでは、レシピは justfile が含まれるディレクトリを作業ディレクトリとして実行されます。
[no-cd] 属性を使うと、just を呼び出したディレクトリを作業ディレクトリとしてレシピを実行できます。
@foo:
pwd
[no-cd]
@bar:
pwd
$ cd subdir
$ just foo
/
$ just bar
/subdir
これは dotenv ファイルの検索や、バッククォートおよび shell() の呼び出し時の作業ディレクトリには影響しないことに注意してください。
set no-cd1.51.0 を使うと、現在のモジュール内のすべてのレシピで、この動作をデフォルトにできます。
set no-cd と set working-directory は、[no-cd] 属性および [working-directory] 属性でレシピごとに上書きできます。
すべてのレシピの作業ディレクトリは、set working-directory := '…' で上書きできます。
set working-directory := 'bar'
@foo:
pwd
$ pwd
/home/bob
$ just foo
/home/bob/bar
特定のレシピの作業ディレクトリは、working-directory 属性1.38.0で上書きできます。
[working-directory: 'bar']
@foo:
pwd
$ pwd
/home/bob
$ just foo
/home/bob/bar
working-directory 設定または working-directory 属性の引数には、値が絶対パスまたは相対パスとなる式1.51.0を指定できます。相対パスの場合は、デフォルトの作業ディレクトリを基準に解釈されます。
レシピ内での作業ディレクトリの変更
レシピの各行は新しいシェルで実行されるため、ある行で作業ディレクトリを変更しても、後続の行には反映されません。
foo:
pwd # This `pwd` will print the same directory…
cd bar
pwd # …as this `pwd`!
これを回避する方法はいくつかあります。1つは、実行するコマンドと同じ行で cd を呼び出す方法です。
foo:
cd bar && pwd
もう1つは、シバンレシピを使う方法です。シバンレシピの本文はスクリプトとして抽出されて実行されるため、全体が1つのシェルインスタンスで実行されます。そのため、シェルスクリプトと同様に、ある行での cd が後続の行にも反映されます。
foo:
#!/usr/bin/env bash
set -euxo pipefail
cd bar
pwd
作業ディレクトリの変更を無効にする
just は通常、justfile が含まれるディレクトリを現在のディレクトリとしてレシピを実行します。これは [no-cd] 属性1.9.0を使って無効にできます。これにより、呼び出し元のディレクトリを基準としたパスを使うレシピや、現在のディレクトリを対象に処理するレシピを作成できます。
たとえば、次の commit レシピは、
[no-cd]
commit file:
git add {{file}}
git commit
[no-cd] によって commit の実行時に just が現在のディレクトリを変更しないため、現在のディレクトリを基準としたパスを使って実行できます。
これは dotenv ファイルの検索や、バッククォートおよび shell() の呼び出し時の作業ディレクトリには影響しないことに注意してください。
構成
インポート
import ステートメントを使うと、別の justfile の内容を 1 つの justfile に含められます。
次の justfile がある場合:
import 'foo/bar.just'
a: b
@echo A
そして、foo/bar.just に次のテキストがある場合:
b:
@echo B
foo/bar.just が justfile に含まれ、レシピ b が定義されます:
$ just b
B
$ just a
B
A
import のパスには絶対パス、またはそのパスを含む justfile の場所からの相対パスを指定できます。インポートパスの先頭にある ~/ は、現在のユーザーのホームディレクトリに置き換えられます。
justfile では順序が関係ないため、インポートされたファイルから、import ステートメントの後に定義されている変数やレシピを参照できます。
インポートされたファイル自体に import を含めることもでき、再帰的に処理されます。
allow-duplicate-recipes と allow-duplicate-variables を指定すると、重複するレシピと変数がそれぞれ互いを上書きするようになり、エラーは発生しません。
モジュール内では、後に定義されたものが先に定義されたものを上書きします:
set allow-duplicate-recipes
foo:
foo:
echo 'yes'
import が関係する場合、事情は残念ながらかなり複雑になり、説明も難しくなります。
階層の浅い定義は常に深い定義を上書きするため、トップレベルのレシピはインポート内のレシピを上書きし、インポート内のレシピは、そのレシピをさらにインポートしているインポート内のレシピを上書きします。
重複する定義が 2 つインポートされ、同じ階層にある場合は、後のインポートの定義ではなく、先のインポートの定義が優先されます。
これは、just がインポートの処理にスタックを使用し、ソース内の順序でインポートをスタックに積み、常にスタックの一番上から処理するためです。そのため、コンパイラーは実際には先のインポートを後に処理します。
これは明らかにバグですが、just には非常に強力な後方互換性の保証があり、誰かの justfile を壊さないよう細心の注意を払っています。修正できるかどうかについては、議論のために issue #2540 を参照してください。
import キーワードの後に ? を付けると、インポートを任意にできます:
import? 'foo/bar.just'
同じソースファイルを複数回インポートしてもエラーにはなりません1.37.0</sup。これにより、たとえば foo.just と bar.just の両方が、共有レシピを含む 3 つ目の justfile(たとえば baz.just)をインポートしていても、baz.just の重複インポートはエラーになりません:
# justfile
import 'foo.just'
import 'bar.just'
# foo.just
import 'baz.just'
foo: baz
# bar.just
import 'baz.just'
bar: baz
# baz
baz:
モジュール
justfileでは、mod文を使ってモジュールを宣言できます1.19.0。
mod文はjust1.31.0で安定化されました。
次のjustfileがあるとします。
mod bar
a:
@echo A
そして、bar.justに次の内容があるとします。
b:
@echo B
bar.justはサブモジュールとしてjustfileに読み込まれます。あるサブモジュールで定義されたレシピ、エイリアス、変数は、別のサブモジュールからは使用できません。また、各モジュールはそれぞれの設定を使用します。
サブモジュール内のレシピは、サブコマンドとして呼び出せます。
$ just bar b
B
または、パス構文を使って呼び出せます。
$ just bar::b
B
モジュール名がfooの場合、justはfoo.just、foo/mod.just、foo/justfile、foo/.justfileの順にモジュールファイルを検索します。後ろの2つの場合、モジュールファイルの大文字と小文字は任意です。
モジュール文は、次の形式で記述できます。
mod foo 'PATH'
これにより、通常の場所ではなく、PATHからモジュールのソースファイルを読み込みます。PATHの先頭にある~/は、現在のユーザーのホームディレクトリに置き換えられます。PATHには、モジュールのソースファイル自体を指定することも、mod.just、justfile、.justfileという名前のモジュールソースファイルを含むディレクトリを指定することもできます。後ろの2つの場合、モジュールファイルの大文字と小文字は任意です。
環境ファイルは、各モジュールに関連する設定に従って読み込まれます。親モジュールの環境変数は、子モジュールから参照できます。
[no-cd]属性のないサブモジュール内のレシピは、作業ディレクトリをサブモジュールのソースファイルがあるディレクトリに設定して実行されます。
justfile()とjustfile_directory()は、サブモジュールのレシピから呼び出された場合でも、常にルートのjustfileのパスと、そのファイルがあるディレクトリを返します。
modキーワードの後に?を付けると、モジュールをオプションにできます。
mod? foo
オプションのモジュールのソースファイルが見つからなくても、エラーにはなりません。レシピまたはエイリアスが、直接または間接的に、ソースファイルのないオプションのモジュールに依存している場合、そのレシピまたはエイリアスは無効になります。無効なレシピまたはエイリアスを呼び出そうとするとエラーになりますが、ほかの無効でないレシピは引き続き実行できます。1.52.0
ソースファイルのないオプションのモジュールは競合しないため、同じ名前でソースファイルのパスが異なるmod文を複数記述できます。ただし、ソースファイルが存在するのは最大1つまでです。
mod? foo 'bar.just'
mod? foo 'baz.just'
モジュールにはドキュメントコメントを付けることができ、--listの出力に表示されます1.30.0。
# foo is a great module!
mod foo
$ just --list
Available recipes:
foo ... # foo is a great module!
モジュールには、たとえばほかのモジュールの変数を参照できないなど、まだ多くの機能が不足しています。詳しくは、モジュール改善の追跡課題をご覧ください。
別のディレクトリにあるjustfileの呼び出し
justに渡された最初の引数に/が含まれている場合、次の処理が行われます。
-
引数を最後の
/で分割します。 -
最後の
/より前の部分をディレクトリとして扱います。justは、現在のディレクトリではなく、そのディレクトリからjustfileの検索を開始します。 -
最後のスラッシュより後の部分を通常の引数として扱います。空の場合は無視されます。
少し奇妙に思えるかもしれませんが、サブディレクトリにあるjustfileでコマンドを実行したい場合に便利です。
たとえば、fooというサブディレクトリがあり、その中にデフォルトレシピでもあるbuildレシピを含むjustfileがあるディレクトリにいる場合、次の指定はすべて同じです。
$ (cd foo && just build)
$ just foo/build
$ just foo/
最初のレシピより後に指定されたレシピは、同じjustfile内で検索されます。たとえば、次の指定はどちらも同じです。
$ just foo/a b
$ (cd foo && just a b)
どちらもfoo/justfile内のレシピaとbを呼び出します。
親の justfile へのフォールバック
レシピが justfile 内に見つからず、fallback 設定が指定されている場合、
just は親ディレクトリから上の階層に向かって justfile を探し、ルートディレクトリに達するまで検索します。fallback 設定が false または未設定の justfile に達すると、just は検索を終了します。
例として、現在のディレクトリに次の justfile があるとします。
set fallback
foo:
echo foo
親ディレクトリには、次の justfile があるとします。
bar:
echo bar
$ just bar
Trying ../justfile
echo bar
bar
グローバルフォールバック Justfile
グローバルフォールバックの justfile は、--global-fallback-justfile <PATH> を使うか、
環境変数 JUST_GLOBAL_FALLBACK_JUSTFILE を設定して指定できます。
justfile が見つからない場合、またはフォールバックの検索に失敗した場合は、
代わりにグローバルフォールバックの justfile が使用されます。作業ディレクトリには、
.git などのディレクトリの存在から判断される現在のプロジェクトのルートが設定されます。
そのようなディレクトリが見つからない場合は、呼び出し元のディレクトリが設定されます。
グローバルフォールバックの justfile 自体で set fallback を使用することもできます。
--justfile、--global-justfile、または --working-directory が渡された場合、
グローバルフォールバックの justfile は無視されます。
リモート Justfile
重複させずに多くの justfile で mod または import のソースファイルをインクルードするには、
省略可能な mod または import と、モジュールのソースを取得するレシピを使えます。
import? 'foo.just'
fetch:
curl https://raw.githubusercontent.com/casey/just/master/justfile > foo.just
上記の justfile では、just fetch を実行すると、
foo.just のレシピが使用できるようになります。
グローバルおよびユーザーの justfile
どこからでも使えるレシピを用意したい場合は、いくつかの方法があります。
グローバル Justfile
just --global-justfile(短縮形は just -g)は、次のパスを順番に検索して
justfile を探します。
$XDG_CONFIG_HOME/just/justfile$HOME/.config/just/justfile$HOME/justfile$HOME/.justfile
複数のプロジェクトで使うレシピをグローバル justfile に入れておけば、 どのディレクトリからでも簡単に実行できます。
ユーザー justfile のヒント
次のワークフローを採用することもできます。ここでは ~/.user.justfile に
justfile を作成したことを前提としていますが、システム上の任意の便利なパスに
この justfile を置くこともできます。
レシピのエイリアス
~/.user.justfile のレシピを名前で呼び出したい場合、また各レシピのエイリアスを
作成しても構わない場合は、シェルの初期化スクリプトに次を追加します。
for recipe in `just --justfile ~/.user.justfile --summary`; do
alias $recipe="just --justfile ~/.user.justfile --working-directory . $recipe"
done
これで、~/.user.justfile に foo というレシピがあれば、コマンドラインで
foo と入力するだけで実行できます。
このようなレシピのエイリアスを作成できると気づくまで、ずいぶん時間がかかりました。
気づくのが遅くなりましたが、この justfile 技術の大きな進歩を皆さんにお届けできて
とてもうれしく思います。
転送エイリアス
各レシピのエイリアスを作成したくない場合は、エイリアスを1つだけ作成できます。
alias .j='just --justfile ~/.user.justfile --working-directory .'
これで、~/.user.justfile に foo というレシピがあれば、コマンドラインで
.j foo と入力するだけで実行できます。
実際にこの機能を使う人はいないと思いますが、一応あります。
¯\_(ツ)_/¯
カスタマイズ
上記のエイリアスには、オプションを追加してカスタマイズできます。たとえば、
justfile のレシピを現在のディレクトリではなくホームディレクトリで実行したい場合は、
次のようにします。
alias .j='just --justfile ~/.user.justfile --working-directory ~'
Markdown の justfile
--justfile の引数が .md で終わる場合、just はインデントされていない
just のフェンス付きコードブロックの内容を抽出し、一時ディレクトリ内の
justfile に書き込みます1.53.0。
# Project
Build the project:
```just
build:
echo Building…
```
$ just --justfile README.md build
echo Building…
Building…
Just スクリプト
justfile の先頭にシバン行を追加して実行可能にすると、just をスクリプトのインタープリターとして使用できます。
$ cat > script <<EOF
#!/usr/bin/env just --justfile
foo:
echo foo
EOF
$ chmod +x script
$ ./script foo
echo foo
foo
シバン付きのスクリプトが実行されると、システムはスクリプトへのパスをシバン内のコマンドの引数として渡します。そのため、シバンが #!/usr/bin/env just --justfile の場合、コマンドは /usr/bin/env just --justfile PATH_TO_SCRIPT になります。
上記のシバンを使うと、just は作業ディレクトリをスクリプトの場所に変更します。作業ディレクトリを変更したくない場合は、#!/usr/bin/env just --working-directory . --justfile を使用してください。
注意:シバン行の分割方法は、オペレーティングシステムによって一貫していません。これまでの例は macOS でのみテストされています。Linux では、env に -S フラグを渡す必要がある場合があります。
#!/usr/bin/env -S just --justfile
default:
echo foo
justfile を隠す
just は、justfile および .justfile という名前の justfile を検索するため、これらを使って justfile を隠すことができます。
コマンドライン
利用可能なレシピの一覧表示
just --list を使うと、レシピをアルファベット順に一覧表示できます。
$ just --list
Available recipes:
build
test
deploy
lint
submodules 内のレシピは、just --list PATH で一覧表示できます。PATH は、スペースまたは :: で区切ったモジュールパスです。
$ cat justfile
mod foo
$ cat foo.just
mod bar
$ cat bar.just
baz:
$ just --list foo bar
Available recipes:
baz
$ just --list foo::bar
Available recipes:
baz
just --summary を使うと、より簡潔に表示できます。
$ just --summary
build test deploy lint
--unsorted を渡すと、justfile に記載されている順序でレシピが表示されます。
test:
echo 'Testing!'
build:
echo 'Building!'
$ just --list --unsorted
Available recipes:
test
build
$ just --summary --unsorted
test build
justfile のレシピをデフォルトで一覧表示するには、default-list1.52.0 を設定します。
set default-list := true
この設定はモジュールごとに適用されるため、default-list が有効な状態でモジュールパスを指定して実行すると、そのモジュールのレシピが一覧表示されます。
環境変数 JUST_DEFAULT_LIST=true を設定するか、--default-list1.52.0 を渡すことで、レシピの一覧表示をデフォルトにすることもできます。
--list-heading を使うと、見出しテキストをカスタマイズできます。
$ just --list --list-heading $'Cool stuff…\n'
Cool stuff…
test
build
また、--list-prefix を使うと、インデントをカスタマイズできます。
$ just --list --list-prefix ····
Available recipes:
····test
····build
--list-heading の引数は、見出しとその後に続く改行の両方を置き換えるため、空でない場合は改行を含める必要があります。この仕様により、空文字列を渡して見出し行を完全に非表示にできます。
$ just --list --list-heading ''
test
build
複数のレシピを実行する
コマンドラインで複数のレシピを一度に実行できます。
build:
make web
serve:
python3 -m http.server -d out 8000
$ just build serve
make web
python3 -m http.server -d out 8000
パラメーターを持つレシピは、他のレシピ名と一致する場合でも引数を消費することに注意してください。
build project:
make {{project}}
serve:
python3 -m http.server -d out 8000
$ just build serve
make: *** No rule to make target `serve'. Stop.
--one フラグを使うと、コマンドラインでの呼び出しを単一のレシピに制限できます。
$ just --one build serve
error: Expected 1 command-line recipe invocation but found 2.
コマンドラインから変数を設定する
変数はコマンドラインから上書きできます。
os := "linux"
test: build
./test --test {{os}}
build:
./build {{os}}
$ just
./build linux
./test --test linux
レシピの前に、NAME=VALUE 形式の引数をいくつでも渡せます。
$ just os=plan9
./build plan9
./test --test plan9
または、--set フラグを使用できます。
$ just --set os bsd
./build bsd
./test --test bsd
サブモジュール内の変数は、変数へのパスを :: で区切って指定することで上書きできます。foo という名前のサブモジュール内にある bar という変数は、foo::bar=VALUE または --set foo::bar VALUE で上書きできます。
コマンドラインオプション
just は、レシピや変数の一覧表示、ダンプ、デバッグに役立つさまざまなコマンドラインオプションをサポートしています。
$ just --list
Available recipes:
js
perl
polyglot
python
ruby
$ just --show perl
perl:
#!/usr/bin/env perl
print "Larry Wall says Hi!\n";
$ just --show polyglot
polyglot: python js perl sh ruby
環境変数でコマンドラインオプションを設定する
一部のコマンドラインオプションは、環境変数で設定できます。
たとえば、不安定な機能は --unstable フラグで有効にできます。
$ just --unstable
または、環境変数 JUST_UNSTABLE を設定して有効にできます。
$ export JUST_UNSTABLE=1
$ just
環境変数は子プロセスに引き継がれるため、環境変数で設定したコマンドラインオプションは just の再帰的な呼び出しにも引き継がれます。一方、引数で設定したコマンドラインオプションは引き継がれません。
環境変数で設定できるオプションについては、just --help を参照してください。
インタラクティブな選択メニューで実行するレシピを選択する
--choose サブコマンドを使うと、just は実行するレシピを選択するための選択メニューを呼び出します。選択メニューは、標準入力からレシピ名を含む行を読み取り、そのうちの1つ以上をスペース区切りで標準出力に出力します。
現在、--choose では引数が必要なレシピを実行する方法がないため、そうしたレシピは選択メニューに渡されません。プライベートレシピとエイリアスもスキップされます。
選択メニューは --chooser フラグで変更できます。--chooser が指定されていない場合、just はまず $JUST_CHOOSER が設定されているかを確認します。設定されていない場合、選択メニューには一般的なファジーファインダーである fzf が使用されます。
選択メニューには引数を含めることができます。たとえば、fzf --exact のように指定できます。
選択メニューはレシピの行と同じ方法で呼び出されます。たとえば、選択メニューが fzf の場合は、sh -cu 'fzf' で呼び出されます。シェルやシェル引数が変更されている場合、選択メニューの呼び出しにもその変更が反映されます。
just で選択メニューを使ったレシピ選択をデフォルトにするには、次のようにデフォルトレシピを設定します。
default:
@just --choose
レシピの実行前に確認を必須にする
just は通常、エラーが発生しない限り、すべてのレシピを実行します。[confirm] 属性1.17.0を使うと、レシピの実行前にターミナルで確認を求めることができます。just に --yes を渡すとこの動作を上書きし、この属性が付いたレシピを自動的に承認します。
確認が必要なレシピに依存するレシピは、依存先のレシピが承認されなかった場合、実行されません。また、確認が必要なレシピの後に渡されたレシピも実行されません。
[confirm]
delete-all:
rm -rf *
カスタム確認プロンプト
デフォルトの確認プロンプトは、[confirm(PROMPT)]1.23.0で変更できます。
[confirm("Are you sure you want to delete everything?")]
delete-everything:
rm -rf *
確認プロンプトには式1.49.0も指定でき、代入やレシピ引数を参照できます。
[confirm("Deploy to " + env + "?")]
deploy env:
echo 'Deploying to {{env}}...'
タイムスタンプ
just は各レシピコマンドの前にタイムスタンプを出力できます。
recipe:
echo one
sleep 2
echo two
$ just --timestamp recipe
[07:28:46] echo one
one
[07:28:46] sleep 2
[07:28:48] echo two
two
デフォルトでは、タイムスタンプは HH:MM:SS 形式で出力されます。--timestamp-format で形式を変更できます。
$ just --timestamp recipe --timestamp-format '%H:%M:%S%.3f %Z'
[07:32:11:.349 UTC] echo one
one
[07:32:11:.350 UTC] sleep 2
[07:32:13:.352 UTC] echo two
two
--timestamp-format の引数には、strftime 形式のフォーマット文字列を指定します。詳しくは
chrono ライブラリのドキュメント
を参照してください。
[timestamp] 属性1.58.0を使うと、特定のレシピでタイムスタンプを有効にできます。
[timestamp]
foo:
echo hello
$ just foo
[07:28:46] echo hello
hello
フォーマット文字列も指定できます。
[timestamp('%H:%M:%S%.3f')]
foo:
echo hello
$ just foo
[07:28:46.487] echo hello
hello
シグナル処理
シグナルは、特定の動作を引き起こすために実行中のプログラムに送信されるメッセージです。たとえば、ctrl-c を押すと、ターミナルのフォアグラウンドプロセスグループに属するすべてのプロセスに SIGINT が送信されます。
just はシグナルを受け取ると終了しようとしますが、実行中の子プロセスを残さないようにも努めます。この2つの目標は、ある程度相反します。
just が子プロセスを残して終了した場合、ユーザーは ps aux | grep で子プロセスを探して手動で kill するしかありません。これは手間のかかる作業です。
致命的なシグナル
SIGHUP、SIGINT、SIGQUIT は、それぞれユーザーがターミナルを閉じたとき、ctrl-c を押したとき、ctrl-\ を押したときに生成され、フォアグラウンドプロセスグループに属するすべてのプロセスに送信されます。
SIGTERM は kill コマンドがデフォルトで送信するシグナルで、指定された対象プロセスのみに送信されます。
子プロセスが実行されていない場合、just は上記のいずれかのシグナルを受け取ると直ちに終了します。
子プロセスが実行中の場合、just は子プロセスを残さないよう、終了するまで待機します。
また、SIGTERM を受け取ると、just は実行中の子プロセスにも SIGTERM を転送します1.41.0</sup。他の致命的なシグナルとは異なり、SIGTERM は just のみに送信された可能性が高いためです。
just が致命的なシグナルを受け取った後に子プロセスが正常終了するかどうかにかかわらず、just は実行を停止します。
実行の継続
[continue]1.54.0属性を使うと、実行中の子プロセスが正常に終了する限り、致命的なシグナルを受け取ってもjustの実行を継続できます。
引数を指定しない場合、[continue]はSIGINT(ctrl-c)を処理し、SIGQUIT(ctrl-\)を使って実行を停止できるようにします。
引数を指定する場合は、"SIGHUP"、"SIGINT"、"SIGQUIT"のように、処理するシグナルを1つ以上明示的に指定できます。
この例では、main.pyがSIGINTを捕捉して正常に終了すると、cleanupが引き続き実行され、justも正常に終了します。
[continue]
test: && cleanup
python3 main.py
cleanup:
echo cleanup
SIGINFO
SIGINFOは、macOSを含むBSD系のオペレーティングシステムで、ユーザーがctrl-tを入力すると、フォアグラウンドプロセスグループ内のすべてのプロセスに送信されます。ただし、Linuxでは送信されません。
justは、すべての子プロセスのIDとコマンド1.41.0の一覧を表示して応答します。
Windows
Windowsでは、ユーザーがctrl-cを入力すると、justはSIGINTを受け取った場合と同じように動作します。それ以外のシグナルはサポートされていません。
シェル補完スクリプト
Bash、Elvish、Fish、Nushell、PowerShell、Zsh用のシェル補完スクリプトは、リリースアーカイブで入手できます。
justバイナリは、just --completions SHELLを使って、同じ補完スクリプトを実行時に生成することもできます。
$ just --completions bash > just
Bash
推奨される方法は、bash-completionsパッケージを使って補完スクリプトを遅延読み込みすることです。
mkdir -p ~/.local/share/bash-completion/completions
just --completions bash > ~/.local/share/bash-completion/completions/just
bash-completionsがインストールされていない場合は、.bashrcで補完スクリプトを読み込めます。
source <(just --completions bash)
alias j=justのようなエイリアスを使う場合、遅延読み込み時には補完スクリプトもjという名前で保存してください。
just --completions bash > ~/.local/share/bash-completion/completions/j
遅延読み込みをしない場合は、.bashrcで補完スクリプトを読み込んだ後に、次の行を追加してください。
complete -F _clap_complete_just -o bashdefault -o default j
Elvish
rc.elvに次の内容を記述します。
set edit:completion:arg-completer[just] = { |@args|
eval (just --completions elvish | slurp)
set @result = (edit:completion:arg-completer[just] $@args)
put $@result
}
Fish
遅延読み込みできるように、補完スクリプトを補完ディレクトリに保存します。
mkdir -p ~/.config/fish/completions
just --completions fish > ~/.config/fish/completions/just.fish
Nushell
まず、補完スクリプトを保存します。
just --completions nushell | save -f ($nu.default-config-dir | path join just.nu)
次に、config.nuに次の内容を記述します。
source just.nu
PowerShell
PowerShellの$PROFILEに次の内容を記述します。
just --completions powershell | Out-String | Invoke-Expression
Zsh
まず、補完スクリプトを保存します。
mkdir -p ~/.zsh/completions
just --completions zsh > ~/.zsh/completions/_just
次に、.zshrcに次の内容を記述します。
fpath=(~/.zsh/completions $fpath)
autoload -U compinit
compinit
manページ
justはjust --manで独自のmanページを出力できます。manページは、由緒あるマークアップ言語であり、Unixにおける最初期の実用的なアプリケーションの1つでもあるroffで記述されています。groffがインストールされている場合は、just --man | groff -mandoc -Tascii | lessでmanページを表示できます。
justfile のフォーマットとダンプ
各 justfile には、空白と改行に関する標準的なフォーマットがあります。
--fmt フラグを使うと、現在の justfile を標準フォーマットのものに上書きできます。
$ cat justfile
# A lot of blank lines
some-recipe:
echo "foo"
$ just --fmt
$ cat justfile
# A lot of blank lines
some-recipe:
echo "foo"
--justfile - を指定して justfile を標準入力から読み込む場合、または Markdown ファイルから抽出する場合、--fmt はフォーマット済みの justfile を標準出力に出力します。
フォーマットは後方互換性が保証されておらず、随時変更される可能性があることに注意してください。
レシピの本体は、デフォルトでは 4 つのスペースでインデントされます。これは、--indentation コマンドラインオプション、JUST_INDENTATION 環境変数、または indentation 設定で変更できます。
set indentation := " "
just --fmt --check を実行すると、チェックモードで --fmt が実行されます。justfile を上書きする代わりに、正しくフォーマットされていれば終了コード 0 で終了し、正しくフォーマットされていなければ差分を出力して終了コード 1 で終了します。
--dump コマンドを使うと、フォーマット済みの justfile を標準出力に出力できます。
$ just --dump > formatted-justfile
--dump コマンドは --dump-format json と併用して、justfile の JSON 表現を出力できます。
キャッシュされたレシピ
just は、呼び出しに一致するエントリーがキャッシュ内に見つかった場合、[cache] 属性1.54.0が付いたレシピの実行をスキップします。[cache] 属性はスクリプトレシピでのみ使用でき、現在は不安定な機能です。
たとえば、image.jpg が存在し、前回の実行以降 image.png の内容と convert -version の出力に変更がなければ、このレシピはスキップされます。
set unstable
[script]
[cache(inputs = "image.png", outputs = "image.jpg", extra = `convert -version`)]
convert:
convert image.png image.jpg
慎重に設計され、使いやすいことが期待される just の他の多くの機能とは異なり、キャッシュされたレシピには本質的な脆弱性があります。キャッシュに依存する前に、その制約を理解することが重要です。以下の注意事項も含め、このセクションをよくお読みください。
親切な注意事項
just はキャッシュされたレシピを問題なくスキップしますが、それが安全であること、また、そもそもキャッシュが意味をなすように、レシピの呼び出しに関する十分な情報がキャッシュキーに含まれていることを確認する責任は利用者にあります。
特に、レシピが実行される状況に関する多くの詳細は、キャッシュキーに含まれていません。
これには、時刻、入力ファイル、出力ファイル、システムバイナリ、オペレーティングシステムのバージョン、データベース、ネットワーク上のシステム、DNS、そしてコンピュータープログラムの実行に影響を与えうる無数の要素が含まれます。
just が採用しているような粗雑なヒューリスティックに基づいて実行をスキップしようとすることには、長くいわくつきの歴史があります。しかし、これは紛れもなく便利で強力なツールであり、役立てていただけることを願って提供されています。
実装
キャッシュは、justfile と同じ場所にある .justcache というディレクトリに保存されます。バージョン管理システムにコミットしないでください。このディレクトリには、シリアライズされたキャッシュキーの JSON オブジェクトの BLAKE3 ハッシュを HASH とする、HASH.json という名前のキャッシュエントリーが格納されます。
キャッシュキーオブジェクトのキーは次のとおりです。
body:評価済みのレシピ本文environment:環境変数名と値のマップexecutor:スクリプトインタープリターまたはシバンextension:スクリプトファイルの拡張子extra:ユーザー指定の値inputs:ファイルパスと内容のハッシュのマップpositional:位置引数recipe:呼び出されたレシピへの、::で区切られたモジュールパスworking_directory:現在の作業ディレクトリ
extra と inputs 以外のすべてのキーは、自動的に設定されます。
呼び出されたレシピのキャッシュキーオブジェクトは、just -vv を使って標準エラーに出力できます。
environment に含める環境変数は、[cache(environment = EXPRESSION])1.59.0 で制御できます。
extra の値は、レシピ引数をスコープ内で評価する任意の式である [cache(extra = EXPRESSION)] を使って指定できます。extra の値が変わると、キャッシュミスが発生します。
just はキャッシュされたレシピを実行する前にキャッシュキーを作成してハッシュ化し、対応するキャッシュエントリーを探します。
キャッシュエントリーが空でなければ、呼び出しをスキップします。
キャッシュエントリーが存在しないか空の場合は、呼び出しを実行し、{} をキャッシュエントリーに書き込みます。
キャッシュエントリーにはファイルロックがかけられるため、複数の just プロセスによるキャッシュ済みレシピの同時実行は安全です。2 つのプロセスが同じキャッシュキーのレシピ呼び出しを実行すると、最初のプロセスがロックを取得してレシピを実行し、キャッシュエントリーに書き込んでからロックを解放します。2 番目のプロセスは、最初のプロセスがロックを解放するまで待機し、エントリーが空でないことを確認して、呼び出しをスキップします。
--no-cache フラグを指定すると、キャッシュを完全にバイパスできます。
キャッシュのクリア
レシピキャッシュは、justfile と同じ場所にある .justcache というディレクトリに保存されます。このディレクトリを削除すると、キャッシュがクリアされます。
just --clean を使ってキャッシュをクリアすることもでき、キャッシュエントリーを選択してクリアできます。
# clear all cache entries
just --clean
# clear cache entries for recipe `foo`
just --clean foo
# clear cache entries for recipe `baz` in submodule `bar`
just --clean bar baz
# clear cache entries for recipes in submodule module `bar`
just --clean bar
# clear cache entries for recipes in submodule module `bar::bob`
just --clean bar bob
# '::'-separated paths may also be used
just --clean bar::bob
環境変数の追加と削除
デフォルトでは、justfile 内でエクスポートまたはエクスポート解除された環境変数はキャッシュキーに含まれますが、justfile の外部でエクスポートされて just に継承された環境変数は含まれません。
[cache(environment = EXPRESSION])1.59.0 を使って、キャッシュキーに含める環境変数を追加または削除できます。
この例では、環境変数 foo はキャッシュキーに含まれませんが、PATH は含まれます。
set unstable
set lists
export foo := 'bar'
[script]
[cache(environment = ['PATH'])]
build:
cc lib.c main.c -o main
入力ファイル
[cache(inputs = FILES)] を使って入力ファイルを指定できます。FILES は、レシピ引数をスコープ内で評価する式で、評価結果の要素はパスです。パスには絶対パス、またはレシピの作業ディレクトリからの相対パスを指定できます。
各入力ファイルは BLAKE3 でハッシュ化され、パスとハッシュのマップを含む inputs キャッシュキーに追加されます。
入力ファイルの内容が変わるとキャッシュキーが変わり、次の呼び出しでキャッシュミスが発生して再実行されます。
入力ファイルが見つからない場合や、ディレクトリへのパスを指定した場合はエラーになります。
この例では、lib.c または main.c が変更されると、build レシピが再実行されます。
set unstable
set lists
[script]
[cache(inputs = ["lib.c", "main.c"])]
build:
cc lib.c main.c -o main
出力ファイル
出力ファイルは、レシピの引数がスコープ内にある状態で評価され、評価結果の要素がパスとなる式 FILES を指定して、[cache(outputs = FILES)] で指定できます。パスは絶対パスでも、レシピの作業ディレクトリからの相対パスでもかまいません。
出力はキャッシュキーに含まれません。
呼び出しをスキップするには、すべての出力ファイルが存在している必要があります。また、呼び出しが正常に実行された後に出力ファイルが存在しない場合は、エラーになります。
この例では、main が存在しない場合は build が再実行され、main を生成せずに実行するとエラーになります。
set unstable
set lists
[script]
[cache(inputs = ["lib.c", "main.c"], outputs = "main")]
build:
cc lib.c main.c -o main
clean:
rm -f main
これにより、clean によって main が削除された場合、build は必ず再実行されます。
リファレンス
属性
レシピ、mod 文、エイリアスには、動作を変更する属性を付与できます。
| 名前 | 種類 | 説明 |
|---|---|---|
[arg(ARG, help="HELP")]1.46.0 | レシピ | 使用方法のメッセージで、ARG のヘルプ文字列 HELP を出力します。定数式を指定できます1.55.0。 |
[arg(ARG, long="LONG")]1.46.0 | レシピ | 引数 ARG の値を --LONG オプションとして渡す必要があります。パラメーターが可変個の場合、このオプションは繰り返し指定できます1.55.0master。 |
[arg(ARG, max="MAX")]1.56.0 | レシピ | 引数 ARG に渡す値を最大 MAX 個に制限します。multiple または可変個のパラメーターが必要です。 |
[arg(ARG, min="MIN")]1.56.0 | レシピ | 引数 ARG に少なくとも MIN 個の値を渡す必要があります。multiple または可変個のパラメーターが必要です。 |
[arg(ARG, pattern="PATTERN")]1.45.0 | レシピ | 引数 ARG の値が正規表現 PATTERN に一致する必要があります。定数式を指定できます1.55.0。 |
[arg(ARG, short="S")]1.46.0 | レシピ | 引数 ARG の値を短縮形 -S オプションとして渡す必要があります。パラメーターが可変個の場合、このオプションは繰り返し指定できます1.55.0。 |
[arg(ARG, value=VALUE)]1.46.0 | レシピ | オプション ARG を値を取らないフラグにします。 |
[cache]1.54.0 | レシピ | キャッシュに一致するエントリーがある場合、レシピの実行をスキップします。詳細はキャッシュされたレシピを参照してください。現在は不安定な機能です。 |
[confirm(PROMPT)]1.23.0 | レシピ | カスタムプロンプトを表示し、レシピの実行前に確認を求めます。 |
[confirm]1.17.0 | レシピ | レシピの実行前に確認を求めます。 |
[continue(SIGNALS)]1.54.0 | レシピ | コマンドが SIGNALS のいずれかによって中断され、正常終了した場合、通常どおり実行を続行します。既定値は SIGINT です。 |
[default]1.43.0 | レシピ | このレシピをモジュールの既定のレシピとして使用します。 |
[doc(DOC)]1.27.0 | モジュール、レシピ | レシピまたはモジュールのドキュメントコメントを DOC に設定します。定数式を指定できます1.56.0。 |
[dragonfly]1.47.0 | 任意1.56.0 | DragonFly BSD で項目を有効にします。 |
[env(NAME, VALUE)] 1.47.0 | レシピ | レシピの環境変数 NAME を VALUE に設定します。NAME と VALUE には式を指定できます1.51.0。 |
[extension(EXT)]1.32.0 | レシピ | シェバン付きレシピスクリプトのファイル拡張子を EXT に設定します。ピリオドを付ける場合は EXT に含めてください。 |
[exit-message]1.39.0 | レシピ | set no-exit-message の設定に関係なく、レシピが失敗した場合にエラーメッセージを出力します。 |
[freebsd]1.47.0 | 任意1.56.0 | FreeBSD で項目を有効にします。 |
[group(NAME)]1.27.0 | モジュール、レシピ | レシピまたはモジュールをグループ NAME に追加します。 |
[android]1.50.0 | 任意1.56.0 | Android で項目を有効にします。 |
[linux]1.8.0 | 任意1.56.0 | Linux で項目を有効にします。 |
[macos]1.8.0 | 任意1.56.0 | macOS で項目を有効にします。 |
[metadata(METADATA)]1.42.0 | レシピ | METADATA をレシピに添付します。 |
[netbsd]1.47.0 | 任意1.56.0 | NetBSD で項目を有効にします。 |
[no-cd]1.9.0 | レシピ | レシピを実行する前にディレクトリを変更しません。 |
[no-exit-message]1.7.0 | レシピ | レシピが失敗してもエラーメッセージを出力しません。 |
[no-quiet]1.23.0 | レシピ | グローバルな静音レシピの設定を上書きし、常にレシピを表示します。 |
[openbsd]1.38.0 | 任意1.56.0 | OpenBSD で項目を有効にします。 |
[parallel]1.42.0 | レシピ | このレシピの依存関係を並列実行します。 |
[positional-arguments]1.29.0 | レシピ | このレシピで位置引数を有効にします。 |
[private]1.10.0 | エイリアス、レシピ | レシピ、エイリアス、または変数をプライベートにします。プライベートレシピを参照してください。 |
[script(COMMAND)]1.32.0 | レシピ | COMMAND で解釈されるスクリプトとしてレシピを実行します。詳細はスクリプトレシピを参照してください。 |
[script]1.33.0 | レシピ | レシピをスクリプトとして実行します。詳細はスクリプトレシピを参照してください。 |
[shell]1.52.0 | レシピ | set default-script を上書きして、レシピをシェルレシピとして実行します。 |
[timestamp(FORMAT)]1.58.0 | レシピ | FORMAT の書式でコマンドのタイムスタンプを出力します。FORMAT には式を指定できます。 |
[timestamp]1.58.0 | レシピ | コマンドのタイムスタンプを出力します。 |
[unix]1.8.0 | 任意1.56.0 | Unix 系 OS で項目を有効にします(macOS を含みます)。 |
[windows]1.8.0 | 任意1.56.0 | Windows で項目を有効にします。 |
[working-directory(PATH)]1.38.0 | レシピ | レシピの作業ディレクトリを設定します。PATH には、相対パスまたは絶対パスを値とする式を指定できます1.51.0。相対パスの場合、既定の作業ディレクトリからの相対パスとして解釈されます。 |
| レシピには、複数行にわたって複数の属性を指定できます。 |
[no-cd]
[private]
foo:
echo "foo"
または、カンマで区切って1行に記述できます1.14.0:
[no-cd, private]
foo:
echo "foo"
引数が1つの属性は、コロンを使って記述できます。
[group: 'bar']
foo:
設定
設定は、解釈と実行を制御します。各設定は、justfile 内のどこか1か所でのみ指定できます。
例:
set shell := ["zsh", "-cu"]
foo:
# this line will be run as `zsh -cu 'ls **/*.txt'`
ls **/*.txt
設定一覧
| 名前 | 値 | デフォルト | 説明 |
|---|---|---|---|
allow-duplicate-recipes | boolean | false | justfile の後に記述されたレシピが、同じ名前の前のレシピを上書きできるようにします。 |
allow-duplicate-variables | boolean | false | justfile の後に記述された変数が、同じ名前の前の変数を上書きできるようにします。 |
default-list | boolean | false | デフォルトのレシピを実行する代わりに、レシピを一覧表示します。 |
default-script1.52.0 | boolean | false | デフォルトのレシピをシェルではなくスクリプトとして実行します。 |
dotenv-command1.54.0 | string | - | コマンドを実行し、その出力を環境ファイルとして読み込みます。 |
dotenv-filename | string | - | 存在する場合、カスタム名の .env ファイルを読み込みます。 |
dotenv-load | boolean | false | 存在する場合、.env ファイルを読み込みます。 |
dotenv-override | boolean | false | .env ファイルの値で既存の環境変数を上書きします。 |
dotenv-path | string | - | カスタムパスから .env ファイルを読み込み、存在しない場合はエラーにします。dotenv-filename より優先されます。 |
dotenv-required | boolean | false | .env ファイルが見つからない場合はエラーにします。 |
export | boolean | false | すべての変数を環境変数としてエクスポートします。 |
fallback | boolean | false | コマンドラインで最初に指定されたレシピが見つからない場合、親ディレクトリで justfile を検索します。 |
guards1.47.0 | boolean | false | レシピ行で ? ガード記号を有効にします。記号を参照してください。 |
ignore-comments | boolean | false | # で始まるシェルレシピ行を無視します。スクリプトレシピには適用されません。 |
indentation1.56.0 | string | - | --fmt または --dump でフォーマットする際に使用する、レシピ本体のインデントを設定します。 |
lazy1.47.0 | boolean | false | 使用されていない変数を評価しません。 |
lists1.53.0 | boolean | false | 値として文字列ではなく文字列のリストを使用できます。現在は不安定です。 |
minimum-version1.55.0 | string | - | just のバージョンが minimum-version より古い場合はエラーにします。"1.55.0" のような MAJOR.MINOR.PATCH 形式の文字列を指定します。 |
no-cd1.51.0 | boolean | false | レシピ属性によってレシピを実行する際に、ディレクトリを変更しません。 |
no-exit-message1.39.0 | boolean | false | レシピが失敗しても終了メッセージを表示しません。 |
positional-arguments | boolean | false | 位置引数を渡します。 |
quiet | boolean | false | 実行前にレシピ行をエコー表示しません。 |
script-interpreter1.33.0 | [COMMAND, ARGS…] | ['sh', '-eu'] | 空の [script] 属性を持つレシピの呼び出しに使用するコマンドを設定します。 |
shell | [COMMAND, ARGS…] | - | レシピの呼び出しとバッククォートの評価に使用するコマンドを設定します。 |
tempdir | string | - | システム既定の一時ディレクトリの代わりに、tempdir 内に一時ディレクトリを作成します。 |
unstable1.31.0 | boolean | false | 不安定な機能を有効にします。 |
windows-powershell | boolean | false | Windows で PowerShell をデフォルトのシェルとして使用します。(非推奨です。set shell の [windows] 属性を使用してください。) |
windows-shell | [COMMAND, ARGS…] | - | レシピの呼び出しとバッククォートの評価に使用するコマンドを設定します。(非推奨です。set shell の [windows] 属性を使用してください。) |
working-directory1.33.0 | string | - | デフォルトの作業ディレクトリからの相対パスで、レシピとバッククォートの作業ディレクトリを設定します。 |
ブール値の設定は、次のように記述できます。
set NAME
これは次の記述と同等です。
set NAME := true
ブール値以外の設定には、文字列と式1.46.0の両方を設定できます。
ただし、設定はバッククォートや多くの関数の動作に影響するため、式にバッククォートや関数呼び出しを直接含めることはできません。また、参照を介して間接的に含めることもできません。
関数
システム情報
arch()— 命令セットアーキテクチャです。次の値を指定できます:"aarch64"、 "arm"、"asmjs"、"hexagon"、"mips"、"msp430"、"powerpc"、 "powerpc64"、"s390x"、"sparc"、"wasm32"、"x86"、"x86_64"、および "xcore"。num_cpus()1.15.0 — 論理 CPU の数です。os()— オペレーティングシステムです。次の値を指定できます:"android"、"bitrig"、 "dragonfly"、"emscripten"、"freebsd"、"haiku"、"ios"、"linux"、 "macos"、"netbsd"、"openbsd"、"solaris"、および "windows"。os_family()— オペレーティングシステムのファミリーです。指定できる値は "unix" と "windows" です。
たとえば、次のようになります。
system-info:
@echo "This is an {{arch()}} machine."
$ just system-info
This is an x86_64 machine.
os_family() 関数を使うと、さまざまなオペレーティングシステムで動作するクロスプラットフォームの justfile を作成できます。例については、cross-platform.just ファイルを参照してください。
外部コマンド
-
shell(command, args...)1.27.0 は、位置引数argsを0個以上指定して実行したシェルスクリプトcommandの標準出力を返します。commandの解釈に使用するシェルは、レシピの行の評価に使われるシェルと同じです。set shell := […]で変更できます。commandは最初の引数として渡されます。そのため、コマンドが'echo $@'で、 デフォルトのシェルコマンドsh -cuに加えてargsに'foo'と'bar'を指定した場合、コマンドライン全体は次のようになります。'sh' '-cu' 'echo $@' 'echo $@' 'foo' 'bar'これにより、
$@が想定どおりに動作し、$1が最初の引数を参照します。$@には、実行するプログラム名として使われることが想定されている最初の位置引数は含まれません。
# arguments can be variables or expressions
file := '/sys/class/power_supply/BAT0/status'
bat0stat := shell('cat $1', file)
# commands can be variables or expressions
command := 'wc -l'
output := shell(command + ' "$1"', 'main.c')
# arguments referenced by the shell command must be used
empty := shell('echo', 'foo')
full := shell('echo $1', 'foo')
error := shell('echo $1')
# Using python as the shell. Since `python -c` sets `sys.argv[0]` to `'-c'`,
# the first "real" positional argument will be `sys.argv[2]`.
set shell := ["python3", "-c"]
olleh := shell('import sys; print(sys.argv[2][::-1])', 'hello')
環境変数
env(key)1.15.0 —keyという名前の環境変数を取得します。環境変数が存在しない場合は中断します。
home_dir := env('HOME')
test:
echo "{{home_dir}}"
$ just
/home/user1
env(key, default)1.15.0 —keyという名前の環境変数を取得します。存在しない場合はdefaultを返します。env_var(key)—env(key)の非推奨の別名です。env_var_or_default(key, default)—env(key, default)の非推奨の別名です。
実行ファイル
-
require(name)1.39.0 — 環境変数PATHに含まれるディレクトリから実行ファイルnameを検索し、そのフルパスを返します。nameの実行ファイルが存在しない場合は、エラーで停止します。bash := require("bash") @test: echo "bash: '{{bash}}'"$ just bash: '/bin/bash' -
which(name)1.39.0 — 環境変数PATHに含まれるディレクトリから実行ファイルnameを検索し、そのフルパスを返します。見つからない場合は空のリストを返します。set lists1.53.0 が必要です。set unstable set lists bosh := which("bosh") @test: echo "bosh: '{{bosh}}'"$ just bosh: ''
呼び出し情報
-
is_dependency()- 現在のレシピが直接実行されているのではなく、別のレシピの依存関係として実行されている場合は文字列trueを返し、それ以外の場合は文字列falseを返します。 -
num_jobs()1.56.0 —--jobsの値を返します。指定されていない場合は空のリスト[]を返します。 -
recipe_name()1.53.0 - 現在のレシピの名前を返します。
呼び出し元のディレクトリ
invocation_directory()-justが呼び出された時点の現在のディレクトリへの絶対パスを取得します。これは、コマンドを実行する前にjustがディレクトリを変更(chdir)する前のパスです。Windows では、invocation_directory()はcygpathを使って、呼び出し元のディレクトリを Cygwin 互換の/区切りのパスに変換します。すべてのプラットフォームで呼び出し元のディレクトリをそのまま返すには、invocation_directory_native()を使用してください。
たとえば、ユーザー(呼び出し元)の観点から見た「現在のディレクトリ」の直下にあるファイルに対して rustfmt を実行するには、次のレシピを使います。
rustfmt:
find {{invocation_directory()}} -name \*.rs -exec rustfmt {} \;
別の方法として、コマンドを現在のディレクトリから実行する必要がある場合は、次のようにします(例)。
build:
cd {{invocation_directory()}}; ./some_script_that_needs_to_be_run_from_here
invocation_directory_native()-justが呼び出された時点の現在のディレクトリへの絶対パスを取得します。これは、コマンドを実行する前にjustがディレクトリを変更(chdir)する前のパスです。
Justfile と Justfile ディレクトリ
-
justfile()- 現在のjustfileのパスを取得します。 -
justfile_directory()- 現在のjustfileの親ディレクトリのパスを取得します。
たとえば、現在の justfile の場所を基準にコマンドを実行するには、次のようにします。
script:
{{justfile_directory()}}/scripts/some_script
ソースファイルとソースディレクトリ
-
source_file()1.27.0 - 現在のソースファイルのパスを取得します。 -
source_directory()1.27.0 - 現在のソースファイルの親ディレクトリのパスを取得します。
source_file() と source_directory() は、ルートの justfile では justfile() および
justfile_directory() と同じように動作します。ただし、インポートまたはサブモジュール内から呼び出された場合は、
それぞれ現在の import または mod ソースファイルのパスとディレクトリを返します。
モジュールとモジュールディレクトリ
-
module_file()- 現在のモジュールファイルのパスを返します。 -
module_directory()- 現在のモジュールファイルの親ディレクトリのパスを返します。 -
module_path()- 現在のモジュールへの::区切りのパスを返します。
module_file() と module_directory() は、ルートの justfile では justfile() および
justfile_directory() と同じように動作します。ただし、サブモジュール内から呼び出された場合は、
現在の mod ソースファイルのパスとディレクトリを返します。
Just プロセスと実行ファイル
just_executable()-just実行ファイルの絶対パスです。just_pid()-just実行ファイルのプロセス ID です。just_version()1.55.0 -just実行ファイルのバージョンです。
たとえば、次のようにします。
just-info:
@echo The executable is at: {{just_executable()}}
@echo The process ID is: {{ just_pid() }}
@echo The version is: {{ just_version() }}
$ just
The executable is at: /bin/just
The process ID is: 420
The version is: 1.54.0
文字列操作
append(suffix, s)1.27.0 -s内の空白区切り文字列にsuffixを追加します。append('/src', 'foo bar baz')→'foo/src bar/src baz/src'prepend(prefix, s)1.27.0 -s内の空白区切り文字列の先頭にprefixを追加します。prepend('src/', 'foo bar baz')→'src/foo src/bar src/baz'encode_uri_component(s)1.27.0 -[A-Za-z0-9_.!~*'()-]を除くs内の文字をパーセントエンコードします。動作は JavaScript のencodeURIComponent関数と一致します。quote(s)- すべてのシングルクォートを'\''に置き換え、sの前後にシングルクォートを追加します。これは、Bourne シェルのほとんどの派生シェルを含む、多くのシェルで特殊文字をエスケープするのに十分です。replace(s, from, to)-s内のfromのすべての出現箇所をtoに置き換えます。replace_regex(s, regex, replacement)-s内のregexのすべての出現箇所をreplacementに置き換えます。正規表現には Rust のregexクレートを使用します。使用例については、 構文のドキュメントを参照してください。 キャプチャグループがサポートされています。replacement文字列には 置換文字列の構文を使用します。trim(s)-sの先頭と末尾の空白を削除します。trim_end(s)-sの末尾の空白を削除します。trim_end_match(s, substring)-substringに一致するsの接尾辞を削除します。trim_end_matches(s, substring)-substringに一致するsの接尾辞を繰り返し削除します。trim_start(s)-sの先頭の空白を削除します。trim_start_match(s, substring)-substringに一致するsの接頭辞を削除します。trim_start_matches(s, substring)-substringに一致するsの接頭辞を繰り返し削除します。
大文字・小文字の変換
capitalize(s)1.7.0 -sの先頭の文字を大文字に変換し、 残りを小文字に変換します。kebabcase(s)1.7.0 -sをkebab-caseに変換します。lowercamelcase(s)1.7.0 -sをlowerCamelCaseに変換します。lowercase(s)-sを小文字に変換します。shoutykebabcase(s)1.7.0 -sをSHOUTY-KEBAB-CASEに変換します。shoutysnakecase(s)1.7.0 -sをSHOUTY_SNAKE_CASEに変換します。snakecase(s)1.7.0 -sをsnake_caseに変換します。titlecase(s)1.7.0 -sをTitle Caseに変換します。uppercamelcase(s)1.7.0 -sをUpperCamelCaseに変換します。uppercase(s)-sを大文字に変換します。
パスの操作
失敗する可能性がある関数
absolute_path(path)- 作業ディレクトリ内の相対パスpathを絶対パスに変換します。 ディレクトリ/fooでのabsolute_path("./bar.txt")は/foo/bar.txtです。canonicalize(path)1.24.0 - シンボリックリンクを解決し、可能な場合は.,..および余分な/を取り除いてpathを正規化します。extension(path)-pathの拡張子です。extension("/foo/bar.txt")はtxtです。file_name(path)- 先頭のディレクトリ要素を取り除いたpathのファイル名です。file_name("/foo/bar.txt")はbar.txtです。file_stem(path)- 拡張子を除いたpathのファイル名です。file_stem("/foo/bar.txt")はbarです。parent_directory(path)-pathの親ディレクトリです。parent_directory("/foo/bar.txt")は/fooです。without_extension(path)- 拡張子を除いたpathです。without_extension("/foo/bar.txt")は/foo/barです。
これらの関数は、たとえばパスに拡張子がない場合などに失敗し、実行が停止することがあります。
失敗しない関数
clean(path)- 余分なパス区切り文字、中間の.要素、および可能な場合は..を取り除いてpathを簡潔にします。clean("foo//bar")はfoo/bar、clean("foo/..")は.、clean("foo/./bar")はfoo/barです。join(a, b…)- この関数は Unix では/、Windows では\を使用するため、 意図しない動作につながることがあります。Windows で特に\を使用したい場合を除き、 常に/を使用する/演算子(例:a / b)を代わりに使用してください。 パスaとパスbを結合します。join("foo/bar", "baz")はfoo/bar/bazです。2 つ以上の引数を指定できます。
ファイルシステムへのアクセス
path_exists(path)- パスが既存のエンティティを指している場合は文字列true、 そうでない場合は文字列falseを返します。シンボリックリンクをたどり、 パスにアクセスできない場合、またはリンク切れのシンボリックリンクを指している場合は、 文字列falseを返します。read(path)1.39.0 -pathにあるファイルの内容を文字列として返します。
アサーションとエラー報告
assert(CONDITION, EXPRESSION)1.27.0 -CONDITIONが false の場合、 メッセージEXPRESSIONでエラーを発生させます。EXPRESSIONは 省略できます1.53.0。error(message)- 実行を中止し、エラーmessageをユーザーに報告します。
UUID とハッシュの生成
blake3(string)1.25.0 -stringの BLAKE3 ハッシュを16進文字列として返します。blake3_file(path)1.25.0 -pathにあるファイルの BLAKE3 ハッシュを16進 文字列として返します。sha256(string)-stringの SHA-256 ハッシュを16進文字列として返します。sha256_file(path)- ファイルpathの SHA-256 ハッシュを16進 文字列として返します。uuid()- ランダムなバージョン 4 の UUID を生成します。
ランダム
choose(n, alphabet)1.27.0 -alphabetからランダムに選択した文字で、 長さnの文字列を生成します。alphabetに同じ文字を複数含めることはできません。 たとえば、choose('64', HEX)は小文字の16進文字からなるランダムな64文字の文字列を生成します。
日時
datetime(format)1.30.0 -formatで指定した形式でローカル時刻を返します。datetime_utc(format)1.30.0 -formatで指定した形式で UTC 時刻を返します。
datetime と datetime_utc の引数は、strftime 形式の書式文字列です。
詳細については、
chrono library docs
を参照してください。
セマンティックバージョン
semver_matches(version, requirement)1.16.0 - セマンティックなversion(例:"0.1.0")がrequirement(例:">=0.1.0")に一致するかを確認し、一致する場合は文字列"true"、それ以外の場合は文字列"false"を返します。
スタイル
-
style(styles)1.37.0 -stylesで指定した名前付きスタイルを組み合わせた、ターミナルのエスケープシーケンスを返します。バージョン 1.37.0 以降でサポートされているスタイルを使用すると、
just自体のスタイルを再現できます。command:エコーされたレシピ行error:エラーwarning:警告
1.55.0 以降でサポートされる追加のスタイルには、名前付きカラーがあります。
blackbluecyangreenmagentaredwhiteyellow
256 色のインデックスカラーは、
0から255までの整数で指定します(例:1、67)。24 ビットカラーは、16 進コード
#RRGGBBまたは#RGBで指定します(例:#065535、#AAA)。また、表示プロパティも指定できます。
blinkbolddimhiddenitalicreversestrikethroughunderline
2 つのストリーム名1.55.0を指定すると、
--color、JUST_COLOR、およびストリームがターミナルに接続されているかどうかに基づいて、justが出力ストリームをカラー表示する場合にのみスタイルが適用されます。stdoutstderr
すべてのカラースタイルはデフォルトで前景色を設定します。また、
fg:を前置した明示的な前景色のバリエーションと、bg:を前置した背景色のバリエーションがあります(例:bg:blue、fg:133、#FFF)。stylesにはスタイルのリストを指定できます。その場合、指定したすべてのスタイルが組み合わされ、最終的なエスケープシーケンスが生成されます。style(styles)が返すエスケープシーケンスは、プレフィックスであることに注意してください。使用後にスタイルをリセットするには、NORMAL定数を使用できます。error message: echo '{{style("error") + message + NORMAL}}' -
style(styles, text)1.55.0 - 1 引数形式と同様に、stylesを使ってtextにスタイルを適用します。スタイルは自動的にリセットされるため、ターミナルをリセットするためにNORMALを使う必要はありません。error message: echo '{{style("error", message)}}'
ユーザーディレクトリ
これらの関数1.23.0は、設定、データ、キャッシュ、実行可能ファイル、ユーザーのホームディレクトリなどに使用する、ユーザー固有のディレクトリへのパスを返します。
Unix では、これらの関数は XDG Base Directory Specification に従います。
macOS と Windows では、これらの関数はシステムで指定されたユーザー固有のディレクトリを返します。たとえば、cache_directory() は macOS では ~/Library/Caches を、Windows では {FOLDERID_LocalAppData} を返します。
詳細については、dirs クレートを参照してください。
cache_directory()- ユーザー固有のキャッシュディレクトリ。config_directory()- ユーザー固有の設定ディレクトリ。config_local_directory()- ユーザー固有のローカル設定ディレクトリ。data_directory()- ユーザー固有のデータディレクトリ。data_local_directory()- ユーザー固有のローカルデータディレクトリ。executable_directory()- ユーザー固有の実行可能ファイル用ディレクトリ。home_directory()- ユーザーのホームディレクトリ。runtime_directory()- ユーザー固有のランタイムディレクトリ。Linux でのみ定義されています。
すべてのプラットフォームで XDG ベースディレクトリを使用する場合は、適切な環境変数とフォールバックを指定して env(…) 関数を使用できます。ただし、XDG 仕様では絶対パスでないパスを無視する必要があるため、仕様に準拠したアプリケーションとの完全な互換性を確保するには、次のようにする必要があります。
xdg_config_dir := if env('XDG_CONFIG_HOME', '') =~ '^/' {
env('XDG_CONFIG_HOME')
} else {
home_directory() / '.config'
}
定数
いくつかの定数があらかじめ定義されています。
| 名前 | 値 | Windows での値 |
|---|---|---|
HEX1.27.0 | "0123456789abcdef" | |
HEXLOWER1.27.0 | "0123456789abcdef" | |
HEXUPPER1.27.0 | "0123456789ABCDEF" | |
PATH_SEP1.41.0 | "/" | "\" |
PATH_VAR_SEP1.41.0 | ":" | ";" |
CLEAR1.37.0 | "\ec" | |
NORMAL1.37.0 | "\e[0m" | |
BOLD1.37.0 | "\e[1m" | |
ITALIC1.37.0 | "\e[3m" | |
UNDERLINE1.37.0 | "\e[4m" | |
INVERT1.37.0 | "\e[7m" | |
HIDE1.37.0 | "\e[8m" | |
STRIKETHROUGH1.37.0 | "\e[9m" | |
BLACK1.37.0 | "\e[30m" | |
RED1.37.0 | "\e[31m" | |
GREEN1.37.0 | "\e[32m" | |
YELLOW1.37.0 | "\e[33m" | |
BLUE1.37.0 | "\e[34m" | |
MAGENTA1.37.0 | "\e[35m" | |
CYAN1.37.0 | "\e[36m" | |
WHITE1.37.0 | "\e[37m" | |
BG_BLACK1.37.0 | "\e[40m" | |
BG_RED1.37.0 | "\e[41m" | |
BG_GREEN1.37.0 | "\e[42m" | |
BG_YELLOW1.37.0 | "\e[43m" | |
BG_BLUE1.37.0 | "\e[44m" | |
BG_MAGENTA1.37.0 | "\e[45m" | |
BG_CYAN1.37.0 | "\e[46m" | |
BG_WHITE1.37.0 | "\e[47m" |
@foo:
echo {{HEX}}
$ just foo
0123456789abcdef
\eで始まる定数は、
ANSI エスケープシーケンスです。
CLEARは、clearコマンドと同様に画面を消去します。それ以外は
\e[Nmの形式で、Nは整数であり、端末の表示属性を設定します。
端末の表示属性を設定するエスケープシーケンスは、たとえばテキストの太さを示すBOLD、テキストスタイルを示すSTRIKETHROUGH、前景色を示すCYAN、背景色を示すBG_BLUEのように組み合わせられます。端末を通常の状態に戻すには、最後にNORMALを指定してください。
一部のシェルでは[が特殊文字として扱われるため、エスケープシーケンスは引用符で囲んでください。
@foo:
echo '{{BOLD + STRIKETHROUGH + CYAN + BG_BLUE}}Hi!{{NORMAL}}'
変更履歴
最新リリースの変更履歴は
CHANGELOG.mdで確認できます。
以前のリリースの変更履歴は
リリースページで確認できます。また、just --changelog
を使うと、justバイナリに変更履歴を出力させることができます。
その他
ファイル変更時のレシピの再実行
watchexecを使うと、ファイルが変更されたときに任意のコマンドを再実行できます。
ファイルが変更されるたびにレシピfooを再実行するには、次のようにします。
watchexec just foo
変更を監視するファイルの指定方法など、詳しくはwatchexec --helpを参照してください。
シェルエイリアス
コマンドをすばやく実行するには、シェルの設定ファイルにalias j=justを記述してください。
文法
justfileの参考文法は
GRAMMAR.mdにあります。
just.sh
justが高機能なRustプログラムになる前は、makeを呼び出す小さなシェルスクリプトでした。以前のバージョンは
contrib/just.shで確認できます。
Node.js package.jsonスクリプトとの互換性
次のエクスポート文を記述すると、justのレシピからローカルのNodeモジュールのバイナリを利用できるようになり、justのレシピコマンドがNode.jsのpackage.jsonファイル内のscriptエントリーに近い動作をするようになります。
export PATH := "./node_modules/.bin:" + env_var('PATH')
Windows のパス
Windows では、invocation_directory() を除き、パスを返すすべての関数が \ 区切りのパスを返します。PowerShell または cmd.exe を使用しない場合、\ がエスケープ文字として解釈されないよう、これらのパスを引用符で囲んでください。
ls:
echo '{{absolute_path(".")}}'
cygpath.exe は、Cygwin や Windows 用の Git など、一部の Windows 向け Unix ユーザーランドディストリビューションに含まれる実行ファイルです。
just は次の 2 か所で cygpath.exe を使用します。
後方互換性のため、invocation_directory() は cygpath.exe を使用して、呼び出し元のディレクトリを Unix 形式の / 区切りパスに変換します。Windows ネイティブ形式のパスを取得するには、invocation_directory_native() を使用してください。Unix では、invocation_directory() と invocation_directory_native() はどちらも同じ Unix 形式のパスを返します。
cygpath.exe は、Unix 形式のシバン行を Windows のパスに変換するためにも使用されます。代わりに [script] 属性を使用することもできます。この属性は cygpath.exe に依存しません。
cygpath.exe が利用できる場合は、パス形式の変換に使用できます。
foo_unix := '/hello/world'
foo_windows := shell('cygpath --windows $1', foo_unix)
bar_windows := 'C:\hello\world'
bar_unix := shell('cygpath --unix $1', bar_windows)
複雑な文字列の出力
echo を使用して文字列を出力できますが、\n などのエスケープシーケンスを処理するうえ、echo の実装によって認識されるエスケープシーケンスが異なるため、多くの場合は printf を使用するほうが適しています。
printf は C 形式の書式文字列と任意の数の引数を受け取り、それらを書式文字列に埋め込みます。
これをインデント付きの三重引用符文字列と組み合わせると、シェルのヒアドキュメントを再現できます。
レシピ本体で {{…}} を使って複雑な文字列を置換すると、空白や引用符の有無によってシェルが複数の引数に分割する場合があり、問題が発生することもあります。複雑な文字列を環境変数としてエクスポートし、"$NAME"(二重引用符に注意してください)で参照する方法も有効です。
これらをすべて組み合わせると、さまざまなエスケープシーケンスや引用符をそのまま保ち、文字列を標準出力にそのまま出力できます。
export FOO := '''
a complicated string with
some dis\tur\bi\ng escape sequences
and "quotes" of 'different' kinds
'''
bar:
printf %s "$FOO"
エージェント向けスキル
エージェント向けのスキルが skills/just にあり、手動でインストールするか、npx skills add casey/just --global でインストールできます。
代替ツールと先行事例
コマンドランナーには事欠きません。just に多少なりとも似た代替ツールには、次のものがあります。
- make:
justに影響を与えた Unix のビルドツールです。元のmakeから派生した現代的なツールはいくつかあり、FreeBSD Make や GNU Make などがあります。 - task:Go で書かれた YAML ベースのコマンドランナーです。
- maid:JavaScript で書かれた Markdown ベースのコマンドランナーです。
- microsoft/just:JavaScript で書かれた JavaScript ベースのコマンドランナーです。
- cargo-make:Rust プロジェクト向けのコマンドランナーです。
- mmake:リモートインクルードなど、さまざまな機能強化を施した
makeのラッパーです。 - robo:Go で書かれた YAML ベースのコマンドランナーです。
- mask:Rust で書かれた Markdown ベースのコマンドランナーです。
- makesure:AWK とシェルで書かれた、シンプルでポータブルなコマンドランナーです。
- haku:Rust で書かれた make のようなコマンドランナーです。
- mise:Rust で書かれた開発環境ツールマネージャーで、TOML ファイル内のタスクとスタンドアロンスクリプトに対応しています。
メタデータ
文字列のリスト形式のメタデータは、[metadata(METADATA)] 属性1.42.0を使用してレシピに付加できます。
[metadata("hello", "goodbye")]
foo:
メタデータは just --dump --dump-format json を使用して読み取れます。
uvを使ったPythonレシピ
uvは、Rustで書かれた優れたクロスプラットフォームのPythonプロジェクトマネージャーです。
[script]属性とscript-interpreter設定を使用すると、justでuvを使ってPythonレシピを簡単に実行できるよう設定できます。
set script-interpreter := ['uv', 'run', '--script']
[script]
hello:
print("Hello from Python!")
[script]
goodbye:
# /// script
# requires-python = ">=3.11"
# dependencies=["sh"]
# ///
import sh
print(sh.echo("Goodbye from Python!"), end='')
もちろん、シバンも使用できます。
hello:
#!/usr/bin/env -S uv run --script
print("Hello from Python!")
miseとの統合
miseは、開発ツールのインストール、環境の管理、タスクの実行を行うツールです。
justとmiseはうまく連携します。justでタスクを定義して実行し、miseで開発ツールをインストールして管理します。
just内でmise環境を読み込むには、次のようにします。
set dotenv-command := 'mise env'
set dotenv-override
test:
node --version
echo $FOO
環境はjustの起動時に一度だけ読み込まれ、すべてのレシピで使用できます。mise envはPATH変数の値を返しますが、この変数は常にすでに設定されているため、set dotenv-overrideが必要です。
miseは対話形式で、mise.tomlを信頼するかどうかを尋ねます。非対話型の環境では、事前にmise trustを実行してください。
mise envは不足しているツールをインストールしないため、先にmise installを実行するか、次のようにして不足しているツールを自動的にインストールしてください。
set dotenv-command := 'mise install -q && mise env'
ツールのバージョンは、justfile全体に対して上書きできます。
set dotenv-command := 'mise env node@22'
または、個々のレシピに対して上書きできます。
[script('mise', 'exec', 'node@22', '--', 'node')]
version:
console.log(process.version);
[script('mise', 'exec', '[email protected]', '--', 'sh', '-eu')]
test:
python -m pytest
代わりに、set shellを使用して、すべてのシェルレシピのすべての行をmise execで実行することもできます。
set shell := ['mise', 'exec', '--', 'sh', '-cu']
test:
node --version
また、[env]属性を使用すると、レシピごとにツールのバージョンを上書きできます。
set shell := ['mise', 'exec', '--', 'sh', '-cu']
[env('MISE_NODE_VERSION', '22')]
test:
node --version
mise execはshより実行に時間がかかるため、set shellを設定すると、コマンド数の多いシェルレシピの実行が目に見えて遅くなることがあります。
環境の有効化
Pythonの仮想環境など、一部のツールでは有効化の手順が必要です。
. .venv/bin/activate
これらのツールは実行中のシェルの環境を変更するため、justが代わりに有効化の手順を実行することはできません。ただし、いくつかの回避策があります。
Python環境を管理する最善の回避策は、uvに切り替えることです。uvは各コマンドに適した環境を設定するため、有効化の手順は不要です。
それができない場合や、ほかのツールを使う場合は、共通の前置処理を作成し、必要なスクリプトレシピに含めることができます。複数行にわたって記述でき、任意の数の手順を含められます。
prelude := '''
set -eux
. .venv/bin/activate
'''
[script]
run:
{{ prelude }}
python script.py
この回避策はシェルレシピでは使えません。シェルレシピはコマンドごとに新しいシェルを起動するためです。
貢献
メモ
現在、
justではプルリクエストを受け付けていません。貢献に関するセクションは、記録として残されています。
justへの貢献を歓迎します!justは最大限に寛容な
CC0パブリックドメインへの提供およびフォールバックライセンスの下で公開されているため、変更内容もこのライセンスの下で公開する必要があります。
はじめに
just は Rust で書かれています。
rustup を使って Rust ツールチェーンをインストールしてください。
just では、幅広いテストが行われています。すべての新機能には、ユニットテストまたはインテグレーションテストを追加する必要があります。ユニットテストは
src にあり、テスト対象のコードと同じ場所に配置され、コードを個別にテストします。インテグレーションテストは
tests ディレクトリ にあり、指定した justfile とコマンドライン引数を使って just を実行し、その出力を確認することで、just バイナリを外部からテストします。
十分なテストカバレッジを確保できる範囲で、実装する機能にとって最も書きやすい種類のテストを作成してください。
ユニットテストは、内部で使われる新しい Rust 関数をテストする際や、開発を支援するために役立ちます。良い例として、三重引用符文字列やバッククォートのインデントを解除する
unindent() 関数 を対象としたユニットテストがあります。unindent() には、関数を直接呼び出すユニットテストで簡単に検証できる、扱いの難しいエッジケースがいくつもあります。
インテグレーションテストは、just バイナリの最終的な動作が正しいことを確認するのに役立ちます。unindent() もインテグレーションテストでカバーされており、三重引用符文字列を評価すると、インデントが正しく解除された値が得られることを確認します。ただし、考えられるすべてのケースを対象とするインテグレーションテストはありません。こうしたケースは、unindent() を直接呼び出す、より高速で簡潔なユニットテストでカバーされています。
インテグレーションテストでは Test 構造体を使います。これは、指定した justfile、引数、環境変数を使って just を簡単に実行し、プログラムの stdout、stderr、終了コードを確認できるビルダーです。
コントリビューションのワークフロー
-
その機能が求められていることを確認します。その機能についての未解決の issue があり、@casey から、良いアイデア、または妥当な提案だというコメントが付いている必要があります。そうした issue がなければ、新しい issue を作成してフィードバックを求めてください。
良い機能であっても、後方互換性がない、実装によってコードベースが過度に複雑になる、または
justの設計哲学に反するなどの理由で、マージできないものは数多くあります。 -
機能の設計を固めます。実装方法や構文が複数考えられる場合は、issue 上で詳細を明確にしてください。
-
justをクローンして、開発を始めます。最適なワークフローは、作業中のコードをエディターで開き、ファイルが変更されるたびにテストを再実行するジョブを並行して動かすことです。cargo-watch をcargo install cargo-watchでインストールし、just watch testを実行すれば、そのようなジョブを動かせます。 -
その機能に対する失敗するテストを追加します。通常は、機能をエンドツーエンドで検証するインテグレーションテストになります。tests からテストを追加する適切なファイルを探すか、tests に新しいファイルを追加し、そのファイルをインポートする
mod文を tests/lib.rs に追加してください。 -
機能を実装します。
-
just ciを実行して、すべてのテスト、リント、チェックが成功することを確認します。mdBook と mdbook-linkcheck が必要です。 -
メンテナーが編集できる状態で、新しいコードを含む PR を作成します。PR では、リベースや細かな修正が必要になることがよくあります。メンテナーが編集できない PR の場合、リベースや修正のたびにコードレビューをやり取りする必要があります。メンテナーが編集できない場合、PR は予告なくクローズされることがあります。
-
フィードバックを反映します。
-
PR がマージされる喜びを味わいましょう!
議論やフィードバックのために、いつでもドラフト PR を作成してください。
ヒント
ここでは、上記のコントリビューションワークフローに加えて活用できる、新しい種類の機能を追加する際のヒントを紹介します。
新しい属性の追加
-
tests/attributes.rs に新しい統合テストを記述します。
-
Attribute列挙型に新しいバリアントを追加します。 -
新しい属性の機能を実装します。
-
just ciを実行し、すべてのテストに合格することを確認します。
Janus
Janus は、変更によって既存の justfile の解釈が壊れたり変わったりしないかを確認するツールです。GitHub 上の公開されている justfile を収集して分析します。
特に大規模な変更や複雑な変更をマージする前に、問題が発生しないことを確認するため、Janus を実行してください。ご自身で実行する必要はありません。必要な変更については、Casey が喜んで実行します。
最低サポート Rust バージョン
最低サポート Rust バージョン(MSRV)は、現在の stable Rust です。より古いバージョンの Rust でもビルドできる場合がありますが、保証はありません。
新しいリリース
just の新しいリリースは頻繁に公開されるため、ユーザーは新機能をすぐに利用できます。
リリースのコミットメッセージには、次のテンプレートを使用します。
Release x.y.z
- Bump version: x.y.z → x.y.z
- Update changelog
- Update changelog contributor credits
- Update dependencies
- Update version references in readme
よくある質問
Just が回避する Make の特異な動作にはどのようなものがありますか?
make には、混乱を招いたり、複雑だったり、汎用的なコマンドランナーとしての使用に適さなかったりする動作があります。
たとえば、状況によっては、make がレシピ内のコマンドを実際には実行しないことがあります。たとえば、test という名前のファイルがあり、次の makefile があるとします。
test:
./test
make はテストの実行を拒否します。
$ make test
make: `test' is up to date.
make は、test レシピが test という名前のファイルを生成すると想定します。このファイルが存在し、レシピにほかの依存関係がないため、make は実行することがないと判断して終了します。
公平を期すと、ビルドシステムとして make を使用する場合、この動作は望ましいものです。しかし、コマンドランナーとして使用する場合には望ましくありません。make 組み込みの .PHONY ターゲット名を使うと、特定のターゲットに対してこの動作を無効にできますが、構文が冗長で覚えにくいことがあります。また、レシピの定義とは別に記述する偽のターゲットの明示的なリストには、誤って新しい通常のターゲットを定義してしまうリスクもあります。just では、すべてのレシピが偽のターゲットとして扱われます。
make の特異な動作のほかの例としては、代入における = と := の違い、makefile の記述を誤った場合に表示される分かりにくいエラーメッセージ、レシピで環境変数を使うために $$ が必要なこと、さまざまな種類の make 間の非互換性などがあります。
Just と Cargo のビルドスクリプトの関係は?
cargo のビルドスクリプトには、Rust プロジェクトのビルド方法を制御するという、かなり限定された用途があります。たとえば、rustc の実行時にフラグを追加したり、外部依存関係をビルドしたり、何らかのコード生成ステップを実行したりします。
一方、just は、開発中に実行するその他のさまざまなコマンドに使います。たとえば、異なる設定でテストを実行する、コードを lint する、ビルド成果物をサーバーにプッシュする、一時ファイルを削除するといったことです。
また、just は Rust で書かれていますが、プロジェクトで使っている言語やビルドシステムに関係なく利用できます。
余談
個人的には、規模の大小を問わず、ほぼすべてのプロジェクトで justfile を作成すると非常に便利だと感じています。
複数のコントリビューターがいる大規模なプロジェクトでは、プロジェクトの作業に必要なコマンドをすべて手元で確認できるファイルがあると、とても便利です。
テスト、ビルド、lint、デプロイなどには、それぞれ別のコマンドを使うことがあるでしょう。それらを一か所にまとめておくと便利ですし、どのコマンドをどう入力すればよいかを人に説明する時間も短縮できます。
さらに、コマンドを気軽に記述できる場所があると、プロジェクトで共有されている知恵のうち、どこにも書き残されていないものも思いつきやすくなります。たとえば、リビジョン管理のワークフローの一部で必要になる難解なコマンド、プロジェクトの依存関係をすべてインストールするコマンド、ビルドシステムに渡す必要があるさまざまなフラグなどです。
レシピのアイデア:
-
プロジェクトのデプロイ/公開
-
リリースモードとデバッグモードでのビルド
-
デバッグモードまたはログを有効にした状態での実行
-
複雑な git ワークフロー
-
依存関係の更新
-
たとえば、高速なテストと低速なテストなど、異なるテストセットの実行や、詳細な出力を有効にしたテストの実行
-
忘れないためにどこかに書き留めておくべき、複雑な一連のコマンド
小規模な個人プロジェクトでも、シェルの履歴を^Reverse検索する代わりに、コマンドを名前で思い出せるのは便利です。また、適当な言語で書かれた古いプロジェクトに戻ったとき、よく分からないビルドシステムでも、必要な作業に使うコマンドがすべて justfile にあり、just と入力すれば何か便利なこと(少なくとも面白いこと!)が起きると分かっているのは、大きな助けになります。
レシピのアイデアについては、
このプロジェクトの justfileや、
公開されている
justfile をご覧ください。
さて、このとても長々とした README については、これでおしまいだと思います。
just を楽しんで使い、コンピューティングに関するあらゆる取り組みで大きな成功と満足を得られることを願っています!
😸