diff --git a/Cargo.toml b/Cargo.toml index 8dc9681..5c9c6bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,6 +89,12 @@ infer-command = [] # Compile without colored output support no-color = ["colored/no-color"] +# Automatic using build.rs: use xclip/xsel binary method for clipboard support +clipboard-bin = ["clipboard"] + +# Automatic using build.rs: use native clipboard crate for clipboard support +clipboard-crate = ["clipboard"] + [dependencies] chbs = "0.0.8" chrono = "0.4" @@ -114,9 +120,9 @@ toml = "0.5" urlshortener = { version = "0.10", default-features = false, optional = true } version-compare = "0.0.8" -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))'.dependencies] which = { version = "2.0", optional = true } -[target.'cfg(not(target_os = "linux"))'.dependencies] -# Package is aliased to clip to prevent name collision with clipboard feature +[target.'cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd")))'.dependencies] +# Aliased to clip to prevent name collision with clipboard feature clip = { version = "0.5", optional = true, package = "clipboard" } diff --git a/README.md b/README.md index cf88540..91e710c 100644 --- a/README.md +++ b/README.md @@ -135,10 +135,10 @@ all available subcommands. - Linux, macOS, Windows or FreeBSD (other BSDs might work) - A terminal :sunglasses: - Internet connection for uploading and downloading -- Linux specific: +- Linux: - OpenSSL & CA certificates: - Ubuntu, Debian and derivatives: `apt install openssl ca-certificates` - - Optional: `xclip` for clipboard support + - Optional: `xclip` or `xsel` for clipboard support - Ubuntu, Debian and derivatives: `apt install xclip` - CentOS/Red Hat/openSUSE/Fedora: `yum install xclip` - Arch: `pacman -S xclip` @@ -534,10 +534,10 @@ empty. Some environment variables may be set at compile time to tweak some defaults. -| Variable | Description | -| :----------- | :------------------------------------- | -| `XCLIP_PATH` | Set fixed `xclip` binary path on Linux | -| `XSEL_PATH` | Set fixed `xsel` binary path on Linux | +| Variable | Description | +| :----------- | :------------------------------------------------------------------------- | +| `XCLIP_PATH` | Set fixed `xclip` binary path when using `clipboard-bin` (Linux, *BSD) | +| `XSEL_PATH` | Set fixed `xsel` binary path when using `clipboard-bin` (Linux, *BSD) | At this time, no configuration or _dotfile_ file support is available. This will be something added in a later release. diff --git a/build.rs b/build.rs index b9d1361..32b3d32 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,37 @@ fn main() { - // xclip and xsel paths are inserted at compile time on Linux - #[cfg(all(feature = "clipboard", target_os = "linux"))] + #[cfg(all( + feature = "clipboard", + any( + target_os = "linux", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd", + ) + ))] { + // Select clipboard binary method + #[cfg(not(feature = "clipboard-crate"))] + println!("cargo:rustc-cfg=feature=\"clipboard-bin\""); + + // xclip and xsel paths are inserted at compile time println!("cargo:rerun-if-env-changed=XCLIP_PATH"); println!("cargo:rerun-if-env-changed=XSEL_PATH"); } + + #[cfg(all( + feature = "clipboard", + not(any( + target_os = "linux", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd", + )) + ))] + { + // Select clipboard crate method + #[cfg(not(feature = "clipboard-bin"))] + println!("cargo:rustc-cfg=feature=\"clipboard-crate\""); + } } diff --git a/src/action/debug.rs b/src/action/debug.rs index bd397ba..7953079 100644 --- a/src/action/debug.rs +++ b/src/action/debug.rs @@ -6,7 +6,7 @@ use prettytable::{format::FormatBuilder, Cell, Row, Table}; use crate::client::to_duration; use crate::cmd::matcher::{debug::DebugMatcher, main::MainMatcher, Matcher}; use crate::error::ActionError; -#[cfg(all(feature = "clipboard", target_os = "linux"))] +#[cfg(feature = "clipboard-bin")] use crate::util::ClipboardType; use crate::util::{api_version_list, features_list, format_bool, format_duration}; @@ -99,7 +99,7 @@ impl<'a> Debug<'a> { ])); // Clipboard information - #[cfg(all(feature = "clipboard", target_os = "linux"))] + #[cfg(feature = "clipboard-bin")] table.add_row(Row::new(vec![ Cell::new("Clipboard:"), Cell::new(&format!("{}", ClipboardType::select())), diff --git a/src/util.rs b/src/util.rs index c1941f4..d3ecb6f 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,10 +1,10 @@ -#[cfg(all(feature = "clipboard", not(target_os = "linux")))] +#[cfg(feature = "clipboard-crate")] extern crate clip; extern crate colored; extern crate directories; extern crate fs2; extern crate open; -#[cfg(all(feature = "clipboard", target_os = "linux"))] +#[cfg(feature = "clipboard-bin")] extern crate which; use std::borrow::Borrow; @@ -13,16 +13,16 @@ use std::ffi::OsStr; #[cfg(feature = "clipboard")] use std::fmt; use std::fmt::{Debug, Display}; -#[cfg(all(feature = "clipboard", target_os = "linux"))] +#[cfg(feature = "clipboard-bin")] use std::io::ErrorKind as IoErrorKind; use std::io::{stderr, stdin, Error as IoError, Write}; use std::path::Path; use std::path::PathBuf; use std::process::{exit, ExitStatus}; -#[cfg(all(feature = "clipboard", target_os = "linux"))] +#[cfg(feature = "clipboard-bin")] use std::process::{Command, Stdio}; -#[cfg(all(feature = "clipboard", not(target_os = "linux")))] +#[cfg(feature = "clipboard-crate")] use self::clip::{ClipboardContext, ClipboardProvider}; use self::colored::*; #[cfg(feature = "history")] @@ -30,7 +30,7 @@ use self::directories::ProjectDirs; use self::fs2::available_space; use chrono::Duration; use failure::{err_msg, Fail}; -#[cfg(all(feature = "clipboard", not(target_os = "linux")))] +#[cfg(feature = "clipboard-crate")] use failure::{Compat, Error}; use ffsend_api::{ api::request::{ensure_success, ResponseError}, @@ -39,7 +39,7 @@ use ffsend_api::{ url::Url, }; use rpassword::prompt_password_stderr; -#[cfg(all(feature = "clipboard", target_os = "linux"))] +#[cfg(feature = "clipboard-bin")] use which::which; use crate::cmd::matcher::MainMatcher; @@ -312,19 +312,19 @@ pub fn set_clipboard(content: String) -> Result<(), ClipboardError> { #[derive(Clone, Eq, PartialEq)] pub enum ClipboardType { /// Native operating system clipboard. - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] Native, /// Manage clipboard through `xclip` on Linux. /// /// May contain a binary path if specified at compile time through the `XCLIP_PATH` variable. - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] Xclip(Option), /// Manage clipboard through `xsel` on Linux. /// /// May contain a binary path if specified at compile time through the `XSEL_PATH` variable. - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] Xsel(Option), } @@ -332,12 +332,12 @@ pub enum ClipboardType { impl ClipboardType { /// Select the clipboard type to use, depending on the runtime system. pub fn select() -> Self { - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] { ClipboardType::Native } - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] { if let Some(path) = option_env!("XCLIP_PATH") { ClipboardType::Xclip(Some(path.to_owned())) @@ -357,11 +357,11 @@ impl ClipboardType { /// Set clipboard contents through the selected clipboard type. pub fn set(&self, content: String) -> Result<(), ClipboardError> { match self { - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] ClipboardType::Native => Self::native_set(content), - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] ClipboardType::Xclip(path) => Self::xclip_set(path.clone(), content), - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] ClipboardType::Xsel(path) => Self::xsel_set(path.clone(), content), } } @@ -369,7 +369,7 @@ impl ClipboardType { /// Set the clipboard through a native interface. /// /// This is used on non-Linux systems. - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] fn native_set(content: String) -> Result<(), ClipboardError> { ClipboardProvider::new() .and_then(|mut context: ClipboardContext| context.set_contents(content)) @@ -377,7 +377,7 @@ impl ClipboardType { .map_err(ClipboardError::Native) } - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] fn xclip_set(path: Option, content: String) -> Result<(), ClipboardError> { Self::sys_cmd_set( "xclip", @@ -388,7 +388,7 @@ impl ClipboardType { ) } - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] fn xsel_set(path: Option, content: String) -> Result<(), ClipboardError> { Self::sys_cmd_set( "xsel", @@ -397,7 +397,7 @@ impl ClipboardType { ) } - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] fn sys_cmd_set( bin: &'static str, command: &mut Command, @@ -441,14 +441,14 @@ impl ClipboardType { impl fmt::Display for ClipboardType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] ClipboardType::Native => write!(f, "native"), - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] ClipboardType::Xclip(path) => match path { None => write!(f, "xclip"), Some(path) => write!(f, "xclip ({})", path), }, - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] ClipboardType::Xsel(path) => match path { None => write!(f, "xsel"), Some(path) => write!(f, "xsel ({})", path), @@ -463,24 +463,24 @@ pub enum ClipboardError { /// A generic error occurred while setting the clipboard contents. /// /// This is for non-Linux systems, using a native clipboard interface. - #[cfg(not(target_os = "linux"))] + #[cfg(feature = "clipboard-crate")] #[fail(display = "failed to access clipboard")] Native(#[cause] Compat), /// The `xclip` or `xsel` binary could not be found on the system, required for clipboard support. - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] #[fail(display = "failed to access clipboard, xclip or xsel is not installed")] NoBinary, /// An error occurred while using `xclip` or `xsel` to set the clipboard contents. /// This problem probably occurred when starting, or while piping the clipboard contents to /// the process. - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] #[fail(display = "failed to access clipboard using {}", _0)] BinaryIo(&'static str, #[cause] IoError), /// `xclip` or `xsel` unexpectetly exited with a non-successful status code. - #[cfg(target_os = "linux")] + #[cfg(feature = "clipboard-bin")] #[fail( display = "failed to use clipboard, {} exited with status code {}", _0, _1 @@ -973,6 +973,10 @@ pub fn features_list() -> Vec<&'static str> { features.push("archive"); #[cfg(feature = "clipboard")] features.push("clipboard"); + #[cfg(feature = "clipboard-bin")] + features.push("clipboard-bin"); + #[cfg(feature = "clipboard-crate")] + features.push("clipboard-crate"); #[cfg(feature = "history")] features.push("history"); #[cfg(feature = "qrcode")]