Git Product home page Git Product logo

just-zh's Introduction

casey/just explain translate-svg

just是保存和运行项目的特定命令的简便方法. 」

中文 | english


更新 ✅

翻译的原文 与日期 最新更新 更多
commit ⏰ 2019-10-07 last 中文翻译

贡献

欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看

生活

If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰


目录


just

crates.io version build status chat on gitter say thanks

just是保存和运行项目的特定命令的简便方法。

命令存储在一个名为justfile,语法启发自make:

build:
    cc *.c -o main

# test everything
test-all: build
    ./test --all

# run a specific test
test TEST: build
    ./test --test {{TEST}}

然后可以使用just <COMMAND>运行它们:

$ just test-all
cc *.c -o main
./test --all
Yay, all your tests passed!

有些困惑,没事,下面就帮你理清一切

just产生详细的错误消息,并避免make不良癖好,因此调试一个 justfile 比调试一个 markfile 文件更容易,也更少惊吓。

如果你需要帮助just,请随时打开一个问题或让我知道gitter。 始终欢迎功能请求和错误报告!

使用手册

安装

just应该能在,具有合理sh的任何系统上运行,包括 Linux、MACOS 和 BSD。

在 Windows 上,just能与由Git for WindowsGitHub DesktopCygwin提供的sh一起工作。

预先构建的 二进制文件

Linux、MacOS 和 Windows 的预构建二进制文件,在releases 页面

您可以使用以下命令,下载 Mac OS 或 Windows 的最新二进制文件,只需将DESTINATION_DIRECTORY替换成你想放置just的目录:

curl -LSfs https://japaric.github.io/trust/install.sh | \
  sh -s -- --git casey/just --to DESTINATION_DIRECTORY

在 Linux 上,使用:

curl -LSfs https://japaric.github.io/trust/install.sh | \
  sh -s -- --git casey/just --target x86_64-unknown-linux-musl --to DESTINATION_DIRECTORY

Homebrew

关于 MacOS,just可以使用Homebrew 包管理器安装。 若还没有 Homebrew 可使用这里的命令安装,然后运行:

brew install just

Scoop

在 Windows 上,just可以使用Scoop 包管理器安装。 若还没有 Scoop 可使用这里的指令安装,然后运行:

scoop install just

Arch Linux

在 Arch Linux, just 作为 AUR包 just, Arch User Repository。几个可以从 AUR 下载包的工具, 包括 yayyaourt.

Void Linux

在 Void Linux, just can be installed with:

sudo xbps-install -S just

Nix

On NixOS, Linux, and MacOS, just 的安装,可使用Nix package manager. Install Nix or NixOS, then run:

nix-env -i just

Cargo

在 Windows、Linux 和 MACOS 上,just可使用 Cargo 安装, 它是rust 语言 包管理器. 可使用这里的说明书安装 Cargo,然后运行:

cargo install just

(您可能还需要添加~/.cargo/bin到你的$PATH。 如果安装后不能运行,请在 shell 配置文件中运行export PATH="$HOME/.cargo/bin:$PATH")

让我们快速开始

安装章节中安装了just后。试运行just --version确保安装正确.

一旦just成功安装和工作, 在项目的根目录中,创建一个名为justfile的文件,具有以下内容:

recipe-name:
    echo 'This is a recipe!'


# 这是一个注释
another-recipe:
    @echo 'This is another recipe.'

当你调用just,它会在当前目录和向上层目录,寻找一个justfile,因此您可以在项目的任何子目录调用它(它就是那么方便)。

若在没有参数的情况下运行just,那当你选择运行justfile的第一个配方(recipe/或者叫‘食谱’也行,反正听上去都好吃):

$ just
echo 'This is a recipe!'
This is a recipe!

一个或多个参数,就会指定要运行的配方(们):

$ just another-recipe
This is another recipe.

just会在运行真正命令之前,将每个命令打印到标准错误(stderr),这就是为什么echo 'This is a recipe!'会被打印。当然你可以使用@作为行开头,这样会抑制打印。echo 'Another recipe.'也就没有打印。

如果命令失败,配方将停止运行。下面的cargo publish只在cargo test成功后运行:

publish:
    cargo test
    # tests passed, time to publish!
    cargo publish

配方可以依赖其他配方。这里test配方依赖build配方,所以build会在test之前运行:

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

依赖关系,总是先运行,即使它们(build)在依赖于它们的配方(test)之后传递:

$ just test build
cc main.c foo.c bar.c -o main
./test
testing... all tests passed!

特性

列出可用的配方

just --list可以列出配方:

$ just --list
Available recipes:
  build
  test
  deploy
  lint

