##// END OF EJS Templates
wix: tell ComponentSearch that it is finding a directory (not a file)...
wix: tell ComponentSearch that it is finding a directory (not a file) This is to fix an issue we've noticed where fresh installations start at `C:\Program Files\Mercurial`, and then upgrades "walk up" the tree and end up in `C:\Program Files` and finally `C:\` (where they stay). ComponentSearch defaults to finding files, which I think means "it produces a string like `C:\Program Files\Mercurial`", whereas with the type being explicitly a directory, it would return `C:\Program Files\Mercurial\` (note the final trailing backslash). Presumably, a latter step then tries to turn that file name into a proper directory, by removing everything after the last `\`. This could likely also be fixed by actually searching for the component for hg.exe itself. That seemed a lot more complicated, as the GUID for hg.exe isn't known in this file (it's one of the "auto-derived" ones). We could also consider adding a Condition that I think could check the Property and ensure it's either empty or ends in a trailing slash, but that would be an installer runtime check and I'm not convinced it'd actually be useful. This will *not* cause existing installations that are in one of the bad directories to fix themselves. Doing that would require a fair amount more understanding of wix and windows installer than I have, and it *probably* wouldn't be possible to be 100% correct about it either (there's nothing preventing a user from intentionally installing it in C:\, though I don't know why they would do so). If someone wants to tackle fixing existing installations, I think that the first installation is actually the only one that shows up in "Add or Remove Programs", and that its registry keys still exist. You might be able to find something under HKEY_USERS that lists both the "good" and the "bad" InstallDirs. Mine was under `HKEY_USERS\S-1-5-18\Software\Mercurial\InstallDir` (C:\), and `HKEY_USERS\S-1-5-21-..numbers..\Software\Mercurial\InstallDir` (C:\Program Files\Mercurial). If you find exactly two, with one being the default path, and the other being a prefix of it, the user almost certainly hit this bug :D We had originally thought that this bug might be due to unattended installations/upgrades, but I no longer think that's the case. We were able to reproduce the issue by uninstalling all copies of Mercurial I could find, installing one version (it chose the correct location), and then starting the installer for a different version (higher or lower didn't matter). I did not need to deal with an unattended or headless installation/upgrade to trigger the issue, but it's possible that my system was "primed" for this bug to happen because of a previous unattended installation/upgrade. Differential Revision: https://phab.mercurial-scm.org/D9891

File last commit:

r46598:fada3387 default
r47159:8deab876 stable
Show More
error.rs
124 lines | 4.0 KiB | application/rls-services+xml | RustLexer
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 use crate::exitcode;
use crate::ui::UiError;
Raphaël Gomès
rhg: use `format_bytes!` for error messages...
r46598 use format_bytes::format_bytes;
Antoine Cezar
rhg: simplify `FindRootError` handling...
r45922 use hg::operations::{FindRootError, FindRootErrorKind};
Simon Sapin
requirements: move loading to hg-core and add parsing...
r46536 use hg::requirements::RequirementsError;
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 use hg::utils::files::get_bytes_from_path;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 use std::convert::From;
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 use std::path::PathBuf;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
/// The kind of command error
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 #[derive(Debug)]
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 pub enum CommandErrorKind {
/// The root of the repository cannot be found
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 RootNotFound(PathBuf),
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 /// The current directory cannot be found
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 CurrentDirNotFound(std::io::Error),
Simon Sapin
requirements: move loading to hg-core and add parsing...
r46536 /// `.hg/requires`
RequirementsError(RequirementsError),
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 /// The standard output stream cannot be written to
StdoutError,
/// The standard error stream cannot be written to
StderrError,
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923 /// The command aborted
Abort(Option<Vec<u8>>),
Antoine Cezar
rhg: add a limited `rhg cat -r` subcommand...
r46113 /// A mercurial capability as not been implemented.
Unimplemented,
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
impl CommandErrorKind {
pub fn get_exit_code(&self) -> exitcode::ExitCode {
match self {
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 CommandErrorKind::RootNotFound(_) => exitcode::ABORT,
CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT,
Simon Sapin
rhg: exit with relevant code for unsupported requirements...
r46549 CommandErrorKind::RequirementsError(
RequirementsError::Unsupported { .. },
) => exitcode::UNIMPLEMENTED_COMMAND,
Simon Sapin
requirements: move loading to hg-core and add parsing...
r46536 CommandErrorKind::RequirementsError(_) => exitcode::ABORT,
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 CommandErrorKind::StdoutError => exitcode::ABORT,
CommandErrorKind::StderrError => exitcode::ABORT,
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923 CommandErrorKind::Abort(_) => exitcode::ABORT,
Antoine Cezar
rhg: add a limited `rhg cat -r` subcommand...
r46113 CommandErrorKind::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND,
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
}
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920
/// Return the message corresponding to the error kind if any
pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
match self {
CommandErrorKind::RootNotFound(path) => {
let bytes = get_bytes_from_path(path);
Raphaël Gomès
rhg: use `format_bytes!` for error messages...
r46598 Some(format_bytes!(
b"abort: no repository found in '{}' (.hg not found)!\n",
bytes.as_slice()
))
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 }
Raphaël Gomès
rhg: use `format_bytes!` for error messages...
r46598 CommandErrorKind::CurrentDirNotFound(e) => Some(format_bytes!(
b"abort: error getting current working directory: {}\n",
e.to_string().as_bytes(),
)),
Simon Sapin
requirements: move loading to hg-core and add parsing...
r46536 CommandErrorKind::RequirementsError(
RequirementsError::Corrupted,
) => Some(
"abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
),
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923 CommandErrorKind::Abort(message) => message.to_owned(),
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 _ => None,
}
}
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
Antoine Cezar
rhg: add Command trait for subcommands implemented by rhg...
r45515 /// The error type for the Command trait
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 #[derive(Debug)]
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 pub struct CommandError {
pub kind: CommandErrorKind,
}
impl CommandError {
/// Exist the process with the corresponding exit code.
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 pub fn exit(&self) {
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 std::process::exit(self.kind.get_exit_code())
}
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920
/// Return the message corresponding to the command error if any
pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
self.kind.get_error_message_bytes()
}
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
impl From<CommandErrorKind> for CommandError {
fn from(kind: CommandErrorKind) -> Self {
CommandError { kind }
}
}
impl From<UiError> for CommandError {
fn from(error: UiError) -> Self {
CommandError {
kind: match error {
UiError::StdoutError(_) => CommandErrorKind::StdoutError,
UiError::StderrError(_) => CommandErrorKind::StderrError,
},
}
}
}
Antoine Cezar
rhg: simplify `FindRootError` handling...
r45922
impl From<FindRootError> for CommandError {
fn from(err: FindRootError) -> Self {
match err.kind {
FindRootErrorKind::RootNotFound(path) => CommandError {
kind: CommandErrorKind::RootNotFound(path),
},
FindRootErrorKind::GetCurrentDirError(e) => CommandError {
kind: CommandErrorKind::CurrentDirNotFound(e),
},
}
}
}
Simon Sapin
requirements: move loading to hg-core and add parsing...
r46536
impl From<RequirementsError> for CommandError {
fn from(err: RequirementsError) -> Self {
CommandError {
kind: CommandErrorKind::RequirementsError(err),
}
}
}