Repository: denoland/deno
File: cli/tools/installer/mod.rs (Rust)

Code before:
    .first()
    .ok_or_else(|| anyhow!("No module URL provided"))?
    .clone();

  // Determine the output path
  let output = if let Some(ref name) = install_flags_global.name {
    let mut output_path = install_dir.join(name);
    if cfg!(windows) {
      output_path = output_path.with_extension("exe");
    }
    output_path.to_string_lossy().into_owned()
  } else {
    format!("{}/", install_dir.to_string_lossy())
  };

  let output_path = PathBuf::from(&output);
  if output_path.is_file() {
    if !install_flags_global.force {
      return Err(anyhow!(
        "Existing installation found. Aborting (Use -f to overwrite).",
      ));
    }
    // Remove the existing file so that the compile step doesn't
    // fail its own safety check (which guards against overwriting
    // files not produced by `deno compile`).
    std::fs::remove_file(&output_path)?;
  }

  let compile_flags = CompileFlags {
    source_file,
    output: Some(output.clone()),
    args: install_flags_global.args,
    target: None,
    no_terminal: false,
    icon: None,
    include: vec![],
    exclude: vec![],
    eszip: false,
  };

  let mut new_flags = flags.as_ref().clone();
  new_flags.subcommand = DenoSubcommand::Compile(compile_flags.clone());

  crate::tools::compile::compile(new_flags, compile_flags).await?;

  log::info!("Successfully installed {}", output);

  if !is_in_path(&install_dir) {
    let installation_dir_str = install_dir.to_string_lossy();
    log::info!("Add {} to PATH", installation_dir_str);
    if cfg!(windows) {

Review comment (bug):
This could fail if the current process is running on Windows. Can you make this a descriptive error?

Also, can you add a test to ensure this fixes the problem and doesn't break in the future?

Code after:
    .first()
    .ok_or_else(|| anyhow!("No module URL provided"))?
    .clone();

  // Determine the output path
  let output = if let Some(ref name) = install_flags_global.name {
    let mut output_path = install_dir.join(name);
    if cfg!(windows) {
      output_path = output_path.with_extension("exe");
    }
    output_path.to_string_lossy().into_owned()
  } else {
    format!("{}/", install_dir.to_string_lossy())
  };

  let output_path = PathBuf::from(&output);
  if output_path.is_file() {
    if !install_flags_global.force {
      return Err(anyhow!(
        "Existing installation found. Aborting (Use -f to overwrite).",
      ));
    }
    // Remove the existing file so that the compile step doesn't
    // fail its own safety check (which guards against overwriting
    // files not produced by `deno compile`).
    std::fs::remove_file(&output_path).with_context(|| {
      format!(
        concat!(
          "Failed to remove existing installation at '{0}'.\n\n",
          "This may be because an existing {1} process is running. Please ensure ",
          "there are no running {1} processes (ex. run `pkill {1}` on Unix or ",
          "`Stop-Process -Name {1}` on Windows), and ensure you have sufficient ",
          "permission to write to the installation path."
        ),
        output_path.display(),
        output_path.file_name().map(|s| s.to_string_lossy()).unwrap_or("<unknown>".into())
      )
    })?;
  }

  let compile_flags = CompileFlags {
    source_file,
    output: Some(output.clone()),
    args: install_flags_global.args,
    target: None,
    no_terminal: false,
    icon: None,
    include: vec![],
    exclude: vec![],
    eszip: false,
  };