Skip to content
This repository has been archived by the owner on Sep 7, 2024. It is now read-only.

Commit

Permalink
Add --install-dir
Browse files Browse the repository at this point in the history
  • Loading branch information
samhh committed Apr 18, 2021
1 parent 3df3052 commit b61f873
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 84 deletions.
69 changes: 35 additions & 34 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::manifest::paths::Browser;
use clap::{crate_authors, crate_name, crate_version, App, Arg, Error as ClapError};

pub enum Argument {
InstallBrowserHost(Browser),
/// The second piece of data is an optional custom installation dir.
InstallBrowserHost(Browser, Option<String>),
ListBookmarks,
OpenBookmarks(Vec<BookmarkId>),
}
Expand All @@ -18,14 +19,15 @@ pub enum CliError {
/// any known flags. An Err value denotes a parsing error, most likely meaning
/// unrecognised flag(s) were passed. This includes help and version flags
/// which must be handled outside this function.
pub fn init() -> Result<Option<Vec<Argument>>, CliError> {
pub fn init() -> Result<Option<Argument>, CliError> {
// Nota bene these strings determine the ordering of the help message
let chrome_arg = "install-chrome";
let chromium_arg = "install-chromium";
let firefox_arg = "install-firefox";
let brave_arg = "install-brave";
let vivaldi_arg = "install-vivaldi";
let edge_arg = "install-edge";
let dir_arg = "install-dir";
let list_arg = "list";
let open_arg = "open";

Expand Down Expand Up @@ -63,6 +65,13 @@ pub fn init() -> Result<Option<Vec<Argument>>, CliError> {
.long("--install-edge")
.about("Install the native messaging host for Edge"),
)
.arg(
Arg::new(dir_arg)
.long("--install-dir")
.about("Specify a custom manifest installation directory")
.takes_value(true)
.value_name("dir"),
)
.arg(
Arg::new(list_arg)
.short('l')
Expand All @@ -81,49 +90,41 @@ pub fn init() -> Result<Option<Vec<Argument>>, CliError> {
.try_get_matches()
.map_err(CliError::Clap)?;

let install_chrome = matches.is_present(chrome_arg);
let install_chromium = matches.is_present(chromium_arg);
let install_firefox = matches.is_present(firefox_arg);
let install_brave = matches.is_present(brave_arg);
let install_vivaldi = matches.is_present(vivaldi_arg);
let install_edge = matches.is_present(edge_arg);
let list_bookmarks = matches.is_present(list_arg);
let open_bookmark_ids = matches.values_of(open_arg);
if let Some(vals) = matches.values_of(open_arg) {
let mut ids = Vec::with_capacity(vals.len());

let mut args = Vec::with_capacity(7);
for val in vals {
ids.push(val.parse().map_err(|_| CliError::BookmarkIdsParseFailed)?);
}

if install_chrome {
args.push(Argument::InstallBrowserHost(Browser::Chrome));
return Ok(Some(Argument::OpenBookmarks(ids)));
}
if install_chromium {
args.push(Argument::InstallBrowserHost(Browser::Chromium));

if matches.is_present(list_arg) {
return Ok(Some(Argument::ListBookmarks));
}
if install_firefox {
args.push(Argument::InstallBrowserHost(Browser::Firefox));

let dir = matches.value_of(dir_arg).map(String::from);
if matches.is_present(chrome_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Chrome, dir)));
}
if install_brave {
args.push(Argument::InstallBrowserHost(Browser::Brave));
if matches.is_present(chromium_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Chromium, dir)));
}
if install_vivaldi {
args.push(Argument::InstallBrowserHost(Browser::Vivaldi));
if matches.is_present(firefox_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Firefox, dir)));
}
if install_edge {
args.push(Argument::InstallBrowserHost(Browser::Edge));
if matches.is_present(brave_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Brave, dir)));
}
if list_bookmarks {
args.push(Argument::ListBookmarks);
if matches.is_present(vivaldi_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Vivaldi, dir)));
}
if let Some(vals) = open_bookmark_ids {
let mut ids = Vec::with_capacity(vals.len());

for val in vals {
ids.push(val.parse().map_err(|_| CliError::BookmarkIdsParseFailed)?);
}

args.push(Argument::OpenBookmarks(ids));
if matches.is_present(edge_arg) {
return Ok(Some(Argument::InstallBrowserHost(Browser::Edge, dir)));
}

Ok(if args.is_empty() { None } else { Some(args) })
Ok(None)
}

