Split cli and lang off in hopes of allowing testing of cli

This commit is contained in:
Josh Hansen 2023-09-24 20:35:36 -07:00
parent 5c1fcc5ae0
commit 47565f2706
34 changed files with 379 additions and 449 deletions

23
Cargo.lock generated
View file

@ -374,6 +374,8 @@ dependencies = [
"clap_complete",
"colored",
"file-owner",
"ghee-cli",
"ghee-lang",
"lazy_static",
"nom",
"path-absolutize",
@ -388,6 +390,27 @@ dependencies = [
"xdg",
]
[[package]]
name = "ghee-cli"
version = "0.1.0"
dependencies = [
"clap",
"ghee-lang",
"thiserror",
]
[[package]]
name = "ghee-lang"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"nom",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "glob"
version = "0.3.1"

View file

@ -7,6 +7,9 @@ default-run = "ghee"
license = "GPL-3.0"
build = "build.rs"
[workspace]
members = [ "cli", "lang" ]
[dependencies]
anyhow = "1.0.75"
atty = "0.2.14"
@ -14,6 +17,8 @@ btrfsutil = { git = "https://github.com/cezarmathe/btrfsutil-rs" }
clap = { version = "4.3.19", features = ["derive"] }
colored = "2.0.4"
file-owner = "0.1.2"
ghee-cli = { path = "cli" }
ghee-lang = { path = "lang" }
lazy_static = "1.4.0"
nom = "7.1.3"
path-absolutize = "3.1.1"
@ -27,8 +32,14 @@ xattr = { version = "1.0.0", default-features = false }
xdg = "2.5.2"
[build-dependencies]
anyhow = "1.0.75"
clap = { version = "4.3.19", features = ["derive"] }
clap_complete = "4.3.2"
ghee-lang = { path = "lang" }
nom = "7.1.3"
serde = { version = "1.0.163", features = ["derive"] }
serde_json = "1.0.96"
thiserror = "1.0.44"
[profile.release]
strip = true

View file

@ -4,7 +4,7 @@ use clap_complete::Shell;
use std::env;
use std::io::Error;
include!("src/cli.rs");
include!("cli/src/lib.rs");
fn main() -> Result<(), Error> {
let outdir = match env::var_os("OUT_DIR") {

9
cli/Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "ghee-cli"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = "*"
ghee-lang = { path = "../lang" }
thiserror = "*"

237
cli/src/lib.rs Normal file
View file

@ -0,0 +1,237 @@
use std::path::PathBuf;
use clap::{builder::ValueParser, Parser, Subcommand};
use thiserror::Error;
use ghee_lang::{Assignment, AssignmentParser, Predicate, PredicateParser, Value, Xattr};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Cli {
/// Subcommand to run. If none is provided, a REPL will be launched
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Error, Debug)]
pub enum TableOpenErr {
#[error("Table path could not be opened because it doesn't exist")]
NoSuchPath,
}
#[derive(Subcommand)]
pub enum Commands {
/// Copy xattr values from one path to another.
Cp {
#[arg(help = "Path to copy xattrs from")]
src: PathBuf,
#[arg(help = "Path to copy xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to copy")]
fields: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// Move xattr values from one path to another.
Mv {
#[arg(help = "Path to move xattrs from")]
src: PathBuf,
#[arg(help = "Path to move xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to move")]
fields: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// Remove xattr values.
Rm {
#[arg(name = "path", help = "Paths to remove xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to remove")]
fields: Vec<Xattr>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(
long,
help = "Don't complain when an xattr doesn't exist; defaults to false"
)]
force: bool,
#[arg(short, long)]
verbose: bool,
},
/// Get and print xattr values for one or more paths.
Get {
#[arg(name = "path", help = "Paths to get xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to get")]
fields: Vec<Xattr>,
#[arg(short, long, help = "Output JSON; lossily decodes as UTF-8")]
json: bool,
#[arg(name = "where", short, long, help = "WHERE clause to filter results by", value_parser = ValueParser::new(PredicateParser{}))]
where_: Vec<Predicate>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(short, long, help = "Include user.ghee prefix in output")]
all: bool,
#[arg(
short,
long,
help = "Sort directory contents as paths are walked; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
#[arg(short, long, help = "Return records even when apparently empty")]
visit_empty: bool,
},
/// Set xattr values
Set {
#[arg(name = "paths", help = "Paths to set xattrs on", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "set", short, long, help = "k=v pairs to set", value_parser = ValueParser::new(AssignmentParser{}))]
field_assignments: Vec<Assignment>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(short, long)]
verbose: bool,
},
/// Insert records into a table, updating related indices
Ins {
#[arg(help = "Path of the table to insert into")]
table_path: PathBuf,
#[arg(
help = "Path of the records, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Remove record from a table, updating related indices
Del {
#[arg(help = "Path of the table to delete from")]
table_path: PathBuf,
#[arg(name = "where", short, long, help = "WHERE clauses specifying what to delete", value_parser = ValueParser::new(PredicateParser{}))]
where_: Vec<Predicate>,
#[arg(help = "Primary key values, subkeys space separated")]
key: Vec<Value>,
#[arg(short, long)]
verbose: bool,
},
/// Index tables
Idx {
#[arg(help = "Path to recursively index")]
src: PathBuf,
#[arg(help = "Path to output the new index to")]
dest: Option<PathBuf>,
#[arg(name = "key", short, long, help = "xattrs to index by")]
keys: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// List directory contents as seen by Ghee
Ls {
#[arg(help = "Paths to list the contents of; current directory by default")]
paths: Vec<PathBuf>,
#[arg(
short,
long,
help = "Sort directory contents; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
},
/// Initialize a directory as a Ghee table with specified primary key, then optionally insert records
Init {
#[arg(help = "Directory to initialize as a Ghee table")]
dir: PathBuf,
#[arg(
name = "key",
short,
long,
help = "xattrs the table will be indexed by"
)]
keys: Vec<Xattr>,
#[arg(
help = "Path of the records to insert, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Like `init`, but creates the directory first, or errors if one exists already
Create {
#[arg(help = "Directory to create and initialize as a Ghee table")]
dir: PathBuf,
#[arg(
name = "key",
short,
long,
help = "xattrs the table will be indexed by"
)]
keys: Vec<Xattr>,
#[arg(
help = "Path of the records to insert, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Commit a table, storing its contents as a BTRFS snapshot
Commit {
#[arg(help = "Directory of the table to commit, or the current directory by default")]
dir: Option<PathBuf>,
#[arg(short, long, help = "A message describing the changes being committed")]
message: Option<String>,
#[arg(short, long)]
verbose: bool,
},
/// Print the commit log
Log {
#[arg(
help = "Directory of the table whose log to print, or the current directory by default"
)]
dir: Option<PathBuf>,
},
/// Create a file, inferring xattrs from path if part of a table
Touch {
#[arg(help = "Path at which to create the file")]
path: PathBuf,
#[arg(short, long, help = "Create parent directories")]
parents: bool,
},
/// Print the status of files in the table, relative to the most recent commit (if any)
Status {
#[arg(
help = "Path of a file in a table; the whole table's status will be listed; defaults to the current directory"
)]
path: Option<PathBuf>,
#[arg(
short,
long,
help = "Sort directory contents; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
},
}

