diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b4c50..bd5d383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ This format is based on [Keep A Changelog](https://keepachangelog.com/en/1.0.0). +## 2.5.0 - 2023-02-22 + +- Exposable hoogle docker image. + ## 2.4.0 - 2023-02-17 - Default `exposeConfig` to `false` in offchain module diff --git a/data/hoogle-exe.gz b/data/hoogle-exe.gz new file mode 100755 index 0000000..ab1d1cf Binary files /dev/null and b/data/hoogle-exe.gz differ diff --git a/nix/hoogle.nix b/nix/hoogle.nix new file mode 100644 index 0000000..6c4d306 --- /dev/null +++ b/nix/hoogle.nix @@ -0,0 +1,84 @@ +# +# Build a hoogle docker image from a haskell.nix project +# +{ pkgs +, lib +, project +, hoogle + # inline-r is known to fail +, banList ? [ "inline-r" ] +, hoogleDirectory +, ... +}: +let + # A static exe with hoogle in it, it is static in order to save on space in the + # docker image. + # + # TODO(Emily, 22 Feb 2023): Can we build this using Nix? + # It's actually quite hard to get ahold of this static build. This works for now + # but is quite unmaintainable. Using some IFD -- provided things work -- should be + # a valid alternative. + hoogle-static = + pkgs.runCommand + "hoogle-static" + { } + '' + mkdir -p $out/bin + cp ${../data/hoogle-exe.gz} $out/bin/hoogle.gz + ${pkgs.gzip}/bin/gzip -d $out/bin/hoogle.gz + ''; + hoogle-database = + pkgs.runCommand "hoogle-generate" + { + buildInputs = (project.flake { }).devShell.nativeBuildInputs; + } + '' + mkdir -p $out + hoogle generate --local --database=$out/local.hoo + ''; + fromPackage = b: + if !(builtins.isNull b) && b.components ? library && b.components.library ? doc + then b.components.library.doc + else null; + + # We filter out any package that doesn't have documentation, collecting them all into a list. + docsMap = + builtins.filter (p: !(builtins.isNull p)) + (builtins.attrValues + (builtins.mapAttrs (n: p: if !(builtins.elem n banList) then fromPackage p else null) project.hsPkgs)); + + # Alpine is simple and lean! + baseImage = pkgs.dockerTools.pullImage { + imageName = "alpine"; + imageDigest = "sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870"; + sha256 = "sha256-uaJxeiRm94tWDBTe51/KwUBKR2vj9i4i3rhotsYPxtM="; + finalImageTag = "3.16.2"; + finalImageName = "alpine"; + }; + + inherit (pkgs.lib) optionalString; +in +pkgs.dockerTools.buildLayeredImage { + name = "liqwid-nix-hoogle"; + tag = "latest"; + fromImage = baseImage; + contents = [ + docsMap + hoogle-static + ]; + config = { + Cmd = [ + "${pkgs.bash}/bin/bash" + "-c" + '' + mkdir -p ./hoogle + cp -r ${hoogle}/* ./hoogle + ${optionalString (hoogleDirectory != null) "cp -r ${hoogleDirectory}/* ./hoogle"} + hoogle server --port 8081 --home https://hoogle.nix.dance --local --host='*' --database ${hoogle-database}/local.hoo --datadir hoogle + '' + ]; + ExposedPorts = { + "8081/tcp" = { }; + }; + }; +} diff --git a/nix/onchain.nix b/nix/onchain.nix index 5fe5a71..28f9530 100644 --- a/nix/onchain.nix +++ b/nix/onchain.nix @@ -108,6 +108,30 @@ in }; }; + hoogleImage = types.submodule { + options = { + enable = lib.mkOption { + type = types.bool; + description = '' + Whether or not to expose a docker image bundling the hoogle server with the packages available. + + Added in: 2.5.0. + ''; + default = false; + }; + + hoogleDirectory = lib.mkOption { + type = types.nullOr types.path; + description = '' + Path to copy hoogle data dir from. + + Added in: 2.5.0. + ''; + default = null; + }; + }; + }; + project = types.submodule { options = { src = lib.mkOption { @@ -181,6 +205,16 @@ in type = shell; }; + hoogleImage = lib.mkOption { + description = '' + Options for the hoogle image. + + Added in: 2.5.0. + ''; + type = hoogleImage; + }; + + enableHaskellFormatCheck = lib.mkOption { type = types.bool; default = true; @@ -490,7 +524,21 @@ in ''; }; - packages = flake.packages; + hoogleImage = lib.ifEnable projectConfig.hoogleImage.enable + { + hoogleImage = import ./hoogle.nix + { + inherit pkgs lib project; + inherit (projectConfig.hoogleImage) hoogleDirectory; + hoogle = assert (lib.assertMsg (self.inputs ? hoogle) '' + [liqwid-nix]: liqwid-nix onchain module is using hoogle. Please provide a 'hoogle' input. + + This input should be taken from https://github.com/ndmitchell/hoogle. + ''); self.inputs.hoogle; + }; + }; + + packages = flake.packages // hoogleImage; checks = lib.fold lib.mergeAttrs { } @@ -511,6 +559,7 @@ in check = utils.combineChecks "combined-checks" checks; + run.nixFormat = { dependencies = [ nixpkgsFmt ];