<commit_before># Create a bash script that is checked with shellcheck. You can either use it
# directly, or use the .bin attribute to get the script in a bin/ directory,
# to be used in a path for example.
{ argbash
, bash_5
, git
, lib
, runCommand
, shellcheck
, stdenv
, writeTextFile
}:
{ name
, docs
, args ? [ ]
, addCommandCompletion ? false
, inRootDir ? false
, redirectTixFiles ? true
, withEnv ? null
, withTmpDir ? false
}: text:
let
  argsTemplate =
    let
      # square brackets are a pain to escape - if even possible. just don't use them...
      escapedDocs = builtins.replaceStrings [ "\n" ] [ " \\n" ] docs;
    in
    writeTextFile {
      inherit name;
      destination = "/${name}.m4"; # destination is needed to have the proper basename for completion

      text =
        ''
          # BASH_ARGV0 sets $0 - which is used in parser.sh for usage information
          # stripping the /nix/store/... path for nicer display
          BASH_ARGV0="$(basename "$0")"

          # ARG_HELP([${name}], [${escapedDocs}])
          ${lib.strings.concatMapStrings (arg: "# " + arg) args}
          # ARG_DEFAULTS_POS()
          # ARGBASH_GO

        '';
    };

  argsParser =
    runCommand "${name}-parser" { }
      "${argbash}/bin/argbash -o $out ${argsTemplate}/${name}.m4";

  bashCompletion =
    runCommand "${name}-completion" { } (
      ''
        ${argbash}/bin/argbash --type completion --strip all ${argsTemplate}/${name}.m4 > $out
      ''

      + lib.optionalString addCommandCompletion ''
        sed 's/COMPREPLY.*compgen -o bashdefault .*$/_command/' -i $out
      ''
    );

  bin =
    writeTextFile {
      inherit name;
      executable = true;
      destination = "/bin/${name}";

      text =
        ''
          #!${bash_5}/bin/bash
          set -euo pipefail

          source ${argsParser}
        ''

        + lib.optionalString redirectTixFiles ''<commit_msg>nix(feat): Force optional arguments to go before positional arguments in argbash scripts<commit_after># Create a bash script that is checked with shellcheck. You can either use it
# directly, or use the .bin attribute to get the script in a bin/ directory,
# to be used in a path for example.
{ argbash
, bash_5
, git
, lib
, runCommand
, shellcheck
, stdenv
, writeTextFile
}:
{ name
, docs
, args ? [ ]
, addCommandCompletion ? false
, inRootDir ? false
, redirectTixFiles ? true
, withEnv ? null
, withTmpDir ? false
}: text:
let
  argsTemplate =
    let
      # square brackets are a pain to escape - if even possible. just don't use them...
      escapedDocs = builtins.replaceStrings [ "\n" ] [ " \\n" ] docs;
    in
    writeTextFile {
      inherit name;
      destination = "/${name}.m4"; # destination is needed to have the proper basename for completion

      text =
        ''
          # BASH_ARGV0 sets $0 - which is used in parser.sh for usage information
          # stripping the /nix/store/... path for nicer display
          BASH_ARGV0="$(basename "$0")"

          # ARG_HELP([${name}], [${escapedDocs}])
          ${lib.strings.concatMapStrings (arg: "# " + arg) args}
          # ARG_POSITIONAL_DOUBLEDASH()
          # ARG_DEFAULTS_POS()
          # ARGBASH_GO

        '';
    };

  argsParser =
    runCommand "${name}-parser" { }
      ''
        ${argbash}/bin/argbash ${argsTemplate}/${name}.m4 > $out

        # This forces optional arguments to go *before* positional arguments,
        # which allows leftovers to pass optional arguments to sub-commands.
        # Example: This way `postgrest-watch -h` will return the help output for watch, while
        # `postgrest-watch postgrest-test-spec -h` will return the help output for test-spec.
        # Taken from: https://github.com/matejak/argbash/issues/114#issuecomment-557108274
        sed '/_positionals_count + 1/a\\t\t\t\tset -- "''${@:1:1}" "--" "''${@:2}"' -i $out
      '';

  bashCompletion =
    runCommand "${name}-completion" { } (
      ''
        ${argbash}/bin/argbash --type completion --strip all ${argsTemplate}/${name}.m4 > $out
      ''

      + lib.optionalString addCommandCompletion ''
        sed 's/COMPREPLY.*compgen -o bashdefault .*$/_command/' -i $out
      ''
    );

  bin =
    writeTextFile {
      inherit name;
      executable = true;
      destination = "/bin/${name}";

      text =
        ''
          #!${bash_5}/bin/bash
          set -euo pipefail

          source ${argsParser}
        ''

        + lib.optionalString redirectTixFiles ''
{'fraction_non_alphanumeric': 0.12854273599642937, 'fraction_numerical': 0.007587592055344789, 'mean_word_length': 2.3126385809312637, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7389207', 'n_tokens_mistral': 1427, 'n_tokens_neox': 1359, 'n_words': 400}