feature-flags (#328)

* use feature flags

* fmt

* fix features

* update ci

* fmt

Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
This commit is contained in:
Conrad Ludgate 2022-04-22 21:14:23 +01:00 committed by GitHub
parent 508d4f4761
commit 7436e4ff65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 141 additions and 81 deletions

View file

@ -63,7 +63,19 @@ jobs:
key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }}
- name: Run cargo test
run: ATUIN_SESSION=beepboopiamasession cargo test --workspace
run: cargo test --all-features --workspace
- name: Run cargo check (all features)
run: cargo check --all-features --workspace
- name: Run cargo check (no features)
run: cargo check --no-default-features --workspace
- name: Run cargo check (sync)
run: cargo check --no-default-features --features sync --workspace
- name: Run cargo check (server)
run: cargo check --no-default-features --features server --workspace
clippy:
runs-on: ubuntu-latest

18
Cargo.lock generated
View file

@ -113,7 +113,6 @@ dependencies = [
"log",
"minspan",
"parse_duration",
"rand 0.8.5",
"regex",
"reqwest",
"rmp-serde",
@ -761,12 +760,6 @@ dependencies = [
"parking_lot 0.11.2",
]
[[package]]
name = "futures-io"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]]
name = "futures-sink"
version = "0.3.21"
@ -786,10 +779,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
@ -1804,19 +1795,20 @@ dependencies = [
[[package]]
name = "rmp"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f55e5fa1446c4d5dd1f5daeed2a4fe193071771a2636274d0d7a3b082aa7ad6"
checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmp-serde"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3eedffbfcc6a428f230c04baf8f59bd73c1781361e4286111fe900849aaddaf"
checksum = "25786b0d276110195fa3d6f3f31299900cf71dfbd6c28450f3f58a0e7f7a347e"
dependencies = [
"byteorder",
"rmp",

View file

@ -29,9 +29,17 @@ atuin = { path = "/usr/bin/atuin" }
[workspace]
members = ["./atuin-client", "./atuin-server", "./atuin-common"]
[features]
# TODO(conradludgate)
# Currently, this keeps the same default built behaviour for v0.8
# We should rethink this by the time we hit a new breaking change
default = ["sync", "server"]
sync = ["atuin-client/sync"]
server = ["atuin-server", "tracing-subscriber"]
[dependencies]
atuin-server = { path = "atuin-server", version = "0.8.1" }
atuin-client = { path = "atuin-client", version = "0.8.1" }
atuin-server = { path = "atuin-server", version = "0.8.1", optional = true }
atuin-client = { path = "atuin-client", version = "0.8.1", default-features = false }
atuin-common = { path = "atuin-common", version = "0.8.1" }
log = "0.4"
@ -59,7 +67,6 @@ clap_complete = "3.1.2"
fs-err = "2.7"
whoami = "1.1.2"
[dependencies.tracing-subscriber]
version = "0.3"
default-features = false
@ -69,8 +76,4 @@ features = [
"registry",
"env-filter",
]
[profile.release]
lto = "fat"
codegen-units = 1
opt-level = 3
optional = true

View file

@ -10,6 +10,17 @@ repository = "https://github.com/ellie/atuin"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["sync"]
sync = [
"urlencoding",
"sodiumoxide",
"reqwest",
"rust-crypto",
"rmp-serde",
"base64",
]
[dependencies]
atuin-common = { path = "../atuin-common", version = "0.8.1" }
@ -23,20 +34,8 @@ chrono-english = "0.1.4"
config = "0.13"
serde = { version = "1.0.126", features = ["derive"] }
serde_json = "1.0.75"
rmp-serde = "1.0.0"
sodiumoxide = "0.2.6"
reqwest = { version = "0.11", features = [
"blocking",
"json",
"rustls-tls",
], default-features = false }
base64 = "0.13.0"
parse_duration = "2.1.1"
rand = "0.8.4"
rust-crypto = "^0.2"
tokio = { version = "1", features = ["full"] }
async-trait = "0.1.49"
urlencoding = "2.1.0"
itertools = "0.10.3"
shellexpand = "2"
sqlx = { version = "0.5", features = [
@ -48,3 +47,17 @@ sqlx = { version = "0.5", features = [
minspan = "0.1.1"
regex = "1.5.4"
fs-err = "2.7"
# sync
urlencoding = { version = "2.1.0", optional = true }
sodiumoxide = { version = "0.2.6", optional = true }
reqwest = { version = "0.11", features = [
"json",
"rustls-tls",
], default-features = false, optional = true }
rust-crypto = { version = "^0.2", optional = true }
rmp-serde = { version = "1.0.0", optional = true }
base64 = { version = "0.13.0", optional = true }
[dev-dependencies]
tokio = { version = "1", features = ["full"] }

View file

@ -38,7 +38,7 @@ pub async fn register(
map.insert("password", password);
let url = format!("{}/user/{}", address, username);
let resp = reqwest::blocking::get(url)?;
let resp = reqwest::get(url).await?;
if resp.status().is_success() {
bail!("username already in use");

View file

@ -77,7 +77,7 @@ pub fn encode_key(key: secretbox::Key) -> Result<String> {
pub fn decode_key(key: String) -> Result<secretbox::Key> {
let buf = base64::decode(key).wrap_err("encryption key is not a valid base64 encoding")?;
let buf: secretbox::Key = rmp_serde::from_read_ref(&buf)
let buf: secretbox::Key = rmp_serde::from_slice(&buf)
.wrap_err("encryption key is not a valid message pack encoding")?;
Ok(buf)
@ -98,7 +98,7 @@ pub fn decrypt(encrypted_history: &EncryptedHistory, key: &secretbox::Key) -> Re
let plaintext = secretbox::open(&encrypted_history.ciphertext, &encrypted_history.nonce, key)
.map_err(|_| eyre!("failed to open secretbox - invalid key?"))?;
let history = rmp_serde::from_read_ref(&plaintext)?;
let history = rmp_serde::from_slice(&plaintext)?;
Ok(history)
}

View file

@ -3,11 +3,15 @@
#[macro_use]
extern crate log;
#[cfg(feature = "sync")]
pub mod api_client;
pub mod database;
#[cfg(feature = "sync")]
pub mod encryption;
#[cfg(feature = "sync")]
pub mod sync;
pub mod database;
pub mod history;
pub mod import;
pub mod ordering;
pub mod settings;
pub mod sync;

View file

@ -8,16 +8,16 @@ use atuin_client::database::Sqlite;
use atuin_client::settings::Settings;
use atuin_common::utils::uuid_v4;
#[cfg(feature = "sync")]
mod sync;
mod event;
mod history;
mod import;
mod init;
mod login;
mod logout;
mod register;
mod search;
mod stats;
mod sync;
use std::path::PathBuf;
#[derive(Subcommand)]
@ -45,25 +45,6 @@ pub enum Cmd {
/// Interactive history search
Search(search::Cmd),
/// Sync with the configured server
Sync {
/// Force re-download everything
#[clap(long, short)]
force: bool,
},
/// Login to the configured server
Login(login::Cmd),
/// Log out
Logout,
/// Register with the configured server
Register(register::Cmd),
/// Print the encryption key for transfer to another machine
Key,
/// Generate shell completions
GenCompletions {
/// Set the shell for generating completions
@ -74,6 +55,10 @@ pub enum Cmd {
#[clap(long, short)]
out_dir: Option<String>,
},
#[cfg(feature = "sync")]
#[clap(flatten)]
Sync(sync::Cmd),
}
impl Cmd {
@ -94,17 +79,6 @@ impl Cmd {
Ok(())
}
Self::Search(search) => search.run(&mut db, &settings).await,
Self::Sync { force } => sync::run(&settings, force, &mut db).await,
Self::Login(l) => l.run(&settings).await,
Self::Logout => logout::run(),
Self::Register(r) => r.run(&settings).await,
Self::Key => {
use atuin_client::encryption::{encode_key, load_key};
let key = load_key(&settings).wrap_err("could not load encryption key")?;
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
println!("{}", encode);
Ok(())
}
Self::Uuid => {
println!("{}", uuid_v4());
Ok(())
@ -128,6 +102,8 @@ impl Cmd {
Ok(())
}
#[cfg(feature = "sync")]
Self::Sync(sync) => sync.run(settings, &mut db).await,
}
}
}

View file

@ -9,6 +9,8 @@ use tabwriter::TabWriter;
use atuin_client::database::{current_context, Database};
use atuin_client::history::History;
use atuin_client::settings::Settings;
#[cfg(feature = "sync")]
use atuin_client::sync;
#[derive(Subcommand)]
@ -143,8 +145,13 @@ impl Cmd {
db.update(&h).await?;
if settings.should_sync()? {
#[cfg(feature = "sync")]
{
debug!("running periodic background sync");
sync::sync(settings, false, db).await?;
}
#[cfg(not(feature = "sync"))]
debug!("not compiled with sync support");
} else {
debug!("sync disabled! not syncing");
}

View file

@ -1,15 +1,64 @@
use eyre::Result;
use atuin_client::database::Database;
use atuin_client::settings::Settings;
use atuin_client::sync;
use clap::Subcommand;
use eyre::{Result, WrapErr};
pub async fn run(
use atuin_client::settings::Settings;
mod login;
mod logout;
mod register;
#[derive(Subcommand)]
#[clap(infer_subcommands = true)]
pub enum Cmd {
/// Sync with the configured server
Sync {
/// Force re-download everything
#[clap(long, short)]
force: bool,
},
/// Login to the configured server
Login(login::Cmd),
/// Log out
Logout,
/// Register with the configured server
Register(register::Cmd),
/// Print the encryption key for transfer to another machine
Key,
}
impl Cmd {
pub async fn run(
self,
settings: Settings,
db: &mut (impl Database + Send + Sync),
) -> Result<()> {
match self {
Self::Sync { force } => run(&settings, force, db).await,
Self::Login(l) => l.run(&settings).await,
Self::Logout => logout::run(),
Self::Register(r) => r.run(&settings).await,
Self::Key => {
use atuin_client::encryption::{encode_key, load_key};
let key = load_key(&settings).wrap_err("could not load encryption key")?;
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
println!("{}", encode);
Ok(())
}
}
}
}
async fn run(
settings: &Settings,
force: bool,
db: &mut (impl Database + Send + Sync),
) -> Result<()> {
sync::sync(settings, force, db).await?;
atuin_client::sync::sync(settings, force, db).await?;
println!(
"Sync complete! {} items in database, force: {}",
db.history_count().await?,

View file

@ -2,6 +2,8 @@ use clap::Subcommand;
use eyre::Result;
mod client;
#[cfg(feature = "server")]
mod server;
#[derive(Subcommand)]
@ -11,6 +13,7 @@ pub enum AtuinCmd {
Client(client::Cmd),
/// Start an atuin server
#[cfg(feature = "server")]
#[clap(subcommand)]
Server(server::Cmd),
}
@ -19,6 +22,7 @@ impl AtuinCmd {
pub async fn run(self) -> Result<()> {
match self {
Self::Client(client) => client.run().await,
#[cfg(feature = "server")]
Self::Server(server) => server.run().await,
}
}