@@ -59,6 +59,12 @@ pub enum Error {
5959
6060 #[ snafu( display( "failed to locate containerfile relative to the {path:?} directory" ) ) ]
6161 NoSuchContainerfileExists { path : String } ,
62+
63+ #[ snafu( display( "failed to open scoped directory as {path}" ) ) ]
64+ OpenScopedDirectory {
65+ source : std:: io:: Error ,
66+ path : String ,
67+ } ,
6268}
6369
6470#[ derive( Debug , Snafu ) ]
@@ -68,6 +74,9 @@ pub enum TargetsError {
6874
6975 #[ snafu( display( "failed to read image config" ) ) ]
7076 ReadImageConfig { source : ImageConfigError } ,
77+
78+ #[ snafu( display( "failed to resolve parent directory of image config at {path}" , path = path. display( ) ) ) ]
79+ ResolveParentDirectory { path : PathBuf } ,
7180}
7281
7382#[ derive( Debug , Default ) ]
@@ -111,9 +120,21 @@ impl Targets {
111120 /// Returns a map of all targets by globbing for (nested) image config files.
112121 ///
113122 /// The search behaviour can be customized using the provided [`TargetsOptions`].
123+ //
124+ // SAFETY: We purposefully allow the `clippy::unwrap_in_result` lint below in this function.
125+ // We can use expect here, because the glob pattern is defined as a constant and the glob
126+ // function only returns an error if the pattern is invalid. We must ensure the pattern is
127+ // valid at compile time, because there is no need to allow an invalid pattern which would
128+ // render this tool inoperable.
129+ //
130+ // FIXME (@Techassi): This attribute can be used on individual unwrap and expect calls since
131+ // Rust 1.91.0. We should move this attribute to not contaminate an unnecessarily large scope
132+ // once we bump the toolchain to 1.91.0.
133+ // See https://github.com/rust-lang/rust-clippy/pull/15445
134+ #[ allow( clippy:: unwrap_in_result) ]
114135 pub fn all ( options : TargetsOptions ) -> Result < Self , TargetsError > {
115136 let image_config_paths = glob ( ImageConfig :: ALL_CONFIGS_GLOB_PATTERN )
116- . expect ( "glob pattern must be valid" )
137+ . expect ( "constant glob pattern must be valid" )
117138 . filter_map ( Result :: ok) ;
118139
119140 let mut targets = Self :: default ( ) ;
@@ -124,7 +145,9 @@ impl Targets {
124145
125146 let image_name = image_config_path
126147 . parent ( )
127- . expect ( "there must be a parent" )
148+ . with_context ( || ResolveParentDirectorySnafu {
149+ path : image_config_path. clone ( ) ,
150+ } ) ?
128151 . to_string_lossy ( )
129152 . into_owned ( ) ;
130153
@@ -336,7 +359,10 @@ impl Bakefile {
336359 // By using a cap-std Dir, we can ensure that the paths provided must be relative to
337360 // the appropriate image folder and wont escape it by providing absolute or relative
338361 // paths with traversals (..).
339- let image_dir = Dir :: open_ambient_dir ( & image_name, ambient_authority ( ) ) . unwrap ( ) ;
362+ let image_dir = Dir :: open_ambient_dir ( & image_name, ambient_authority ( ) )
363+ . with_context ( |_| OpenScopedDirectorySnafu {
364+ path : image_name. clone ( ) ,
365+ } ) ?;
340366
341367 let dockerfile_path = if let Some ( custom_path) = & image_options. dockerfile {
342368 ensure ! (
0 commit comments