1- use std:: path:: PathBuf ;
2-
3- use crate :: core:: cache:: {
4- get_absolute_path, get_package_info, get_repo_info, list_sources, now_iso, write_sources,
5- PackageEntry , RepoEntry ,
6- } ;
7- use crate :: core:: git:: { fetch_repo_source, fetch_source} ;
8- use crate :: core:: registries:: repo:: { parse_repo_spec, resolve_repo} ;
9- use crate :: core:: registries:: {
10- detect_input_type, parse_package_spec, resolve_package, PackageSpec , Registry ,
11- } ;
12- use crate :: core:: version:: detect_installed_version;
13-
14- fn log ( verbose : bool , msg : & str ) {
15- if verbose {
16- eprintln ! ( "{msg}" ) ;
17- }
18- }
19-
20- fn handle_package ( spec : & str , cwd : & str , verbose : bool ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
21- let parsed = parse_package_spec ( spec) ;
22- let registry = parsed. registry ;
23- let name = parsed. name . clone ( ) ;
24- let mut version = parsed. version . clone ( ) ;
25-
26- // Check cache if version is specified
27- if let Some ( ref v) = version {
28- if let Some ( existing) = get_package_info ( & name, registry) {
29- if existing. version == * v {
30- let abs = get_absolute_path ( & existing. path ) ;
31- println ! ( "{}" , abs. display( ) ) ;
32- return Ok ( ( ) ) ;
33- }
34- }
35- }
36-
37- // Detect installed version for npm
38- if version. is_none ( ) && registry == Registry :: Npm {
39- let detected = detect_installed_version ( & name, & PathBuf :: from ( cwd) ) ;
40- if let Some ( v) = detected {
41- version = Some ( v. clone ( ) ) ;
42- if let Some ( existing) = get_package_info ( & name, registry) {
43- if existing. version == v {
44- let abs = get_absolute_path ( & existing. path ) ;
45- println ! ( "{}" , abs. display( ) ) ;
46- return Ok ( ( ) ) ;
47- }
48- }
49- }
50- }
51-
52- log (
53- verbose,
54- & format ! ( "Fetching {name} from {}..." , registry. label( ) ) ,
55- ) ;
56-
57- let pkg_spec = PackageSpec {
58- registry,
59- name : name. clone ( ) ,
60- version,
61- } ;
62- let resolved = resolve_package ( & pkg_spec) ?;
63- log ( verbose, & format ! ( " → Cloning at {}..." , resolved. git_tag) ) ;
64-
65- let result = fetch_source ( & resolved) ;
66-
67- if !result. success {
68- return Err ( format ! ( "Failed: {}" , result. error. as_deref( ) . unwrap_or( "unknown" ) ) . into ( ) ) ;
69- }
70-
71- if let Some ( ref warn) = result. error {
72- log ( verbose, & format ! ( " ⚠ {warn}" ) ) ;
73- }
74-
75- // Update index
76- let ( mut packages, repos) = list_sources ( ) ;
77- let entry = PackageEntry {
78- name : result. package . clone ( ) ,
79- version : result. version . clone ( ) ,
80- registry : result. registry . unwrap_or ( Registry :: Npm ) ,
81- path : result. path . clone ( ) ,
82- fetched_at : now_iso ( ) ,
83- } ;
84- if let Some ( idx) = packages
85- . iter ( )
86- . position ( |p| p. name == entry. name && p. registry == entry. registry )
87- {
88- packages[ idx] = entry;
89- } else {
90- packages. push ( entry) ;
91- }
92- write_sources ( packages, repos) ?;
93-
94- let abs = get_absolute_path ( & result. path ) ;
95- log ( verbose, & format ! ( " ✓ Cached at {}" , abs. display( ) ) ) ;
96- println ! ( "{}" , abs. display( ) ) ;
97- Ok ( ( ) )
98- }
99-
100- fn handle_repo ( spec : & str , _cwd : & str , verbose : bool ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
101- let repo_spec = match parse_repo_spec ( spec) {
102- Some ( s) => s,
103- None => {
104- return Err ( format ! ( "Invalid repository format: {spec}" ) . into ( ) ) ;
105- }
106- } ;
107-
108- let display = format ! ( "{}/{}/{}" , repo_spec. host, repo_spec. owner, repo_spec. repo) ;
109-
110- // Check cache
111- if let Some ( ref r) = repo_spec. git_ref {
112- if let Some ( existing) = get_repo_info ( & display) {
113- if existing. version == * r {
114- let abs = get_absolute_path ( & existing. path ) ;
115- println ! ( "{}" , abs. display( ) ) ;
116- return Ok ( ( ) ) ;
117- }
118- }
119- }
120-
121- log (
122- verbose,
123- & format ! ( "Fetching {}/{}..." , repo_spec. owner, repo_spec. repo) ,
124- ) ;
125- let resolved = resolve_repo ( & repo_spec) ?;
126- log ( verbose, & format ! ( " → Cloning at {}..." , resolved. git_ref) ) ;
127-
128- let result = fetch_repo_source ( & resolved) ;
129-
130- if !result. success {
131- return Err ( format ! ( "Failed: {}" , result. error. as_deref( ) . unwrap_or( "unknown" ) ) . into ( ) ) ;
132- }
133-
134- if let Some ( ref warn) = result. error {
135- log ( verbose, & format ! ( " ⚠ {warn}" ) ) ;
136- }
137-
138- // Update index
139- let ( packages, mut repos) = list_sources ( ) ;
140- let entry = RepoEntry {
141- name : result. package . clone ( ) ,
142- version : result. version . clone ( ) ,
143- path : result. path . clone ( ) ,
144- fetched_at : now_iso ( ) ,
145- } ;
146- if let Some ( idx) = repos. iter ( ) . position ( |r| r. name == entry. name ) {
147- repos[ idx] = entry;
148- } else {
149- repos. push ( entry) ;
150- }
151- write_sources ( packages, repos) ?;
152-
153- let abs = get_absolute_path ( & result. path ) ;
154- log ( verbose, & format ! ( " ✓ Cached at {}" , abs. display( ) ) ) ;
155- println ! ( "{}" , abs. display( ) ) ;
156- Ok ( ( ) )
157- }
158-
159- fn run_one ( spec : & str , cwd : & str , verbose : bool ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
160- let input_type = detect_input_type ( spec) ;
161-
162- if input_type == "repo" {
163- handle_repo ( spec, cwd, verbose)
164- } else {
165- handle_package ( spec, cwd, verbose)
166- }
167- }
1+ use crate :: core:: fetcher:: ensure_cached;
1682
1693pub fn run (
1704 specs : & [ String ] ,
@@ -173,7 +7,8 @@ pub fn run(
1737) -> Result < ( ) , Box < dyn std:: error:: Error > > {
1748 let cwd = cwd. unwrap_or ( "." ) ;
1759 for spec in specs {
176- run_one ( spec, cwd, verbose) ?;
10+ let outcome = ensure_cached ( spec, cwd, verbose) ?;
11+ println ! ( "{}" , outcome. path. display( ) ) ;
17712 }
17813 Ok ( ( ) )
17914}
0 commit comments