@@ -4,6 +4,7 @@ pub mod install;
4
4
pub mod resolver;
5
5
6
6
use std:: borrow:: Borrow ;
7
+ use std:: fs:: File ;
7
8
use std:: io:: { ErrorKind , Read , Seek } ;
8
9
use std:: path:: { Path , PathBuf } ;
9
10
@@ -23,6 +24,14 @@ use crate::TCLI_HOME;
23
24
24
25
use self :: index:: PackageIndex ;
25
26
27
+ #[ derive( Serialize , Deserialize , Debug ) ]
28
+ pub struct PackageMetadata {
29
+ #[ serde( flatten) ]
30
+ manifest : PackageManifestV1 ,
31
+ reference : String ,
32
+ icon : PathBuf ,
33
+ }
34
+
26
35
#[ derive( Serialize , Deserialize , Debug , Clone ) ]
27
36
pub enum PackageSource {
28
37
Remote ( String ) ,
@@ -43,7 +52,7 @@ pub struct Package {
43
52
impl Package {
44
53
/// Attempt to resolve the package from the local cache or remote.
45
54
/// This does not download the package, it just finds its "source".
46
- pub async fn resolve_new ( ident : impl Borrow < PackageReference > ) -> Result < Self , Error > {
55
+ pub async fn from_any ( ident : impl Borrow < PackageReference > ) -> Result < Self , Error > {
47
56
if cache:: get_cache_location ( ident. borrow ( ) ) . exists ( ) {
48
57
return Package :: from_cache ( ident) . await ;
49
58
}
@@ -110,7 +119,9 @@ impl Package {
110
119
/// Load package metadata from an arbitrary path, extracting it into the cache if it passes
111
120
// manifest validation.
112
121
pub async fn from_path ( ident : PackageReference , path : & Path ) -> Result < Self , Error > {
113
- let package = Package :: from_repo ( ident) . await ?;
122
+ // let package = Package::from_repo(ident).await?;
123
+ add_to_cache ( & ident, File :: open ( path) . map_fs_error ( path) ?) ?;
124
+ let package = Package :: from_cache ( ident) . await ?;
114
125
115
126
Ok ( Package {
116
127
identifier : package. identifier ,
@@ -119,64 +130,39 @@ impl Package {
119
130
} )
120
131
}
121
132
122
- /// Resolve the package into a discrete path. This will download the package if it is not cached,
123
- // otherwise it will return its cached path.
124
- pub async fn resolve ( & self , reporter : & dyn ProgressBarTrait ) -> Result < PathBuf , Error > {
133
+ /// Resolve the package into a discrete path, returning None if it does not exist locally.
134
+ pub async fn get_path ( & self ) -> Option < PathBuf > {
125
135
match & self . source {
126
136
PackageSource :: Local ( path) => add_to_cache (
127
137
& self . identifier ,
128
- std :: fs :: File :: open ( path) . map_fs_error ( path) ?,
129
- ) ,
130
- PackageSource :: Remote ( _ ) => self . download ( reporter ) . await ,
131
- PackageSource :: Cache ( path ) => Ok ( path . clone ( ) ) ,
138
+ File :: open ( path) . map_fs_error ( path) . ok ( ) ?,
139
+ ) . ok ( ) ,
140
+ PackageSource :: Cache ( path ) => Some ( path . clone ( ) ) ,
141
+ PackageSource :: Remote ( _ ) => None ,
132
142
}
133
143
}
134
144
135
- pub async fn add (
136
- & self ,
137
- project_state : & Path ,
138
- reporter : Box < dyn ProgressBarTrait > ,
139
- ) -> Result < ( ) , Error > {
140
- let cache_path = self . resolve ( reporter. as_ref ( ) ) . await ?;
141
- let install_dir = project_state. join ( self . identifier . to_string ( ) ) ;
142
-
143
- if install_dir. is_dir ( ) {
144
- fs:: remove_dir_all ( & install_dir)
145
- . await
146
- . map_fs_error ( & install_dir) ?;
147
- }
148
-
149
- for item in walkdir:: WalkDir :: new ( & cache_path) . into_iter ( ) {
150
- let item = item?;
151
-
152
- let dest_path = install_dir. join ( item. path ( ) . strip_prefix ( & cache_path) . unwrap ( ) ) ;
153
-
154
- if item. file_type ( ) . is_dir ( ) {
155
- tokio:: fs:: create_dir_all ( & dest_path)
156
- . await
157
- . map_fs_error ( & dest_path) ?;
158
- } else if item. file_type ( ) . is_file ( ) {
159
- tokio:: fs:: copy ( item. path ( ) , & dest_path)
160
- . await
161
- . map_fs_error ( & dest_path) ?;
162
- }
163
- }
164
-
165
- let finished_msg = format ! (
166
- "{} {}-{} ({})" ,
167
- "[✓]" . green( ) ,
168
- self . identifier. namespace. bold( ) ,
169
- self . identifier. name. bold( ) ,
170
- self . identifier. version. to_string( ) . truecolor( 90 , 90 , 90 )
171
- ) ;
172
-
173
- reporter. println ( & finished_msg) ;
174
- reporter. finish_and_clear ( ) ;
175
-
176
- Ok ( ( ) )
145
+ /// Get the metadata associated with this package. This will return None
146
+ /// the package does not exist locally.
147
+ pub async fn get_metadata ( & self ) -> Result < Option < PackageMetadata > , Error > {
148
+ let Some ( package_dir) = self . get_path ( ) . await else {
149
+ return Ok ( None ) ;
150
+ } ;
151
+ let manifest = {
152
+ let str = fs:: read_to_string ( package_dir. join ( "manifest.json" ) ) . await ?;
153
+ serde_json:: from_str :: < PackageManifestV1 > ( & str) ?
154
+ } ;
155
+ let icon = package_dir. join ( "icon.png" ) ;
156
+ let reference = package_dir. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ;
157
+
158
+ Ok ( Some ( PackageMetadata {
159
+ manifest,
160
+ reference,
161
+ icon,
162
+ } ) )
177
163
}
178
164
179
- async fn download ( & self , reporter : & dyn ProgressBarTrait ) -> Result < PathBuf , Error > {
165
+ pub async fn download ( & self , reporter : & dyn ProgressBarTrait ) -> Result < PathBuf , Error > {
180
166
let PackageSource :: Remote ( package_source) = & self . source else {
181
167
panic ! ( "Invalid use, this is a local package." )
182
168
} ;
0 commit comments