just --summary则更简洁:

$ just --summary
build test deploy lint

Aliases

Aliases 让配方拥有替代名称:

alias b := build

build:
  echo 'Building!'
$ just b
build
echo 'Building!'
Building!

文档注释

just --list会让配方之前的相近注释,出现:

# build stuff
build:
  ./bin/build


# test stuff
test:
  ./bin/test
$ just --list
Available recipes:
    build # build stuff
    test # test stuff

变量和替代

变量、字符串、concatenation 和 substitution ,都通过使用{{…​}}支持:

version := "0.2.7"
tardir  := "awesomesauce-" + version
tarball := tardir + ".tar.gz"

publish:
    rm -f {{tarball}}
    mkdir {{tardir}}
    cp README.md *.c {{tardir}}
    tar zcvf {{tarball}} {{tardir}}
    scp {{tarball}} [email protected]:release/
    rm -rf {{tarball}} {{tardir}}

转义 {{

写一份包含{{的配方,要使用{{ "{{" }}:

braces:
	echo 'I {{ "{{" }}LOVE}} curly braces!'

(上面 LOVE 旁边的,未闭合的}}会忽略,因此不需要转义).

另一个选择是把所有你想转义的文本,插入到插槽({{中}})中:

braces:
	echo '{{'I {{LOVE}} curly braces!'}}'

Strings

双引号字符串支持转义序列:

string-with-tab             := "\t"
string-with-newline         := "\n"
string-with-carriage-return := "\r"
string-with-double-quote    := "\""
string-with-slash           := "\\"
$ just --evaluate
"tring-with-carriage-return := "
string-with-double-quote    := """
string-with-newline         := "
"
string-with-slash           := "\"
string-with-tab             := "     "

单引号字符串不识别转义序列,可能包含空格行:

escapes := '\t\n\r\"\\'

line-breaks := 'hello
this
is
  a
     raw
string!
'
$ just --evaluate
escapes := "\t\n\r\"\\"

line-breaks := "hello
this
is
  a
     raw
string!
"

函数

只提供一些内置函数,在编写配方时可能有用.

系统信息

  • arch() - 系统指令体系结构,可能的值是:"aarch64","arm","asmjs","hexagon","mips","msp430","powerpc","powerpc64","s390x","sparc","wasm32","x86","x86_64""xcore".

  • 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

环境变量

  • env_var(key) - 用名称key检索环境变量,如果不存在会中止.

  • env_var_or_default(key, default) - 用名称key检索环境变量,如果它不存在则返回default值.

调用 目录

  • invocation_directory() - 检索当前工作目录的路径, 在just执行命令更改它(用 chdir)之前。

例如,调用rustfmt只作用于"当前目录"下的文件(从用户/调用方的角度),使用以下规则:

rustfmt:
    find {{invocation_directory()}} -name \*.rs -exec rustfmt {} \;

或者,如果您的命令需要从当前目录运行,您可以使用(例如):

build:
    cd {{invocation_directory()}}; ./some_script_that_needs_to_be_run_from_here

Dotenv 集成

just将从名为.env文件中,加载环境变量。 此文件可以与您的 justfile 位于同一个目录中, 或是父目录。这些变量都是环境变量, 因不是just变量,所以在配方和反引号中必须要使用$VARIABLE_NAME获取。

例如,如果你.env文件包含:

# 注释,会被忽略
DATABASE_ADDRESS=localhost:6379
SERVER_PORT=1337

你的 justfile 包含:

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

执行命令可使用反引号

反引号可用来存储命令的结果:

localhost := `dumpinterfaces | cut -d: -f2 | sed 's/\/.*//' | sed 's/ //g'`

serve:
    ./serve {{localhost}} 8080

使用命令行工具,设置变量

变量可以通过命令行重写.

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

环境变量

export关键字会将作为环境变量,导入到配方中:

export RUST_BACKTRACE := "1"

test:
    # will print a stack trace if it crashes
    cargo test

配方 参数

配方可能有参数。这里的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 := '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

默认值可以是任意表达式,但 concatenations 必须被圆括号包裹:

arch := "wasm"

test triple=(arch + "-unknown-unknown"):
  ./test {{triple}}

配方的最后一个参数可以是变量。这在参数名称之前,用+表示:

backup +FILES:
  scp {{FILES}} [email protected]:

变量参数接受一个或多个参数,并由包含空格分隔的参数字符串,扩展:

$ 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

具有默认参数的变量参数,可接受零个或多个参数:

commit MESSAGE +FLAGS='':
  git commit {{FLAGS}} -m "{{MESSAGE}}"

{{…​}}替换可能需要引号,如果它们包含空格。例如,如果你有以下配方:

search QUERY:
    lynx https://www.google.com/?q={{QUERY}}

你的类型是:

$ just search "cat toupee"

Just会运行命令lynx [https://www.google.com/?q=cat](https://www.google.com/?q=cat) toupee,将被sh解析为lynx,[https://www.google.com/?q=cat](https://www.google.com/?q=cat)toupee,而不是你想的lynx[https://www.google.com/?q=cat](https://www.google.com/?q=cat) toupee

你可以通过添加引号来修正这个问题:

search QUERY:
    lynx 'https://www.google.com/?q={{QUERY}}'

用其他语言来写配方

以一个#!开始的配方会作为脚本执行,所以你可以用其他语言编写:

polyglot: python js perl sh ruby

python:
    #!/usr/bin/env python3
    print('Hello from python!')

js:
    #!/usr/bin/env node
    console.log('Greetings from justfile!')

perl:
    #!/usr/bin/env perl
    print "Larry Wall says Hi!\n";

sh:
    #!/usr/bin/env sh
    hello='Yo'
    echo "$hello from a shell script!"

ruby:
    #!/usr/bin/env ruby
    puts "Hello from ruby!"
$ just polyglot
Hello from python!
Greetings from justfile!
Larry Wall says Hi!
Yo from a shell script!
Hello from ruby!

多行结构语句

配方没有执行一个初始 shebang,并且是一行一行运行的。这意味着,多行结构语句的运行,可能不是你想的那样。

例如, 下面的 justfile:

    conditional:
        if true; then
            echo 'True!'
        fi

conditional语句下的缩进空格, 会给出解析错误:

    $ just conditional
    error: Recipe line has extra leading whitespace
      |
    3 |         echo 'True!'
      |     ^^^^^^^^^^^^^^^^

要使这个工作,你要把条件语句放在同一行,用\转为新行,或是添加一个 shebang 到你的配方中。下面有些参考。

if statements

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 loops

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 loops

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
        do ping -c 1 server
    done

命令行选项

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

运行just --help查看所有选项.

私有配方

名称以一个_开头的配方和 aliases,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

这对于配方帮手来说是有用的,因为它们只是用来作为其他配方的依赖.

安静配方

配方名称可以用"@"前缀,在每行之前反转"@"的含义:

@quiet:
  echo hello
  echo goodbye
  @# all done!

现在,只有用"@"开头的台词会回响:

$ j quiet
hello
goodbye
# all done!

在其他目录调用 Justfiles

如果第一个参数传递给just包含一个/,那会发生以下情况:

  1. 参数以最后一个/,拆分.

  2. 拆分后的,前半部分被视为目录。just会开始在那里搜索 justfile,而不是在当前目录中搜索。

  3. 后部分被当作一个普通的参数,或者,若它是空的,则被忽略。

这看起来有点奇怪,但是如果您希望运行子目录中的 justfile 中的命令,这是很有用的。

例如,如果您在包含名为foo子目录,其中包含一个带有build(也是默认配方)配方的 justfile,以下每条命令都是相等的:

$ (cd foo && just build)
$ just foo/build
$ just foo/

Just 脚本

通过添加一个 shebang 到一个 justfile 文件的顶部,就能让它可执行化。just 就作为了脚本执行器:

$ cat > script <<EOF
#!/usr/bin/env just --justfile

foo:
  echo foo
EOF
$ chmod +x script
$ ./script foo
echo foo
foo

若一个执行脚本带有一个 shebang, 系统会提供一个脚本的路径,作为命令参数。 所以,#!/usr/bin/env just --justfile, 这个命令完整是 /usr/bin/env just --justfile PATH_TO_SCRIPT

使用上面的 shebang, just 会将工作目录改为脚本所在的目录。 如果不想改变工作目录, 使用 #!/usr/bin/env just --working-directory . --justfile

杂记(炸鸡?)

好'译'名

搭配工具

just很好搭配的工具,包括:

  • watchexec-一个简单的工具,它监视路径,并在检测到修改时,运行命令.

Shell Alias(别名)

为了闪电般的命令运行,把alias j=just放在 shell 的配置文件中.

语法 高亮

justfile语法足够接近make,您可能希望告诉编辑器使用 make 语法高亮显示。

Vim

对于 Vim,您可以将以下内容放入~/.vim/filetype.vim:

if exists("did_load_filetypes")
  finish
endif

augroup filetypedetect
  au BufNewFile,BufRead Justfile,justfile setf make
augroup END

Vim 和 Emacs

在一个justfile中包括以下内容,能在 Vim 和 Emacs 中启用语法高亮显示:

# Local Variables:
# mode: makefile
# End:
# vim: set ft=make :

Visual Studio Code

VS 代码的skellock扩展是可用的哦. (github 库)

您可以通过运行命令安装它:

code --install-extension skellock.just

Kakoune

Kakoune 支持justfile语法高亮出笼啦,感谢 TeddyDD.

其他编辑器

请随时给我发送必要的命令,使语法高亮工作在您的编辑器的选择,以便我可以在这里包括他们.

语法

justfile 的非规范语法可以在GRAMMAR.md.

just.sh

以前的just是一个花哨的 Rust 程序,它是一个小小的 shell 脚本,其调用make. 您可以在extras/just.sh中找到旧版本。

无定向项目的 Justfile

如果你想要一些命令在任何地方都可用,把它们放进去.~/.justfile,并将下列内容添加到 shell 初始化文件中:

alias .j='just --justfile ~/.justfile --working-directory ~'

或者,如果你宁愿他们运行在当前目录:

alias .j='just --justfile ~/.justfile --working-directory .'

我敢肯定没有人真正使用这个功能,但它在那里.

¯\_(ツ)_/¯

Janus

Janus 是收集和分析 justfiles 的工具,并确定新版 just 更新与变化,对现有 justfiles 的解析。

在合并一个格外大的变更之前, 要运行 Janus 确保没有破坏。 不要担心 Janus 的运行有多麻烦, Casey(原作者) 会为你,在需要它时,对变更运行 Janus。

FAQ

make 的什么不良癖好,just 避免了?

make 有一些混淆或复杂的行为,或者说,使它不适合用作一般的命令运行器.

一个例子是,有时 make 不会在配方中运行命令。例如,如果有一个文件叫test,例子如下且运行它:

test:
  ./test

Make 实际上,会拒绝运行它:

$ make test
make: `test' is up to date.

Make 发觉这个test配方,并假定它产生一个名为test的文件。 然后, 该文件已存在,因此假定配方不需要运行。

公平地说,当使用 make 作为构建系统时,这种行为是可取的,但是当使用它作为命令运行程序时,则不是那么回事。

其他一些例子,包括必须理解=:=赋值两者之间的区别;弄乱 makefile 的话,产生混乱的错误消息;不得不通过$$,在配方中使用环境变量;以及 Make 不同风格的配方之间的不相容性。

just 和 cargo build 脚本有一腿吗?

Cargo build 脚本有一个非常具体的用途,这是控制 Cargo , 正确建立你的 Rust 项目。这可能包括将命令行参数添加到rustc中调用,建立外部依赖,或运行某种代码生成步骤.

just,则控制另一方面,是开发过程中部分,需要运行的所有其他杂项命令。比如在不同的配置中运行测试、链接代码、将构建工件推送到服务器、删除临时文件等等.

而且,虽然just写于 Rust 语言,但它可以被使用在许多地方,而不在意你的项目使用的语言或构建系统.

进一步漫谈

我个人觉得写了justfile很有用,它几乎用到每一个项目,无论大小.

在一个有多个贡献者的大型项目中,拥有一个包含所有命令的文件来处理项目是非常有用的.

可能需要测试、构建、lint、部署等不同的命令,将它们全部放在一个地方很有用,并且减少了告诉人们要运行哪些命令,以及如何键入命令的时间.

而且,有了一个易于放置命令的地方,您很可能会想到其他有用的,项目集体智慧的部分东西,但智慧被集中在一起,没有到处扔,像:神秘命令需要修订控制工作流程的某些部分一样;安装所有项目的依赖项,或者您可能需要传递给构建系统的所有随机参数.

配方的一些想法:

  • 部署/发布项目

  • 发布模式与调试模式的构建

  • 运行调试模式或启用日志记录

  • 复杂的 git 工作流

  • 更新依赖关系

  • 运行不同的测试集,例如快速测试和完整测试,或者用详细的输出来运行它们.

  • 任何复杂的命令集,如果只是为了能够记得它们,你就应该写在某个地方(当然是 justfile 啦).

即使对于小型的个人项目,能够按名称记住命令也是很好的,而不是^反向搜索 shell 历史记录。也许在神秘(莫名其妙)的构建系统,使用未知语言编写的旧项目, 若是使用just,那justfile可是会知道您需要执行,还是想要的所有命令,这对于您来说是巨大的好处。如果你输入just可能会发生一些有用(或至少有趣!)的事情.

有关配方的建议,请查看这个项目的justfile或者一些justfile野花.

无论如何,这是我认为的赞,且详细的 README 文件.

我希望你喜欢用just,并在您的所有计算体系工作中找到巨大的成功和满足感!

😸

just-zh's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.