Misc. clap improvements, , more accurate value names, ...

This commit is contained in:
2025-12-15 00:46:56 +09:00
parent 7b79f7b163
commit 6e914dec34
17 changed files with 26 additions and 33 deletions

View File

@@ -24,34 +24,30 @@ pub use show_privs::*;
pub use show_user::*;
pub use unlock_user::*;
use clap::Parser;
use clap::Subcommand;
use crate::core::protocol::{ClientToServerMessageStream, Response};
#[derive(Parser, Debug, Clone)]
#[derive(Subcommand, Debug, Clone)]
#[command(subcommand_required = true)]
pub enum ClientCommand {
/// Check whether you are authorized to manage the specified databases or users.
#[command()]
CheckAuth(CheckAuthArgs),
/// Create one or more databases
#[command()]
CreateDb(CreateDbArgs),
/// Delete one or more databases
#[command()]
DropDb(DropDbArgs),
/// Print information about one or more databases
///
/// If no database name is provided, all databases you have access will be shown.
#[command()]
ShowDb(ShowDbArgs),
/// Print user privileges for one or more databases
///
/// If no database names are provided, all databases you have access to will be shown.
#[command()]
ShowPrivs(ShowPrivsArgs),
/// Change user privileges for one or more databases. See `edit-privs --help` for details.
@@ -116,29 +112,23 @@ pub enum ClientCommand {
EditPrivs(EditPrivsArgs),
/// Create one or more users
#[command()]
CreateUser(CreateUserArgs),
/// Delete one or more users
#[command()]
DropUser(DropUserArgs),
/// Change the MySQL password for a user
#[command()]
PasswdUser(PasswdUserArgs),
/// Print information about one or more users
///
/// If no username is provided, all users you have access will be shown.
#[command()]
ShowUser(ShowUserArgs),
/// Lock account for one or more users
#[command()]
LockUser(LockUserArgs),
/// Unlock account for one or more users
#[command()]
UnlockUser(UnlockUserArgs),
}

View File

@@ -15,7 +15,7 @@ use tokio_stream::StreamExt;
#[derive(Parser, Debug, Clone)]
pub struct CheckAuthArgs {
/// The MySQL database(s) or user(s) to check authorization for
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "NAME")]
name: Vec<String>,
/// Treat the provided names as users instead of databases

View File

@@ -16,7 +16,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct CreateDbArgs {
/// The MySQL database(s) to create
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "DB_NAME")]
name: Vec<MySQLDatabase>,
/// Print the information as JSON

View File

@@ -17,7 +17,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct CreateUserArgs {
/// The MySQL user(s) to create
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "USER_NAME")]
username: Vec<MySQLUser>,
/// Do not ask for a password, leave it unset

View File

@@ -19,7 +19,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct DropDbArgs {
/// The MySQL database(s) to drop
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "DB_NAME")]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
name: Vec<MySQLDatabase>,

View File

@@ -19,7 +19,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct DropUserArgs {
/// The MySQL user(s) to drop
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "USER_NAME")]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
username: Vec<MySQLUser>,

View File

