about summary refs log tree commit diff
path: root/pkgs/tools/misc/bat-extras/default.nix
blob: 0f98b819b0f7b15a5f9eb254bdd4ce5aa53cb767 (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
{ stdenv, callPackage, fetchFromGitHub, bash, makeWrapper, ncurses, bat
# batgrep and batwatch
, less
# 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
 }:

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 = "20200408";

    src = fetchFromGitHub {
      owner  = "eth-p";
      repo   = pname;
      rev    = "v${version}";
      sha256 = "184d5rwasfpgbj2k98alg3wy8jmzna2dgfik98w2a297ky67s51v";
      fetchSubmodules = true;
    };

    nativeBuildInputs = [ bash makeWrapper ];

    dontConfigure = true;

    postPatch = ''
      substituteInPlace lib/constants.sh \
        --replace 'EXECUTABLE_BAT="bat"' 'EXECUTABLE_BAT="${bat}/bin/bat"'

      patchShebangs --build test.sh test/shimexec .test-framework/bin/best.sh
      wrapProgram .test-framework/bin/best.sh \
        --prefix PATH : "${ncurses}/bin"
    '';

    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;
    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 <<<"$(bash ./test.sh --compiled --list --porcelain)"
      (( ''${#test_suites[@]} != 0 )) || {
        echo "Couldn't find any library test suites"
        exit 1
      }
      bash ./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 stdenv.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 lilyball ];
      platforms   = platforms.all;
    };
  };
  script =
    name: # the name of the script
    dependencies: # the tools we need to prefix onto PATH
    stdenv.mkDerivation {
      pname = "${core.pname}-${name}";
      inherit (core) version;

      src = core;

      nativeBuildInputs = [ bash 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;
      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}
      '' + stdenv.lib.optionalString (dependencies != []) ''
        wrapProgram $out/bin/${name} \
          --prefix PATH : ${stdenv.lib.makeBinPath dependencies}
      '' + ''
        runHook postInstall
      '';

      # We already patched
      dontPatchShebangs = true;

      inherit (core) meta;
    };
  optionalDep = cond: dep:
    assert cond -> dep != null;
    stdenv.lib.optional cond dep;
in
{
  batgrep = script "batgrep" [ less ripgrep ];
  batman = (script "batman" []).overrideAttrs (drv: {
    doCheck = stdenv.isDarwin; # test fails on Linux due to SIGPIPE (eth-p/bat-extras#19)
  });
  batwatch = script "batwatch" ([ less ] ++ optionalDep withEntr entr);
  prettybat = (script "prettybat" ([]
    ++ optionalDep withShFmt shfmt
    ++ optionalDep withPrettier nodePackages.prettier
    ++ optionalDep withClangTools clang-tools
    ++ optionalDep withRustFmt rustfmt)
  ).overrideAttrs (drv: {
    doCheck = stdenv.isDarwin; # test fails on Linux due to SIGPIPE (eth-p/bat-extras#19)
  });
}