1
1
mirror of https://github.com/casey/just.git synced 2024-11-22 02:09:44 +03:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Casey Rodarmor
b63efb70a5
Center readme (#1178) 2022-05-04 06:35:03 +00:00
Casey Rodarmor
3adef6d4b7
Style and add links to homepage (#1177) 2022-05-04 06:27:27 +00:00
Casey Rodarmor
9a7067e624
Fix readme badge links (#1176) 2022-05-04 06:13:58 +00:00
Casey Rodarmor
12fe9371f6
Generate book from readme (#1155) 2022-05-04 06:05:55 +00:00
Casey Rodarmor
e5ce303845
Release 1.1.3 (#1175)
- Bump version: 1.1.2 → 1.1.3
- Update changelog
- Update dependencies
- Update man page
2022-05-03 22:21:14 -07:00
Casey Rodarmor
db35a58a61
Skip duplicate recipe arguments (#1174) 2022-05-04 05:04:55 +00:00
22 changed files with 331 additions and 155 deletions

View File

@ -44,7 +44,7 @@ jobs:
with:
components: clippy, rustfmt
override: true
toolchain: 1.47.0
toolchain: 1.53.0
- uses: Swatinem/rust-cache@v1
@ -73,3 +73,23 @@ jobs:
sudo apt-get update
sudo apt-get install ripgrep
./bin/forbid
- name: Install `mdbook`
if: ${{ matrix.os == 'ubuntu-latest' }}
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: latest
- name: Build book
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
cargo run --package generate-book
mdbook build book
- name: Deploy Pages
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/master' && matrix.os == 'ubuntu-latest'
with:
github_token: ${{secrets.GITHUB_TOKEN}}
publish_branch: gh-pages
publish_dir: www

2
.gitignore vendored
View File

@ -1,5 +1,6 @@
/.vagrant
/README.html
/book/src
/fuzz/artifacts
/fuzz/corpus
/fuzz/target
@ -7,3 +8,4 @@
/test-utilities/Cargo.lock
/test-utilities/target
/tmp
/www/man

View File

@ -1,6 +1,18 @@
Changelog
=========
[1.1.3](https://github.com/casey/just/releases/tag/1.1.3) - 2022-5-3
--------------------------------------------------------------------
### Fixed
- Skip duplicate recipe arguments (#1174)
### Misc
- Fix install script (#1172)
- Document that `invocation_directory()` returns an absolute path (#1162)
- Fix absolute_path documentation (#1160)
- Add cross-platform justfile example (#1152)
[1.1.2](https://github.com/casey/just/releases/tag/1.1.2) - 2022-3-30
---------------------------------------------------------------------

140
Cargo.lock generated
View File

@ -31,12 +31,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -60,12 +54,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23"
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -90,9 +78,9 @@ dependencies = [
[[package]]
name = "cradle"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87b52996a34486c5577ea4a2c37dfa25a99eabfab81ca0a3d71711a7d13059ca"
checksum = "7096122c1023d53de7298f322590170540ad3eba46bbc2750b495f098c27c09a"
dependencies = [
"rustversion",
]
@ -109,9 +97,9 @@ dependencies = [
[[package]]
name = "ctrlc"
version = "3.2.1"
version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
dependencies = [
"nix",
"winapi",
@ -186,6 +174,23 @@ dependencies = [
"instant",
]
[[package]]
name = "generate-book"
version = "0.0.0"
dependencies = [
"pulldown-cmark",
"pulldown-cmark-to-cmark",
]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "heck"
version = "0.3.3"
@ -233,7 +238,7 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "just"
version = "1.1.2"
version = "1.1.3"
dependencies = [
"ansi_term",
"atty",
@ -280,9 +285,9 @@ checksum = "441225017b106b9f902e97947a6d31e44ebcf274b91bdbfb51e5c477fcd468e5"
[[package]]
name = "libc"
version = "0.2.121"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
name = "linked-hash-map"
@ -292,39 +297,28 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "log"
version = "0.4.16"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nix"
version = "0.23.1"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
@ -338,9 +332,9 @@ dependencies = [
[[package]]
name = "pretty_assertions"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c038cb5319b9c704bf9c227c261d275bfec0ad438118a2787ce47944fb228b"
checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563"
dependencies = [
"ansi_term",
"ctor",
@ -374,18 +368,39 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.36"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.17"
name = "pulldown-cmark"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58"
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
dependencies = [
"bitflags",
"getopts",
"memchr",
"unicase",
]
[[package]]
name = "pulldown-cmark-to-cmark"
version = "10.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eafb76310f7dc895b5d83d24f2a00e244fc8a68ef94f4257eb4060984d0385f"
dependencies = [
"pulldown-cmark",
]
[[package]]
name = "quote"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
@ -454,18 +469,18 @@ checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [
"proc-macro2",
"quote",
@ -474,9 +489,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.79"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [
"itoa",
"ryu",
@ -495,9 +510,9 @@ dependencies = [
[[package]]
name = "snafu"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eba135d2c579aa65364522eb78590cdf703176ef71ad4c32b00f58f7afb2df5"
checksum = "5177903bf45656592d9eb5c0e22f408fc023aae51dbe2088889b71633ba451f2"
dependencies = [
"doc-comment",
"snafu-derive",
@ -505,11 +520,11 @@ dependencies = [
[[package]]
name = "snafu-derive"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a7fe9b0669ef117c5cabc5549638528f36771f058ff977d7689deb517833a75"
checksum = "410b26ed97440d90ced3e2488c868d56a86e2064f5d7d6f417909b286afe25e5"
dependencies = [
"heck 0.3.3",
"heck 0.4.0",
"proc-macro2",
"quote",
"syn",
@ -569,9 +584,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.90"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f"
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
dependencies = [
"proc-macro2",
"quote",
@ -642,6 +657,15 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-segmentation"
version = "1.9.0"
@ -656,9 +680,9 @@ checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "vec_map"

View File

@ -1,6 +1,6 @@
[package]
name = "just"
version = "1.1.2"
version = "1.1.3"
description = "🤖 Just a command runner"
authors = ["Casey Rodarmor <casey@rodarmor.com>"]
license = "CC0-1.0"
@ -13,7 +13,7 @@ categories = ["command-line-utilities", "development-tools"]
keywords = ["command-line", "task", "runner", "development", "utility"]
[workspace]
members = [".", "bin/ref-type"]
members = [".", "bin/ref-type", "bin/generate-book"]
[dependencies]
ansi_term = "0.12.0"

View File

@ -1,16 +1,30 @@
↖️ Table of Contents
`just`
======
<h1 align="center"><code>just</code></h1>
![crates.io version](https://img.shields.io/crates/v/just.svg)
![build status](https://github.com/casey/just/workflows/Build/badge.svg)
![downloads](https://img.shields.io/github/downloads/casey/just/total.svg)
![chat on discord](https://img.shields.io/discord/695580069837406228?logo=discord)
![say thanks](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)
<div align="center">
<a href="https://crates.io/crates/just">
<img src="https://img.shields.io/crates/v/just.svg" alt="crates.io version">
</a>
<a href="https://github.com/casey/just/actions">
<img src="https://github.com/casey/just/workflows/Build/badge.svg" alt="build status">
</a>
<a href="https://github.com/casey/just/releases">
<img src="https://img.shields.io/github/downloads/casey/just/total.svg" alt="downloads">
</a>
<a href="https://discord.gg/ezYScXR">
<img src="https://img.shields.io/discord/695580069837406228?logo=discord" alt="chat on discord">
</a>
<a href="mailto:casey@rodarmor.com?subject=Thanks%20for%20Just!">
<img src="https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg" alt="say thanks">
</a>
</div>
<br>
`just` is a handy way to save and run project-specific commands.
This readme is also available as a [book](https://just.systems/man/);
(非官方中文文档,[这里](https://github.com/chinanf-boy/just-zh),快看过来!)
Commands, called recipes, are stored in a file called `justfile` with syntax inspired by `make`:

View File

@ -0,0 +1,9 @@
[package]
name = "generate-book"
version = "0.0.0"
edition = "2018"
publish = false
[dependencies]
pulldown-cmark = "0.9.1"
pulldown-cmark-to-cmark = "10.0.1"

View File

@ -0,0 +1,51 @@
use {
pulldown_cmark::{
Event,
HeadingLevel::{H2, H3},
Options, Parser, Tag,
},
pulldown_cmark_to_cmark::cmark,
std::{error::Error, fs},
};
fn main() -> Result<(), Box<dyn Error>> {
fs::remove_dir_all("book/src").ok();
fs::create_dir("book/src")?;
let txt = fs::read_to_string("README.md")?;
let mut chapters = vec![(1usize, Vec::new())];
for event in Parser::new_ext(&txt, Options::all()) {
if let Event::Start(Tag::Heading(level @ (H2 | H3), ..)) = event {
chapters.push((if level == H2 { 2 } else { 3 }, Vec::new()));
}
chapters.last_mut().unwrap().1.push(event);
}
let mut summary = String::new();
for (i, (level, chapter)) in chapters.into_iter().enumerate() {
let mut txt = String::new();
cmark(chapter.iter(), &mut txt)?;
let title = if i == 0 {
txt = txt.split_inclusive('\n').skip(1).collect::<String>();
"Introduction"
} else {
txt.lines().next().unwrap().split_once(' ').unwrap().1
};
let path = format!("book/src/chapter_{}.md", i + 1);
fs::write(&path, &txt)?;
summary.push_str(&format!(
"{}- [{}](chapter_{}.md)\n",
" ".repeat((level.saturating_sub(1)) * 4),
title,
i + 1
));
}
fs::write("book/src/SUMMARY.md", summary)?;
Ok(())
}

9
book/book.toml Normal file
View File

@ -0,0 +1,9 @@
[book]
authors = ["Casey Rodarmor"]
language = "en"
multilingual = false
src = "src"
title = "Just Programmer's Manual"
[build]
build-dir = "../www/man"

View File

@ -1,55 +0,0 @@
:root {
--width-target: calc(100vw / 6);
--height-target: calc(100vh / 3);
--size: min(var(--width-target), var(--height-target));
--margin-vertical: calc((100vh - var(--size) * 2) / 2);
--margin-horizontal: calc((100vw - var(--size) * 5) / 2);
}
* {
margin: 0;
padding: 0;
}
html {
background-color: black;
color: white;
overflow: hidden;
text-align: center;
}
a {
color: white;
text-decoration: none;
}
#just {
font-family: sans-serif;
font-size: var(--size);
line-height: var(--size);
display: grid;
grid-template-columns: repeat(4, 1fr);
margin-bottom: var(--margin-vertical);
margin-left: var(--margin-horizontal);
margin-right: var(--margin-horizontal);
margin-top: var(--margin-vertical);
}
#just > * {
height: var(--size);
width: var(--size);
}
#subtitle {
font-style: italic;
}
/* just is an isogram */
#j:after { content: 'j'; }
#j:hover:after { content: 'J'; }
#u:after { content: 'u'; }
#u:hover:after { content: 'U'; }
#s:after { content: 's'; }
#s:hover:after { content: 'S'; }
#t:after { content: 't'; }
#t:hover:after { content: 'T'; }

View File

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.5.
.TH JUST "1" "March 2022" "just 1.1.2" "Just Manual"
.TH JUST "1" "May 2022" "just 1.1.3" "Just Manual"
.SH NAME
just \- save and run commands
.SH DESCRIPTION
just 1.1.2
just 1.1.3
\- Please see https://github.com/casey/just for more information.
.SS "USAGE:"
.IP

View File

@ -1,4 +1,4 @@
#![allow(clippy::unknown_clippy_lints)]
#![allow(unknown_lints)]
#![allow(clippy::unnecessary_wraps)]
use crate::common::*;

View File

@ -284,6 +284,15 @@ impl<'src> Justfile<'src> {
search: &Search,
ran: &mut BTreeSet<Vec<String>>,
) -> RunResult<'src, ()> {
let mut invocation = vec![recipe.name().to_owned()];
for argument in arguments {
invocation.push((*argument).to_string());
}
if ran.contains(&invocation) {
return Ok(());
}
let (outer, positional) = Evaluator::evaluate_parameters(
context.config,
dotenv,
@ -300,20 +309,19 @@ impl<'src> Justfile<'src> {
Evaluator::recipe_evaluator(context.config, dotenv, &scope, context.settings, search);
for Dependency { recipe, arguments } in recipe.dependencies.iter().take(recipe.priors) {
let mut invocation = vec![recipe.name().to_owned()];
let arguments = arguments
.iter()
.map(|argument| evaluator.evaluate_expression(argument))
.collect::<RunResult<Vec<String>>>()?;
for argument in arguments {
invocation.push(evaluator.evaluate_expression(argument)?);
}
if !ran.contains(&invocation) {
let arguments = invocation
.iter()
.skip(1)
.map(String::as_ref)
.collect::<Vec<&str>>();
self.run_recipe(context, recipe, &arguments, dotenv, search, ran)?;
}
self.run_recipe(
context,
recipe,
&arguments.iter().map(String::as_ref).collect::<Vec<&str>>(),
dotenv,
search,
ran,
)?;
}
recipe.run(context, dotenv, scope.child(), search, &positional)?;
@ -339,11 +347,6 @@ impl<'src> Justfile<'src> {
}
}
let mut invocation = vec![recipe.name().to_owned()];
for argument in arguments {
invocation.push((*argument).to_string());
}
ran.insert(invocation);
Ok(())
}

View File

@ -192,10 +192,10 @@ mod tests {
if cfg!(windows) {
assert_eq!(settings.shell_binary(&config), "powershell.exe");
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
} else {
assert_eq!(settings.shell_binary(&config), "sh");
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
}
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
}
}

View File

@ -33,6 +33,7 @@ mod quiet;
mod quote;
mod readme;
mod regexes;
mod run;
mod search;
mod shebang;
mod shell;

19
tests/run.rs Normal file
View File

@ -0,0 +1,19 @@
use crate::common::*;
#[test]
fn dont_run_duplicate_recipes() {
Test::new()
.justfile(
"
foo:
# foo
",
)
.args(&["foo", "foo"])
.stderr(
"
# foo
",
)
.run();
}

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

68
www/index.css Normal file
View File

@ -0,0 +1,68 @@
:root {
--width-target: calc(100vw / 6);
--height-target: calc(100vh / 3);
--size: min(var(--width-target), var(--height-target));
--margin-vertical: calc((100vh - var(--size) * 2) / 2);
--margin-horizontal: calc((100vw - var(--size) * 5) / 2);
}
* {
margin: 0;
padding: 0;
}
html {
background-color: black;
color: white;
overflow: hidden;
text-align: center;
font-family: sans-serif;
font-size: var(--size);
line-height: var(--size);
}
a {
color: white;
text-decoration: none;
}
a:hover {
text-shadow: 0 0 5px #fff;
}
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
margin-bottom: var(--margin-vertical);
margin-left: var(--margin-horizontal);
margin-right: var(--margin-horizontal);
margin-top: var(--margin-vertical);
}
body > * {
width: var(--size);
}
body > div {
height: var(--size);
text-shadow: 0 0 5px #fff;
}
body > a {
align-items: center;
display: flex;
font-size: calc(var(--size) / 9);
height: calc(var(--size) / 2);
justify-content: center;
line-height: calc(var(--size) / 9);
}
/* just is an isogram */
#j:after { content: 'j'; }
#j:hover:after { content: 'J'; }
#u:after { content: 'u'; }
#u:hover:after { content: 'U'; }
#s:after { content: 's'; }
#s:hover:after { content: 'S'; }
#t:after { content: 't'; }
#t:hover:after { content: 'T'; }

View File

@ -7,15 +7,14 @@
<link href="index.css" rel="stylesheet" type="text/css">
</head>
<body>
<a href="https://github.com/casey/just">
<div id="just">
<div id="j"></div>
<div id="u"></div>
<div id="s"></div>
<div id="t"></div>
</div>
<div id="subtitle">a command runner</div>
</a>
<div id="j"></div>
<div id="u"></div>
<div id="s"></div>
<div id="t"></div>
<a href="https://github.com/casey/just">github</a>
<a href="man/">manual</a>
<a href="https://discord.gg/ezYScXR">discord</a>
<a href="https://crates.io/crates/just">crates.io</a>
</body>
</html>
<!-- Love, Casey -->