Skip to content

Commit 0f0b41a

Browse files
committed
xtask: Streamline error handling
1 parent d75612a commit 0f0b41a

File tree

4 files changed

+96
-82
lines changed

4 files changed

+96
-82
lines changed

xtask/src/build.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn build(sh: &Shell, flags: flags::Build) -> anyhow::Result<()> {
5454

5555
if flags.release {
5656
// Perform wasm-opt on plugin
57-
wasm_opt_plugins(sh, plugin_name).with_context(err_context)?;
57+
wasm_opt_plugin(sh, plugin_name).with_context(err_context)?;
5858
} else {
5959
// Must copy plugins to zellij-utils, too!
6060
let source = PathBuf::from(
@@ -82,7 +82,7 @@ pub fn build(sh: &Shell, flags: flags::Build) -> anyhow::Result<()> {
8282
/// for filenames ending with `.wasm`. For this to work the plugins must be built beforehand.
8383
// TODO: Should this panic if there is no plugin found? What should we do when only some plugins
8484
// have been built before?
85-
pub fn wasm_opt_plugins(sh: &Shell, plugin_name: &str) -> anyhow::Result<()> {
85+
pub fn wasm_opt_plugin(sh: &Shell, plugin_name: &str) -> anyhow::Result<()> {
8686
let err_context = || format!("failed to run 'wasm-opt' on plugin '{plugin_name}'");
8787

8888
let wasm_opt = wasm_opt(sh).with_context(err_context)?;
@@ -102,11 +102,7 @@ pub fn wasm_opt_plugins(sh: &Shell, plugin_name: &str) -> anyhow::Result<()> {
102102
.join("release")
103103
.join(plugin_name)
104104
.with_extension("wasm");
105-
//target_dir.push("wasm32-wasi");
106-
//target_dir.push("release");
107-
//plugin_name
108-
//target_dir.push(plugin);
109-
//
105+
110106
if !plugin.is_file() {
111107
return Err(anyhow::anyhow!("No plugin found at '{}'", plugin.display()))
112108
.with_context(err_context);
@@ -115,7 +111,7 @@ pub fn wasm_opt_plugins(sh: &Shell, plugin_name: &str) -> anyhow::Result<()> {
115111
Some(name) => name,
116112
None => {
117113
return Err(anyhow::anyhow!(
118-
"Couldn't read filename containing invalid unicode"
114+
"couldn't read filename containing invalid unicode"
119115
))
120116
.with_context(err_context)
121117
},
@@ -145,7 +141,7 @@ fn wasm_opt(_sh: &Shell) -> anyhow::Result<PathBuf> {
145141
Err(e) => {
146142
println!("!! 'wasm-opt' wasn't found but is needed for this build step.");
147143
println!("!! Please install it from here: https://github.com/WebAssembly/binaryen");
148-
Err(e).context("Couldn't find 'wasm-opt' executable")
144+
Err(e).context("couldn't find 'wasm-opt' executable")
149145
},
150146
}
151147
}
@@ -154,21 +150,19 @@ fn wasm_opt(_sh: &Shell) -> anyhow::Result<PathBuf> {
154150
// mkdir -p ${root_dir}/assets/man
155151
// mandown ${root_dir}/docs/MANPAGE.md 1 > ${root_dir}/assets/man/zellij.1
156152
pub fn manpage(sh: &Shell) -> anyhow::Result<()> {
157-
let mandown = mandown(sh)?;
153+
let err_context = "failed to generate manpage";
154+
155+
let mandown = mandown(sh).context(err_context)?;
158156

159157
let project_root = crate::project_root();
160158
let asset_dir = &project_root.join("assets").join("man");
161-
sh.create_dir(&asset_dir)
162-
.context("Couldn't create asset dir for plugins")?;
159+
sh.create_dir(&asset_dir).context(err_context)?;
163160
let _pd = sh.push_dir(asset_dir);
164161

165-
let text = cmd!(sh, "{mandown} {project_root}/docs/MANPAGE.md 1")
162+
cmd!(sh, "{mandown} {project_root}/docs/MANPAGE.md 1")
166163
.read()
167-
.context("Generating man pages failed")?;
168-
sh.write_file("zellij.1", text)
169-
.context("Writing man pages failed")?;
170-
171-
Ok(())
164+
.and_then(|text| sh.write_file("zellij.1", text))
165+
.context(err_context)
172166
}
173167

174168
/// Get the path to a `mandown` executable.

xtask/src/format.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::Context;
44
use std::path::{Path, PathBuf};
55
use xshell::{cmd, Shell};
66

7-
pub fn format(sh: &Shell, _flags: flags::Format) -> anyhow::Result<()> {
7+
pub fn format(sh: &Shell, flags: flags::Format) -> anyhow::Result<()> {
88
let cargo = check_rustfmt()
99
.and_then(|_| crate::cargo())
1010
.context("failed to run task 'format'")?;
@@ -17,8 +17,11 @@ pub fn format(sh: &Shell, _flags: flags::Format) -> anyhow::Result<()> {
1717
crate::status(&msg);
1818
println!("{}", msg);
1919

20-
cmd!(sh, "{cargo} fmt")
21-
.run()
20+
let mut cmd = cmd!(sh, "{cargo} fmt");
21+
if flags.check {
22+
cmd = cmd.arg("--check");
23+
}
24+
cmd.run()
2225
.with_context(|| format!("Failed to format '{subcrate}'"))?;
2326
}
2427
Ok(())

xtask/src/main.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
// - publish-zellij: `cargo publish [tile, client, server, utils, tile-utils, zellij]`
3838

3939
mod build;
40+
mod ci;
4041
mod clippy;
4142
mod dist;
4243
mod flags;
@@ -86,6 +87,7 @@ fn main() -> anyhow::Result<()> {
8687
flags::XtaskCmd::Make(flags) => pipelines::make(shell, flags),
8788
flags::XtaskCmd::Install(flags) => pipelines::install(shell, flags),
8889
flags::XtaskCmd::Run(flags) => pipelines::run(shell, flags),
90+
flags::XtaskCmd::Ci(flags) => ci::main(shell, flags),
8991
}?;
9092

9193
let elapsed = now.elapsed().as_secs();
@@ -116,7 +118,8 @@ pub fn status(msg: &str) {
116118
}
117119

118120
fn deprecation_notice() -> anyhow::Result<()> {
119-
Err(anyhow::anyhow!(" !!! cargo make has been deprecated by zellij !!!
121+
Err(anyhow::anyhow!(
122+
" !!! cargo make has been deprecated by zellij !!!
120123
121124
Our build system is now `cargo xtask`. Don't worry, you won't have to install
122125
anything!
@@ -137,5 +140,6 @@ anything!
137140
| make install /path/to/binary | xtask install /path/to/binary |
138141
| make publish | N/A |
139142
| make manpage | N/A |
140-
"))
143+
"
144+
))
141145
}

xtask/src/pipelines.rs

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,28 @@ use xshell::{cmd, Shell};
1515
/// - test
1616
/// - clippy
1717
pub fn make(sh: &Shell, flags: flags::Make) -> anyhow::Result<()> {
18-
format::format(sh, flags::Format {})?;
19-
build::build(
20-
sh,
21-
flags::Build {
22-
release: flags.release,
23-
no_plugins: false,
24-
plugins_only: false,
25-
},
26-
)?;
27-
test::test(sh, flags::Test { args: vec![] })?;
28-
clippy::clippy(sh, flags::Clippy {})?;
29-
Ok(())
18+
let err_context = || format!("failed to run pipeline 'make' with args {flags:?}");
19+
20+
if flags.clean {
21+
crate::cargo()
22+
.and_then(|cargo| cmd!(sh, "{cargo} clean").run().map_err(anyhow::Error::new))
23+
.with_context(err_context)?;
24+
}
25+
26+
format::format(sh, flags::Format { check: false })
27+
.and_then(|_| {
28+
build::build(
29+
sh,
30+
flags::Build {
31+
release: flags.release,
32+
no_plugins: false,
33+
plugins_only: false,
34+
},
35+
)
36+
})
37+
.and_then(|_| test::test(sh, flags::Test { args: vec![] }))
38+
.and_then(|_| clippy::clippy(sh, flags::Clippy {}))
39+
.with_context(err_context)
3040
}
3141

3242
/// Generate a runnable executable.
@@ -39,6 +49,8 @@ pub fn make(sh: &Shell, flags: flags::Make) -> anyhow::Result<()> {
3949
/// - [`manpage`](build::manpage)
4050
/// - Copy the executable to [target file](flags::Install::destination)
4151
pub fn install(sh: &Shell, flags: flags::Install) -> anyhow::Result<()> {
52+
let err_context = || format!("failed to run pipeline 'install' with args {flags:?}");
53+
4254
// Build and optimize plugins
4355
build::build(
4456
sh,
@@ -47,84 +59,85 @@ pub fn install(sh: &Shell, flags: flags::Install) -> anyhow::Result<()> {
4759
no_plugins: false,
4860
plugins_only: true,
4961
},
50-
)?;
51-
52-
// Build the main executable
53-
build::build(
54-
sh,
55-
flags::Build {
56-
release: true,
57-
no_plugins: true,
58-
plugins_only: false,
59-
},
60-
)?;
61-
62-
// Generate man page
63-
build::manpage(sh)?;
62+
)
63+
.and_then(|_| {
64+
// Build the main executable
65+
build::build(
66+
sh,
67+
flags::Build {
68+
release: true,
69+
no_plugins: true,
70+
plugins_only: false,
71+
},
72+
)
73+
})
74+
.and_then(|_| {
75+
// Generate man page
76+
build::manpage(sh)
77+
})
78+
.with_context(err_context)?;
6479

6580
// Copy binary to destination
6681
let destination = if flags.destination.is_absolute() {
67-
flags.destination
82+
flags.destination.clone()
6883
} else {
6984
std::env::current_dir()
7085
.context("Can't determine current working directory")?
71-
.join(flags.destination)
86+
.join(&flags.destination)
7287
};
7388
sh.change_dir(crate::project_root());
7489
sh.copy_file("target/release/zellij", &destination)
75-
.with_context(|| format!("Failed to copy executable to '{}", destination.display()))?;
76-
Ok(())
90+
.with_context(err_context)
7791
}
7892

7993
/// Run zellij debug build.
8094
pub fn run(sh: &Shell, flags: flags::Run) -> anyhow::Result<()> {
95+
let err_context = || format!("failed to run pipeline 'run' with args {flags:?}");
96+
8197
build::build(
8298
sh,
8399
flags::Build {
84100
release: false,
85101
no_plugins: false,
86102
plugins_only: true,
87103
},
88-
)?;
89-
90-
crate::cargo()
91-
.and_then(|cargo| {
92-
cmd!(sh, "{cargo} run")
93-
.args(flags.args)
94-
.run()
95-
.context("command failure")
96-
})
97-
.context("failed to run debug build")
104+
)
105+
.and_then(|_| crate::cargo())
106+
.and_then(|cargo| {
107+
cmd!(sh, "{cargo} run")
108+
.args(&flags.args)
109+
.run()
110+
.map_err(anyhow::Error::new)
111+
})
112+
.with_context(err_context)
98113
}
99114

100115
/// Bundle all distributable content to `target/dist`.
101116
///
102117
/// This includes the optimized zellij executable from the [`install`] pipeline, the man page, the
103118
/// `.desktop` file and the application logo.
104119
pub fn dist(sh: &Shell, _flags: flags::Dist) -> anyhow::Result<()> {
120+
let err_context = || format!("failed to run pipeline 'dist'");
121+
105122
sh.change_dir(crate::project_root());
106123
if sh.path_exists("target/dist") {
107-
sh.remove_path("target/dist")
108-
.context("Failed to clean up dist directory")?;
124+
sh.remove_path("target/dist").with_context(err_context)?;
109125
}
110126
sh.create_dir("target/dist")
111-
.context("Failed to create dist directory")?;
112-
113-
install(
114-
sh,
115-
flags::Install {
116-
destination: crate::project_root().join("./target/dist/zellij"),
117-
},
118-
)
119-
.context("Failed to build zellij for distributing")?;
127+
.map_err(anyhow::Error::new)
128+
.and_then(|_| {
129+
install(
130+
sh,
131+
flags::Install {
132+
destination: crate::project_root().join("./target/dist/zellij"),
133+
},
134+
)
135+
})
136+
.with_context(err_context)?;
120137

121138
sh.create_dir("target/dist/man")
122-
.context("Failed to create directory for man pages in dist folder")?;
123-
sh.copy_file("assets/man/zellij.1", "target/dist/man/zellij.1")
124-
.context("Failed to copy generated manpage to dist folder")?;
125-
sh.copy_file("assets/zellij.desktop", "target/dist/zellij.desktop")
126-
.context("Failed to copy zellij desktop file to dist folder")?;
127-
sh.copy_file("assets/logo.png", "target/dist/logo.png")
128-
.context("Failed to copy zellij logo to dist folder")?;
129-
Ok(())
139+
.and_then(|_| sh.copy_file("assets/man/zellij.1", "target/dist/man/zellij.1"))
140+
.and_then(|_| sh.copy_file("assets/zellij.desktop", "target/dist/zellij.desktop"))
141+
.and_then(|_| sh.copy_file("assets/logo.png", "target/dist/logo.png"))
142+
.with_context(err_context)
130143
}

0 commit comments

Comments
 (0)