@@ -7,20 +7,42 @@ use crate::{
7
7
print:: PrintSender ,
8
8
} ;
9
9
use omnibor:: {
10
- embedding:: NoEmbed , hashes:: Sha256 , storage:: FileSystemStorage , InputManifestBuilder ,
11
- IntoArtifactId , RelationKind ,
10
+ embedding:: { EmbeddingMode , NoEmbed } ,
11
+ hashes:: Sha256 ,
12
+ storage:: { FileSystemStorage , InMemoryStorage , Storage } ,
13
+ ArtifactId , InputManifestBuilder , IntoArtifactId , RelationKind , ShouldStore ,
14
+ } ;
15
+ use pathbuf:: pathbuf;
16
+ use std:: {
17
+ env:: current_dir,
18
+ fs:: File ,
19
+ io:: Write ,
20
+ path:: { Path , PathBuf } ,
12
21
} ;
13
- use tracing:: debug;
14
22
15
23
/// Run the `manifest create` subcommand.
16
24
pub async fn run ( _tx : & PrintSender , app : & App , args : & ManifestCreateArgs ) -> Result < ( ) > {
17
- let root = app. args . dir ( ) . ok_or_else ( || Error :: NoRoot ) ?;
18
- debug ! ( root = %root. display( ) ) ;
19
-
20
- let storage = FileSystemStorage :: new ( root) . map_err ( Error :: StorageInitFailed ) ?;
25
+ let root = app. args . dir ( ) . ok_or ( Error :: NoRoot ) ?;
21
26
22
- let mut builder = InputManifestBuilder :: < Sha256 , NoEmbed , _ > :: with_storage ( storage) ;
27
+ if args. no_store {
28
+ let storage = InMemoryStorage :: new ( ) ;
29
+ let builder = InputManifestBuilder :: < Sha256 , NoEmbed , _ > :: with_storage ( storage) ;
30
+ create_with_builder ( args, builder)
31
+ } else {
32
+ let storage = FileSystemStorage :: new ( root) . map_err ( Error :: StorageInitFailed ) ?;
33
+ let builder = InputManifestBuilder :: < Sha256 , NoEmbed , _ > :: with_storage ( storage) ;
34
+ create_with_builder ( args, builder)
35
+ }
36
+ }
23
37
38
+ fn create_with_builder < E , S > (
39
+ args : & ManifestCreateArgs ,
40
+ mut builder : InputManifestBuilder < Sha256 , E , S > ,
41
+ ) -> Result < ( ) >
42
+ where
43
+ E : EmbeddingMode ,
44
+ S : Storage < Sha256 > ,
45
+ {
24
46
for input in & args. inputs {
25
47
let aid = input. clone ( ) . into_artifact_id ( ) . map_err ( Error :: IdFailed ) ?;
26
48
builder
@@ -38,9 +60,44 @@ pub async fn run(_tx: &PrintSender, app: &App, args: &ManifestCreateArgs) -> Res
38
60
. map_err ( Error :: AddRelationFailed ) ?;
39
61
}
40
62
41
- builder
42
- . finish ( & args. target )
63
+ let should_store = if args. no_store {
64
+ ShouldStore :: No
65
+ } else {
66
+ ShouldStore :: Yes
67
+ } ;
68
+
69
+ let transaction_ids = builder
70
+ . finish ( & args. target , should_store)
43
71
. map_err ( Error :: ManifestBuildFailed ) ?;
44
72
73
+ let path = manifest_file_path ( args. output . as_deref ( ) , transaction_ids. target_aid ( ) ) ?;
74
+
75
+ let mut output_file = File :: create_new ( & path) . map_err ( |source| Error :: CantWriteManifest {
76
+ path : path. to_path_buf ( ) ,
77
+ source,
78
+ } ) ?;
79
+
80
+ output_file
81
+ // SAFETY: We just constructed the manifest, so we know it's fine.
82
+ . write_all ( & transaction_ids. manifest ( ) . as_bytes ( ) . unwrap ( ) )
83
+ . map_err ( |source| Error :: CantWriteManifest {
84
+ path : path. to_path_buf ( ) ,
85
+ source,
86
+ } ) ?;
87
+
45
88
Ok ( ( ) )
46
89
}
90
+
91
+ fn manifest_file_path ( output : Option < & Path > , target_aid : ArtifactId < Sha256 > ) -> Result < PathBuf > {
92
+ let dir = match & output {
93
+ Some ( dir) => dir. to_path_buf ( ) ,
94
+ None => match current_dir ( ) {
95
+ Ok ( dir) => dir,
96
+ Err ( _) => return Err ( Error :: NoOutputDir ) ,
97
+ } ,
98
+ } ;
99
+
100
+ let file_name = format ! ( "{}.manifest" , target_aid. as_hex( ) ) ;
101
+
102
+ Ok ( pathbuf ! [ & dir, & file_name] )
103
+ }
0 commit comments