diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 186aff4bc..51e2918c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,11 +15,13 @@ jobs: - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e.tar.gz + if: matrix.os != 'ARM64' - uses: cachix/cachix-action@v12 with: name: digitallyinduced signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + if: matrix.os != 'ARM64' - run: git clone https://github.com/digitallyinduced/ihp-boilerplate.git - name: Cache build directory uses: actions/cache@v2 @@ -27,6 +29,7 @@ jobs: path: | ihp-boilerplate/build key: ${{ runner.os }}-ghc + if: matrix.os != 'ARM64' - run: | cd ihp-boilerplate php ../.github/patch-flakes.php ${{ github.ref }} ${{ github.event.repository.full_name }} diff --git a/.github/workflows/keep_releases_in_cachix.yml b/.github/workflows/keep_releases_in_cachix.yml index e9dd51f0c..83c210c5e 100644 --- a/.github/workflows/keep_releases_in_cachix.yml +++ b/.github/workflows/keep_releases_in_cachix.yml @@ -14,11 +14,13 @@ jobs: - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e.tar.gz + if: matrix.os != 'ARM64' - uses: cachix/cachix-action@v12 with: name: digitallyinduced signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + if: matrix.os != 'ARM64' - run: git clone https://github.com/digitallyinduced/ihp-boilerplate.git - run: | cd ihp-boilerplate diff --git a/.github/workflows/pr_compile_check.yml b/.github/workflows/pr_compile_check.yml index 9f055a933..bb4402db5 100644 --- a/.github/workflows/pr_compile_check.yml +++ b/.github/workflows/pr_compile_check.yml @@ -10,10 +10,12 @@ jobs: - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e.tar.gz + if: matrix.os != 'ARM64' - uses: cachix/cachix-action@v12 with: name: digitallyinduced skipPush: true + if: matrix.os != 'ARM64' - run: | cd $GITHUB_WORKSPACE mkdir -p ~/.config/nixpkgs diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 527f7147e..b0c93de77 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,9 +13,11 @@ jobs: - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/a95ed9fe764c3ba2bf2d2fa223012c379cd6b32e.tar.gz + if: matrix.os != 'ARM64' - uses: cachix/cachix-action@v12 with: name: digitallyinduced signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + if: matrix.os != 'ARM64' - run: nix develop --impure --command tests diff --git a/Guide/editors.markdown b/Guide/editors.markdown index 992ca8764..26f78b3c4 100644 --- a/Guide/editors.markdown +++ b/Guide/editors.markdown @@ -214,34 +214,38 @@ To quickly look up function type signatures you can use the built-in hoogle serv To install it: -1. Open `default.nix` -2. Add `withHoogle = true;` to the `haskellEnv` block, like this: +1. Open `flake.nix` +2. Add `withHoogle = true;` to the `ihp` project block, inside `perSystem` function invocation like this: ```nix -let - ihp = builtins.fetchGit { - url = "https://github.com/digitallyinduced/ihp.git"; - ref = "refs/tags/v0.14.0"; - }; - haskellEnv = import "${ihp}/NixSupport/default.nix" { - ihp = ihp; - haskellDeps = p: with p; [ - cabal-install - base - wai - text - hlint - p.ihp - ]; - otherDeps = p: with p; [ - # Native dependencies, e.g. imagemagick - ]; - projectPath = ./.; - - withHoogle = true; # <------- +... +outputs = inputs@{ ihp, flake-parts, systems, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + + systems = import systems; + imports = [ ihp.flakeModules.default ]; + + perSystem = { pkgs, ... }: { + ihp = { + enable = true; + projectPath = ./.; + packages = with pkgs; [ + # Native dependencies, e.g. imagemagick + ]; + haskellPackages = p: with p; [ + # Haskell dependencies go here + p.ihp + cabal-install + base + wai + text + hlint + ]; + withHoogle = true; # <------- + }; + }; + }; -in - haskellEnv ``` Run `devenv up` to remake your dev environment. @@ -249,5 +253,5 @@ Run `devenv up` to remake your dev environment. After that you can use the following command to start hoogle at `localhost:8080`: ```bash -nix-shell --run 'hoogle server --local -p 8080' +hoogle server --local -p 8080 ``` diff --git a/Guide/layout.html b/Guide/layout.html index 483ce7b57..00b1ab944 100644 --- a/Guide/layout.html +++ b/Guide/layout.html @@ -106,7 +106,7 @@ IHP Casts API Docs Newsletter - IHP Forum + IHP Forum StackOverflow #ihp
diff --git a/Guide/testing.markdown b/Guide/testing.markdown index 3a5fbde78..746b6d03f 100644 --- a/Guide/testing.markdown +++ b/Guide/testing.markdown @@ -24,6 +24,7 @@ The following setup and tests can be viewed in the [Blog example](https://github ```haskell # Test/Main.hs + module Main where import Test.Hspec @@ -128,6 +129,12 @@ package flags have changed, resetting and loading new packages... Loaded GHCi configuration from /home/amitaibu/Sites/Haskell/ihp/blog/.ghci ``` +Another way of executing the tests, that we'll use on CI, is to use the `runghc` command, while running `devenv up` on another tab: + +``` +nix-shell --run "runghc $(make print-ghc-extensions) -i. -ibuild -iConfig Test/Main.hs" +``` + ## Setting the Current User During Testing Use `withUser` to call an action with a specific user during testing: @@ -293,3 +300,65 @@ tests = aroundAll (withIHPApp WebApplication config) do ## Advanced For more details on how to structure test suites see the [Hspec manual](http://hspec.github.io/) (a Haskell testing library). You also might want to check out the cool [Hedgehog](https://hedgehog.qa/) library for automated property tests. + +## GitHub Actions + +The following GitHub Action workflow can be used to run the tests on CI: + +```yaml +# .github/workflows/test.yml + +name: Test + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + pull_request: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + tests: + name: Run Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + with: + nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/51bcdc4cdaac48535dabf0ad4642a66774c609ed.tar.gz + + # Use the cachix cache for faster builds. + - name: Cachix Init + uses: cachix/cachix-action@v12 + with: + name: digitallyinduced + skipPush: true + + # Install devenv. + - uses: cachix/cachix-action@v12 + with: + name: devenv + - name: Install devenv.sh + run: nix profile install github:cachix/devenv/latest + shell: sh + + # Install direnv, which also `direnv allow`s the project. + - uses: HatsuneMiku3939/direnv-action@v1 + with: + direnvVersion: 2.32.3 + + - run: | + # Build generated files. + nix-shell --run "make build/Generated/Types.hs" + + # Start the project in the background. + nix-shell --run "devenv up &" + + # Execute the tests. + nix-shell --run "runghc $(make print-ghc-extensions) -i. -ibuild -iConfig Test/Main.hs" +``` diff --git a/IHP/RouterSupport.hs b/IHP/RouterSupport.hs index 0a35bc64a..2e88ea0be 100644 --- a/IHP/RouterSupport.hs +++ b/IHP/RouterSupport.hs @@ -644,7 +644,7 @@ instance {-# OVERLAPPABLE #-} (Show controller, AutoRoute controller) => HasPath -- | Parses the HTTP Method from the request and returns it. getMethod :: (?context :: RequestContext) => Parser StdMethod getMethod = - case parseMethod ?context.request.requestMethod of + case parseMethod ?context.request.requestMethod of Left error -> fail (ByteString.unpack error) Right method -> pure method {-# INLINABLE getMethod #-} @@ -968,6 +968,5 @@ routeParam paramName = -- -- > Show project -- --- See https://forum.ihpapp.com/ShowThread?threadId=ad73d6a5-2481-4e2f-af46-9bf8849f998b -- See https://github.com/digitallyinduced/ihp/issues/840 instance ((T.TypeError (T.Text "Looks like you forgot to pass a " :<>: (T.ShowType argument) :<>: T.Text " to this " :<>: (T.ShowType controller))), Data argument, Data controller, Data (argument -> controller)) => AutoRoute (argument -> controller) where diff --git a/IHP/SchemaCompiler.hs b/IHP/SchemaCompiler.hs index 55efdc4bc..8bcff36fd 100644 --- a/IHP/SchemaCompiler.hs +++ b/IHP/SchemaCompiler.hs @@ -450,7 +450,7 @@ findForeignKeyConstraint CreateTable { name } column = compileEnumDataDefinitions :: (?schema :: Schema) => Statement -> Text compileEnumDataDefinitions CreateEnumType { values = [] } = "" -- Ignore enums without any values compileEnumDataDefinitions enum@(CreateEnumType { name, values }) = - "data " <> modelName <> " = " <> (intercalate " | " valueConstructors) <> " deriving (Eq, Show, Read, Enum)\n" + "data " <> modelName <> " = " <> (intercalate " | " valueConstructors) <> " deriving (Eq, Show, Read, Enum, Bounded)\n" <> "instance FromField " <> modelName <> " where\n" <> indent (unlines (map compileFromFieldInstanceForValue values)) <> " fromField field (Just value) = returnError ConversionFailed field (\"Unexpected value for enum value. Got: \" <> Data.String.Conversions.cs value)\n" diff --git a/README.md b/README.md index d0d89308b..66a463077 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ - - + + - +

@@ -157,7 +157,7 @@ There's more on the IHP website. Questions, or need help with haskell type errors? [Join our Slack Community](https://ihp.digitallyinduced.com/Slack) -[Also check out the IHP Forum!](https://forum.ihpapp.com/) +[Also check out the IHP Forum!](https://discuss.ihp.digitallyinduced.com/) ## Contributing diff --git a/flake-module.nix b/flake-module.nix index 50a14e208..5cdd568e5 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -59,6 +59,14 @@ ihpFlake: type = lib.types.path; }; + withHoogle = lib.mkOption { + description = '' + Enable Hoogle support. Adds `hoogle` command to PATH. + ''; + type = lib.types.bool; + default = false; + }; + dontCheckPackages = lib.mkOption { description = '' List of Haskell package names whose tests are skipped during build. @@ -166,7 +174,9 @@ ihpFlake: containers = lib.mkForce {}; languages.haskell.enable = true; - languages.haskell.package = ghcCompiler.ghc.withPackages cfg.haskellPackages; + languages.haskell.package = (if cfg.withHoogle + then ghcCompiler.ghc.withHoogle + else ghcCompiler.ghc.withPackages) cfg.haskellPackages; languages.haskell.languageServer = ghcCompiler.haskell-language-server; languages.haskell.stack = null; # Stack is not used in IHP diff --git a/flake.lock b/flake.lock index e20c5f638..70270fc75 100644 --- a/flake.lock +++ b/flake.lock @@ -488,17 +488,17 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1694477507, - "narHash": "sha256-RtUmM5s6vnx1W+tnrGzXArVScJ/IoGmqCLM177k5O5A=", - "owner": "NixOS", + "lastModified": 1696172942, + "narHash": "sha256-hKlB5InxJjDxLy5NJ4tQKEJ39Om81H87uoo0HHBG2UU=", + "owner": "mpscholten", "repo": "nixpkgs", - "rev": "ff303118b2ec262eb342eab88ae79318fac66d52", + "rev": "3cdb4f45a50eb2a6a1a65f324e8243cedef4b19c", "type": "github" }, "original": { - "owner": "NixOS", + "owner": "mpscholten", + "ref": "fix-ghc-m1-issue", "repo": "nixpkgs", - "rev": "ff303118b2ec262eb342eab88ae79318fac66d52", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 8e3bed93b..54e7a02a2 100644 --- a/flake.nix +++ b/flake.nix @@ -3,7 +3,7 @@ inputs = { # TODO use nixpkgs-unstable and just .lock a version? - nixpkgs.url = "github:NixOS/nixpkgs?rev=ff303118b2ec262eb342eab88ae79318fac66d52"; + nixpkgs.url = "github:mpscholten/nixpkgs/fix-ghc-m1-issue"; # pre-defined set of default target systems systems.url = "github:nix-systems/default"; diff --git a/ihp-hsx/ihp-hsx.cabal b/ihp-hsx/ihp-hsx.cabal index 382ac4f9a..c5a98594d 100644 --- a/ihp-hsx/ihp-hsx.cabal +++ b/ihp-hsx/ihp-hsx.cabal @@ -19,15 +19,15 @@ source-repository head library default-language: Haskell2010 build-depends: - base >= 4.16.3 && < 4.17 - , blaze-html >= 0.9.1 && < 0.10 - , bytestring >= 0.11.3 && < 0.12 - , template-haskell >= 2.18.0 && < 2.19 - , text >= 1.2.5 && < 1.3 - , containers >= 0.6.5 && < 0.7 - , blaze-markup >= 0.8.2 && < 0.9 - , ghc >= 9.2.4 && < 9.3 - , megaparsec >= 9.2.1 && < 9.3 + base >= 4.17.0 && < 4.18 + , blaze-html >= 0.9.1 && < 0.10 + , bytestring >= 0.11.3 && < 0.12 + , template-haskell >= 2.19.0 && < 2.20 + , text >= 2.0.1 && < 2.1 + , containers >= 0.6.6 && < 0.7 + , blaze-markup >= 0.8.2 && < 0.9 + , ghc >= 9.4.4 && < 9.5 + , megaparsec >= 9.2.2 && < 9.3 , string-conversions >= 0.4.0 && < 0.5 default-extensions: OverloadedStrings