14
lang/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "ghee-lang"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "*"
clap = "*"
thiserror = "*"
nom = "*"
serde = "*"
serde_json = "*"

View file

@ -9,7 +9,7 @@ use nom::{character::complete::char, combinator::map, multi::separated_list1, IR
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;
use crate::{xattr_values, xattr_values_from_path, Record};
use crate::Record;
use super::{
value::Value,
@ -106,28 +106,6 @@ impl Key {
self.subkeys.iter()
}
/// Return the value of this key for the specified path
/// TODO Get only the relevant xattrs
pub fn value_for_path(&self, path: &PathBuf) -> Result<Vec<Value>> {
let xattrs = xattr_values(path)?;
let mut values: Vec<Value> = Vec::with_capacity(self.subkeys.len());
for subkey in self.subkeys.iter() {
let value =
xattrs
.get(subkey)
.cloned()
.ok_or_else(|| KeyErr::SubkeyValueNotFoundOnPath {
subkey: subkey.clone(),
path: path.clone(),
})?;
values.push(value);
}
Ok(values)
}
pub fn value_for_record(&self, record: &Record) -> Result<Vec<Value>> {
let mut values: Vec<Value> = Vec::with_capacity(self.subkeys.len());
@ -155,11 +133,6 @@ impl Key {
Ok(base_path)
}
/// The xattrs inferred from the path itself
pub fn record_for_path(&self, base_path: &PathBuf, path: &PathBuf) -> Result<Record> {
xattr_values_from_path(self, base_path, path)
}
}
impl<S: ToString, I: IntoIterator<Item = S>> From<I> for Key {
@ -217,7 +190,7 @@ pub fn parse_key(i: &[u8]) -> IResult<&[u8], Key> {
#[cfg(test)]
mod test {
use crate::parser::{key::Key, xattr::parse_xattr};
use crate::{xattr::parse_xattr, Key};
#[test]
fn test_from_string_iter() {

View file

@ -1,9 +1,11 @@
use std::collections::BTreeMap;
use nom::{
bytes::complete::take_while, character::complete::char, character::is_space,
multi::separated_list0, sequence::delimited, IResult,
};
use self::value::{parse_value_not_all_consuming, Value};
pub type Record = BTreeMap<Xattr, Value>;
pub fn space(i: &[u8]) -> IResult<&[u8], &[u8]> {
take_while(move |x| is_space(x))(i)
@ -49,10 +51,16 @@ fn test_array() {
);
}
pub mod assignment;
pub mod index;
pub mod key;
pub mod predicate;
pub mod relation;
pub mod value;
pub mod xattr;
mod assignment;
mod key;
mod predicate;
mod relation;
mod value;
mod xattr;
pub use assignment::*;
pub use key::*;
pub use predicate::*;
pub use relation::*;
pub use value::*;
pub use xattr::*;

View file

@ -1,253 +1,23 @@
use std::{env::current_dir, ffi::OsString, path::PathBuf};
use clap::{builder::ValueParser, Parser, Subcommand};
use clap::Parser;
use ghee_cli::{Cli, Commands};
use ghee_lang::Key;
use rustyline::error::ReadlineError;
use rustyline::DefaultEditor;
use thiserror::Error;
use ghee::{
cmd::{commit, cp, create, del, get, idx, init, ins, log, ls, mv, rm, set, status, touch},
parser::{
assignment::{Assignment, AssignmentParser},
key::Key,
predicate::{Predicate, PredicateParser},
value::Value,
xattr::Xattr,
},
APP_NAME, PKG_NAME, XDG_DIRS,
};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
/// Subcommand to run. If none is provided, a REPL will be launched
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Error, Debug)]
pub enum TableOpenErr {
#[error("Table path could not be opened because it doesn't exist")]
NoSuchPath,
}
#[derive(Subcommand)]
enum Commands {
/// Copy xattr values from one path to another.
Cp {
#[arg(help = "Path to copy xattrs from")]
src: PathBuf,
#[arg(help = "Path to copy xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to copy")]
fields: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// Move xattr values from one path to another.
Mv {
#[arg(help = "Path to move xattrs from")]
src: PathBuf,
#[arg(help = "Path to move xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to move")]
fields: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// Remove xattr values.
Rm {
#[arg(name = "path", help = "Paths to remove xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to remove")]
fields: Vec<Xattr>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(
long,
help = "Don't complain when an xattr doesn't exist; defaults to false"
)]
force: bool,
#[arg(short, long)]
verbose: bool,
},
/// Get and print xattr values for one or more paths.
Get {
#[arg(name = "path", help = "Paths to get xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to get")]
fields: Vec<Xattr>,
#[arg(short, long, help = "Output JSON; lossily decodes as UTF-8")]
json: bool,
#[arg(name = "where", short, long, help = "WHERE clause to filter results by", value_parser = ValueParser::new(PredicateParser{}))]
where_: Vec<Predicate>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(short, long, help = "Include user.ghee prefix in output")]
all: bool,
#[arg(
short,
long,
help = "Sort directory contents as paths are walked; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
#[arg(short, long, help = "Return records even when apparently empty")]
visit_empty: bool,
},
/// Set xattr values
Set {
#[arg(name = "paths", help = "Paths to set xattrs on", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "set", short, long, help = "k=v pairs to set", value_parser = ValueParser::new(AssignmentParser{}))]
field_assignments: Vec<Assignment>,
#[arg(long, help = "Process paths nonrecursively; defaults to false")]
flat: bool,
#[arg(short, long)]
verbose: bool,
},
/// Insert records into a table, updating related indices
Ins {
#[arg(help = "Path of the table to insert into")]
table_path: PathBuf,
#[arg(
help = "Path of the records, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Remove record from a table, updating related indices
Del {
#[arg(help = "Path of the table to delete from")]
table_path: PathBuf,
#[arg(name = "where", short, long, help = "WHERE clauses specifying what to delete", value_parser = ValueParser::new(PredicateParser{}))]
where_: Vec<Predicate>,
#[arg(help = "Primary key values, subkeys space separated")]
key: Vec<Value>,
#[arg(short, long)]
verbose: bool,
},
/// Index tables
Idx {
#[arg(help = "Path to recursively index")]
src: PathBuf,
#[arg(help = "Path to output the new index to")]
dest: Option<PathBuf>,
#[arg(name = "key", short, long, help = "xattrs to index by")]
keys: Vec<Xattr>,
#[arg(short, long)]
verbose: bool,
},
/// List directory contents as seen by Ghee
Ls {
#[arg(help = "Paths to list the contents of; current directory by default")]
paths: Vec<PathBuf>,
#[arg(
short,
long,
help = "Sort directory contents; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
},
/// Initialize a directory as a Ghee table with specified primary key, then optionally insert records
Init {
#[arg(help = "Directory to initialize as a Ghee table")]
dir: PathBuf,
#[arg(
name = "key",
short,
long,
help = "xattrs the table will be indexed by"
)]
keys: Vec<Xattr>,
#[arg(
help = "Path of the records to insert, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Like `init`, but creates the directory first, or errors if one exists already
Create {
#[arg(help = "Directory to create and initialize as a Ghee table")]
dir: PathBuf,
#[arg(
name = "key",
short,
long,
help = "xattrs the table will be indexed by"
)]
keys: Vec<Xattr>,
#[arg(
help = "Path of the records to insert, JSON, one record per line; if omitted, the same format is taken from stdin"
)]
records_path: Option<PathBuf>,
#[arg(short, long)]
verbose: bool,
},
/// Commit a table, storing its contents as a BTRFS snapshot
Commit {
#[arg(help = "Directory of the table to commit, or the current directory by default")]
dir: Option<PathBuf>,
#[arg(short, long, help = "A message describing the changes being committed")]
message: Option<String>,
#[arg(short, long)]
verbose: bool,
},
/// Print the commit log
Log {
#[arg(
help = "Directory of the table whose log to print, or the current directory by default"
)]
dir: Option<PathBuf>,
},
/// Create a file, inferring xattrs from path if part of a table
Touch {
#[arg(help = "Path at which to create the file")]
path: PathBuf,
#[arg(short, long, help = "Create parent directories")]
parents: bool,
},
/// Print the status of files in the table, relative to the most recent commit (if any)
Status {
#[arg(
help = "Path of a file in a table; the whole table's status will be listed; defaults to the current directory"
)]
path: Option<PathBuf>,
#[arg(
short,
long,
help = "Sort directory contents; disable for potential speedup on large listings",
default_value_t = true
)]
sort: bool,
},
}
fn repl() -> rustyline::Result<()> {
println!("{} {}", *APP_NAME, env!("CARGO_PKG_VERSION"));
println!();

View file

@ -1,78 +0,0 @@
use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Copy xattr values from one path to another.
Cp {
#[arg(help = "Path to copy xattrs from")]
src: PathBuf,
#[arg(help = "Path to copy xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to copy")]
fields: Vec<String>,
#[arg(short, long)]
verbose: bool,
},
/// Move xattr values from one path to another.
Mv {
#[arg(help = "Path to move xattrs from")]
src: PathBuf,
#[arg(help = "Path to move xattrs to")]
dest: PathBuf,
#[arg(name = "field", short, long, help = "xattrs to move")]
fields: Vec<String>,
#[arg(short, long)]
verbose: bool,
},
/// Remove xattr values.
Rm {
#[arg(name = "path", help = "Paths to remove xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to remove")]
fields: Vec<String>,
#[arg(short, long)]
verbose: bool,
},
/// Get and print xattr values for one or more paths.
Get {
#[arg(name = "path", help = "Paths to get xattrs from", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "field", short, long, help = "xattrs to get")]
fields: Vec<String>,
#[arg(short, long, help = "Output JSON; lossily decodes as UTF-8")]
json: bool,
},
/// Set xattr values
Set {
#[arg(name = "paths", help = "Paths to set xattrs on", required = true)]
paths: Vec<PathBuf>,
#[arg(name = "set", short, long, help = "k=v pairs to set")]
field_assignments: Vec<String>,
#[arg(short, long)]
verbose: bool,
},
/// Index tables
Idx {
#[arg(help = "Path to recursively index")]
src: PathBuf,
#[arg(help = "Path to output the new index to")]
dest: PathBuf,
#[arg(name = "key", short, long, help = "xattrs to index by")]
keys: Vec<String>,
#[arg(short, long)]
verbose: bool,
},
}

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use std::path::PathBuf;
use crate::parser::xattr::Xattr;
use ghee_lang::Xattr;
use super::cp_or_mv::{cp_or_mv, CopyOrMove};

