@@ -8,6 +8,19 @@ use crate::ui::quoted_path;
88/// The name given to the default manifest file.
99pub const DEFAULT_MANIFEST_FILE : & str = "spin.toml" ;
1010
11+ /// Attempts to find a manifest. If a path is provided, that path is resolved
12+ /// using `resolve_manifest_file_path`; otherwise, a directory search is carried out
13+ /// using `search_upwards_for_manifest`. If a manifest is found, a boolean is
14+ /// also returned indicating if it was the default: this can be used to
15+ /// notify the user that a non-default manifest is being used.
16+ pub fn find_manifest_file_path ( provided_path : Option < impl AsRef < Path > > ) -> Result < ( PathBuf , bool ) > {
17+ match provided_path {
18+ Some ( provided_path) => resolve_manifest_file_path ( provided_path) . map ( |p| ( p, true ) ) ,
19+ None => search_upwards_for_manifest ( )
20+ . ok_or_else ( || anyhow ! ( "\" {}\" not found" , DEFAULT_MANIFEST_FILE ) ) ,
21+ }
22+ }
23+
1124/// Resolves a manifest path provided by a user, which may be a file or
1225/// directory, to a path to a manifest file.
1326pub fn resolve_manifest_file_path ( provided_path : impl AsRef < Path > ) -> Result < PathBuf > {
@@ -36,6 +49,30 @@ pub fn resolve_manifest_file_path(provided_path: impl AsRef<Path>) -> Result<Pat
3649 }
3750}
3851
52+ /// Starting from the current directory, searches upward through
53+ /// the directory tree for a manifest (that is, a file with the default
54+ /// manifest name `spin.toml`). If found, the path to the manifest
55+ /// is returned, with a boolean flag indicating if the found path was
56+ /// the default (i.e. `spin.toml` in the current directory).
57+ /// If no matching file is found, the function returns None.
58+ pub fn search_upwards_for_manifest ( ) -> Option < ( PathBuf , bool ) > {
59+ let mut inferred_dir = std:: env:: current_dir ( ) . unwrap ( ) ;
60+ let mut is_default = true ;
61+
62+ loop {
63+ let candidate = inferred_dir. join ( DEFAULT_MANIFEST_FILE ) ;
64+
65+ if candidate. is_file ( ) {
66+ return Some ( ( candidate, is_default) ) ;
67+ }
68+
69+ is_default = false ;
70+ let parent = inferred_dir. parent ( ) ?;
71+
72+ inferred_dir = parent. to_owned ( ) ;
73+ }
74+ }
75+
3976/// Resolves the parent directory of a path, returning an error if the path
4077/// has no parent. A path with a single component will return ".".
4178pub fn parent_dir ( path : impl AsRef < Path > ) -> Result < PathBuf > {
0 commit comments