{ 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) }); }