1- use std:: env;
2- use std:: fs;
1+ use std:: error:: Error ;
32use std:: path:: { Path , PathBuf } ;
43use std:: process:: Command ;
4+ use std:: { env, fs, io} ;
5+
6+ type DynError = Box < dyn Error + Send + Sync > ;
57
68/// Represents the configuration for building LuaJIT artifacts.
79pub struct Build {
@@ -87,6 +89,13 @@ impl Build {
8789
8890 /// Builds the LuaJIT artifacts.
8991 pub fn build ( & mut self ) -> Artifacts {
92+ self . try_build ( ) . expect ( "LuaJIT build failed" )
93+ }
94+
95+ /// Attempts to build the LuaJIT artifacts.
96+ ///
97+ /// Returns an error if the build fails.
98+ pub fn try_build ( & mut self ) -> Result < Artifacts , DynError > {
9099 let target = & self . target . as_ref ( ) . expect ( "TARGET is not set" ) [ ..] ;
91100
92101 if target. contains ( "msvc" ) {
@@ -96,7 +105,7 @@ impl Build {
96105 self . build_unix ( )
97106 }
98107
99- fn build_unix ( & mut self ) -> Artifacts {
108+ fn build_unix ( & mut self ) -> Result < Artifacts , DynError > {
100109 let target = & self . target . as_ref ( ) . expect ( "TARGET is not set" ) [ ..] ;
101110 let host = & self . host . as_ref ( ) . expect ( "HOST is not set" ) [ ..] ;
102111 let out_dir = self . out_dir . as_ref ( ) . expect ( "OUT_DIR is not set" ) ;
@@ -109,22 +118,23 @@ impl Build {
109118 // Cleanup
110119 for dir in [ & build_dir, & lib_dir, & include_dir] {
111120 if dir. exists ( ) {
112- fs:: remove_dir_all ( dir)
113- . unwrap_or_else ( |e| panic ! ( "cannot remove {}: {e}" , dir. display( ) ) ) ;
121+ fs:: remove_dir_all ( dir) . context ( || format ! ( "Cannot remove {}" , dir. display( ) ) ) ?;
114122 }
115- fs:: create_dir_all ( dir)
116- . unwrap_or_else ( |e| panic ! ( "cannot create {}: {e}" , dir. display( ) ) ) ;
123+ fs:: create_dir_all ( dir) . context ( || format ! ( "Cannot create {}" , dir. display( ) ) ) ?;
117124 }
118- cp_r ( & source_dir, & build_dir) ;
125+ cp_r ( & source_dir, & build_dir) ? ;
119126
120127 // Copy release version file
121128 let relver = build_dir. join ( ".relver" ) ;
122- fs:: copy ( manifest_dir. join ( "luajit_relver.txt" ) , & relver) . unwrap ( ) ;
129+ fs:: copy ( manifest_dir. join ( "luajit_relver.txt" ) , & relver)
130+ . context ( || format ! ( "Cannot copy 'luajit_relver.txt'" ) ) ?;
123131
124132 // Fix permissions for certain build situations
125- let mut perms = fs:: metadata ( & relver) . unwrap ( ) . permissions ( ) ;
133+ let mut perms = ( fs:: metadata ( & relver) . map ( |md| md. permissions ( ) ) )
134+ . context ( || format ! ( "Cannot read permissions for '{}'" , relver. display( ) ) ) ?;
126135 perms. set_readonly ( false ) ;
127- fs:: set_permissions ( relver, perms) . unwrap ( ) ;
136+ fs:: set_permissions ( & relver, perms)
137+ . context ( || format ! ( "Cannot set permissions for '{}'" , relver. display( ) ) ) ?;
128138
129139 let mut cc = cc:: Build :: new ( ) ;
130140 cc. warnings ( false ) ;
@@ -170,7 +180,7 @@ impl Build {
170180 } ;
171181
172182 let compiler_path =
173- which:: which ( compiler_path) . unwrap_or_else ( |_| panic ! ( "cannot find {compiler_path}" ) ) ;
183+ which:: which ( compiler_path) . context ( || format ! ( "Cannot find {compiler_path}" ) ) ? ;
174184 let bindir = compiler_path. parent ( ) . unwrap ( ) ;
175185 let compiler_path = compiler_path. to_str ( ) . unwrap ( ) ;
176186 let compiler_args = compiler. cflags_env ( ) ;
@@ -229,12 +239,13 @@ impl Build {
229239
230240 make. env ( "BUILDMODE" , "static" ) ;
231241 make. env ( "XCFLAGS" , xcflags. join ( " " ) ) ;
232- self . run_command ( make, "building LuaJIT" ) ;
242+ self . run_command ( & mut make)
243+ . context ( || format ! ( "Error running '{make:?}'" ) ) ?;
233244
234245 Artifacts :: make ( & build_dir, & include_dir, & lib_dir, false )
235246 }
236247
237- fn build_msvc ( & mut self ) -> Artifacts {
248+ fn build_msvc ( & mut self ) -> Result < Artifacts , DynError > {
238249 let target = & self . target . as_ref ( ) . expect ( "TARGET is not set" ) [ ..] ;
239250 let out_dir = self . out_dir . as_ref ( ) . expect ( "OUT_DIR is not set" ) ;
240251 let manifest_dir = Path :: new ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
@@ -246,17 +257,16 @@ impl Build {
246257 // Cleanup
247258 for dir in [ & build_dir, & lib_dir, & include_dir] {
248259 if dir. exists ( ) {
249- fs:: remove_dir_all ( dir)
250- . unwrap_or_else ( |e| panic ! ( "cannot remove {}: {e}" , dir. display( ) ) ) ;
260+ fs:: remove_dir_all ( dir) . context ( || format ! ( "Cannot remove {}" , dir. display( ) ) ) ?;
251261 }
252- fs:: create_dir_all ( dir)
253- . unwrap_or_else ( |e| panic ! ( "cannot create {}: {e}" , dir. display( ) ) ) ;
262+ fs:: create_dir_all ( dir) . context ( || format ! ( "Cannot create {}" , dir. display( ) ) ) ?;
254263 }
255- cp_r ( & source_dir, & build_dir) ;
264+ cp_r ( & source_dir, & build_dir) ? ;
256265
257266 // Copy release version file
258- #[ rustfmt:: skip]
259- fs:: copy ( manifest_dir. join ( "luajit_relver.txt" ) , build_dir. join ( ".relver" ) ) . unwrap ( ) ;
267+ let relver = build_dir. join ( ".relver" ) ;
268+ fs:: copy ( manifest_dir. join ( "luajit_relver.txt" ) , & relver)
269+ . context ( || format ! ( "Cannot copy 'luajit_relver.txt'" ) ) ?;
260270
261271 let mut msvcbuild = Command :: new ( build_dir. join ( "src" ) . join ( "msvcbuild.bat" ) ) ;
262272 msvcbuild. current_dir ( build_dir. join ( "src" ) ) ;
@@ -270,28 +280,24 @@ impl Build {
270280 msvcbuild. env ( k, v) ;
271281 }
272282
273- self . run_command ( msvcbuild, "building LuaJIT" ) ;
283+ self . run_command ( & mut msvcbuild)
284+ . context ( || format ! ( "Error running'{msvcbuild:?}'" ) ) ?;
274285
275286 Artifacts :: make ( & build_dir, & include_dir, & lib_dir, true )
276287 }
277288
278- fn run_command ( & self , mut command : Command , desc : & str ) {
279- let status = command. status ( ) . unwrap ( ) ;
289+ fn run_command ( & self , command : & mut Command ) -> io :: Result < ( ) > {
290+ let status = command. status ( ) ? ;
280291 if !status. success ( ) {
281- panic ! (
282- "
283- Error {desc}:
284- Command: {command:?}
285- Exit status: {status}
286- "
287- ) ;
292+ return Err ( io:: Error :: other ( format ! ( "exited with status {status}" ) ) ) ;
288293 }
294+ Ok ( ( ) )
289295 }
290296}
291297
292- fn cp_r ( src : & Path , dst : & Path ) {
293- for f in fs:: read_dir ( src) . unwrap ( ) {
294- let f = f. unwrap ( ) ;
298+ fn cp_r ( src : & Path , dst : & Path ) -> Result < ( ) , DynError > {
299+ for f in fs:: read_dir ( src) . context ( || format ! ( "Cannot read directory '{}'" , src . display ( ) ) ) ? {
300+ let f = f. context ( || format ! ( "Cannot read entry in '{}'" , src . display ( ) ) ) ? ;
295301 let path = f. path ( ) ;
296302 let name = path. file_name ( ) . unwrap ( ) ;
297303
@@ -302,13 +308,16 @@ fn cp_r(src: &Path, dst: &Path) {
302308
303309 let dst = dst. join ( name) ;
304310 if f. file_type ( ) . unwrap ( ) . is_dir ( ) {
305- fs:: create_dir_all ( & dst) . unwrap ( ) ;
306- cp_r ( & path, & dst) ;
311+ fs:: create_dir_all ( & dst)
312+ . context ( || format ! ( "Cannot create directory '{}'" , dst. display( ) ) ) ?;
313+ cp_r ( & path, & dst) ?;
307314 } else {
308315 let _ = fs:: remove_file ( & dst) ;
309- fs:: copy ( & path, & dst) . unwrap ( ) ;
316+ fs:: copy ( & path, & dst)
317+ . context ( || format ! ( "Cannot copy '{}' to '{}'" , path. display( ) , dst. display( ) ) ) ?;
310318 }
311319 }
320+ Ok ( ( ) )
312321}
313322
314323impl Artifacts {
@@ -345,21 +354,42 @@ impl Artifacts {
345354 }
346355 }
347356
348- fn make ( build_dir : & Path , include_dir : & Path , lib_dir : & Path , is_msvc : bool ) -> Self {
357+ fn make (
358+ build_dir : & Path ,
359+ include_dir : & Path ,
360+ lib_dir : & Path ,
361+ is_msvc : bool ,
362+ ) -> Result < Self , DynError > {
349363 for f in & [ "lauxlib.h" , "lua.h" , "luaconf.h" , "luajit.h" , "lualib.h" ] {
350- fs:: copy ( build_dir. join ( "src" ) . join ( f) , include_dir. join ( f) ) . unwrap ( ) ;
364+ let from = build_dir. join ( "src" ) . join ( f) ;
365+ let to = include_dir. join ( f) ;
366+ fs:: copy ( & from, & to)
367+ . context ( || format ! ( "Cannot copy '{}' to '{}'" , from. display( ) , to. display( ) ) ) ?;
351368 }
352369
353370 let lib_name = if !is_msvc { "luajit" } else { "lua51" } ;
354371 let lib_file = if !is_msvc { "libluajit.a" } else { "lua51.lib" } ;
355372 if build_dir. join ( "src" ) . join ( lib_file) . exists ( ) {
356- fs:: copy ( build_dir. join ( "src" ) . join ( lib_file) , lib_dir. join ( lib_file) ) . unwrap ( ) ;
373+ let from = build_dir. join ( "src" ) . join ( lib_file) ;
374+ let to = lib_dir. join ( lib_file) ;
375+ fs:: copy ( & from, & to)
376+ . context ( || format ! ( "Cannot copy '{}' to '{}'" , from. display( ) , to. display( ) ) ) ?;
357377 }
358378
359- Artifacts {
379+ Ok ( Artifacts {
360380 lib_dir : lib_dir. to_path_buf ( ) ,
361381 include_dir : include_dir. to_path_buf ( ) ,
362382 libs : vec ! [ lib_name. to_string( ) ] ,
363- }
383+ } )
384+ }
385+ }
386+
387+ trait ErrorContext < T > {
388+ fn context ( self , f : impl FnOnce ( ) -> String ) -> Result < T , DynError > ;
389+ }
390+
391+ impl < T , E : Error > ErrorContext < T > for Result < T , E > {
392+ fn context ( self , f : impl FnOnce ( ) -> String ) -> Result < T , DynError > {
393+ self . map_err ( |e| format ! ( "{}: {e}" , f( ) ) . into ( ) )
364394 }
365395}
0 commit comments