Skip to content

Commit c2b1b74

Browse files
committed
dist: attach manifest download functions to DownloadCfg
1 parent 7435d63 commit c2b1b74

File tree

3 files changed

+107
-103
lines changed

3 files changed

+107
-103
lines changed

src/dist/download.rs

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use std::time::{Duration, Instant};
88
use anyhow::{Context, Result, anyhow};
99
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
1010
use sha2::{Digest, Sha256};
11-
use tracing::{debug, warn};
11+
use tracing::{debug, info, warn};
1212
use url::Url;
1313

1414
use crate::config::Cfg;
15-
use crate::dist::DEFAULT_DIST_SERVER;
16-
use crate::dist::temp;
15+
use crate::dist::manifest::Manifest;
16+
use crate::dist::{Channel, DEFAULT_DIST_SERVER, ToolchainDesc, temp};
1717
use crate::download::{download_file, download_file_with_resume};
1818
use crate::errors::RustupError;
1919
use crate::process::Process;
@@ -136,6 +136,88 @@ impl<'a> DownloadCfg<'a> {
136136
utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned())
137137
}
138138

139+
pub(crate) async fn dl_v2_manifest(
140+
&self,
141+
update_hash: Option<&Path>,
142+
toolchain: &ToolchainDesc,
143+
cfg: &Cfg<'_>,
144+
) -> Result<Option<(Manifest, String)>> {
145+
let manifest_url = toolchain.manifest_v2_url(&cfg.dist_root_url, self.process);
146+
match self
147+
.download_and_check(&manifest_url, update_hash, None, ".toml")
148+
.await
149+
{
150+
Ok(manifest_dl) => {
151+
// Downloaded ok!
152+
let Some((manifest_file, manifest_hash)) = manifest_dl else {
153+
return Ok(None);
154+
};
155+
let manifest_str = utils::read_file("manifest", &manifest_file)?;
156+
let manifest =
157+
Manifest::parse(&manifest_str).with_context(|| RustupError::ParsingFile {
158+
name: "manifest",
159+
path: manifest_file.to_path_buf(),
160+
})?;
161+
162+
Ok(Some((manifest, manifest_hash)))
163+
}
164+
Err(any) => {
165+
if let Some(err @ RustupError::ChecksumFailed { .. }) =
166+
any.downcast_ref::<RustupError>()
167+
{
168+
// Manifest checksum mismatched.
169+
warn!("{err}");
170+
171+
if cfg.dist_root_url.starts_with(DEFAULT_DIST_SERVER) {
172+
info!(
173+
"this is likely due to an ongoing update of the official release server, please try again later"
174+
);
175+
info!(
176+
"see <https://github.com/rust-lang/rustup/issues/3390> for more details"
177+
);
178+
} else {
179+
info!(
180+
"this might indicate an issue with the third-party release server '{}'",
181+
cfg.dist_root_url
182+
);
183+
info!(
184+
"see <https://github.com/rust-lang/rustup/issues/3885> for more details"
185+
);
186+
}
187+
}
188+
Err(any)
189+
}
190+
}
191+
}
192+
193+
pub(super) async fn dl_v1_manifest(
194+
&self,
195+
dist_root: &str,
196+
toolchain: &ToolchainDesc,
197+
) -> Result<Vec<String>> {
198+
let root_url = toolchain.package_dir(dist_root);
199+
200+
if let Channel::Version(ver) = &toolchain.channel {
201+
// This is an explicit version. In v1 there was no manifest,
202+
// you just know the file to download, so synthesize one.
203+
let installer_name = format!("{}/rust-{}-{}.tar.gz", root_url, ver, toolchain.target);
204+
return Ok(vec![installer_name]);
205+
}
206+
207+
let manifest_url = toolchain.manifest_v1_url(dist_root, self.process);
208+
let manifest_dl = self
209+
.download_and_check(&manifest_url, None, None, "")
210+
.await?;
211+
let (manifest_file, _) = manifest_dl.unwrap();
212+
let manifest_str = utils::read_file("manifest", &manifest_file)?;
213+
let urls = manifest_str
214+
.lines()
215+
.map(|s| format!("{root_url}/{s}"))
216+
.collect();
217+
218+
Ok(urls)
219+
}
220+
139221
/// Downloads a file, sourcing its hash from the same url with a `.sha256` suffix.
140222
/// If `update_hash` is present, then that will be compared to the downloaded hash,
141223
/// and if they match, the download is skipped.

src/dist/mod.rs

