Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion aria/contents/docs/libra/command/config/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Manage configuration entries by adding, retrieving, listing, or deleting them in
List all configuration entries from the database.
_Does not require `key` or `value_pattern`._

- `--name-only`
Output only the names of config variables for --list
_Only valid with `--list`._

- `-d`, `--default <value>`
Return the given default value if no matching key is found.
_Only valid with `--get` `--get-all`._
Expand All @@ -49,5 +53,6 @@ Manage configuration entries by adding, retrieving, listing, or deleting them in
Print help information.

<Note type="note" title="Note">
Only one of `--add`, `--get`, `--get-all`, `--unset`, `--unset-all`, or `--list` can be used at a time. Use `--default` only with `--get` and `--get-all`.
Only one of `--add`, `--get`, `--get-all`, `--unset`, `--unset-all`, or `--list` can be used at a time. Use `--default` only with `--get` and `--get-all`.
Use `--name-only` only with `--list`.
</Note>
21 changes: 18 additions & 3 deletions libra/src/command/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub struct ConfigArgs {
/// List all the configuration entries from database
#[clap(long, short, group("mode"))]
pub list: bool,
/// If set, only print the key string of the configuration entry instead of the key=value.
/// This is only valid when `list` is set.
#[clap(long("name-only"), requires = "list")]
pub name_only: bool,
/// The key string of the configuration entry, should be like configuration.[name].key
#[clap(value_name("key"), required_unless_present("list"))]
pub key: Option<String>,
Expand All @@ -40,6 +44,11 @@ impl ConfigArgs {
if self.default.is_some() && !(self.get || self.get_all) {
return Err("default value is only valid when get (get_all) is set".to_string());
}
// validate that name_only is only valid when list is set
if self.name_only && !self.list {
return Err("--name-only is only valid when --list is set".to_string());
}

Ok(())
}
}
Expand All @@ -56,7 +65,7 @@ pub async fn execute(args: ConfigArgs) {
return;
}
if args.list {
list_config().await;
list_config(args.name_only).await;
} else {
let origin_key = args.key.unwrap();
let key: Key = parse_key(origin_key).await;
Expand Down Expand Up @@ -201,9 +210,15 @@ async fn unset_all_config(key: &Key, valuepattern: Option<&str>) {
}

/// List all configurations
async fn list_config() {
async fn list_config(name_only: bool) {
let configurations = config::Config::list_all().await;
for (key, value) in configurations {
println!("{key}={value}");
// If name_only is set, only print the key string
// Otherwise, print the key=value pair
if name_only {
println!("{key}");
} else {
println!("{key}={value}");
}
}
}
144 changes: 144 additions & 0 deletions libra/tests/command/config_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ async fn test_config_get_failed() {
key: Some("user.name".to_string()),
valuepattern: Some("value".to_string()),
default: Some("erasernoob".to_string()),
name_only: false,
};
config::execute(args).await;
}
Expand All @@ -45,6 +46,7 @@ async fn test_config_get_all() {
key: Some("user.name".to_string()),
valuepattern: Some("erasernoob".to_string()),
default: None,
name_only: false,
};
config::execute(arg1).await;

Expand All @@ -58,6 +60,7 @@ async fn test_config_get_all() {
key: Some("user.name".to_string()),
valuepattern: None,
default: None,
name_only: false,
};
config::execute(args).await;
}
Expand All @@ -82,6 +85,7 @@ async fn test_config_get_all_with_default() {
key: Some("user.name".to_string()),
valuepattern: Some("value".to_string()),
default: Some("erasernoob".to_string()),
name_only: false,
};
config::execute(args).await;
}
Expand All @@ -107,6 +111,7 @@ async fn test_config_get() {
key: Some("user.name".to_string()),
valuepattern: Some("erasernoob".to_string()),
default: None,
name_only: false,
};
config::execute(arg1).await;

Expand All @@ -120,6 +125,7 @@ async fn test_config_get() {
key: Some("user.name".to_string()),
valuepattern: None,
default: None,
name_only: false,
};
config::execute(args).await;
}
Expand All @@ -143,6 +149,144 @@ async fn test_config_get_with_default() {
key: Some("user.name".to_string()),
valuepattern: None,
default: Some("erasernoob".to_string()),
name_only: false,
};
config::execute(args).await;
}

#[tokio::test]
#[serial]
async fn test_config_list() {
let temp_path = tempdir().unwrap();
// start a new libra repository in a temporary directory
test::setup_with_new_libra_in(temp_path.path()).await;

// set the current working directory to the temporary path
let _guard = test::ChangeDirGuard::new(temp_path.path());

// Add the config first
let arg1 = config::ConfigArgs {
add: true,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: false,
key: Some("user.name".to_string()),
valuepattern: Some("erasernoob".to_string()),
default: None,
name_only: false,
};
config::execute(arg1).await;

let arg2 = config::ConfigArgs {
add: true,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: false,
key: Some("user.email".to_string()),
valuepattern: Some("erasernoob@example.com".to_string()),
default: None,
name_only: false,
};
config::execute(arg2).await;

// List configs
let args = config::ConfigArgs {
add: false,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: true,
key: None,
valuepattern: None,
default: None,
name_only: false,
};
assert!(args.validate().is_ok());
config::execute(args).await;
}

#[tokio::test]
#[serial]
async fn test_config_list_name_only() {
let temp_path = tempdir().unwrap();
// start a new libra repository in a temporary directory
test::setup_with_new_libra_in(temp_path.path()).await;

// set the current working directory to the temporary path
let _guard = test::ChangeDirGuard::new(temp_path.path());

// Add the config first
let arg1 = config::ConfigArgs {
add: true,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: false,
key: Some("user.name".to_string()),
valuepattern: Some("erasernoob".to_string()),
default: None,
name_only: false,
};
config::execute(arg1).await;

let arg2 = config::ConfigArgs {
add: true,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: false,
key: Some("user.email".to_string()),
valuepattern: Some("erasernoob@example.com".to_string()),
default: None,
name_only: false,
};
config::execute(arg2).await;

// List configs with name_only set to true
let args = config::ConfigArgs {
add: false,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: true,
key: None,
valuepattern: None,
default: None,
name_only: true,
};
assert!(args.validate().is_ok());
config::execute(args).await;
}

#[tokio::test]
#[serial]
async fn test_config_list_name_only_without_list() {
let temp_path = tempdir().unwrap();
// start a new libra repository in a temporary directory
test::setup_with_new_libra_in(temp_path.path()).await;

// set the current working directory to the temporary path
let _guard = test::ChangeDirGuard::new(temp_path.path());

let args = config::ConfigArgs {
add: false,
get: false,
get_all: false,
unset: false,
unset_all: false,
list: false,
key: None,
valuepattern: None,
default: None,
name_only: true,
};
assert!(args.validate().is_err());
}
Loading