Skip to content

Commit 58a536c

Browse files
committed
Add Build::try_build method
1 parent daaeb63 commit 58a536c

File tree

1 file changed

+51
-20
lines changed

1 file changed

+51
-20
lines changed

src/lib.rs

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::env;
2+
use std::error::Error;
23
use std::fs;
34
use std::path::{Path, PathBuf};
45

@@ -92,14 +93,25 @@ impl Build {
9293

9394
/// Builds the Lua artifacts for the specified version.
9495
pub fn build(&self, version: Version) -> Artifacts {
95-
let target = &self.target.as_ref().expect("TARGET is not set")[..];
96-
let out_dir = self.out_dir.as_ref().expect("OUT_DIR is not set");
96+
match self.try_build(version) {
97+
Ok(artifacts) => artifacts,
98+
Err(err) => panic!("{err}"),
99+
}
100+
}
101+
102+
/// Attempts to build the Lua artifacts for the specified version.
103+
///
104+
/// Returns an error if the build fails.
105+
pub fn try_build(&self, version: Version) -> Result<Artifacts, Box<dyn Error>> {
106+
let target = self.target.as_ref().ok_or("TARGET is not set")?;
107+
let out_dir = self.out_dir.as_ref().ok_or("OUT_DIR is not set")?;
97108
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
98109
let mut source_dir = manifest_dir.join(version.source_dir());
99110
let include_dir = out_dir.join("include");
100111

101112
if !include_dir.exists() {
102-
fs::create_dir_all(&include_dir).unwrap();
113+
fs::create_dir_all(&include_dir)
114+
.context(|| format!("Cannot create '{}'", include_dir.display()))?;
103115
}
104116

105117
let mut config = cc::Build::new();
@@ -148,27 +160,33 @@ impl Build {
148160

149161
let cpp_source_dir = out_dir.join("cpp_source");
150162
if cpp_source_dir.exists() {
151-
fs::remove_dir_all(&cpp_source_dir).unwrap();
163+
fs::remove_dir_all(&cpp_source_dir)
164+
.context(|| format!("Cannot remove '{}'", cpp_source_dir.display()))?;
152165
}
153-
fs::create_dir_all(&cpp_source_dir).unwrap();
166+
fs::create_dir_all(&cpp_source_dir)
167+
.context(|| format!("Cannot create '{}'", cpp_source_dir.display()))?;
154168

155-
for file in fs::read_dir(&source_dir).unwrap() {
156-
let file = file.unwrap();
169+
for file in fs::read_dir(&source_dir)
170+
.context(|| format!("Cannot read '{}'", source_dir.display()))?
171+
{
172+
let file = file?;
157173
let filename = file.file_name();
158-
let filename = filename.to_str().unwrap();
174+
let filename = &*filename.to_string_lossy();
159175
let src_file = source_dir.join(file.file_name());
160176
let dst_file = cpp_source_dir.join(file.file_name());
161177

162-
let mut content = fs::read(src_file).unwrap();
178+
let mut content = fs::read(&src_file)
179+
.context(|| format!("Cannot read '{}'", src_file.display()))?;
163180
if ["lauxlib.h", "lua.h", "lualib.h"].contains(&filename) {
164181
content.splice(0..0, b"extern \"C\" {\n".to_vec());
165182
content.extend(b"\n}".to_vec())
166183
}
167-
fs::write(dst_file, content).unwrap();
184+
fs::write(&dst_file, content)
185+
.context(|| format!("Cannot write to '{}'", dst_file.display()))?;
168186
}
169187
source_dir = cpp_source_dir
170188
}
171-
_ => panic!("don't know how to build Lua for {target}"),
189+
_ => Err(format!("don't know how to build Lua for {target}"))?,
172190
}
173191

174192
if let Lua54 = version {
@@ -199,19 +217,22 @@ impl Build {
199217
.include(&source_dir)
200218
.flag("-w") // Suppress all warnings
201219
.flag_if_supported("-fno-common") // Compile common globals like normal definitions
202-
.add_files_by_ext(&source_dir, "c")
220+
.add_files_by_ext(&source_dir, "c")?
203221
.out_dir(out_dir)
204-
.compile(version.lib_name());
222+
.try_compile(version.lib_name())?;
205223

206224
for f in &["lauxlib.h", "lua.h", "luaconf.h", "lualib.h"] {
207-
fs::copy(source_dir.join(f), include_dir.join(f)).unwrap();
225+
let from = source_dir.join(f);
226+
let to = include_dir.join(f);
227+
fs::copy(&from, &to)
228+
.context(|| format!("Cannot copy '{}' to '{}'", from.display(), to.display()))?;
208229
}
209230

210-
Artifacts {
231+
Ok(Artifacts {
211232
include_dir,
212233
lib_dir: out_dir.clone(),
213234
libs: vec![version.lib_name().to_string()],
214-
}
235+
})
215236
}
216237
}
217238

@@ -263,19 +284,29 @@ impl Artifacts {
263284
}
264285
}
265286

287+
trait ErrorContext<T> {
288+
fn context(self, f: impl FnOnce() -> String) -> Result<T, Box<dyn Error>>;
289+
}
290+
291+
impl<T, E: Error> ErrorContext<T> for Result<T, E> {
292+
fn context(self, f: impl FnOnce() -> String) -> Result<T, Box<dyn Error>> {
293+
self.map_err(|e| format!("{}: {e}", f()).into())
294+
}
295+
}
296+
266297
trait AddFilesByExt {
267-
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> &mut Self;
298+
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> Result<&mut Self, Box<dyn Error>>;
268299
}
269300

270301
impl AddFilesByExt for cc::Build {
271-
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> &mut Self {
302+
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> Result<&mut Self, Box<dyn Error>> {
272303
for entry in fs::read_dir(dir)
273-
.unwrap()
304+
.context(|| format!("Cannot read '{}'", dir.display()))?
274305
.filter_map(|e| e.ok())
275306
.filter(|e| e.path().extension() == Some(ext.as_ref()))
276307
{
277308
self.file(entry.path());
278309
}
279-
self
310+
Ok(self)
280311
}
281312
}

0 commit comments

Comments
 (0)