@@ -5,6 +5,7 @@ use futures_util::TryStreamExt;
55use reqwest:: Client ;
66use rv_lockfile:: datatypes:: GemSection ;
77use rv_lockfile:: datatypes:: GemfileDotLock ;
8+ use rv_lockfile:: datatypes:: Spec ;
89use url:: Url ;
910
1011use crate :: config:: Config ;
@@ -103,7 +104,7 @@ async fn download_gems<'i>(
103104 lockfile : GemfileDotLock < ' i > ,
104105 cache : & rv_cache:: Cache ,
105106 max_concurrent_requests : usize ,
106- ) -> Result < Vec < Vec < Downloaded > > > {
107+ ) -> Result < Vec < Vec < Downloaded < ' i > > > > {
107108 let all_sources = futures_util:: stream:: iter ( lockfile. gem ) ;
108109 let downloaded: Vec < _ > = all_sources
109110 . map ( |gem_source| download_gem_source ( gem_source, cache, max_concurrent_requests) )
@@ -113,9 +114,23 @@ async fn download_gems<'i>(
113114 Ok ( downloaded)
114115}
115116
116- struct Downloaded {
117+ struct Downloaded < ' i > {
117118 contents : Bytes ,
118119 from : Url ,
120+ spec : Spec < ' i > ,
121+ }
122+
123+ fn url_for_spec ( remote : & str , spec : & Spec < ' _ > ) -> Result < Url > {
124+ let gem_name = spec. gem_version . name ;
125+ let gem_version = spec. gem_version . version ;
126+ let path = format ! ( "gems/{gem_name}-{gem_version}.gem" ) ;
127+ let url = url:: Url :: parse ( remote)
128+ . map_err ( |err| Error :: BadRemote {
129+ remote : remote. to_owned ( ) ,
130+ err,
131+ } ) ?
132+ . join ( & path) ?;
133+ Ok ( url)
119134}
120135
121136/// Downloads all gems from a particular gem source,
@@ -124,41 +139,30 @@ async fn download_gem_source<'i>(
124139 gem_source : GemSection < ' i > ,
125140 cache : & rv_cache:: Cache ,
126141 max_concurrent_requests : usize ,
127- ) -> Result < Vec < Downloaded > > {
142+ ) -> Result < Vec < Downloaded < ' i > > > {
128143 // TODO: If the gem server needs user credentials, accept them and add them to this client.
129144 let client = rv_http_client ( ) ?;
130145
131146 // Get all URLs for downloading all gems from this source.
132- let urls = gem_source
133- . specs
134- . iter ( )
135- . map ( |gem| {
136- let remote = gem_source. remote ;
137- let gem_name = gem. gem_version . name ;
138- let gem_version = gem. gem_version . version ;
139- let path = format ! ( "gems/{gem_name}-{gem_version}.gem" ) ;
140- let url = url:: Url :: parse ( remote)
141- . map_err ( |err| Error :: BadRemote {
142- remote : remote. to_owned ( ) ,
143- err,
144- } ) ?
145- . join ( & path) ?;
146- Ok ( url)
147- } )
148- . collect :: < Result < Vec < Url > > > ( ) ?;
149147
150148 // Download them all, concurrently.
151- let url_stream = futures_util:: stream:: iter ( urls ) ;
152- let downloaded_gems: Vec < _ > = url_stream
153- . map ( |url | download_gem ( url , & client, cache) )
149+ let spec_stream = futures_util:: stream:: iter ( gem_source . specs ) ;
150+ let downloaded_gems: Vec < _ > = spec_stream
151+ . map ( |spec | download_gem ( gem_source . remote , spec , & client, cache) )
154152 . buffered ( max_concurrent_requests)
155153 . try_collect ( )
156154 . await ?;
157155 Ok ( downloaded_gems)
158156}
159157
160158/// Download a single gem, from the given URL, using the given client.
161- async fn download_gem ( url : Url , client : & Client , cache : & rv_cache:: Cache ) -> Result < Downloaded > {
159+ async fn download_gem < ' i > (
160+ remote : & str ,
161+ spec : Spec < ' i > ,
162+ client : & Client ,
163+ cache : & rv_cache:: Cache ,
164+ ) -> Result < Downloaded < ' i > > {
165+ let url = url_for_spec ( remote, & spec) ?;
162166 eprintln ! ( "Downloading from {url}" ) ;
163167 let cache_key = rv_cache:: cache_digest ( url. as_ref ( ) ) ;
164168 let cache_path = cache
@@ -181,6 +185,7 @@ async fn download_gem(url: Url, client: &Client, cache: &rv_cache::Cache) -> Res
181185 Ok ( Downloaded {
182186 contents,
183187 from : url,
188+ spec,
184189 } )
185190}
186191
0 commit comments