1- use anyhow:: Result ;
1+ use anyhow:: { Result , bail } ;
22use clap:: { Parser , Subcommand } ;
33use comfy_table:: Table ;
44use flint:: {
55 build:: build,
6- repo:: { self , update_manifest} ,
6+ repo:: { self , get_package, update_manifest} ,
7+ run:: { install, start} ,
78} ;
89use std:: {
910 fs,
@@ -18,7 +19,6 @@ mod utils;
1819/// Simple program to greet a person
1920#[ derive( Parser ) ]
2021#[ command( version, about, long_about = None ) ]
21- #[ command( styles = CLAP_STYLING ) ]
2222struct Args {
2323 /// Install system-wide (requires root)
2424 #[ arg( long, conflicts_with = "user" ) ]
@@ -45,16 +45,37 @@ enum Command {
4545 repo_name : String ,
4646 } ,
4747 /// Install a package
48- Install ,
48+ Install {
49+ /// The Repository to install from
50+ #[ arg( long) ]
51+ repo_name : Option < String > ,
52+ /// The package to install
53+ package : String ,
54+ } ,
4955 /// Remove a package
50- Remove ,
56+ Remove {
57+ repo_name : Option < String > ,
58+ package : String ,
59+ } ,
5160 /// Interact with bundles
5261 Bundle {
5362 #[ command( subcommand) ]
5463 command : BundleCommands ,
5564 } ,
5665 /// Updates a repository and its packages
5766 Update ,
67+ /// Run a package's entrypoint
68+ Run {
69+ /// The Repository the package is in
70+ #[ arg( long) ]
71+ repo_name : Option < String > ,
72+ /// The package to install
73+ package : String ,
74+ /// The entrypoint in question. Will default to the first entrypoint
75+ entrypoint : Option < String > ,
76+ /// Extra arguments
77+ args : Option < Vec < String > > ,
78+ } ,
5879}
5980
6081#[ derive( Subcommand ) ]
@@ -118,106 +139,179 @@ fn main() -> Result<()> {
118139 } ;
119140
120141 match args. command {
121- Command :: Repo { command } => match command {
122- RepoCommands :: Create { repo_name } => repo:: create ( & path. join ( repo_name) ) ?,
123-
124- RepoCommands :: List => {
125- let mut table = Table :: new ( ) ;
126-
127- table. set_header ( vec ! [
128- "Name" ,
129- "Title" ,
130- "URL" ,
131- "Hash Kind" ,
132- "Homepage" ,
133- "License" ,
134- "Version" ,
135- ] ) ;
142+ Command :: Repo { command } => repo_commands ( path, command) ?,
143+
144+ Command :: Build {
145+ build_manifest_path,
146+ repo_name,
147+ } => {
148+ build ( & build_manifest_path, & path. join ( repo_name) ) ?;
149+ }
150+
151+ Command :: Install { repo_name, package } => {
152+ let target_repo_path: PathBuf = if let Some ( repo_name) = repo_name {
153+ path. join ( repo_name)
154+ } else {
155+ let mut possible_repos = Vec :: new ( ) ;
136156
137157 for repo_entry in fs:: read_dir ( path) ? {
138158 let repo_dir = repo_entry?;
139- let repo_name = repo_dir. file_name ( ) ;
140- let repo_name_str = repo_name. to_str ( ) . unwrap ( ) ;
141-
142- let repo = repo:: read_manifest ( & repo_dir. path ( ) ) ?;
143-
144- table. add_row ( vec ! [
145- & repo_name_str,
146- repo. metadata. title. unwrap_or_default( ) . as_str( ) ,
147- & repo. updates_url. unwrap_or_default( ) ,
148- & repo. hash_kind. to_string( ) ,
149- & repo. metadata. homepage_url. unwrap_or_default( ) ,
150- & repo. metadata. license. unwrap_or_default( ) ,
151- & repo. metadata. version. unwrap_or_default( ) ,
152- ] ) ;
159+ let package = get_package ( & repo_dir. path ( ) , & package) ;
160+
161+ if package. is_ok ( ) {
162+ possible_repos. push ( ( repo_dir. path ( ) , package?) ) ;
163+ }
153164 }
154165
155- println ! ( "{table}" ) ;
156- }
166+ if possible_repos. is_empty ( ) {
167+ bail ! ( "No Repositories contain that package." )
168+ }
157169
158- RepoCommands :: Add {
159- repo_name,
160- remote_url,
161- } => todo ! ( ) ,
170+ if possible_repos. len ( ) == 1 {
171+ possible_repos. first ( ) . unwrap ( ) . 0 . clone ( )
172+ } else {
173+ todo ! (
174+ "Multiple Repositories contain Multiple versions of this package. Handling for this is currently not implemented."
175+ )
176+ }
177+ } ;
162178
163- RepoCommands :: Remove { repo_name } => {
164- fs:: remove_dir_all ( path. join ( repo_name) ) ?;
165- }
179+ install ( & target_repo_path, & package) ?;
180+ }
166181
167- RepoCommands :: Update {
168- homepage_url,
169- license,
170- title,
171- version,
172- repo_name,
173- } => {
174- let repo_path = & path. join ( repo_name) ;
175- let mut repo = repo:: read_manifest ( repo_path) ?;
176-
177- if title. is_some ( ) {
178- repo. metadata . title = title;
179- }
180- if homepage_url. is_some ( ) {
181- repo. metadata . homepage_url = homepage_url;
182+ Command :: Remove { repo_name, package } => todo ! ( ) ,
183+
184+ Command :: Bundle { command } => todo ! ( ) ,
185+
186+ Command :: Update => todo ! ( ) ,
187+
188+ Command :: Run {
189+ repo_name,
190+ package,
191+ entrypoint,
192+ args,
193+ } => {
194+ let target_repo_path: PathBuf = if let Some ( repo_name) = repo_name {
195+ path. join ( repo_name)
196+ } else {
197+ let mut possible_repos = Vec :: new ( ) ;
198+
199+ for repo_entry in fs:: read_dir ( path) ? {
200+ let repo_dir = repo_entry?;
201+ let package = get_package ( & repo_dir. path ( ) , & package) ;
202+
203+ if package. is_ok ( ) {
204+ possible_repos. push ( ( repo_dir. path ( ) , package?) ) ;
205+ }
182206 }
183- if license. is_some ( ) {
184- repo. metadata . license = license;
207+
208+ if possible_repos. is_empty ( ) {
209+ bail ! ( "No Repositories contain that package." )
185210 }
186- if version. is_some ( ) {
187- repo. metadata . version = version;
211+
212+ if possible_repos. len ( ) == 1 {
213+ possible_repos. first ( ) . unwrap ( ) . 0 . clone ( )
214+ } else {
215+ todo ! (
216+ "Multiple Repositories contain Multiple versions of this package. Handling for this is currently not implemented."
217+ )
188218 }
219+ } ;
220+
221+ let entrypoint = entrypoint. unwrap_or_else ( || {
222+ let package = get_package ( & target_repo_path, & package) . unwrap ( ) ;
189223
190- let manifest_serialized = & serde_yaml:: to_string ( & repo) ?;
191- let signature = sign ( repo_path, manifest_serialized) ?;
224+ // TODO: Make this cleaner
225+ package. commands . first ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . into ( )
226+ } ) ;
192227
193- update_manifest ( repo_path, manifest_serialized, & signature. to_bytes ( ) ) ?;
228+ start (
229+ & target_repo_path,
230+ & package,
231+ & entrypoint,
232+ args. unwrap_or_default ( ) ,
233+ ) ?;
234+ }
235+ } ;
236+
237+ Ok ( ( ) )
238+ }
239+
240+ fn repo_commands ( path : & Path , command : RepoCommands ) -> Result < ( ) > {
241+ match command {
242+ RepoCommands :: Create { repo_name } => repo:: create ( & path. join ( repo_name) ) ?,
243+
244+ RepoCommands :: List => {
245+ let mut table = Table :: new ( ) ;
246+
247+ table. set_header ( vec ! [
248+ "Name" ,
249+ "Title" ,
250+ "URL" ,
251+ "Hash Kind" ,
252+ "Homepage" ,
253+ "License" ,
254+ "Version" ,
255+ ] ) ;
256+
257+ for repo_entry in fs:: read_dir ( path) ? {
258+ let repo_dir = repo_entry?;
259+ let repo_name = repo_dir. file_name ( ) ;
260+ let repo_name_str = repo_name. to_str ( ) . unwrap ( ) ;
261+
262+ let repo = repo:: read_manifest ( & repo_dir. path ( ) ) ?;
263+
264+ table. add_row ( vec ! [
265+ & repo_name_str,
266+ repo. metadata. title. unwrap_or_default( ) . as_str( ) ,
267+ & repo. updates_url. unwrap_or_default( ) ,
268+ & repo. hash_kind. to_string( ) ,
269+ & repo. metadata. homepage_url. unwrap_or_default( ) ,
270+ & repo. metadata. license. unwrap_or_default( ) ,
271+ & repo. metadata. version. unwrap_or_default( ) ,
272+ ] ) ;
194273 }
195- } ,
196274
197- Command :: Build {
198- build_manifest_path,
275+ println ! ( "{table}" ) ;
276+ }
277+ RepoCommands :: Add {
199278 repo_name,
200- } => {
201- build ( & build_manifest_path, & path. join ( repo_name) ) ?;
279+ remote_url,
280+ } => todo ! ( ) ,
281+
282+ RepoCommands :: Remove { repo_name } => {
283+ fs:: remove_dir_all ( path. join ( repo_name) ) ?;
202284 }
203285
204- Command :: Install => todo ! ( ) ,
286+ RepoCommands :: Update {
287+ homepage_url,
288+ license,
289+ title,
290+ version,
291+ repo_name,
292+ } => {
293+ let repo_path = & path. join ( repo_name) ;
294+ let mut repo = repo:: read_manifest ( repo_path) ?;
205295
206- Command :: Remove => todo ! ( ) ,
296+ if title. is_some ( ) {
297+ repo. metadata . title = title;
298+ }
299+ if homepage_url. is_some ( ) {
300+ repo. metadata . homepage_url = homepage_url;
301+ }
302+ if license. is_some ( ) {
303+ repo. metadata . license = license;
304+ }
305+ if version. is_some ( ) {
306+ repo. metadata . version = version;
307+ }
207308
208- Command :: Bundle { command } => todo ! ( ) ,
309+ let manifest_serialized = & serde_yaml:: to_string ( & repo) ?;
310+ let signature = sign ( repo_path, manifest_serialized) ?;
209311
210- Command :: Update => todo ! ( ) ,
312+ update_manifest ( repo_path, manifest_serialized, & signature. to_bytes ( ) ) ?;
313+ }
211314 } ;
212315
213316 Ok ( ( ) )
214317}
215-
216- pub const CLAP_STYLING : clap:: builder:: styling:: Styles = clap:: builder:: styling:: Styles :: styled ( )
217- . header ( clap_cargo:: style:: HEADER )
218- . usage ( clap_cargo:: style:: USAGE )
219- . literal ( clap_cargo:: style:: LITERAL )
220- . placeholder ( clap_cargo:: style:: PLACEHOLDER )
221- . error ( clap_cargo:: style:: ERROR )
222- . valid ( clap_cargo:: style:: VALID )
223- . invalid ( clap_cargo:: style:: INVALID ) ;
0 commit comments