blob: 0dbde16e27a91d5931202a6a2bae4451d0a2d29a [file] [edit]
//! For opening files or URLs with the preferred application.
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use crate::CargoResult;
use crate::GlobalContext;
use crate::context::PathAndArgs;
/// Opens a file path using the preferred application.
///
/// 1. Try `doc.browser` config first
/// 2. Then `$BROWSER`
/// 3. Finally system default opener
pub fn open(path: &Path, gctx: &GlobalContext) -> CargoResult<()> {
let config_browser = {
let cfg: Option<PathAndArgs> = gctx.get("doc.browser")?;
cfg.map(|path_args| (path_args.path.resolve_program(gctx), path_args.args))
};
let mut shell = gctx.shell();
let link = shell.err_file_hyperlink(&path);
shell.status("Opening", format!("{link}{}{link:#}", path.display()))?;
let browser =
config_browser.or_else(|| Some((PathBuf::from(gctx.get_env_os("BROWSER")?), Vec::new())));
match browser {
Some((browser, initial_args)) => {
if let Err(e) = Command::new(&browser).args(initial_args).arg(path).status() {
shell.warn(format!(
"Couldn't open docs with {}: {}",
browser.to_string_lossy(),
e
))?;
}
}
None => {
if let Err(e) = opener::open(&path) {
let e = e.into();
crate::display_warning_with_error("couldn't open docs", &e, &mut shell);
}
}
};
Ok(())
}