diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 4d578eeba..a2dc8e06b 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -19,8 +19,14 @@ use uucore::libc::mode_t; use uucore::mode; use uucore::{format_usage, show_error}; -static ABOUT: &str = "Change the mode of each FILE to MODE. - With --reference, change the mode of each FILE to that of RFILE."; +const ABOUT: &str = "Change the mode of each FILE to MODE.\n\ + With --reference, change the mode of each FILE to that of RFILE."; +const USAGE: &str = "\ + {} [OPTION]... MODE[,MODE]... FILE... + {} [OPTION]... OCTAL-MODE FILE... + {} [OPTION]... --reference=RFILE FILE..."; +const LONG_USAGE: &str = + "Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'."; mod options { pub const CHANGES: &str = "changes"; @@ -34,15 +40,6 @@ mod options { pub const FILE: &str = "FILE"; } -const USAGE: &str = "\ - {} [OPTION]... MODE[,MODE]... FILE... - {} [OPTION]... OCTAL-MODE FILE... - {} [OPTION]... --reference=RFILE FILE..."; - -fn get_long_usage() -> &'static str { - "Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'." -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut args = args.collect_lossy(); @@ -51,9 +48,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE"). let mode_had_minus_prefix = mode::strip_minus_from_mode(&mut args); - let after_help = get_long_usage(); - - let matches = uu_app().after_help(after_help).try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let changes = matches.get_flag(options::CHANGES); let quiet = matches.get_flag(options::QUIET); diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index b53f6135a..bebdd4d36 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -11,26 +11,22 @@ use uucore::display::print_verbatim; use uucore::error::{UResult, UUsageError}; use uucore::format_usage; -static ABOUT: &str = "Strip last component from file name"; +const ABOUT: &str = "Strip last component from file name"; const USAGE: &str = "{} [OPTION] NAME..."; +const LONG_USAGE: &str = "\ + Output each NAME with its last non-slash component and trailing slashes \n\ + removed; if NAME contains no /'s, output '.' (meaning the current directory)."; mod options { pub const ZERO: &str = "zero"; pub const DIR: &str = "dir"; } -fn get_long_usage() -> &'static str { - "Output each NAME with its last non-slash component and trailing slashes \n\ - removed; if NAME contains no /'s, output '.' (meaning the current directory)." -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_lossy(); - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let separator = if matches.get_flag(options::ZERO) { "\0" diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 046091b34..9aced8ba5 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -22,8 +22,10 @@ use uucore::{format_usage, show, show_if_err}; static DEFAULT_PERM: u32 = 0o755; -static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist"; +const ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist"; const USAGE: &str = "{} [OPTION]... [USER]"; +const LONG_USAGE: &str = + "Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'."; mod options { pub const MODE: &str = "mode"; @@ -32,10 +34,6 @@ mod options { pub const DIRS: &str = "dirs"; } -fn get_long_usage() -> &'static str { - "Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'." -} - #[cfg(windows)] fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result { Ok(DEFAULT_PERM) @@ -92,9 +90,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // Linux-specific options, not implemented // opts.optflag("Z", "context", "set SELinux security context" + // " of each created directory to CTX"), - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let dirs = matches .get_many::(options::DIRS) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 850e18408..0d621355d 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -37,8 +37,22 @@ struct Options { verbose: bool, } -static ABOUT: &str = "Remove (unlink) the FILE(s)"; +const ABOUT: &str = "Remove (unlink) the FILE(s)"; const USAGE: &str = "{} [OPTION]... FILE..."; +const LONG_USAGE: &str = "\ +By default, rm does not remove directories. Use the --recursive (-r or -R) +option to remove each listed directory, too, along with all of its contents + +To remove a file whose name starts with a '-', for example '-foo', +use one of these commands: +rm -- -foo + +rm ./-foo + +Note that if you use rm to remove a file, it might be possible to recover +some of its contents, given sufficient expertise and/or time. For greater +assurance that the contents are truly unrecoverable, consider using shred."; + static OPT_DIR: &str = "dir"; static OPT_INTERACTIVE: &str = "interactive"; static OPT_FORCE: &str = "force"; @@ -53,28 +67,9 @@ static PRESUME_INPUT_TTY: &str = "-presume-input-tty"; static ARG_FILES: &str = "files"; -fn get_long_usage() -> String { - String::from( - "By default, rm does not remove directories. Use the --recursive (-r or -R) - option to remove each listed directory, too, along with all of its contents - - To remove a file whose name starts with a '-', for example '-foo', - use one of these commands: - rm -- -foo - - rm ./-foo - - Note that if you use rm to remove a file, it might be possible to recover - some of its contents, given sufficient expertise and/or time. For greater - assurance that the contents are truly unrecoverable, consider using shred.", - ) -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let files: Vec = matches .get_many::(ARG_FILES) diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 119c9c7fb..2d0949223 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -13,7 +13,7 @@ use uucore::fsext::{ pretty_filetype, pretty_fstype, pretty_time, read_fs_list, statfs, BirthTime, FsMeta, }; use uucore::libc::mode_t; -use uucore::{entries, format_usage, show_error, show_warning}; +use uucore::{entries, format_usage, help_section, help_usage, show_error, show_warning}; use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use std::borrow::Cow; @@ -24,8 +24,9 @@ use std::os::unix::fs::{FileTypeExt, MetadataExt}; use std::os::unix::prelude::OsStrExt; use std::path::Path; -const ABOUT: &str = "Display file or file system status."; -const USAGE: &str = "{} [OPTION]... FILE..."; +const ABOUT: &str = help_section!("about", "stat.md"); +const USAGE: &str = help_usage!("stat.md"); +const LONG_USAGE: &str = help_section!("long usage", "stat.md"); mod options { pub const DEREFERENCE: &str = "dereference"; @@ -751,67 +752,9 @@ impl Stater { } } -fn get_long_usage() -> &'static str { - " -The valid format sequences for files (without --file-system): - - %a access rights in octal (note '#' and '0' printf flags) - %A access rights in human readable form - %b number of blocks allocated (see %B) - %B the size in bytes of each block reported by %b - %C SELinux security context string - %d device number in decimal - %D device number in hex - %f raw mode in hex - %F file type - %g group ID of owner - %G group name of owner - %h number of hard links - %i inode number - %m mount point - %n file name - %N quoted file name with dereference if symbolic link - %o optimal I/O transfer size hint - %s total size, in bytes - %t major device type in hex, for character/block device special files - %T minor device type in hex, for character/block device special files - %u user ID of owner - %U user name of owner - %w time of file birth, human-readable; - if unknown - %W time of file birth, seconds since Epoch; 0 if unknown - %x time of last access, human-readable - %X time of last access, seconds since Epoch - %y time of last data modification, human-readable - %Y time of last data modification, seconds since Epoch - %z time of last status change, human-readable - %Z time of last status change, seconds since Epoch - -Valid format sequences for file systems: - - %a free blocks available to non-superuser - %b total data blocks in file system - %c total file nodes in file system - %d free file nodes in file system - %f free blocks in file system - %i file system ID in hex - %l maximum length of filenames - %n file name - %s block size (for faster transfers) - %S fundamental block size (for block counts) - %t file system type in hex - %T file system type in human readable form - -NOTE: your shell may have its own version of stat, which usually supersedes -the version described here. Please refer to your shell's documentation -for details about the options it supports. -" -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let stater = Stater::new(&matches)?; let exit_status = stater.exec(); diff --git a/src/uu/stat/stat.md b/src/uu/stat/stat.md new file mode 100644 index 000000000..5c8f86bc6 --- /dev/null +++ b/src/uu/stat/stat.md @@ -0,0 +1,64 @@ +# stat + +## About + +Display file or file system status. + +## Usage +``` +stat [OPTION]... FILE... +``` + +## Long Usage + +The valid format sequences for files (without --file-system): + + %a access rights in octal (note '#' and '0' printf flags) + %A access rights in human readable form + %b number of blocks allocated (see %B) + %B the size in bytes of each block reported by %b + %C SELinux security context string + %d device number in decimal + %D device number in hex + %f raw mode in hex + %F file type + %g group ID of owner + %G group name of owner + %h number of hard links + %i inode number + %m mount point + %n file name + %N quoted file name with dereference if symbolic link + %o optimal I/O transfer size hint + %s total size, in bytes + %t major device type in hex, for character/block device special files + %T minor device type in hex, for character/block device special files + %u user ID of owner + %U user name of owner + %w time of file birth, human-readable; - if unknown + %W time of file birth, seconds since Epoch; 0 if unknown + %x time of last access, human-readable + %X time of last access, seconds since Epoch + %y time of last data modification, human-readable + %Y time of last data modification, seconds since Epoch + %z time of last status change, human-readable + %Z time of last status change, seconds since Epoch + +Valid format sequences for file systems: + + %a free blocks available to non-superuser + %b total data blocks in file system + %c total file nodes in file system + %d free file nodes in file system + %f free blocks in file system + %i file system ID in hex + %l maximum length of filenames + %n file name + %s block size (for faster transfers) + %S fundamental block size (for block counts) + %t file system type in hex + %T file system type in human readable form + +NOTE: your shell may have its own version of stat, which usually supersedes +the version described here. Please refer to your shell's documentation +for details about the options it supports. diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index d63f8bced..8ccd08366 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -19,8 +19,11 @@ use crate::operation::DeleteOperation; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; -static ABOUT: &str = "Translate or delete characters"; +const ABOUT: &str = "Translate or delete characters"; const USAGE: &str = "{} [OPTION]... SET1 [SET2]"; +const LONG_USAGE: &str = "\ + Translate, squeeze, and/or delete characters from standard input, \ + writing to standard output."; mod options { pub const COMPLEMENT: &str = "complement"; @@ -30,19 +33,11 @@ mod options { pub const SETS: &str = "sets"; } -fn get_long_usage() -> String { - "Translate, squeeze, and/or delete characters from standard input, \ - writing to standard output." - .to_string() -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_lossy(); - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let delete_flag = matches.get_flag(options::DELETE); let complement_flag = matches.get_flag(options::COMPLEMENT); diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index 5a5ef0a97..090865313 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -73,8 +73,25 @@ impl TruncateMode { } } -static ABOUT: &str = "Shrink or extend the size of each file to the specified size."; +const ABOUT: &str = "Shrink or extend the size of each file to the specified size."; const USAGE: &str = "{} [OPTION]... [FILE]..."; +const LONG_USAGE: &str = "\ +SIZE is an integer with an optional prefix and optional unit. +The available units (K, M, G, T, P, E, Z, and Y) use the following format: + 'KB' => 1000 (kilobytes) + 'K' => 1024 (kibibytes) + 'MB' => 1000*1000 (megabytes) + 'M' => 1024*1024 (mebibytes) + 'GB' => 1000*1000*1000 (gigabytes) + 'G' => 1024*1024*1024 (gibibytes) +SIZE may also be prefixed by one of the following to adjust the size of each +file based on its current size: + '+' => extend by + '-' => reduce by + '<' => at most + '>' => at least + '/' => round down to multiple of + '%' => round up to multiple of"; pub mod options { pub static IO_BLOCKS: &str = "io-blocks"; @@ -84,32 +101,10 @@ pub mod options { pub static ARG_FILES: &str = "files"; } -fn get_long_usage() -> String { - String::from( - " - SIZE is an integer with an optional prefix and optional unit. - The available units (K, M, G, T, P, E, Z, and Y) use the following format: - 'KB' => 1000 (kilobytes) - 'K' => 1024 (kibibytes) - 'MB' => 1000*1000 (megabytes) - 'M' => 1024*1024 (mebibytes) - 'GB' => 1000*1000*1000 (gigabytes) - 'G' => 1024*1024*1024 (gibibytes) - SIZE may also be prefixed by one of the following to adjust the size of each - file based on its current size: - '+' => extend by - '-' => reduce by - '<' => at most - '>' => at least - '/' => round down to multiple of - '%' => round up to multiple of", - ) -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app() - .after_help(get_long_usage()) + .after_help(LONG_USAGE) .try_get_matches_from(args) .map_err(|e| { e.print().expect("Error writing clap::Error"); diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index 7275e8877..79ed743bb 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -15,8 +15,14 @@ use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::format_usage; -static ABOUT: &str = "Report or omit repeated lines."; +const ABOUT: &str = "Report or omit repeated lines."; const USAGE: &str = "{} [OPTION]... [INPUT [OUTPUT]]..."; +const LONG_USAGE: &str = "\ + Filter adjacent matching lines from INPUT (or standard input),\n\ + writing to OUTPUT (or standard output).\n\n\ + Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\ + You may want to sort the input first, or use 'sort -u' without 'uniq'."; + pub mod options { pub static ALL_REPEATED: &str = "all-repeated"; pub static CHECK_CHARS: &str = "check-chars"; @@ -241,20 +247,9 @@ fn opt_parsed(opt_name: &str, matches: &ArgMatches) -> UResult String { - String::from( - "Filter adjacent matching lines from INPUT (or standard input),\n\ - writing to OUTPUT (or standard output). - Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\ - You may want to sort the input first, or use 'sort -u' without 'uniq'.\n", - ) -} - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app() - .after_help(get_long_usage()) - .try_get_matches_from(args)?; + let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; let files: Vec = matches .get_many::(ARG_FILES)