Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_syntax/tests/fixture/mod.rs

6.1 KiB, 1 run

created by r1870400018:62028, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! A command line shaped like Ore's, the first real caller of the argv path: long-only options,
2//! optional and repeated values, words after `--`, and commands' own sentences for absence and
3//! excess.
4use oxedyne_fe2o3_syntax::{
5 arg::{
6 Arg,
7 ArgConfig,
8 },
9 cmd::{
10 Cmd,
11 CmdConfig,
12 },
13 core::{
14 Syntax,
15 SyntaxConfig,
16 SyntaxRef,
17 },
18 help::Topic,
19 val::Val,
20};
21
22use oxedyne_fe2o3_core::prelude::*;
23use oxedyne_fe2o3_jdat::{
24 prelude::*,
25 version::SemVer,
26};
27
28pub const BACK_MISSING: &str = "back names one state to go back to.";
29pub const BACK_EXCESS: &str = "back names one state to go back to, and paths go after --.";
30pub const REST_MISSING: &str = "There is nothing after the --: name the paths to put back.";
31pub const FORGET_MISSING: &str = "forget needs something to forget.";
32
33fn long(name: &str, help: &str) -> Arg {
34 Arg::from(ArgConfig {
35 name: fmt!("{}", name),
36 hyph2: Some(fmt!("{}", name)),
37 help: Some(fmt!("{}", help)),
38 ..Default::default()
39 })
40}
41
42fn long_val(name: &str, val: Val, help: &str) -> Arg {
43 Arg::from(ArgConfig {
44 name: fmt!("{}", name),
45 hyph2: Some(fmt!("{}", name)),
46 vals: vec![val],
47 help: Some(fmt!("{}", help)),
48 ..Default::default()
49 })
50}
51
52pub fn ore() -> Outcome<SyntaxRef> {
53 let mut s = Syntax::from(SyntaxConfig {
54 name: fmt!("ore"),
55 ver: SemVer::new(0, 1, 0),
56 about: Some(fmt!("version control whose unit of history is the whole edit")),
57 one_cmd: true,
58 footer: Some(fmt!("Every command except init and help begins by capturing the \
59 working copy, so nothing has to be staged.")),
60 ..Default::default()
61 });
62
63 // Record
64 let mut c = Cmd::from(CmdConfig {
65 name: fmt!("init"),
66 help: Some(fmt!("Create a repository, minting a replica and a signing key.")),
67 cat: fmt!("Record"),
68 vals: vec![Val::text("dir").optional()
69 .help("Where to create it. Default: the current directory.")],
70 ..Default::default()
71 });
72 c = res!(c.add_arg(long("unsigned", "Record without signing")));
73 c = res!(c.add_arg(long_val("mirror", Val::text("path"), "Keep a git mirror at this path")));
74 s = res!(s.add_cmd(c));
75
76 let c = Cmd::from(CmdConfig {
77 name: fmt!("mark"),
78 help: Some(fmt!("Capture the working copy and name this point in history.")),
79 cat: fmt!("Record"),
80 vals: vec![
81 Val::text("name").help("The mark's name"),
82 Val::text("message").many().help("Words of the mark's message"),
83 ],
84 ..Default::default()
85 });
86 s = res!(s.add_cmd(c));
87
88 let mut c = Cmd::from(CmdConfig {
89 name: fmt!("key"),
90 help: Some(fmt!("Mint or replace this replica's keys: signing, content, veil.")),
91 cat: fmt!("Record"),
92 ..Default::default()
93 });
94 c = res!(c.add_arg(long_val("veil", Val::text("key").optional(), "Veil the store")));
95 c = res!(c.add_arg(long("veil-key", "Print the veil key")));
96 s = res!(s.add_cmd(c));
97
98 // Go back
99 let c = Cmd::from(CmdConfig {
100 name: fmt!("back"),
101 help: Some(fmt!("Put the working copy back to a mark (records nothing).")),
102 cat: fmt!("Go back"),
103 vals: vec![Val::text("mark").missing(BACK_MISSING).help("The mark to go back to")],
104 rest: Some(Val::text("path").one_or_more().missing(REST_MISSING)
105 .help("Put back only these paths")),
106 excess: Some(fmt!("{}", BACK_EXCESS)),
107 ..Default::default()
108 });
109 s = res!(s.add_cmd(c));
110
111 let mut c = Cmd::from(CmdConfig {
112 name: fmt!("forget"),
113 help: Some(fmt!("Take content out of operations, keep their shape, record why.")),
114 cat: fmt!("Go back"),
115 vals: vec![Val::text("op|path").one_or_more().missing(FORGET_MISSING)
116 .help("An operation or a path")],
117 ..Default::default()
118 });
119 c = res!(c.add_arg(long_val("reason", Val::text("text"), "Why, for the record")));
120 c = res!(c.add_arg(long("dry-run", "Say what would be forgotten, and write nothing")));
121 s = res!(s.add_cmd(c));
122
123 // Exchange
124 let mut c = Cmd::from(CmdConfig {
125 name: fmt!("sync"),
126 help: Some(fmt!("Exchange operations with another repository or a relay.")),
127 cat: fmt!("Exchange"),
128 vals: vec![Val::text("repo|url").help("The root of another Ore repository this \
129 machine can reach, or a relay named https://<host>/<account>/<repository>.")],
130 detail: Some(fmt!("Both ends end up holding every operation either held, and \
131 nothing is ever overwritten: a sync only adds.\n\
132 \n\
133 A relay is reached the same way:\n\
134 \n\
135 \x20 ore sync https://relay.example/me/notes\n\
136 \n\
137 Neither end needs to be still for a sync.")),
138 see: vec![fmt!("relay")],
139 ..Default::default()
140 });
141 c = res!(c.add_arg(long("pull-only",
142 "Take what the other end has, hand over nothing, and record nothing here")));
143 c = res!(c.add_arg(long("dry-run", "Say what a sync would bring, and write nothing")));
144 c = res!(c.add_arg(long_val("oresyn-max", Val::new(Kind::U8, "n"),
145 "Hold this end to an older ORESYN vocabulary")));
146 s = res!(s.add_cmd(c));
147
148 s = res!(s.add_topic(Topic::new(
149 "capture",
150 "what every command does first",
151 "Every command but init begins by capturing the working copy: each file that has \
152 changed since the last capture becomes an operation in the log.",
153 )));
154 s = res!(s.add_topic(Topic::new(
155 "relay",
156 "exchanging through a server",
157 "A relay holds a repository's operations for machines that cannot reach each other.",
158 )));
159
160 Ok(SyntaxRef::new(s))
161}
162
163#[allow(dead_code)]
164pub fn words(line: &str) -> Vec<String> {
165 line.split_whitespace().map(|w| w.to_string()).collect()
166}