@@ -30,6 +30,7 @@ use crate::{
pub struct EditPrivsArgs {
/// The MySQL database to edit privileges for
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
#[arg(value_name = "DB_NAME")]
pub name: Option<MySQLDatabase>,
#[arg(

View File

@@ -18,7 +18,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct LockUserArgs {
/// The MySQL user(s) to loc
#[arg(num_args = 1..)]
#[arg(num_args = 1.., value_name = "USER_NAME")]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
username: Vec<MySQLUser>,

View File

@@ -23,6 +23,7 @@ use crate::{
pub struct PasswdUserArgs {
/// The MySQL user whose password is to be changed
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
#[arg(value_name = "USER_NAME")]
username: MySQLUser,
/// Read the new password from a file instead of prompting for it

View File

@@ -18,7 +18,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct ShowDbArgs {
/// The MySQL database(s) to show
#[arg(num_args = 0..)]
#[arg(num_args = 0.., value_name = "DB_NAME")]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
name: Vec<MySQLDatabase>,

View File

@@ -19,7 +19,7 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct ShowPrivsArgs {
/// The MySQL database(s) to show privileges for
#[arg(num_args = 0..)]
#[arg(num_args = 0.., value_name = "DB_NAME")]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
name: Vec<MySQLDatabase>,

View File

@@ -18,8 +18,8 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct ShowUserArgs {
/// The MySQL user(s) to show
#[arg(num_args = 0..)]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
#[arg(num_args = 0.., value_name = "USER_NAME")]
username: Vec<MySQLUser>,
/// Print the information as JSON

View File

@@ -18,8 +18,8 @@ use crate::{
#[derive(Parser, Debug, Clone)]
pub struct UnlockUserArgs {
/// The MySQL user(s) to unlock
#[arg(num_args = 1..)]
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
#[arg(num_args = 1.., value_name = "USER_NAME")]
username: Vec<MySQLUser>,
/// Print the information as JSON

View File

@@ -1,4 +1,4 @@
use clap::Parser;
use clap::{Parser, Subcommand};
use clap_complete::ArgValueCompleter;
use futures_util::{SinkExt, StreamExt};
use std::os::unix::net::UnixStream as StdUnixStream;
@@ -98,7 +98,7 @@ pub struct Args {
// NOTE: mysql-dbadm explicitly calls privileges "permissions".
// This is something we're trying to move away from.
// See https://git.pvv.ntnu.no/Projects/muscl/issues/29
#[derive(Parser)]
#[derive(Subcommand)]
pub enum Command {
/// create the DATABASE(s).
Create(CreateArgs),

View File

@@ -1,4 +1,4 @@
use clap::Parser;
use clap::{Parser, Subcommand};
use clap_complete::ArgValueCompleter;
use futures_util::{SinkExt, StreamExt};
use std::path::PathBuf;
@@ -67,7 +67,7 @@ pub struct Args {
config: Option<PathBuf>,
}
#[derive(Parser)]
#[derive(Subcommand)]
pub enum Command {
/// create the USER(s).
Create(CreateArgs),

View File

@@ -75,9 +75,12 @@ const LONG_VERSION: &str = long_version();
version,
about,
disable_help_subcommand = true,
propagate_version = true,
before_long_help = ASCII_BANNER,
after_long_help = KIND_REGARDS,
long_version = LONG_VERSION,
// NOTE: All non-registered "subcommands" are processed before Arg::parse() is called.
subcommand_required = true,
)]
struct Args {
#[command(subcommand)]
@@ -169,8 +172,8 @@ fn handle_dynamic_completion() -> anyhow::Result<Option<()>> {
let command = match argv0.as_str() {
"muscl" => Args::command(),
"mysql-dbadm" => mysql_dbadm::Command::command(),
"mysql-useradm" => mysql_useradm::Command::command(),
"mysql-dbadm" => mysql_dbadm::Args::command(),
"mysql-useradm" => mysql_useradm::Args::command(),
command => anyhow::bail!("Unknown executable name: `{}`", command),
};

View File

@@ -1,7 +1,7 @@
use std::path::PathBuf;
use anyhow::Context;
use clap::Parser;
use clap::{Parser, Subcommand};
use clap_verbosity_flag::{InfoLevel, Verbosity};
use tracing_subscriber::prelude::*;
@@ -26,15 +26,13 @@ pub struct ServerArgs {
pub disable_landlock: bool,
}
#[derive(Parser, Debug, Clone)]
#[derive(Subcommand, Debug, Clone)]
pub enum ServerCommand {
/// Start the server and listen for incoming connections on the unix socket
/// specified in the configuration file.
#[command()]
Listen,
/// Start the server using systemd socket activation.
#[command()]
SocketActivate,
}