From 6d08491f1ca33ca25270b1cab568830805ffe8a1 Mon Sep 17 00:00:00 2001 From: Noah Masur <7386960+nmasur@users.noreply.github.com> Date: Mon, 4 Jul 2022 19:17:58 -0400 Subject: [PATCH] add haskell programming template --- flake.nix | 4 + hosts/desktop/default.nix | 1 + modules/programming/haskell.nix | 8 + modules/shell/fish/default.nix | 2 + .../fish/functions/git-push-upstream.fish | 2 - templates/haskell/.envrc | 1 + templates/haskell/.gitignore | 27 ++ templates/haskell/.hlint.yaml | 12 + templates/haskell/app/Main.hs | 4 + templates/haskell/bench/Main.hs | 4 + templates/haskell/cabal.project | 5 + templates/haskell/flake.lock | 419 ++++++++++++++++++ templates/haskell/flake.nix | 54 +++ templates/haskell/hello.cabal | 68 +++ templates/haskell/hie.yaml | 16 + templates/haskell/src/Lib.hs | 7 + templates/haskell/test/Spec.hs | 8 + 17 files changed, 640 insertions(+), 2 deletions(-) create mode 100644 modules/programming/haskell.nix create mode 100644 templates/haskell/.envrc create mode 100644 templates/haskell/.gitignore create mode 100644 templates/haskell/.hlint.yaml create mode 100644 templates/haskell/app/Main.hs create mode 100644 templates/haskell/bench/Main.hs create mode 100644 templates/haskell/cabal.project create mode 100644 templates/haskell/flake.lock create mode 100644 templates/haskell/flake.nix create mode 100644 templates/haskell/hello.cabal create mode 100644 templates/haskell/hie.yaml create mode 100644 templates/haskell/src/Lib.hs create mode 100644 templates/haskell/test/Spec.hs diff --git a/flake.nix b/flake.nix index 60f5ccf..195e861 100644 --- a/flake.nix +++ b/flake.nix @@ -97,6 +97,10 @@ path = ./templates/python; description = "Legacy Python template"; }; + haskell = { + path = ./templates/haskell; + description = "Haskell template"; + }; }; }; diff --git a/hosts/desktop/default.nix b/hosts/desktop/default.nix index 2fd0f3a..1c009c6 100644 --- a/hosts/desktop/default.nix +++ b/hosts/desktop/default.nix @@ -35,5 +35,6 @@ nixpkgs.lib.nixosSystem { ../../modules/services/gnupg.nix ../../modules/services/mullvad.nix ../../modules/programming/nix.nix + ../../modules/programming/haskell.nix ]; } diff --git a/modules/programming/haskell.nix b/modules/programming/haskell.nix new file mode 100644 index 0000000..0439350 --- /dev/null +++ b/modules/programming/haskell.nix @@ -0,0 +1,8 @@ +{ ... }: { + + # Binary Cache for Haskell.nix + nix.settings.trusted-public-keys = + [ "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" ]; + nix.settings.substituters = [ "https://cache.iog.io" ]; + +} diff --git a/modules/shell/fish/default.nix b/modules/shell/fish/default.nix index d05b582..669a207 100644 --- a/modules/shell/fish/default.nix +++ b/modules/shell/fish/default.nix @@ -112,6 +112,8 @@ # Nix ns = "nix-shell -p"; nps = "nix repl ''"; + nixo = "man configuration.nix"; + nixh = "man home-configuration.nix"; # Docker dc = "$DOTS/bin/docker_cleanup"; diff --git a/modules/shell/fish/functions/git-push-upstream.fish b/modules/shell/fish/functions/git-push-upstream.fish index 95bfcbe..a768efe 100644 --- a/modules/shell/fish/functions/git-push-upstream.fish +++ b/modules/shell/fish/functions/git-push-upstream.fish @@ -2,5 +2,3 @@ set -l branch (git branch 2>/dev/null | grep '^\*' | colrm 1 2) and set -l command "git push --set-upstream origin $branch" and commandline -r $command and commandline -f execute -and echo "git push --set-upstream origin $branch" -and git push --set-upstream origin $branch diff --git a/templates/haskell/.envrc b/templates/haskell/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/templates/haskell/.envrc @@ -0,0 +1 @@ +use flake diff --git a/templates/haskell/.gitignore b/templates/haskell/.gitignore new file mode 100644 index 0000000..edb8907 --- /dev/null +++ b/templates/haskell/.gitignore @@ -0,0 +1,27 @@ +### Nix ### +result + +### Haskell ### +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* diff --git a/templates/haskell/.hlint.yaml b/templates/haskell/.hlint.yaml new file mode 100644 index 0000000..17dec4a --- /dev/null +++ b/templates/haskell/.hlint.yaml @@ -0,0 +1,12 @@ +# template-haskell example hlint file + +# Generalise map to fmap, ++ to <>. Off by default +- group: + name: generalise + enabled: true + +- ignore: + name: Use section + +- ignore: + name: Use infix diff --git a/templates/haskell/app/Main.hs b/templates/haskell/app/Main.hs new file mode 100644 index 0000000..87e6679 --- /dev/null +++ b/templates/haskell/app/Main.hs @@ -0,0 +1,4 @@ +import Lib + +main :: IO () +main = putStrLn "this is my app" diff --git a/templates/haskell/bench/Main.hs b/templates/haskell/bench/Main.hs new file mode 100644 index 0000000..04c2719 --- /dev/null +++ b/templates/haskell/bench/Main.hs @@ -0,0 +1,4 @@ +import Lib + +main :: IO () +main = putStrLn "heyyyyyyyyyyyyyyyyyyyy" diff --git a/templates/haskell/cabal.project b/templates/haskell/cabal.project new file mode 100644 index 0000000..167e7be --- /dev/null +++ b/templates/haskell/cabal.project @@ -0,0 +1,5 @@ +packages: + ./ + +package hello + tests: True diff --git a/templates/haskell/flake.lock b/templates/haskell/flake.lock new file mode 100644 index 0000000..57aa8ad --- /dev/null +++ b/templates/haskell/flake.lock @@ -0,0 +1,419 @@ +{ + "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1640353650, + "narHash": "sha256-N1t6M3/wqj90AEdRkeC8i923gQYUpzSr8b40qVOZ1Rk=", + "owner": "haskell", + "repo": "cabal", + "rev": "942639c18c0cd8ec53e0a6f8d120091af35312cd", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1641652457, + "narHash": "sha256-BlFPKP4C4HRUJeAbdembX1Rms1LD380q9s0qVDeoAak=", + "owner": "haskell", + "repo": "cabal", + "rev": "f27667f8ec360c475027dcaee0138c937477b070", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1656065134, + "narHash": "sha256-oc6E6ByIw3oJaIyc67maaFcnjYOz1mMcOtHxbEf9NwQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "bee6a7250dd1b01844a2de7e02e4df7d8a0a206c", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1656724378, + "narHash": "sha256-JdtnbKzKiP1GMWuVt3aQYELxFb8A2OhH/TJBfPn3QMg=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "6e2d054b0876d3f9709da1df9dfe27325886927e", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskellNix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-utils": "flake-utils_2", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "hackage": "hackage", + "hpc-coveralls": "hpc-coveralls", + "hydra": "hydra", + "nix-tools": "nix-tools", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1656752829, + "narHash": "sha256-Xz7aGLynjihmgp5a9dTX5Ax5GsL3Fcd2GQUEJ2BEYAU=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "4e100b2ad96c221a78580701aa0a5a4f48f49130", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "hydra": { + "inputs": { + "nix": "nix", + "nixpkgs": [ + "haskellNix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1646878427, + "narHash": "sha256-KtbrofMtN8GlM7D+n90kixr7QpSlVmdN+vK5CA/aRzc=", + "owner": "NixOS", + "repo": "hydra", + "rev": "28b682b85b7efc5cf7974065792a1f22203a5927", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1643066034, + "narHash": "sha256-xEPeMcNJVOeZtoN+d+aRwolpW8mFSEQx76HTRdlhPhg=", + "owner": "NixOS", + "repo": "nix", + "rev": "a1cd7e58606a41fcf62bf8637804cf8306f17f62", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.6.0", + "repo": "nix", + "type": "github" + } + }, + "nix-tools": { + "flake": false, + "locked": { + "lastModified": 1649424170, + "narHash": "sha256-XgKXWispvv5RCvZzPb+p7e6Hy3LMuRjafKMl7kXzxGw=", + "owner": "input-output-hk", + "repo": "nix-tools", + "rev": "e109c94016e3b6e0db7ed413c793e2d4bdb24aa7", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "nix-tools", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1632864508, + "narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "82891b5e2c2359d7e58d08849e4c89511ab94234", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.05-small", + "type": "indirect" + } + }, + "nixpkgs-2003": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1645296114, + "narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1648744337, + "narHash": "sha256-bYe1dFJAXovjqiaPKrmAbSBEK5KUkgwVaZcTbSoJ7hg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0a58eebd8ec65ffdef2ce9562784123a73922052", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "indirect" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1648219316, + "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "haskellNix": "haskellNix", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ] + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1656638371, + "narHash": "sha256-waxiLSFvKxpaG4zl8YpLtuhLf5OrFi6CgAIZAOXpnQ8=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "4f1ad0f4b0f01010df8dab254fc8b453934823e7", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/templates/haskell/flake.nix b/templates/haskell/flake.nix new file mode 100644 index 0000000..f6eb37e --- /dev/null +++ b/templates/haskell/flake.nix @@ -0,0 +1,54 @@ +# Derived from: https://github.com/jonascarpay/template-haskell +# More info here: https://jonascarpay.com/posts/2021-01-28-haskell-project-template.html + +{ + description = "hello"; + + inputs.haskellNix.url = "github:input-output-hk/haskell.nix"; + inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, flake-utils, haskellNix }: + flake-utils.lib.eachDefaultSystem (system: + let + overlay = self: _: { + hsPkgs = self.haskell-nix.project' rec { + src = ./.; + compiler-nix-name = "ghc8107"; + shell = { + tools = { + cabal = "latest"; + ghcid = "latest"; + haskell-language-server = "latest"; + hlint = "latest"; + # See https://github.com/input-output-hk/haskell.nix/issues/1337 + ormolu = { + version = "latest"; + modules = [ + ({ lib, ... }: { + options.nonReinstallablePkgs = + lib.mkOption { apply = lib.remove "Cabal"; }; + }) + ]; + }; + }; + ## ormolu that uses ImportQualifiedPost. + ## To use, remove ormolu from the shell.tools section above, and uncomment the following lines. + # buildInputs = + # let + # ormolu = pkgs.haskell-nix.tool compiler-nix-name "ormolu" "latest"; + # ormolu-wrapped = pkgs.writeShellScriptBin "ormolu" '' + # ${ormolu}/bin/ormolu --ghc-opt=-XImportQualifiedPost $@ + # ''; + # in + # [ ormolu-wrapped ]; + }; + }; + }; + pkgs = import nixpkgs { + inherit system; + overlays = [ haskellNix.overlay overlay ]; + }; + flake = pkgs.hsPkgs.flake { }; + in flake // { defaultPackage = flake.packages."hello:exe:hello-exe"; }); +} diff --git a/templates/haskell/hello.cabal b/templates/haskell/hello.cabal new file mode 100644 index 0000000..b912910 --- /dev/null +++ b/templates/haskell/hello.cabal @@ -0,0 +1,68 @@ +cabal-version: 2.4 +name: hello +version: 0 +license: BSD-3-Clause +build-type: Simple +license-file: LICENSE +author: AUTHNAME +maintainer: AUTHNAME +copyright: CURRENTYEAR AUTHNAME +tested-with: GHC ==8.6.3 || ==8.8.3 || ==8.10.5 +extra-doc-files: + CHANGELOG.md + README.md + +-- category: +-- description: description +-- synopsis: one-line synopsis +-- homepage: https://github.com/FIXME/hello#readme +-- source-repository head +-- type: git +-- location: git://github.com/FIXME/hello.git + +common common-options + build-depends: base >=4.9 && <5 + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-uni-patterns + -Wincomplete-record-updates -Wredundant-constraints + -fhide-source-paths -Wpartial-fields + +library + import: common-options + hs-source-dirs: src + exposed-modules: Lib + build-depends: + , containers + , mtl + +executable hello-exe + import: common-options + hs-source-dirs: app + main-is: Main.hs + build-depends: hello + ghc-options: -threaded -rtsopts -with-rtsopts=-N + +test-suite hello-test + import: common-options + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , hspec + , HUnit + , hello + , QuickCheck + + ghc-options: -threaded -rtsopts -with-rtsopts=-N + +benchmark hello-bench + import: common-options + type: exitcode-stdio-1.0 + hs-source-dirs: bench + main-is: Main.hs + build-depends: + , criterion + , hello + + ghc-options: -threaded -rtsopts -with-rtsopts=-N diff --git a/templates/haskell/hie.yaml b/templates/haskell/hie.yaml new file mode 100644 index 0000000..e62b4ea --- /dev/null +++ b/templates/haskell/hie.yaml @@ -0,0 +1,16 @@ +cradle: + multi: + # - path: "ignore/" + # config: {cradle: {none: }} + + - path: "src" + config: {cradle: {cabal: {component: "lib:hello"}}} + + - path: "app" + config: {cradle: {cabal: {component: "hello:hello-exe"}}} + + - path: "test" + config: {cradle: {cabal: {component: "hello:hello-test"}}} + + - path: "bench" + config: {cradle: {cabal: {component: "hello:hello-bench"}}} diff --git a/templates/haskell/src/Lib.hs b/templates/haskell/src/Lib.hs new file mode 100644 index 0000000..b37cc56 --- /dev/null +++ b/templates/haskell/src/Lib.hs @@ -0,0 +1,7 @@ +module Lib + ( someFunc, + ) +where + +someFunc :: IO () +someFunc = putStrLn "this is a lib" diff --git a/templates/haskell/test/Spec.hs b/templates/haskell/test/Spec.hs new file mode 100644 index 0000000..029d688 --- /dev/null +++ b/templates/haskell/test/Spec.hs @@ -0,0 +1,8 @@ +import Test.Hspec + +main :: IO () +main = + hspec $ + describe "hello-test" $ + it "works" $ + 2 + 2 `shouldBe` (4 :: Int)