"Fossies" - the Fresh Open Source Software Archive

Member "fd-8.1.1/src/app.rs" (25 May 2020, 24391 Bytes) of package /linux/privat/fd-8.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Rust source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "app.rs": 8.0.0_vs_8.1.0.

    1 use clap::{crate_version, App, AppSettings, Arg};
    2 
    3 pub fn build_app() -> App<'static, 'static> {
    4     let mut app = App::new("fd")
    5         .version(crate_version!())
    6         .usage("fd [FLAGS/OPTIONS] [<pattern>] [<path>...]")
    7         .setting(AppSettings::ColoredHelp)
    8         .setting(AppSettings::DeriveDisplayOrder)
    9         .after_help(
   10             "Note: `fd -h` prints a short and concise overview while `fd --help` gives all \
   11                  details.",
   12         )
   13         .arg(
   14             Arg::with_name("hidden")
   15                 .long("hidden")
   16                 .short("H")
   17                 .overrides_with("hidden")
   18                 .help("Search hidden files and directories")
   19                 .long_help(
   20                     "Include hidden directories and files in the search results (default: \
   21                          hidden files and directories are skipped). Files and directories are \
   22                          considered to be hidden if their name starts with a `.` sign (dot).",
   23                 ),
   24         )
   25         .arg(
   26             Arg::with_name("no-ignore")
   27                 .long("no-ignore")
   28                 .short("I")
   29                 .overrides_with("no-ignore")
   30                 .help("Do not respect .(git|fd)ignore files")
   31                 .long_help(
   32                     "Show search results from files and directories that would otherwise be \
   33                          ignored by '.gitignore', '.ignore', '.fdignore', or the global ignore file.",
   34                 ),
   35         )
   36         .arg(
   37             Arg::with_name("no-ignore-vcs")
   38                 .long("no-ignore-vcs")
   39                 .overrides_with("no-ignore-vcs")
   40                 .hidden_short_help(true)
   41                 .long_help(
   42                     "Show search results from files and directories that would otherwise be \
   43                          ignored by '.gitignore' files.",
   44                 ),
   45         )
   46         .arg(
   47             Arg::with_name("no-global-ignore-file")
   48                 .long("no-global-ignore-file")
   49                 .hidden(true)
   50                 .long_help("Do not respect the global ignore file."),
   51         )
   52         .arg(
   53             Arg::with_name("rg-alias-hidden-ignore")
   54                 .short("u")
   55                 .long("unrestricted")
   56                 .multiple(true)
   57                 .hidden_short_help(true)
   58                 .long_help(
   59                     "Alias for '--no-ignore'. Can be repeated. '-uu' is an alias for \
   60                          '--no-ignore --hidden'.",
   61                 ),
   62         )
   63         .arg(
   64             Arg::with_name("case-sensitive")
   65                 .long("case-sensitive")
   66                 .short("s")
   67                 .overrides_with_all(&["ignore-case", "case-sensitive"])
   68                 .help("Case-sensitive search (default: smart case)")
   69                 .long_help(
   70                     "Perform a case-sensitive search. By default, fd uses case-insensitive \
   71                          searches, unless the pattern contains an uppercase character (smart \
   72                          case).",
   73                 ),
   74         )
   75         .arg(
   76             Arg::with_name("ignore-case")
   77                 .long("ignore-case")
   78                 .short("i")
   79                 .overrides_with_all(&["case-sensitive", "ignore-case"])
   80                 .help("Case-insensitive search (default: smart case)")
   81                 .long_help(
   82                     "Perform a case-insensitive search. By default, fd uses case-insensitive \
   83                          searches, unless the pattern contains an uppercase character (smart \
   84                          case).",
   85                 ),
   86         )
   87         .arg(
   88             Arg::with_name("glob")
   89                 .long("glob")
   90                 .short("g")
   91                 .conflicts_with("fixed-strings")
   92                 .overrides_with("glob")
   93                 .help("Glob-based search (default: regular expression)")
   94                 .long_help("Perform a glob-based search instead of a regular expression search."),
   95         )
   96         .arg(
   97             Arg::with_name("regex")
   98                 .long("regex")
   99                 .overrides_with_all(&["glob", "regex"])
  100                 .hidden_short_help(true)
  101                 .long_help(
  102                     "Perform a regular-expression based search (default). This can be used to \
  103                          override --glob.",
  104                 ),
  105         )
  106         .arg(
  107             Arg::with_name("fixed-strings")
  108                 .long("fixed-strings")
  109                 .short("F")
  110                 .alias("literal")
  111                 .overrides_with("fixed-strings")
  112                 .hidden_short_help(true)
  113                 .long_help(
  114                     "Treat the pattern as a literal string instead of a regular expression.",
  115                 ),
  116         )
  117         .arg(
  118             Arg::with_name("absolute-path")
  119                 .long("absolute-path")
  120                 .short("a")
  121                 .overrides_with("absolute-path")
  122                 .help("Show absolute instead of relative paths")
  123                 .long_help(
  124                     "Shows the full path starting from the root as opposed to relative paths.",
  125                 ),
  126         )
  127         .arg(
  128             Arg::with_name("list-details")
  129                 .long("list-details")
  130                 .short("l")
  131                 .conflicts_with("absolute-path")
  132                 .help("Use a long listing format with file metadata")
  133                 .long_help(
  134                     "Use a detailed listing format like 'ls -l'. This is basically an alias \
  135                          for '--exec-batch ls -l' with some additional 'ls' options. This can be \
  136                          used to see more metadata, to show symlink targets and to achieve a \
  137                          deterministic sort order.",
  138                 ),
  139         )
  140         .arg(
  141             Arg::with_name("follow")
  142                 .long("follow")
  143                 .short("L")
  144                 .alias("dereference")
  145                 .overrides_with("follow")
  146                 .help("Follow symbolic links")
  147                 .long_help(
  148                     "By default, fd does not descend into symlinked directories. Using this \
  149                          flag, symbolic links are also traversed.",
  150                 ),
  151         )
  152         .arg(
  153             Arg::with_name("full-path")
  154                 .long("full-path")
  155                 .short("p")
  156                 .overrides_with("full-path")
  157                 .help("Search full path (default: file-/dirname only)")
  158                 .long_help(
  159                     "By default, the search pattern is only matched against the filename (or \
  160                          directory name). Using this flag, the pattern is matched against the \
  161                          full path.",
  162                 ),
  163         )
  164         .arg(
  165             Arg::with_name("null_separator")
  166                 .long("print0")
  167                 .short("0")
  168                 .overrides_with("print0")
  169                 .conflicts_with("list-details")
  170                 .help("Separate results by the null character")
  171                 .long_help(
  172                     "Separate search results by the null character (instead of newlines). \
  173                          Useful for piping results to 'xargs'.",
  174                 ),
  175         )
  176         .arg(
  177             Arg::with_name("max-depth")
  178                 .long("max-depth")
  179                 .short("d")
  180                 .takes_value(true)
  181                 .value_name("depth")
  182                 .help("Set maximum search depth (default: none)")
  183                 .long_help(
  184                     "Limit the directory traversal to a given depth. By default, there is no \
  185                          limit on the search depth.",
  186                 ),
  187         )
  188         // support --maxdepth as well, for compatibility with rg
  189         .arg(
  190             Arg::with_name("rg-depth")
  191                 .long("maxdepth")
  192                 .hidden(true)
  193                 .takes_value(true)
  194         )
  195         .arg(
  196             Arg::with_name("min-depth")
  197                 .long("min-depth")
  198                 .takes_value(true)
  199                 .value_name("depth")
  200                 .hidden_short_help(true)
  201                 .long_help(
  202                     "Only show search results starting at the given depth. \
  203                      See also: '--max-depth' and '--exact-depth'",
  204                 ),
  205         )
  206         .arg(
  207             Arg::with_name("exact-depth")
  208                 .long("exact-depth")
  209                 .takes_value(true)
  210                 .value_name("depth")
  211                 .hidden_short_help(true)
  212                 .conflicts_with_all(&["max-depth", "min-depth"])
  213                 .long_help(
  214                     "Only show search results at the exact given depth. This is an alias for \
  215                      '--min-depth <depth> --max-depth <depth>'.",
  216                 ),
  217         )
  218         .arg(
  219             Arg::with_name("file-type")
  220                 .long("type")
  221                 .short("t")
  222                 .multiple(true)
  223                 .number_of_values(1)
  224                 .takes_value(true)
  225                 .value_name("filetype")
  226                 .possible_values(&[
  227                     "f",
  228                     "file",
  229                     "d",
  230                     "directory",
  231                     "l",
  232                     "symlink",
  233                     "x",
  234                     "executable",
  235                     "e",
  236                     "empty",
  237                     "s",
  238                     "socket",
  239                     "p",
  240                     "pipe",
  241                 ])
  242                 .hide_possible_values(true)
  243                 .help(
  244                     "Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \
  245                          empty (e), socket (s), pipe (p)",
  246                 )
  247                 .long_help(
  248                     "Filter the search by type (multiple allowable filetypes can be specified):\n  \
  249                        'f' or 'file':         regular files\n  \
  250                        'd' or 'directory':    directories\n  \
  251                        'l' or 'symlink':      symbolic links\n  \
  252                        'x' or 'executable':   executables\n  \
  253                        'e' or 'empty':        empty files or directories\n  \
  254                        's' or 'socket':       socket\n  \
  255                        'p' or 'pipe':         named pipe (FIFO)",
  256                 ),
  257         )
  258         .arg(
  259             Arg::with_name("extension")
  260                 .long("extension")
  261                 .short("e")
  262                 .multiple(true)
  263                 .number_of_values(1)
  264                 .takes_value(true)
  265                 .value_name("ext")
  266                 .help("Filter by file extension")
  267                 .long_help(
  268                     "(Additionally) filter search results by their file extension. Multiple \
  269                          allowable file extensions can be specified.",
  270                 ),
  271         )
  272         .arg(
  273             Arg::with_name("exec")
  274                 .long("exec")
  275                 .short("x")
  276                 .min_values(1)
  277                 .allow_hyphen_values(true)
  278                 .value_terminator(";")
  279                 .value_name("cmd")
  280                 .conflicts_with("list-details")
  281                 .help("Execute a command for each search result")
  282                 .long_help(
  283                     "Execute a command for each search result.\n\
  284                      All arguments following --exec are taken to be arguments to the command until the \
  285                      argument ';' is encountered.\n\
  286                      Each occurrence of the following placeholders is substituted by a path derived from the \
  287                      current search result before the command is executed:\n  \
  288                        '{}':   path\n  \
  289                        '{/}':  basename\n  \
  290                        '{//}': parent directory\n  \
  291                        '{.}':  path without file extension\n  \
  292                        '{/.}': basename without file extension",
  293                 ),
  294         )
  295         .arg(
  296             Arg::with_name("exec-batch")
  297                 .long("exec-batch")
  298                 .short("X")
  299                 .min_values(1)
  300                 .allow_hyphen_values(true)
  301                 .value_terminator(";")
  302                 .value_name("cmd")
  303                 .conflicts_with_all(&["exec", "list-details"])
  304                 .help("Execute a command with all search results at once")
  305                 .long_help(
  306                     "Execute a command with all search results at once.\n\
  307                      All arguments following --exec-batch are taken to be arguments to the command until the \
  308                      argument ';' is encountered.\n\
  309                      A single occurrence of the following placeholders is authorized and substituted by the paths derived from the \
  310                      search results before the command is executed:\n  \
  311                        '{}':   path\n  \
  312                        '{/}':  basename\n  \
  313                        '{//}': parent directory\n  \
  314                        '{.}':  path without file extension\n  \
  315                        '{/.}': basename without file extension",
  316                 ),
  317         )
  318         .arg(
  319             Arg::with_name("exclude")
  320                 .long("exclude")
  321                 .short("E")
  322                 .takes_value(true)
  323                 .value_name("pattern")
  324                 .number_of_values(1)
  325                 .multiple(true)
  326                 .help("Exclude entries that match the given glob pattern")
  327                 .long_help(
  328                     "Exclude files/directories that match the given glob pattern. This \
  329                          overrides any other ignore logic. Multiple exclude patterns can be \
  330                          specified.",
  331                 ),
  332         )
  333         .arg(
  334             Arg::with_name("ignore-file")
  335                 .long("ignore-file")
  336                 .takes_value(true)
  337                 .value_name("path")
  338                 .number_of_values(1)
  339                 .multiple(true)
  340                 .hidden_short_help(true)
  341                 .long_help(
  342                     "Add a custom ignore-file in '.gitignore' format. These files have a low \
  343                          precedence.",
  344                 ),
  345         )
  346         .arg(
  347             Arg::with_name("color")
  348                 .long("color")
  349                 .short("c")
  350                 .takes_value(true)
  351                 .value_name("when")
  352                 .possible_values(&["never", "auto", "always"])
  353                 .hide_possible_values(true)
  354                 .help("When to use colors: never, *auto*, always")
  355                 .long_help(
  356                     "Declare when to use color for the pattern match output:\n  \
  357                        'auto':      show colors if the output goes to an interactive console (default)\n  \
  358                        'never':     do not use colorized output\n  \
  359                        'always':    always use colorized output",
  360                 ),
  361         )
  362         .arg(
  363             Arg::with_name("threads")
  364                 .long("threads")
  365                 .short("j")
  366                 .takes_value(true)
  367                 .value_name("num")
  368                 .hidden_short_help(true)
  369                 .long_help(
  370                     "Set number of threads to use for searching & executing (default: number \
  371                          of available CPU cores)",
  372                 ),
  373         )
  374         .arg(
  375             Arg::with_name("size")
  376                 .long("size")
  377                 .short("S")
  378                 .takes_value(true)
  379                 .number_of_values(1)
  380                 .allow_hyphen_values(true)
  381                 .multiple(true)
  382                 .help("Limit results based on the size of files.")
  383                 .long_help(
  384                     "Limit results based on the size of files using the format <+-><NUM><UNIT>.\n   \
  385                         '+': file size must be greater than or equal to this\n   \
  386                         '-': file size must be less than or equal to this\n   \
  387                         'NUM':  The numeric size (e.g. 500)\n   \
  388                         'UNIT': The units for NUM. They are not case-sensitive.\n\
  389                      Allowed unit values:\n    \
  390                          'b':  bytes\n    \
  391                          'k':  kilobytes (base ten, 10^3 = 1000 bytes)\n    \
  392                          'm':  megabytes\n    \
  393                          'g':  gigabytes\n    \
  394                          't':  terabytes\n    \
  395                          'ki': kibibytes (base two, 2^10 = 1024 bytes)\n    \
  396                          'mi': mebibytes\n    \
  397                          'gi': gibibytes\n    \
  398                          'ti': tebibytes",
  399                 ),
  400         )
  401         .arg(
  402             Arg::with_name("max-buffer-time")
  403                 .long("max-buffer-time")
  404                 .takes_value(true)
  405                 .hidden(true)
  406                 .long_help(
  407                     "Amount of time in milliseconds to buffer, before streaming the search \
  408                          results to the console.",
  409                 ),
  410         )
  411         .arg(
  412             Arg::with_name("changed-within")
  413                 .long("changed-within")
  414                 .alias("change-newer-than")
  415                 .takes_value(true)
  416                 .value_name("date|dur")
  417                 .number_of_values(1)
  418                 .help("Filter by file modification time (newer than)")
  419                 .long_help(
  420                     "Filter results based on the file modification time. The argument can be provided \
  421                      as a specific point in time (YYYY-MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). \
  422                      '--change-newer-than' can be used as an alias.\n\
  423                      Examples:\n    \
  424                          --changed-within 2weeks\n    \
  425                          --change-newer-than '2018-10-27 10:00:00'",
  426                 ),
  427         )
  428         .arg(
  429             Arg::with_name("changed-before")
  430                 .long("changed-before")
  431                 .alias("change-older-than")
  432                 .takes_value(true)
  433                 .value_name("date|dur")
  434                 .number_of_values(1)
  435                 .help("Filter by file modification time (older than)")
  436                 .long_help(
  437                     "Filter results based on the file modification time. The argument can be provided \
  438                      as a specific point in time (YYYY-MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). \
  439                      '--change-older-than' can be used as an alias.\n\
  440                      Examples:\n    \
  441                          --changed-before '2018-10-27 10:00:00'\n    \
  442                          --change-older-than 2weeks",
  443                 ),
  444         )
  445         .arg(
  446             Arg::with_name("max-results")
  447                 .long("max-results")
  448                 .takes_value(true)
  449                 .value_name("count")
  450                 // We currently do not support --max-results in combination with
  451                 // program execution because the results that come up in a --max-results
  452                 // search are non-deterministic. Users might think that they can run the
  453                 // same search with `--exec rm` attached and get a reliable removal of
  454                 // the files they saw in the previous search.
  455                 .conflicts_with_all(&["exec", "exec-batch", "list-details"])
  456                 .hidden_short_help(true)
  457                 .long_help("Limit the number of search results to 'count' and quit immediately."),
  458         )
  459         .arg(
  460             Arg::with_name("max-one-result")
  461                 .short("1")
  462                 .hidden_short_help(true)
  463                 .overrides_with("max-results")
  464                 .conflicts_with_all(&["exec", "exec-batch", "list-details"])
  465                 .long_help("Limit the search to a single result and quit immediately. \
  466                                 This is an alias for '--max-results=1'.")
  467         )
  468         .arg(
  469             Arg::with_name("show-errors")
  470                 .long("show-errors")
  471                 .hidden_short_help(true)
  472                 .overrides_with("show-errors")
  473                 .long_help(
  474                     "Enable the display of filesystem errors for situations such as \
  475                          insufficient permissions or dead symlinks.",
  476                 ),
  477         )
  478         .arg(
  479             Arg::with_name("base-directory")
  480                 .long("base-directory")
  481                 .takes_value(true)
  482                 .value_name("path")
  483                 .number_of_values(1)
  484                 .hidden_short_help(true)
  485                 .long_help(
  486                     "Change the current working directory of fd to the provided path. The \
  487                          means that search results will be shown with respect to the given base \
  488                          path. Note that relative paths which are passed to fd via the positional \
  489                          <path> argument or the '--search-path' option will also be resolved \
  490                          relative to this directory.",
  491                 ),
  492         )
  493         .arg(
  494             Arg::with_name("pattern").help(
  495                 "the search pattern - a regular expression unless '--glob' is used (optional)",
  496             ),
  497         )
  498         .arg(
  499             Arg::with_name("path-separator")
  500                 .takes_value(true)
  501                 .value_name("separator")
  502                 .long("path-separator")
  503                 .hidden_short_help(true)
  504                 .long_help(
  505                     "Set the path separator to use when printing file paths. The default is \
  506                          the OS-specific separator ('/' on Unix, '\\' on Windows).",
  507                 ),
  508         )
  509         .arg(
  510             Arg::with_name("path")
  511                 .multiple(true)
  512                 .help("the root directory for the filesystem search (optional)")
  513                 .long_help(
  514                     "The directory where the filesystem search is rooted (optional). If \
  515                          omitted, search the current working directory.",
  516                 ),
  517         )
  518         .arg(
  519             Arg::with_name("search-path")
  520                 .long("search-path")
  521                 .takes_value(true)
  522                 .conflicts_with("path")
  523                 .multiple(true)
  524                 .hidden_short_help(true)
  525                 .number_of_values(1)
  526                 .long_help(
  527                     "Provide paths to search as an alternative to the positional <path> \
  528                          argument. Changes the usage to `fd [FLAGS/OPTIONS] --search-path <path> \
  529                          --search-path <path2> [<pattern>]`",
  530                 ),
  531         );
  532 
  533     if cfg!(unix) {
  534         app = app.arg(
  535             Arg::with_name("owner")
  536                 .long("owner")
  537                 .short("o")
  538                 .takes_value(true)
  539                 .value_name("user:group")
  540                 .help("Filter by owning user and/or group")
  541                 .long_help(
  542                     "Filter files by their user and/or group. \
  543                      Format: [(user|uid)][:(group|gid)]. Either side is optional. \
  544                      Precede either side with a '!' to exclude files instead.\n\
  545                      Examples:\n    \
  546                          --owner john\n    \
  547                          --owner :students\n    \
  548                          --owner '!john:students'",
  549                 ),
  550         );
  551     }
  552 
  553     // Make `--one-file-system` available only on Unix and Windows platforms, as per the
  554     // restrictions on the corresponding option in the `ignore` crate.
  555     // Provide aliases `mount` and `xdev` for people coming from `find`.
  556     if cfg!(any(unix, windows)) {
  557         app = app.arg(
  558             Arg::with_name("one-file-system")
  559                 .long("one-file-system")
  560                 .aliases(&["mount", "xdev"])
  561                 .hidden_short_help(true)
  562                 .long_help(
  563                     "By default, fd will traverse the file system tree as far as other options \
  564                      dictate. With this flag, fd ensures that it does not descend into a \
  565                      different file system than the one it started in. Comparable to the -mount \
  566                      or -xdev filters of find(1).",
  567                 ),
  568         );
  569     }
  570 
  571     app
  572 }