pub fn exit_with_stdout_err<T: std::fmt::Display>(msg: T) -> ! {
Expand Down
89 changes: 41 additions & 48 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::manifest::installer::install_manifest;
use crate::native_messaging::NativeMessagingError;
use crate::server::{map_init_err_friendly_msg, InitError, Server};
use clap::ErrorKind;
use std::path::PathBuf;

fn main() {
let db = get_db_path()
Expand All @@ -27,7 +28,7 @@ fn main() {

// Native messaging can provide its own arguments we don't care about, so
// ignore any unrecognised arguments
let recognised_args = cli::init().unwrap_or_else(|err| match err {
let recognised_arg = cli::init().unwrap_or_else(|err| match err {
CliError::Clap(clap_err) => match clap_err.kind {
ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => clap_err.exit(),
_ => None,
Expand All @@ -38,58 +39,50 @@ fn main() {
});

// Only continue to native messaging if no recognised flags are found
if let Some(args) = recognised_args {
if let Some(arg) = recognised_arg {
match db {
Ok(db) => {
for arg in args {
match arg {
Argument::InstallBrowserHost(browser) => {
let installed = install_manifest(&browser);
Ok(db) => match arg {
Argument::InstallBrowserHost(browser, path) => {
let installed = install_manifest(&browser, path.map(PathBuf::from));

match installed {
Ok(path) => {
println!(
"Successfully installed host for {:?} to:\n\t{:?}",
&browser, path,
);
}
Err(err) => {
exit_with_stdout_err(format!(
"Failed to install host for {:?}:\n\t{}",
&browser, err
));
}
};
match installed {
Ok(path) => {
println!(
"Successfully installed host for {:?} to:\n\t{:?}",
&browser, path,
);
}
Argument::ListBookmarks => match db.get_all_bookmarks() {
Ok(bms) => {
for bm in bms {
println!("{} {}", bm.id, bm.metadata);
}
}
Err(_) => {
exit_with_stdout_err("Failed to fetch bookmarks from database.");
}
},
Argument::OpenBookmarks(ids) => match db.get_bookmarks_by_id(ids) {
Ok(bms) => {
for bm in bms {
if webbrowser::open(&bm.url).is_err() {
exit_with_stdout_err(
"Failed to open bookmark in web browser.",
);
}
}
}
Err(_) => {
exit_with_stdout_err(
"Failed to fetch selected bookmarks from database.",
);
Err(err) => {
exit_with_stdout_err(format!(
"Failed to install host for {:?}:\n\t{}",
&browser, err
));
}
};
}
Argument::ListBookmarks => match db.get_all_bookmarks() {
Ok(bms) => {
for bm in bms {
println!("{} {}", bm.id, bm.metadata);
}
}
Err(_) => {
exit_with_stdout_err("Failed to fetch bookmarks from database.");
}
},
Argument::OpenBookmarks(ids) => match db.get_bookmarks_by_id(ids) {
Ok(bms) => {
for bm in bms {
if webbrowser::open(&bm.url).is_err() {
exit_with_stdout_err("Failed to open bookmark in web browser.");
}
},
}
}
}
}
Err(_) => {
exit_with_stdout_err("Failed to fetch selected bookmarks from database.");
}
},
},
Err(err) => {
exit_with_stdout_err(map_init_err_friendly_msg(&err));
}
Expand Down
8 changes: 6 additions & 2 deletions src/manifest/installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ use std::fs;
use std::io::Write;
use std::path::PathBuf;

pub fn install_manifest(browser: &Browser) -> Result<PathBuf, String> {
pub fn install_manifest(browser: &Browser, path: Option<PathBuf>) -> Result<PathBuf, String> {
// Create native messaging path if it doesn't already exist
let manifest_path = get_manifest_path(&browser)?;
let manifest_path = match path {
Some(p) => Ok(p),
None => get_manifest_path(&browser),
}?;

fs::create_dir_all(&manifest_path)
.map_err(|_| "Failed to create native messaging directory.")?;

Expand Down

0 comments on commit b61f873

Please sign in to comment.