View file

@ -1,12 +1,9 @@
use anyhow::{Context, Result};
use ghee_lang::{Assignment, Xattr};
use std::{fmt::Formatter, path::PathBuf};
use crate::{
list_xattrs,
parser::{assignment::Assignment, xattr::Xattr},
xattr_value,
};
use crate::{list_xattrs, xattr_value};
use super::{rm, set};
@ -78,7 +75,9 @@ pub(crate) fn cp_or_mv(
#[cfg(test)]
mod test {
use crate::{parser::value::Value, test_support::Scenario, xattr_values};
use ghee_lang::Value;
use crate::{test_support::Scenario, xattr_values};
use super::{cp_or_mv, CopyOrMove};

View file

@ -1,12 +1,12 @@
use anyhow::Result;
use btrfsutil::subvolume::Subvolume;
use ghee_lang::Key;
use thiserror::Error;
use std::fs::{create_dir, create_dir_all};
use std::path::PathBuf;
use crate::parser::key::Key;
use crate::GheeErr;
use super::init;
@ -54,7 +54,9 @@ pub fn create(dir: &PathBuf, key: &Key, verbose: bool) -> Result<()> {
#[cfg(test)]
mod test {
use crate::{parser::key::Key, test_support::TempDirAuto};
use ghee_lang::Key;
use crate::test_support::TempDirAuto;
use super::create;

View file

@ -1,12 +1,8 @@
use anyhow::Result;
use ghee_lang::{Key, Predicate, Value};
use thiserror::Error;
use crate::{
parser::{key::Key, predicate::Predicate, value::Value},
table_info,
walk::walk_records,
xattr_values, Record,
};
use crate::{table_info, walk::walk_records, xattr_values, Record};
use std::{collections::BTreeMap, fs::remove_file, path::PathBuf};
@ -139,12 +135,10 @@ pub fn del(
mod test {
use std::{cell::Cell, rc::Rc};
use ghee_lang::{parse_predicate, Value};
use crate::{
parser::{predicate::parse_predicate, value::Value},
record_count, table_info,
test_support::Scenario,
walk::walk_records,
xattr_values,
record_count, table_info, test_support::Scenario, walk::walk_records, xattr_values,
};
use super::{del, unlink_record};

View file

@ -1,11 +1,9 @@
use anyhow::Result;
use ghee_lang::{Predicate, Value, Xattr};
use serde::Serialize;
use thiserror::Error;
use crate::{
parser::{predicate::Predicate, value::Value, xattr::Xattr},
walk::walk_records,
};
use crate::walk::walk_records;
use std::{collections::BTreeMap, io::Write, path::PathBuf};
@ -92,7 +90,9 @@ pub fn get(
#[cfg(test)]
mod test {
use crate::{cmd::create, parser::key::Key, test_support::TempDirAuto};
use ghee_lang::Key;
use crate::{cmd::create, test_support::TempDirAuto};
use super::get;

View file

@ -1,4 +1,6 @@
use anyhow::Result;
use ghee_lang::Key;
use ghee_lang::Xattr;
use thiserror::Error;
use std::fs::hard_link;
@ -10,11 +12,8 @@ use std::path::Path;
use walkdir::WalkDir;
use crate::declare_closure_indices;
use crate::parser::xattr::Xattr;
use crate::paths::sub_idx_path;
use crate::parser::key::Key;
use std::path::PathBuf;
use super::init;
@ -106,7 +105,9 @@ pub fn idx(src: &PathBuf, dest: Option<&PathBuf>, keys: &Key, verbose: bool) ->
#[cfg(test)]
mod test {
use crate::{cmd::init, parser::key::Key, table_info, test_support::TempDirAuto};
use ghee_lang::Key;
use crate::{cmd::init, table_info, test_support::TempDirAuto};
use super::idx;

View file

@ -1,9 +1,10 @@
use std::{collections::BTreeMap, path::PathBuf};
use anyhow::Result;
use ghee_lang::Key;
use thiserror::Error;
use crate::{parser::key::Key, set_table_info, table_info, GheeErr, TableInfo};
use crate::{set_table_info, table_info, GheeErr, TableInfo};
#[derive(Error, Debug)]
pub enum TableInitErr {
@ -46,11 +47,9 @@ pub fn init(dir: &PathBuf, key: &Key, verbose: bool) -> Result<()> {
#[cfg(test)]
mod test {
use crate::{
parser::{key::Key, xattr::parse_xattr},
table_info,
test_support::TempDirAuto,
};
use ghee_lang::{parse_xattr, Key};
use crate::{table_info, test_support::TempDirAuto};
use super::init;

View file

@ -5,12 +5,10 @@ use std::{
};
use anyhow::Result;
use ghee_lang::{Key, Value, Xattr};
use thiserror::Error;
use crate::{
parser::{key::Key, value::Value, xattr::Xattr},
table_info, Record,
};
use crate::{table_info, Record};
#[derive(Error, Debug)]
pub enum InsErr {
@ -170,7 +168,9 @@ pub fn ins_records(
#[cfg(test)]
mod test {
use crate::{parser::value::Value, test_support::Scenario, xattr_values};
use ghee_lang::Value;
use crate::{test_support::Scenario, xattr_values};
#[test]
fn test_ins() {

View file

@ -2,11 +2,11 @@ use std::path::PathBuf;
use anyhow::Result;
use colored::Colorize;
use ghee_lang::Value;
use xattr;
use crate::{
parser::value::Value, paths::table_snapshot_path, xattr_value, XATTR_MOST_RECENT_SNAPSHOT,
XATTR_SNAPSHOT_MESSAGE,
paths::table_snapshot_path, xattr_value, XATTR_MOST_RECENT_SNAPSHOT, XATTR_SNAPSHOT_MESSAGE,
};
pub fn log(dir: &PathBuf) -> Result<()> {

View file

@ -1,9 +1,8 @@
use anyhow::Result;
use ghee_lang::Xattr;
use std::path::PathBuf;
use crate::parser::xattr::Xattr;
use super::cp_or_mv::{cp_or_mv, CopyOrMove};
/** Move xattrs from `src` to `dest` */

View file

@ -1,14 +1,10 @@
use anyhow::Result;
use ghee_lang::{Key, Xattr};
use thiserror::Error;
use std::{collections::BTreeSet, fs::remove_file, path::PathBuf};
use crate::{
containing_table_info,
parser::{key::Key, xattr::Xattr},
walk::walk_paths,
xattr_values,
};
use crate::{containing_table_info, walk::walk_paths, xattr_values};
#[derive(Error, Debug)]
pub enum RmErr {

View file

@ -1,15 +1,11 @@
use anyhow::{Context, Result};
use ghee_lang::{Assignment, Value, Xattr};
use path_absolutize::*;
use thiserror::Error;
use walkdir::WalkDir;
use crate::parser::value::Value;
use crate::{containing_table_info, xattr_values, Record};
use crate::parser::xattr::Xattr;
use crate::parser::assignment::Assignment;
use std::collections::HashSet;
use std::fs::{create_dir_all, hard_link, remove_file};
use std::path::{Path, PathBuf};
@ -146,9 +142,10 @@ mod test {
path::PathBuf,
};
use ghee_lang::{parse_assignment, Value, Xattr};
use crate::{
cmd::ins::ins_records,
parser::{assignment::parse_assignment, value::Value, xattr::Xattr},
test_support::{Scenario, TempDirAuto},
xattr_values, Record,
};

View file

@ -66,9 +66,10 @@ pub fn status(path: &PathBuf, sort: bool) -> Result<()> {
mod test {
use std::path::Path;
use ghee_lang::Key;
use crate::{
cmd::create,
parser::key::Key,
test_support::{CurrentDirGuard, TempDirAuto},
};

View file

@ -6,7 +6,7 @@ use std::{
use anyhow::Result;
use path_absolutize::Absolutize;
use crate::{containing_table_info, write_xattr_values};
use crate::{containing_table_info, write_xattr_values, xattr_values_from_path};
/**
* Create a file at `path`; if part of a table, initialize its
@ -25,7 +25,7 @@ pub fn touch(path: &PathBuf, create_parents: bool) -> Result<()> {
File::create(&path)?;
if let Some(info) = containing_table_info(&path)? {
let xattrs = info.key.record_for_path(info.path(), &path)?;
let xattrs = xattr_values_from_path(&info.key, info.path(), &path)?;
write_xattr_values(path, &xattrs)?;
}
@ -35,7 +35,9 @@ pub fn touch(path: &PathBuf, create_parents: bool) -> Result<()> {
#[cfg(test)]
mod test {
use crate::{cmd::init, parser::key::Key, test_support::TempDirAuto, xattr_values};
use ghee_lang::Key;
use crate::{cmd::init, test_support::TempDirAuto, xattr_values};
use super::touch;

View file

@ -1,9 +1,7 @@
#[macro_use]
extern crate lazy_static;
pub mod cli;
pub mod cmd;
pub mod parser;
pub mod paths;
#[cfg(test)]
mod test_support;
@ -15,12 +13,7 @@ use std::{
path::{Path, PathBuf},
};
use parser::{
key::Key,
predicate::Predicate,
value::{parse_value, Value},
xattr::{parse_xattr, Xattr},
};
use ghee_lang::{parse_value, parse_xattr, Key, Namespace, Predicate, Record, Value, Xattr};
use anyhow::Result;
use serde::{Deserialize, Serialize};
@ -28,8 +21,6 @@ use thiserror::Error;
use walkdir::{DirEntry, WalkDir};
use xdg::BaseDirectories;
use crate::parser::xattr::Namespace;
/// Uppercase the first character in a string
/// https://stackoverflow.com/a/38406885/5374919
fn uppercase_first(s: &str) -> String {
@ -415,8 +406,6 @@ pub fn set_table_info<P: AsRef<Path>>(dir: P, info: &TableInfo) -> Result<()> {
)
}
pub type Record = BTreeMap<Xattr, Value>;
#[derive(Error, Debug)]
pub enum IndexListPushErr {
#[error("Table info not found at {0}; can only push to initialized tables")]
@ -473,17 +462,12 @@ mod test {
fs::{create_dir_all, File},
};
use ghee_lang::{parse_predicate, parse_xattr, Key, Namespace, Value, Xattr};
use crate::{
best_index,
cmd::{idx, init},
containing_table_info, declare_indices, index_list_push,
parser::{
key::Key,
predicate::parse_predicate,
value::Value,
xattr::{parse_xattr, Namespace, Xattr},
},
set_table_info, table_info,
containing_table_info, declare_indices, index_list_push, set_table_info, table_info,
test_support::{Scenario, TempDirAuto},
write_xattr_values, xattr_values, xattr_values_from_path, Record, TableInfo,
};

View file

@ -1,11 +1,10 @@
use anyhow::Result;
use ghee_lang::{Key, Namespace};
use std::{ffi::OsString, path::PathBuf};
use thiserror::Error;
use crate::parser::{key::Key, xattr::Namespace};
#[derive(Error, Debug)]
pub enum SubIdxPathErr {
#[error("The provided key was empty")]

View file

@ -6,12 +6,10 @@ use std::{
path::{Path, PathBuf},
};
use ghee_lang::{Key, Xattr};
use tempdir::TempDir;
use crate::{
cmd::{idx, init, ins},
parser::{key::Key, xattr::Xattr},
};
use crate::cmd::{idx, init, ins};
/** A test scenario
*

View file

@ -3,16 +3,11 @@ use std::path::PathBuf;
use anyhow::Result;
use walkdir::{DirEntry, WalkDir};
use ghee_lang::{Key, Namespace, Predicate, Value, Xattr};
use crate::{
best_index, containing_table_info, is_hidden,
parser::{
key::Key,
predicate::Predicate,
value::Value,
xattr::{Namespace, Xattr},
},
table_info, xattr_values, xattr_values_from_path, Record, TableInfo, DEFAULT_KEY,
XATTR_GHEE_LOWER, XATTR_GHEE_UPPER,
best_index, containing_table_info, is_hidden, table_info, xattr_values, xattr_values_from_path,
Record, TableInfo, DEFAULT_KEY, XATTR_GHEE_LOWER, XATTR_GHEE_UPPER,
};
pub struct PathVisit<'a, 'b, 'c> {
@ -228,14 +223,11 @@ mod test {
rc::Rc,
};
use ghee_lang::{parse_assignment, parse_predicate, Key, Predicate};
use crate::{
cmd::{init, set},
declare_indices,
parser::{
assignment::parse_assignment,
key::Key,
predicate::{parse_predicate, Predicate},
},
test_support::{Scenario, TempDirAuto},
};