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:
parent
508d4f4761
commit
7436e4ff65
14 changed files with 141 additions and 81 deletions
14
.github/workflows/rust.yml
vendored
14
.github/workflows/rust.yml
vendored
|
@ -63,7 +63,19 @@ jobs:
|
||||||
key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Run cargo test
|
- 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:
|
clippy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -113,7 +113,6 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"minspan",
|
"minspan",
|
||||||
"parse_duration",
|
"parse_duration",
|
||||||
"rand 0.8.5",
|
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
|
@ -761,12 +760,6 @@ dependencies = [
|
||||||
"parking_lot 0.11.2",
|
"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]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
|
@ -786,10 +779,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
"slab",
|
"slab",
|
||||||
|
@ -1804,19 +1795,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp"
|
name = "rmp"
|
||||||
version = "0.8.10"
|
version = "0.8.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f55e5fa1446c4d5dd1f5daeed2a4fe193071771a2636274d0d7a3b082aa7ad6"
|
checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp-serde"
|
name = "rmp-serde"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3eedffbfcc6a428f230c04baf8f59bd73c1781361e4286111fe900849aaddaf"
|
checksum = "25786b0d276110195fa3d6f3f31299900cf71dfbd6c28450f3f58a0e7f7a347e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"rmp",
|
"rmp",
|
||||||
|
|
19
Cargo.toml
19
Cargo.toml
|
@ -29,9 +29,17 @@ atuin = { path = "/usr/bin/atuin" }
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["./atuin-client", "./atuin-server", "./atuin-common"]
|
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]
|
[dependencies]
|
||||||
atuin-server = { path = "atuin-server", version = "0.8.1" }
|
atuin-server = { path = "atuin-server", version = "0.8.1", optional = true }
|
||||||
atuin-client = { path = "atuin-client", version = "0.8.1" }
|
atuin-client = { path = "atuin-client", version = "0.8.1", default-features = false }
|
||||||
atuin-common = { path = "atuin-common", version = "0.8.1" }
|
atuin-common = { path = "atuin-common", version = "0.8.1" }
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -59,7 +67,6 @@ clap_complete = "3.1.2"
|
||||||
fs-err = "2.7"
|
fs-err = "2.7"
|
||||||
whoami = "1.1.2"
|
whoami = "1.1.2"
|
||||||
|
|
||||||
|
|
||||||
[dependencies.tracing-subscriber]
|
[dependencies.tracing-subscriber]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
@ -69,8 +76,4 @@ features = [
|
||||||
"registry",
|
"registry",
|
||||||
"env-filter",
|
"env-filter",
|
||||||
]
|
]
|
||||||
|
optional = true
|
||||||
[profile.release]
|
|
||||||
lto = "fat"
|
|
||||||
codegen-units = 1
|
|
||||||
opt-level = 3
|
|
||||||
|
|
|
@ -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
|
# 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]
|
[dependencies]
|
||||||
atuin-common = { path = "../atuin-common", version = "0.8.1" }
|
atuin-common = { path = "../atuin-common", version = "0.8.1" }
|
||||||
|
|
||||||
|
@ -23,20 +34,8 @@ chrono-english = "0.1.4"
|
||||||
config = "0.13"
|
config = "0.13"
|
||||||
serde = { version = "1.0.126", features = ["derive"] }
|
serde = { version = "1.0.126", features = ["derive"] }
|
||||||
serde_json = "1.0.75"
|
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"
|
parse_duration = "2.1.1"
|
||||||
rand = "0.8.4"
|
|
||||||
rust-crypto = "^0.2"
|
|
||||||
tokio = { version = "1", features = ["full"] }
|
|
||||||
async-trait = "0.1.49"
|
async-trait = "0.1.49"
|
||||||
urlencoding = "2.1.0"
|
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
shellexpand = "2"
|
shellexpand = "2"
|
||||||
sqlx = { version = "0.5", features = [
|
sqlx = { version = "0.5", features = [
|
||||||
|
@ -48,3 +47,17 @@ sqlx = { version = "0.5", features = [
|
||||||
minspan = "0.1.1"
|
minspan = "0.1.1"
|
||||||
regex = "1.5.4"
|
regex = "1.5.4"
|
||||||
fs-err = "2.7"
|
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"] }
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub async fn register(
|
||||||
map.insert("password", password);
|
map.insert("password", password);
|
||||||
|
|
||||||
let url = format!("{}/user/{}", address, username);
|
let url = format!("{}/user/{}", address, username);
|
||||||
let resp = reqwest::blocking::get(url)?;
|
let resp = reqwest::get(url).await?;
|
||||||
|
|
||||||
if resp.status().is_success() {
|
if resp.status().is_success() {
|
||||||
bail!("username already in use");
|
bail!("username already in use");
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub fn encode_key(key: secretbox::Key) -> Result<String> {
|
||||||
|
|
||||||
pub fn decode_key(key: String) -> Result<secretbox::Key> {
|
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 = 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")?;
|
.wrap_err("encryption key is not a valid message pack encoding")?;
|
||||||
|
|
||||||
Ok(buf)
|
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)
|
let plaintext = secretbox::open(&encrypted_history.ciphertext, &encrypted_history.nonce, key)
|
||||||
.map_err(|_| eyre!("failed to open secretbox - invalid 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)
|
Ok(history)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,15 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
pub mod api_client;
|
pub mod api_client;
|
||||||
pub mod database;
|
#[cfg(feature = "sync")]
|
||||||
pub mod encryption;
|
pub mod encryption;
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
pub mod sync;
|
||||||
|
|
||||||
|
pub mod database;
|
||||||
pub mod history;
|
pub mod history;
|
||||||
pub mod import;
|
pub mod import;
|
||||||
pub mod ordering;
|
pub mod ordering;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod sync;
|
|
||||||
|
|
|
@ -8,16 +8,16 @@ use atuin_client::database::Sqlite;
|
||||||
use atuin_client::settings::Settings;
|
use atuin_client::settings::Settings;
|
||||||
use atuin_common::utils::uuid_v4;
|
use atuin_common::utils::uuid_v4;
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
mod sync;
|
||||||
|
|
||||||
mod event;
|
mod event;
|
||||||
mod history;
|
mod history;
|
||||||
mod import;
|
mod import;
|
||||||
mod init;
|
mod init;
|
||||||
mod login;
|
|
||||||
mod logout;
|
|
||||||
mod register;
|
|
||||||
mod search;
|
mod search;
|
||||||
mod stats;
|
mod stats;
|
||||||
mod sync;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
|
@ -45,25 +45,6 @@ pub enum Cmd {
|
||||||
/// Interactive history search
|
/// Interactive history search
|
||||||
Search(search::Cmd),
|
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
|
/// Generate shell completions
|
||||||
GenCompletions {
|
GenCompletions {
|
||||||
/// Set the shell for generating completions
|
/// Set the shell for generating completions
|
||||||
|
@ -74,6 +55,10 @@ pub enum Cmd {
|
||||||
#[clap(long, short)]
|
#[clap(long, short)]
|
||||||
out_dir: Option<String>,
|
out_dir: Option<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
#[clap(flatten)]
|
||||||
|
Sync(sync::Cmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
|
@ -94,17 +79,6 @@ impl Cmd {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::Search(search) => search.run(&mut db, &settings).await,
|
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 => {
|
Self::Uuid => {
|
||||||
println!("{}", uuid_v4());
|
println!("{}", uuid_v4());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -128,6 +102,8 @@ impl Cmd {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
Self::Sync(sync) => sync.run(settings, &mut db).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ use tabwriter::TabWriter;
|
||||||
use atuin_client::database::{current_context, Database};
|
use atuin_client::database::{current_context, Database};
|
||||||
use atuin_client::history::History;
|
use atuin_client::history::History;
|
||||||
use atuin_client::settings::Settings;
|
use atuin_client::settings::Settings;
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
use atuin_client::sync;
|
use atuin_client::sync;
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
|
@ -143,8 +145,13 @@ impl Cmd {
|
||||||
db.update(&h).await?;
|
db.update(&h).await?;
|
||||||
|
|
||||||
if settings.should_sync()? {
|
if settings.should_sync()? {
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
{
|
||||||
debug!("running periodic background sync");
|
debug!("running periodic background sync");
|
||||||
sync::sync(settings, false, db).await?;
|
sync::sync(settings, false, db).await?;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
|
debug!("not compiled with sync support");
|
||||||
} else {
|
} else {
|
||||||
debug!("sync disabled! not syncing");
|
debug!("sync disabled! not syncing");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,64 @@
|
||||||
use eyre::Result;
|
|
||||||
|
|
||||||
use atuin_client::database::Database;
|
use atuin_client::database::Database;
|
||||||
use atuin_client::settings::Settings;
|
use clap::Subcommand;
|
||||||
use atuin_client::sync;
|
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,
|
settings: &Settings,
|
||||||
force: bool,
|
force: bool,
|
||||||
db: &mut (impl Database + Send + Sync),
|
db: &mut (impl Database + Send + Sync),
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
sync::sync(settings, force, db).await?;
|
atuin_client::sync::sync(settings, force, db).await?;
|
||||||
println!(
|
println!(
|
||||||
"Sync complete! {} items in database, force: {}",
|
"Sync complete! {} items in database, force: {}",
|
||||||
db.history_count().await?,
|
db.history_count().await?,
|
||||||
|
|
|
@ -2,6 +2,8 @@ use clap::Subcommand;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
|
|
||||||
|
#[cfg(feature = "server")]
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
|
@ -11,6 +13,7 @@ pub enum AtuinCmd {
|
||||||
Client(client::Cmd),
|
Client(client::Cmd),
|
||||||
|
|
||||||
/// Start an atuin server
|
/// Start an atuin server
|
||||||
|
#[cfg(feature = "server")]
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
Server(server::Cmd),
|
Server(server::Cmd),
|
||||||
}
|
}
|
||||||
|
@ -19,6 +22,7 @@ impl AtuinCmd {
|
||||||
pub async fn run(self) -> Result<()> {
|
pub async fn run(self) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Client(client) => client.run().await,
|
Self::Client(client) => client.run().await,
|
||||||
|
#[cfg(feature = "server")]
|
||||||
Self::Server(server) => server.run().await,
|
Self::Server(server) => server.run().await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue