Add --ephemeral cli flag

This commit is contained in:
Joscha 2022-08-22 20:58:11 +02:00
parent f76c6a557d
commit 68bd6042c5
4 changed files with 48 additions and 19 deletions

View file

@ -18,6 +18,7 @@ Procedure when bumping the version number:
- Account login and logout - Account login and logout
- Authentication dialog for password-protected rooms - Authentication dialog for password-protected rooms
- Error popups in rooms when something goes wrong - Error popups in rooms when something goes wrong
- `--ephemeral` flag that prevents cove from storing data permanently
### Changed ### Changed
- Reduced amount of unnecessary redraws - Reduced amount of unnecessary redraws

View file

@ -61,28 +61,41 @@ struct Args {
/// Path to a directory for cove to store its data in. /// Path to a directory for cove to store its data in.
#[clap(long, short)] #[clap(long, short)]
data_dir: Option<PathBuf>, data_dir: Option<PathBuf>,
/// If set, cove won't store data permanently.
#[clap(long, short, action)]
ephemeral: bool,
/// Measure the width of characters as displayed by the terminal emulator /// Measure the width of characters as displayed by the terminal emulator
/// instead of guessing the width. /// instead of guessing the width.
#[clap(long, short, action)] #[clap(long, short, action)]
measure_widths: bool, measure_widths: bool,
#[clap(subcommand)] #[clap(subcommand)]
command: Option<Command>, command: Option<Command>,
} }
fn data_dir(args_data_dir: Option<PathBuf>) -> PathBuf {
if let Some(data_dir) = args_data_dir {
data_dir
} else {
let dirs =
ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories");
dirs.data_dir().to_path_buf()
}
}
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let args = Args::parse(); let args = Args::parse();
let data_dir = if let Some(data_dir) = args.data_dir { let vault = if args.ephemeral {
data_dir vault::launch_in_memory()?
} else { } else {
let dirs = let data_dir = data_dir(args.data_dir);
ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories");
dirs.data_dir().to_path_buf()
};
println!("Data dir: {}", data_dir.to_string_lossy()); println!("Data dir: {}", data_dir.to_string_lossy());
vault::launch(&data_dir.join("vault.db"))?
let vault = vault::launch(&data_dir.join("vault.db"))?; };
match args.command.unwrap_or_default() { match args.command.unwrap_or_default() {
Command::Run => run(&vault, args.measure_widths).await?, Command::Run => run(&vault, args.measure_widths).await?,

View file

@ -20,9 +20,14 @@ enum Request {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Vault { pub struct Vault {
tx: mpsc::UnboundedSender<Request>, tx: mpsc::UnboundedSender<Request>,
ephemeral: bool,
} }
impl Vault { impl Vault {
pub fn ephemeral(&self) -> bool {
self.ephemeral
}
pub async fn close(&self) { pub async fn close(&self) {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
let _ = self.tx.send(Request::Close(tx)); let _ = self.tx.send(Request::Close(tx));
@ -64,12 +69,26 @@ fn run(mut conn: Connection, mut rx: mpsc::UnboundedReceiver<Request>) {
} }
} }
fn launch_from_connection(mut conn: Connection, ephemeral: bool) -> rusqlite::Result<Vault> {
conn.pragma_update(None, "foreign_keys", true)?;
conn.pragma_update(None, "trusted_schema", false)?;
println!("Opening vault");
migrate::migrate(&mut conn)?;
prepare::prepare(&mut conn)?;
let (tx, rx) = mpsc::unbounded_channel();
thread::spawn(move || run(conn, rx));
Ok(Vault { tx, ephemeral })
}
pub fn launch(path: &Path) -> rusqlite::Result<Vault> { pub fn launch(path: &Path) -> rusqlite::Result<Vault> {
// If this fails, rusqlite will complain about not being able to open the db // If this fails, rusqlite will complain about not being able to open the db
// file, which saves me from adding a separate vault error type. // file, which saves me from adding a separate vault error type.
let _ = fs::create_dir_all(path.parent().expect("path to file")); let _ = fs::create_dir_all(path.parent().expect("path to file"));
let mut conn = Connection::open(path)?; let conn = Connection::open(path)?;
// Setting locking mode before journal mode so no shared memory files // Setting locking mode before journal mode so no shared memory files
// (*-shm) need to be created by sqlite. Apparently, setting the journal // (*-shm) need to be created by sqlite. Apparently, setting the journal
@ -78,13 +97,11 @@ pub fn launch(path: &Path) -> rusqlite::Result<Vault> {
// https://sqlite.org/pragma.html#pragma_locking_mode // https://sqlite.org/pragma.html#pragma_locking_mode
conn.pragma_update(None, "locking_mode", "exclusive")?; conn.pragma_update(None, "locking_mode", "exclusive")?;
conn.pragma_update(None, "journal_mode", "wal")?; conn.pragma_update(None, "journal_mode", "wal")?;
conn.pragma_update(None, "foreign_keys", true)?;
conn.pragma_update(None, "trusted_schema", false)?;
migrate::migrate(&mut conn)?; launch_from_connection(conn, false)
prepare::prepare(&mut conn)?; }
let (tx, rx) = mpsc::unbounded_channel(); pub fn launch_in_memory() -> rusqlite::Result<Vault> {
thread::spawn(move || run(conn, rx)); let conn = Connection::open_in_memory()?;
Ok(Vault { tx }) launch_from_connection(conn, true)
} }

View file

@ -1,8 +1,6 @@
use rusqlite::Connection; use rusqlite::Connection;
pub fn prepare(conn: &mut Connection) -> rusqlite::Result<()> { pub fn prepare(conn: &mut Connection) -> rusqlite::Result<()> {
println!("Opening vault");
// Cache ids of tree roots. // Cache ids of tree roots.
conn.execute_batch( conn.execute_batch(
" "