melib/notmuch: show informative error messages if libloading fails
Add instructions on how to solve this, and also a config setting `library_file_path` to set the path manually if necessary.pull/144/head
parent
eb5949dc9b
commit
a484b397c6
|
@ -182,7 +182,11 @@ Its format is described below in
|
|||
\&.
|
||||
.El
|
||||
.Ss notmuch only
|
||||
.Ic root_mailbox
|
||||
notmuch is supported by loading the dynamic library libnotmuch.
|
||||
If its location is missing from your library paths, you must add it yourself.
|
||||
Alternatively, you can specify its path by using a setting.
|
||||
.Bl -tag -width 36n
|
||||
.It Ic root_mailbox
|
||||
points to the directory which contains the
|
||||
.Pa .notmuch/
|
||||
subdirectory.
|
||||
|
@ -192,10 +196,15 @@ You must explicitly state the mailboxes you want in the
|
|||
field and set the
|
||||
.Ar query
|
||||
property to each of them.
|
||||
.It Ic library_file_path Ar Path
|
||||
Use an arbitrary location of libnotmuch by specifying its full filesystem path.
|
||||
.Pq Em optional
|
||||
.El
|
||||
Example:
|
||||
.Bd -literal
|
||||
[accounts.notmuch]
|
||||
format = "notmuch"
|
||||
#library_file_path = "/opt/homebrew/lib/libnotmuch.5.dylib"
|
||||
\&...
|
||||
[accounts.notmuch.mailboxes]
|
||||
"INBOX" = { query="tag:inbox", subscribe = true }
|
||||
|
|
|
@ -108,10 +108,45 @@ impl Default for Backends {
|
|||
|
||||
#[cfg(feature = "notmuch_backend")]
|
||||
pub const NOTMUCH_ERROR_MSG: &str =
|
||||
"libnotmuch5 was not found in your system. Make sure it is installed and in the library paths.\n";
|
||||
"libnotmuch5 was not found in your system. Make sure it is installed and in the library paths. For a custom file path, use `library_file_path` setting in your notmuch account.\n";
|
||||
#[cfg(not(feature = "notmuch_backend"))]
|
||||
pub const NOTMUCH_ERROR_MSG: &str = "this version of meli is not compiled with notmuch support. Use an appropriate version and make sure libnotmuch5 is installed and in the library paths.\n";
|
||||
|
||||
#[cfg(not(feature = "notmuch_backend"))]
|
||||
pub const NOTMUCH_ERROR_DETAILS: &str = "";
|
||||
|
||||
#[cfg(all(feature = "notmuch_backend", target_os = "unix"))]
|
||||
pub const NOTMUCH_ERROR_DETAILS: &str = r#"If you have installed the library manually, try setting the `LD_LIBRARY_PATH` environment variable to its `lib` directory. Otherwise, set it to the location of libnotmuch.5.so. Example:
|
||||
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/notmuch/lib" meli
|
||||
|
||||
or, put this in your shell init script (.bashenv, .zshenv, .bashrc, .zshrc, .profile):
|
||||
|
||||
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/notmuch/lib"
|
||||
|
||||
You can also set any location by specifying the library file path with the configuration flag `library_file_path`."#;
|
||||
|
||||
#[cfg(all(feature = "notmuch_backend", target_os = "macos"))]
|
||||
pub const NOTMUCH_ERROR_DETAILS: &str = r#"If you have installed the library via homebrew, try setting the `DYLD_LIBRARY_PATH` environment variable to its `lib` directory. Otherwise, set it to the location of libnotmuch.5.dylib. Example:
|
||||
|
||||
DYLD_LIBRARY_PATH="$(brew --prefix)/lib" meli
|
||||
|
||||
or, put this in your shell init script (.bashenv, .zshenv, .bashrc, .zshrc, .profile):
|
||||
|
||||
export DYLD_LIBRARY_PATH="$(brew --prefix)/lib"
|
||||
|
||||
Make sure to append to DYLD_LIBRARY_PATH if it's not empty, by prepending a colon to the libnotmuch5.dylib location:
|
||||
|
||||
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$(brew --prefix)/lib"
|
||||
|
||||
You can also set any location by specifying the library file path with the configuration flag `library_file_path`."#;
|
||||
|
||||
#[cfg(all(
|
||||
feature = "notmuch_backend",
|
||||
not(any(target_os = "unix", target_os = "macos"))
|
||||
))]
|
||||
pub const NOTMUCH_ERROR_DETAILS: &str = r#"If notmuch is installed but the library isn't found, consult your system's documentation on how to make dynamic libraries discoverable."#;
|
||||
|
||||
impl Backends {
|
||||
pub fn new() -> Self {
|
||||
let mut b = Backends {
|
||||
|
@ -156,19 +191,13 @@ impl Backends {
|
|||
}
|
||||
#[cfg(feature = "notmuch_backend")]
|
||||
{
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let dlpath = "libnotmuch.so.5";
|
||||
#[cfg(target_os = "macos")]
|
||||
let dlpath = "libnotmuch.5.dylib";
|
||||
if unsafe { libloading::Library::new(dlpath) }.is_ok() {
|
||||
b.register(
|
||||
"notmuch".to_string(),
|
||||
Backend {
|
||||
create_fn: Box::new(|| Box::new(|f, i, ev| NotmuchDb::new(f, i, ev))),
|
||||
validate_conf_fn: Box::new(NotmuchDb::validate_config),
|
||||
},
|
||||
);
|
||||
}
|
||||
b.register(
|
||||
"notmuch".to_string(),
|
||||
Backend {
|
||||
create_fn: Box::new(|| Box::new(|f, i, ev| NotmuchDb::new(f, i, ev))),
|
||||
validate_conf_fn: Box::new(NotmuchDb::validate_config),
|
||||
},
|
||||
);
|
||||
}
|
||||
#[cfg(feature = "jmap_backend")]
|
||||
{
|
||||
|
@ -187,6 +216,10 @@ impl Backends {
|
|||
if !self.map.contains_key(key) {
|
||||
if key == "notmuch" {
|
||||
eprint!("{}", NOTMUCH_ERROR_MSG);
|
||||
#[cfg(feature = "notmuch_backend")]
|
||||
{
|
||||
eprint!("{}", NOTMUCH_ERROR_DETAILS);
|
||||
}
|
||||
}
|
||||
panic!("{} is not a valid mail backend", key);
|
||||
}
|
||||
|
@ -206,13 +239,18 @@ impl Backends {
|
|||
.get(key)
|
||||
.ok_or_else(|| {
|
||||
MeliError::new(format!(
|
||||
"{}{} is not a valid mail backend",
|
||||
"{}{} is not a valid mail backend. {}",
|
||||
if key == "notmuch" {
|
||||
NOTMUCH_ERROR_MSG
|
||||
} else {
|
||||
""
|
||||
},
|
||||
key
|
||||
key,
|
||||
if cfg!(feature = "notmuch_backend") {
|
||||
NOTMUCH_ERROR_DETAILS
|
||||
} else {
|
||||
""
|
||||
},
|
||||
))
|
||||
})?
|
||||
.validate_conf_fn)(s)
|
||||
|
|
|
@ -310,10 +310,30 @@ impl NotmuchDb {
|
|||
event_consumer: BackendEventConsumer,
|
||||
) -> Result<Box<dyn MailBackend>> {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let dlpath = "libnotmuch.so.5";
|
||||
let mut dlpath = "libnotmuch.so.5";
|
||||
#[cfg(target_os = "macos")]
|
||||
let dlpath = "libnotmuch.5.dylib";
|
||||
let lib = Arc::new(unsafe { libloading::Library::new(dlpath)? });
|
||||
let mut dlpath = "libnotmuch.5.dylib";
|
||||
let mut custom_dlpath = false;
|
||||
if let Some(lib_path) = s.extra.get("library_file_path") {
|
||||
dlpath = lib_path.as_str();
|
||||
custom_dlpath = true;
|
||||
}
|
||||
let lib = Arc::new(unsafe {
|
||||
match libloading::Library::new(dlpath) {
|
||||
Ok(l) => l,
|
||||
Err(err) => {
|
||||
if custom_dlpath {
|
||||
return Err(MeliError::new(format!("Notmuch `library_file_path` setting value `{}` for account {} does not exist or is a directory or not a valid library file.",dlpath, s.name()))
|
||||
.set_kind(ErrorKind::Configuration)
|
||||
.set_source(Some(Arc::new(err))));
|
||||
} else {
|
||||
return Err(MeliError::new("Could not load libnotmuch!")
|
||||
.set_details(super::NOTMUCH_ERROR_DETAILS)
|
||||
.set_source(Some(Arc::new(err))));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let mut path = Path::new(s.root_mailbox.as_str()).expand();
|
||||
if !path.exists() {
|
||||
return Err(MeliError::new(format!(
|
||||
|
@ -423,6 +443,15 @@ impl NotmuchDb {
|
|||
path.pop();
|
||||
|
||||
let account_name = s.name().to_string();
|
||||
if let Some(lib_path) = s.extra.remove("library_file_path") {
|
||||
if !Path::new(&lib_path).exists() || Path::new(&lib_path).is_dir() {
|
||||
return Err(MeliError::new(format!(
|
||||
"Notmuch `library_file_path` setting value `{}` for account {} does not exist or is a directory.",
|
||||
&lib_path,
|
||||
s.name()
|
||||
)).set_kind(ErrorKind::Configuration));
|
||||
}
|
||||
}
|
||||
for (k, f) in s.mailboxes.iter_mut() {
|
||||
if f.extra.remove("query").is_none() {
|
||||
return Err(MeliError::new(format!(
|
||||
|
|
Loading…
Reference in New Issue