Lines changed: 15 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,20 +1134,20 @@ async fn try_update_from_dist_(
11341134

11351135
// TODO: Add a notification about which manifest version is going to be used
11361136
info!("syncing channel updates for {toolchain_str}");
1137-
match dl_v2_manifest(
1138-
download,
1139-
// Even if manifest has not changed, we must continue to install requested components.
1140-
// So if components or targets is not empty, we skip passing `update_hash` so that
1141-
// we essentially degenerate to `rustup component add` / `rustup target add`
1142-
if components.is_empty() && targets.is_empty() {
1143-
Some(update_hash)
1144-
} else {
1145-
None
1146-
},
1147-
toolchain,
1148-
cfg,
1149-
)
1150-
.await
1137+
match download
1138+
.dl_v2_manifest(
1139+
// Even if manifest has not changed, we must continue to install requested components.
1140+
// So if components or targets is not empty, we skip passing `update_hash` so that
1141+
// we essentially degenerate to `rustup component add` / `rustup target add`
1142+
if components.is_empty() && targets.is_empty() {
1143+
Some(update_hash)
1144+
} else {
1145+
None
1146+
},
1147+
toolchain,
1148+
cfg,
1149+
)
1150+
.await
11511151
{
11521152
Ok(Some((m, hash))) => {
11531153
match m.get_rust_version() {
@@ -1243,7 +1243,7 @@ async fn try_update_from_dist_(
12431243
}
12441244

12451245
// If the v2 manifest is not found then try v1
1246-
let manifest = match dl_v1_manifest(&cfg.dist_root_url, download, toolchain).await {
1246+
let manifest = match download.dl_v1_manifest(&cfg.dist_root_url, toolchain).await {
12471247
Ok(m) => m,
12481248
Err(err) => match err.downcast_ref::<RustupError>() {
12491249
Some(RustupError::ChecksumFailed { .. }) => return Err(err),
@@ -1279,84 +1279,6 @@ async fn try_update_from_dist_(
12791279
result
12801280
}
12811281

1282-
pub(crate) async fn dl_v2_manifest(
1283-
download: &DownloadCfg<'_>,
1284-
update_hash: Option<&Path>,
1285-
toolchain: &ToolchainDesc,
1286-
cfg: &Cfg<'_>,
1287-
) -> Result<Option<(ManifestV2, String)>> {
1288-
let manifest_url = toolchain.manifest_v2_url(&cfg.dist_root_url, download.process);
1289-
match download
1290-
.download_and_check(&manifest_url, update_hash, None, ".toml")
1291-
.await
1292-
{
1293-
Ok(manifest_dl) => {
1294-
// Downloaded ok!
1295-
let Some((manifest_file, manifest_hash)) = manifest_dl else {
1296-
return Ok(None);
1297-
};
1298-
let manifest_str = utils::read_file("manifest", &manifest_file)?;
1299-
let manifest =
1300-
ManifestV2::parse(&manifest_str).with_context(|| RustupError::ParsingFile {
1301-
name: "manifest",
1302-
path: manifest_file.to_path_buf(),
1303-
})?;
1304-
1305-
Ok(Some((manifest, manifest_hash)))
1306-
}
1307-
Err(any) => {
1308-
if let Some(err @ RustupError::ChecksumFailed { .. }) =
1309-
any.downcast_ref::<RustupError>()
1310-
{
1311-
// Manifest checksum mismatched.
1312-
warn!("{err}");
1313-
1314-
if cfg.dist_root_url.starts_with(DEFAULT_DIST_SERVER) {
1315-
info!(
1316-
"this is likely due to an ongoing update of the official release server, please try again later"
1317-
);
1318-
info!("see <https://github.com/rust-lang/rustup/issues/3390> for more details");
1319-
} else {
1320-
info!(
1321-
"this might indicate an issue with the third-party release server '{}'",
1322-
cfg.dist_root_url
1323-
);
1324-
info!("see <https://github.com/rust-lang/rustup/issues/3885> for more details");
1325-
}
1326-
}
1327-
Err(any)
1328-
}
1329-
}
1330-
}
1331-
1332-
async fn dl_v1_manifest(
1333-
dist_root: &str,
1334-
download: &DownloadCfg<'_>,
1335-
toolchain: &ToolchainDesc,
1336-
) -> Result<Vec<String>> {
1337-
let root_url = toolchain.package_dir(dist_root);
1338-
1339-
if let Channel::Version(ver) = &toolchain.channel {
1340-
// This is an explicit version. In v1 there was no manifest,
1341-
// you just know the file to download, so synthesize one.
1342-
let installer_name = format!("{}/rust-{}-{}.tar.gz", root_url, ver, toolchain.target);
1343-
return Ok(vec![installer_name]);
1344-
}
1345-
1346-
let manifest_url = toolchain.manifest_v1_url(dist_root, download.process);
1347-
let manifest_dl = download
1348-
.download_and_check(&manifest_url, None, None, "")
1349-
.await?;
1350-
let (manifest_file, _) = manifest_dl.unwrap();
1351-
let manifest_str = utils::read_file("manifest", &manifest_file)?;
1352-
let urls = manifest_str
1353-
.lines()
1354-
.map(|s| format!("{root_url}/{s}"))
1355-
.collect();
1356-
1357-
Ok(urls)
1358-
}
1359-
13601282
fn date_from_manifest_date(date_str: &str) -> Option<NaiveDate> {
13611283
NaiveDate::parse_from_str(date_str, "%Y-%m-%d").ok()
13621284
}

src/toolchain/distributable.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,13 @@ impl<'a> DistributableToolchain<'a> {
445445
}
446446

447447
pub async fn show_dist_version(&self) -> anyhow::Result<Option<String>> {
448-
match crate::dist::dl_v2_manifest(
449-
&DownloadCfg::new(self.toolchain.cfg),
450-
Some(&self.toolchain.cfg.get_hash_file(&self.desc, false)?),
451-
&self.desc,
452-
self.toolchain.cfg,
453-
)
454-
.await?
448+
match DownloadCfg::new(self.toolchain.cfg)
449+
.dl_v2_manifest(
450+
Some(&self.toolchain.cfg.get_hash_file(&self.desc, false)?),
451+
&self.desc,
452+
self.toolchain.cfg,
453+
)
454+
.await?
455455
{
456456
Some((manifest, _)) => Ok(Some(manifest.get_rust_version()?.to_string())),
457457
None => Ok(None),

0 commit comments

Comments
 (0)