1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use clap::{Arg, Command};
use mimalloc::MiMalloc;
use spacetimedb_cli::*;
use spacetimedb_paths::cli::CliTomlPath;
use spacetimedb_paths::{RootDir, SpacetimePaths};
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Compute matches before loading the config, because `Config` has an observable `drop` method
// (which deletes a lockfile),
// and Clap calls `exit` on parse failure rather than panicing, so destructors never run.
let matches = get_command().get_matches();
let (cmd, subcommand_args) = matches.subcommand().unwrap();
let paths = match matches.get_one::<RootDir>("root_dir") {
Some(dir) => SpacetimePaths::from_root_dir(dir),
None => SpacetimePaths::platform_defaults()?,
};
let cli_toml = matches
.get_one::<CliTomlPath>("config_path")
.cloned()
.unwrap_or_else(|| paths.cli_config_dir.cli_toml());
let config = Config::load(cli_toml)?;
exec_subcommand(config, &paths, cmd, subcommand_args).await?;
Ok(())
}
fn get_command() -> Command {
Command::new("spacetime")
.arg_required_else_help(true)
.subcommand_required(true)
.arg(
Arg::new("root_dir")
.long("root-dir")
.help("The root directory to store all spacetime files in.")
.value_parser(clap::value_parser!(RootDir)),
)
.arg(
Arg::new("config_path")
.long("config-path")
.help("The path to the cli.toml config file")
.value_parser(clap::value_parser!(CliTomlPath)),
)
.subcommands(get_subcommands())
.help_expected(true)
.help_template(
r#"
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ │
│ ⢀⠔⠁ │
│ ⣠⡞⠁ │
│ ⣀⣀⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣀⣀⣀⣀⣀⣀⣀⣤⣤⡴⠒ ⢀⣠⡾⠋ │
│ ⢀⣤⣶⣾88888888888888888888⠿⠋ ⢀⣴8⡟⠁ │
│ ⢀⣤⣾88888⡿⠿⠛⠛⠛⠛⠛⠛⠛⠛⠻⠿88888⠟⠁ ⣠⣾88⡟ │
│ ⢀⣴88888⠟⠋⠁ ⣀⣤⠤⠶⠶⠶⠶⠶⠤⣤⣀ ⠉⠉⠉ ⢀⣴⣾888⡟ │
│ ⣠88888⠋ ⣠⠶⠋⠉ ⠉⠙⠶⣄ ⢀⣴888888⠃ │
│ ⣰8888⡟⠁ ⣰⠟⠁ ⠈⠻⣆ ⠈⢿888888 │
│ ⢠8888⡟ ⡼⠁ ⠈⢧ ⠈⢿8888⡿ │
│ ⣼8888⠁ ⢸⠇ ⠸⡇ ⠘8888⣷ │
│ 88888 8 8 88888 │
│ ⢿8888⡄ ⢸⡆ ⢰⡇ ⢀8888⡟ │
│ ⣾8888⣷⡀ ⢳⡀ ⢀⡞ ⣼8888⠃ │
│ 888888⣷⡀ ⠹⣦⡀ ⢀⣴⠏ ⢀⣼8888⠏ │
│ ⢠888888⠟⠁ ⠙⠶⣄⣀ ⣀⣠⠶⠋ ⣠88888⠋ │
│ ⣼888⡿⠟⠁ ⣀⣀⣀ ⠉⠛⠒⠶⠶⠶⠶⠶⠒⠛⠉ ⢀⣠⣴88888⠟⠁ │
│ ⣼88⡿⠋ ⢀⣴88888⣶⣦⣤⣤⣤⣤⣤⣤⣤⣤⣶⣾88888⡿⠛⠁ │
│ ⢀⣼8⠟⠁ ⣠⣶88888888888888888888⡿⠿⠛⠁ │
│ ⣠⡾⠋⠁ ⠤⠞⠛⠛⠉⠉⠉⠉⠉⠉⠉⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠉⠉ │
│ ⢀⡼⠋ │
│ ⢀⠔⠁ │
│ │
│ │
│ .d8888b. 888 d8b 8888888b. 888888b. │
│ d88P Y88b 888 Y8P 888 "Y88b 888 "88b │
│ Y88b. 888 888 888 888 .88P │
│ "Y888b. 88888b. 8888b. .d8888b .d88b. 888888 888 88888b.d88b. .d88b. 888 888 8888888K. │
│ "Y88b. 888 "88b "88b d88P" d8P Y8b 888 888 888 "888 "88b d8P Y8b 888 888 888 "Y88b │
│ "888 888 888 .d888888 888 88888888 888 888 888 888 888 88888888 888 888 888 888 │
│ Y88b d88P 888 d88P 888 888 Y88b. Y8b. Y88b. 888 888 888 888 Y8b. 888 .d88P 888 d88P │
│ "Y8888P" 88888P" "Y888888 "Y8888P "Y8888 "Y888 888 888 888 888 "Y8888 8888888P" 8888888P" │
│ 888 │
│ 888 │
│ 888 │
│ "Multiplayer at the speed of light" │
│ │
├───────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ SpacetimeDB Command Line Tool │
│ Easily interact with a SpacetimeDB node │
│ │
│ Give us feedback in our Discord server: │
│ https://discord.gg/spacetimedb │
└───────────────────────────────────────────────────────────────────────────────────────────────────────┘
Usage:
{usage}
Options:
{options}
Commands:
{subcommands}
"#,
)
}