about summary refs log tree commit diff
path: root/pkgs/tools/misc/bat-extras/default.nix
blob: 1c3a805367f2968c114563817bd241ad7d3e3054 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{ lib, stdenv, fetchFromGitHub, makeWrapper, bat
# batdiff, batgrep, and batwatch
, coreutils
, getconf
, less
# tests
, bash
, zsh
, fish
# batgrep
, ripgrep
# prettybat
, withShFmt ? shfmt != null, shfmt ? null
, withPrettier ? nodePackages?prettier, nodePackages ? null
, withClangTools ? clang-tools != null, clang-tools ? null
, withRustFmt ? rustfmt != null, rustfmt ? null
# batwatch
, withEntr ? entr != null, entr ? null
# batdiff
, gitMinimal
, withDelta ? delta != null, delta ? null
# batman
, util-linux
}:

let
  # Core derivation that all the others are based on.
  # This includes the complete source so the per-script derivations can run the tests.
  core = stdenv.mkDerivation rec {
    pname   = "bat-extras";
    version = "2024.07.10";

    src = fetchFromGitHub {
      owner  = "eth-p";
      repo   = "bat-extras";
      rev    = "v${version}";
      hash   = "sha256-6IRAKSy5f/WcQZBcJKVSweTjHLznzdxhsyx074bXnUQ=";
      fetchSubmodules = true;
    };

    # bat needs to be in the PATH during building so EXECUTABLE_BAT picks it up
    nativeBuildInputs = [ bat ];

    dontConfigure = true;

    postPatch = ''
      patchShebangs --build test.sh test/shimexec .test-framework/bin/best.sh
    '';

    buildPhase = ''
      runHook preBuild
      bash ./build.sh --minify=none --no-verify
      runHook postBuild
    '';

    # Run the library tests as they don't have external dependencies
    doCheck = true;
    nativeCheckInputs = [ bash fish zsh ] ++ (lib.optionals stdenv.isDarwin [ getconf ]);
    checkPhase = ''
      runHook preCheck
      # test list repeats suites. Unique them
      declare -A test_suites
      while read -r action arg _; do
        [[ "$action" == "test_suite" && "$arg" == lib_* ]] &&
        test_suites+=(["$arg"]=1)
      done <<<"$(./test.sh --compiled --list --porcelain)"
      (( ''${#test_suites[@]} != 0 )) || {
        echo "Couldn't find any library test suites"
        exit 1
      }
      ./test.sh --compiled $(printf -- "--suite %q\n" "''${!test_suites[@]}")
      runHook postCheck
    '';

    installPhase = ''
      runHook preInstall
      cp -a . $out
      runHook postInstall
    '';

    # A few random files have shebangs. Don't patch them, they don't make it into the final output.
    # The per-script derivations will go ahead and patch the files they actually install.
    dontPatchShebangs = true;

    meta = with lib; {
      description = "Bash scripts that integrate bat with various command line tools";
      homepage    = "https://github.com/eth-p/bat-extras";
      license     = with licenses; [ mit ];
      maintainers = with maintainers; [ bbigras ];
      platforms   = platforms.all;
    };
  };
  script =
    name: # the name of the script
    dependencies: # the tools we need to prefix onto PATH
    stdenv.mkDerivation {
      pname = name;
      inherit (core) version;

      src = core;

      nativeBuildInputs = [ makeWrapper ];
      # Make the dependencies available to the tests.
      buildInputs = dependencies;

      # Patch shebangs now because our tests rely on them
      postPatch = ''
        patchShebangs --host bin/${name}
      '';

      dontConfigure = true;
      dontBuild = true; # we've already built

      doCheck = true;
      nativeCheckInputs = [ bat bash fish zsh ] ++ (lib.optionals stdenv.isDarwin [ getconf ]);
      checkPhase = ''
        runHook preCheck
        bash ./test.sh --compiled --suite ${name}
        runHook postCheck
      '';

      installPhase = ''
        runHook preInstall
        mkdir -p $out/bin
        cp -p bin/${name} $out/bin/${name}
      '' + lib.optionalString (dependencies != []) ''
        wrapProgram $out/bin/${name} \
          --prefix PATH : ${lib.makeBinPath dependencies}
      '' + ''
        runHook postInstall
      '';

      # We already patched
      dontPatchShebangs = true;

      meta = core.meta // {
        mainProgram = name;
      };
    };
  optionalDep = cond: dep:
    assert cond -> dep != null;
    lib.optional cond dep;
in
{
  batdiff = script "batdiff" ([ less coreutils gitMinimal ] ++ optionalDep withDelta delta);
  batgrep = script "batgrep" [ less coreutils ripgrep ];
  batman = script "batman" (lib.optionals stdenv.isLinux [ util-linux ]);
  batpipe = script "batpipe" [ less ];
  batwatch = script "batwatch" ([ less coreutils ] ++ optionalDep withEntr entr);
  prettybat = script "prettybat" ([]
    ++ optionalDep withShFmt shfmt
    ++ optionalDep withPrettier nodePackages.prettier
    ++ optionalDep withClangTools clang-tools
    ++ optionalDep withRustFmt rustfmt);
}