Change:
I just cloned this rust repo and attemped to build it by calling It initialized submodules, started downloading and failed repeatedly: Waiting longer causes messages above to repeat. It's not connection issue, because it always fails after ~30 seconds of downloading (Messages above repeat in ~2 minutes). I also tried changing to here: What caused download to succeed in a few (1-2) minutes. So I assume it's to blame. version:
I got x.py to test libcore once, but after I updated my local clone of rust, I started getting this repeatedly:
I am nuking my entire rust clone in case changes to the bootstrap are incompatible to previous artifacts produced by previous versions. Why does x.py need to download submodules like and if I am only trying to test ? edit: apparently, this is expected
Nope, I am still getting the DownloadFile exception after refreshing everything, including updating MSYS2 to get curl to 7.65.1, trying the MSYS2 that comes along with git, and messing with
your issue is different and there is no involved (it downloads file through PowerShell). You can see this MSYS2 patch how to make it use instead:
Thank you, it works now
original issue (from comment 0) is not resolved. reported another issue that isn't solved either, there is only workaround available.
We should probably fallback to trying curl if the powershell invocation fails. Reopening. I think a PR would work best here.
For some reason, the powershell download is working again on both my MSYS2 install and from git bash. We still want that fallback though. I couldn't PR a fix though, because I don't know how the exception handling is working in that Python script.
Actually, since I should learn Python anyway, should I PR a fix? Is it as simple as detecting an exception occurred and refactoring the if-else statement in a way that it would also run ?
That's what I would suggest -- we can make it pretty simple and if anything goes wrong with the powershell call then fallback to curl
It might also make sense to try curl before using powershell, as suggested by in label: +E-easy

Discussion:
def _download(path, url, probably_big, verbose, exception, help_on_error=None): <ins> # Try to use curl (potentially available on win32 #    https://devblogs.microsoft.com/commandline/tar-and-curl-come-to-windows/) # If an error occurs: #  - If we are on win32 fallback to powershell #  - Otherwise raise the error if appropriate </ins> if probably_big or verbose: print("downloading {}".format(url)) <del> # see https://serverfault.com/questions/301128/how-to-download if sys.platform == 'win32': run(["PowerShell.exe", "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)], verbose=verbose, exception=exception) else: </del> <ins> platform_is_win32 = sys.platform == 'win32' try: </ins> if probably_big or verbose: option = "-#" else: option = "-s" <del> require(["curl", "--version"]) </del> <ins> # If curl is not present on Win32, we shoud not sys.exit #   but raise `CalledProcessError` or `OSError` instead require(["curl", "--version"], exception=platform_is_win32) </ins> run(["curl", option, "-L", # Follow redirect. "-y", "30", "-Y", "10",    # timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30",  # timeout if cannot connect within 30 seconds "--retry", "3", "-Sf", "-o", path, url], verbose=verbose, <del> exception=exception, </del> <ins> exception=True, # Will raise RuntimeError on failure </ins> help_on_error=help_on_error) <ins> except (subprocess.CalledProcessError, OSError, RuntimeError): # see http://serverfault.com/questions/301128/how-to-download if platform_is_win32: run(["PowerShell.exe", "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)], verbose=verbose, exception=exception) # Check if the RuntimeError raised by run(curl) should be silenced elif verbose or exception: raise </ins> def verify(path, expected, verbose):

sys.exit(err) <del> def require(cmd, exit=True): </del> <ins> def require(cmd, exit=True, exception=False): </ins> '''Run a command, returning its output. On error, <del> If `exit` is `True`, exit the process. Otherwise, return None.''' </del> <ins> If `exception` is `True`, raise the error Otherwise If `exit` is `True`, exit the process Else return None.''' </ins> try: return subprocess.check_output(cmd).strip() except (subprocess.CalledProcessError, OSError) as exc: <del> if not exit: return None print("error: unable to run `{}`: {}".format(' '.join(cmd), exc)) print("Please make sure it's installed and in the path.") sys.exit(1) </del> <ins> if exception: raise elif exit: print("error: unable to run `{}`: {}".format(' '.join(cmd), exc)) print("Please make sure it's installed and in the path.") sys.exit(1) return None </ins> def format_build_time(duration):

use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{ <del> exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, CiEnv, </del> <ins> check_run, exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, CiEnv, </ins> }; mod builder;

try_run_suppressed(cmd) } <ins> /// Runs a command, printing out nice contextual information if it fails. /// Returns false if do not execute at all, otherwise returns its /// `status.success()`. fn check_run(&self, cmd: &mut Command) -> bool { if self.config.dry_run { return true; } self.verbose(&format!("running: {:?}", cmd)); check_run(cmd, self.is_verbose()) } </ins> pub fn is_verbose(&self) -> bool { self.verbosity > 0 }

fn download_with_retries(builder: &Builder<'_>, tempfile: &str, url: &str) { println!("downloading {}", url); <del> // FIXME: check if curl is installed instead of skipping straight to powershell if builder.build.build.contains("windows-msvc") { for _ in 0..3 { if builder.try_run(Command::new("PowerShell.exe").args(&[ "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", &format!( "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", url, tempfile ), ])) { return; </del> <ins> // Try curl. If that fails and we are on windows, fallback to PowerShell. if !builder.check_run(Command::new("curl").args(&[ "-#", "-y", "30", "-Y", "10", // timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30", // timeout if cannot connect within 30 seconds "--retry", "3", "-Sf", "-o", tempfile, url, ])) { if builder.build.build.contains("windows-msvc") { println!("Fallback to PowerShell"); for _ in 0..3 { if builder.try_run(Command::new("PowerShell.exe").args(&[ "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", &format!( "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", url, tempfile ), ])) { return; } println!("nspurious failure, trying again"); </ins> } <del> println!("nspurious failure, trying again"); </del> } <del> } else { builder.run(Command::new("curl").args(&[ "-#", "-y", "30", "-Y", "10", // timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30", // timeout if cannot connect within 30 seconds "--retry", "3", "-Sf", "-o", tempfile, url, ])); </del> <ins> std::process::exit(1); </ins> } }

status.success() } <ins> pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { let status = match cmd.status() { Ok(status) => status, Err(e) => { println!("failed to execute command: {:?}nerror: {}", cmd, e); return false; } }; if !status.success() && print_cmd_on_fail { println!( "nncommand did not execute successfully: {:?}n expected success, got: {}nn", cmd, status ); } status.success() } </ins> pub fn run_suppressed(cmd: &mut Command) { if !try_run_suppressed(cmd) { std::process::exit(1);