diff --git a/ChangeLog.md b/ChangeLog.md index 152a405f2..6ef8457cd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,7 +4,7 @@ This project's release branch is `master`. This log is written from the perspect ## Unreleased -* Update reflex-platform to yet unreleased version with GHC 8.10. +* Update reflex-platform to yet unreleased version with GHC 8.10 and nixpkgs 21.05 \[Update note once release is cut.\] * Documentation @@ -12,6 +12,7 @@ This project's release branch is `master`. This log is written from the perspect * [#919](https://github.com/obsidiansystems/obelisk/pull/919): Document useful command for testing Obelisk branches to CONTRIBUTING.md * [#931](https://github.com/obsidiansystems/obelisk/pull/931): For `ob deploy init`, command-line option `--check-known-host` corrected in readme, caveat added for multiple matching host-keypairs. * building + * [#1004](https://github.com/obsidiansystems/obelisk/pull/1004): Fix closure compiler sometimes crashing. Similar to #956, but for when it tries to report errors. (see: [closure-compiler#3720](https://github.com/google/closure-compiler/issues/3720)) * [#956](https://github.com/obsidiansystems/obelisk/pull/956): Squelch closure-compiler warnings. They are not very helpful and can cause issues (see: [closure-compiler#3720](https://github.com/google/closure-compiler/issues/3720)) * nix * [#889](https://github.com/obsidiansystems/obelisk/pull/889): Remove override of `acme` module that pinned it to the version in `nixpkgs-20.03`. This is used for automatic https certificate provisioning. @@ -39,6 +40,11 @@ This project's release branch is `master`. This log is written from the perspect * [#930](https://github.com/obsidiansystems/obelisk/pull/930): Add an error to `ob run` when `static` is called with a path to a file that doesn't exist * [#940](https://github.com/obsidiansystems/obelisk/pull/940): Automatically restart the server when configuration is updated via `ob deploy push`. * [#959](https://github.com/obsidiansystems/obelisk/pull/959): Add an error to `ob run` when `staticFilePath` is called with a path to a file that doesn't exist + * [#1011](https://github.com/obsidiansystems/obelisk/pull/1011): Update default iOS SDK to 15.0 + * [#835](https://github.com/obsidiansystems/obelisk/pull/835): Rebuild static assets in fewer circumstances: + * Watch `frontend`, `backend`, `common`, and `static` instead of the project root to avoid spurious rebuilds when other files change + * Don't call `nix show-derivation` to decide whether to rebuild since it seems to do about as much work as a no-op nix-build + * Add a debug message indicating which file changes triggered the static file rebuild ## v1.0.0.0 - 2022-01-04 diff --git a/README.md b/README.md index 27bd099f7..d7ba75311 100644 --- a/README.md +++ b/README.md @@ -198,9 +198,11 @@ If the `useGHC810` argument is set to false, or not given, then GHC 8.6 will be In this section we will demonstrate how to deploy your Obelisk app to an Amazon EC2 instance. Obelisk deployments are configured for EC2 by default (see [Custom Non-EC2 Deployment](#custom-non-ec2-deployment)). +Note: Most NixOS EC2 instances should just *work* regardless of obelisk version + First create a new EC2 instance: -1. Launch a NixOS 19.09 EC2 instance (we recommend [this AMI](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#LaunchInstanceWizard:ami=ami-00a8eeaf232a74f84)) +1. Launch a NixOS 22.05 EC2 instance (we recommend [this AMI](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#LaunchInstances:ami=ami-0223db08811f6fb2d)) 1. In the instance configuration wizard ensure that your instance has at least 1GB RAM and 10GB disk space. 1. When prompted save your AWS private key (`~/myaws.pem`) somewhere safe. We'll need it later during deployment. 1. Go to "Security Groups", select your instance's security group and under "Inbound" tab add a new rule for HTTP port 80 and HTTPS port 443. diff --git a/all-builds.nix b/all-builds.nix index 6c06bbd3a..c90a2ca96 100644 --- a/all-builds.nix +++ b/all-builds.nix @@ -60,7 +60,6 @@ let rawSkeleton = import ./skeleton { inherit obelisk; }; skeleton = withSkeletonOptions rawSkeleton { withHoogle = true; # cache the Hoogle database for the skeleton - __withGhcide = true; # cache the ghcide build for the skeleton }; serverSkeletonExe = rawSkeleton.exe; diff --git a/default.nix b/default.nix index 46bcf4b3c..cea6bf484 100644 --- a/default.nix +++ b/default.nix @@ -1,6 +1,6 @@ { system ? builtins.currentSystem , profiling ? false -, iosSdkVersion ? "13.2" +, iosSdkVersion ? "15.0" , config ? {} , terms ? { # Accepted terms, conditions, and licenses security.acme.acceptTerms = false; @@ -90,7 +90,8 @@ in rec { ${if optimizationLevel == null then '' ln -s "$dir/all.unminified.js" "$dir/all.js" '' else '' - '${pkgs.closurecompiler}/bin/closure-compiler' ${if externs == null then "" else "--externs '${externs}'"} --externs '${reflex-platform.ghcjsExternsJs}' -O '${optimizationLevel}' --jscomp_warning=checkVars --warning_level=QUIET --create_source_map="$dir/all.js.map" --source_map_format=V3 --js_output_file="$dir/all.js" "$dir/all.unminified.js" + # NOTE: "--error_format JSON" avoids closurecompiler crashes when trying to report errors. + '${pkgs.closurecompiler}/bin/closure-compiler' --error_format JSON ${if externs == null then "" else "--externs '${externs}'"} --externs '${reflex-platform.ghcjsExternsJs}' -O '${optimizationLevel}' --jscomp_warning=checkVars --warning_level=QUIET --create_source_map="$dir/all.js.map" --source_map_format=V3 --js_output_file="$dir/all.js" "$dir/all.unminified.js" echo '//# sourceMappingURL=all.js.map' >> "$dir/all.js" ''} done @@ -332,10 +333,7 @@ in rec { shellToolOverrides = lib.composeExtensions self.userSettings.shellToolOverrides - (if self.userSettings.__withGhcide - then (import ./haskell-overlays/ghcide.nix) - else (_: _: {}) - ); + (_: _: {}); project = reflexPlatformProject ({...}: self.projectConfig); projectConfig = { diff --git a/dep/hnix/default.nix b/dep/hnix/default.nix index 7a0477867..2b4d4ab11 100644 --- a/dep/hnix/default.nix +++ b/dep/hnix/default.nix @@ -1,7 +1,2 @@ # DO NOT HAND-EDIT THIS FILE -import ((import {}).fetchFromGitHub ( - let json = builtins.fromJSON (builtins.readFile ./github.json); - in { inherit (json) owner repo rev sha256; - private = json.private or false; - } -)) +import (import ./thunk.nix) \ No newline at end of file diff --git a/dep/hnix/github.json b/dep/hnix/github.json index b35524000..b10ae880b 100644 --- a/dep/hnix/github.json +++ b/dep/hnix/github.json @@ -1,7 +1,9 @@ { "owner": "haskell-nix", "repo": "hnix", - "branch": "master", - "rev": "6c9c7c310c54372b3db0fdf5a0137b395cde1bdb", - "sha256": "1i5903b7lxqn2s3jarb14h6wdq8bxiik1hp0xy43w5w1hgvvq0g5" + "branch": "hackage-0.12.0.1", + "private": false, + "rev": "0f23778ffe64fe24c2119866437cc53735262856", + "sha256": "sha256-yAR3cIVI/DwuBSlvAt1nKG5a0QcsJlGpsr9ndpZBc0U=", + "fetchSubmodules": true } diff --git a/dep/hnix/thunk.nix b/dep/hnix/thunk.nix new file mode 100644 index 000000000..20f2d28c2 --- /dev/null +++ b/dep/hnix/thunk.nix @@ -0,0 +1,12 @@ +# DO NOT HAND-EDIT THIS FILE +let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }: + if !fetchSubmodules && !private then builtins.fetchTarball { + url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256; + } else (import (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz"; + sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr"; +}) {}).fetchFromGitHub { + inherit owner repo rev sha256 fetchSubmodules private; + }; + json = builtins.fromJSON (builtins.readFile ./github.json); +in fetch json \ No newline at end of file diff --git a/dep/reflex-platform/github.json b/dep/reflex-platform/github.json index 5ae049dc1..17960950b 100644 --- a/dep/reflex-platform/github.json +++ b/dep/reflex-platform/github.json @@ -3,6 +3,6 @@ "repo": "reflex-platform", "branch": "develop", "private": false, - "rev": "9ebc4aa483e94ea52a20ce3641e72b43328d40ae", - "sha256": "1fynvarxlcbcszawcipc1137rz1r9nv96jjb8vgpdkjg9rwk0pas" + "rev": "6c8830e059a6d2859cb1b65acefed3c2f1d216d3", + "sha256": "sha256:06kv45yq8qan0p22wzj5c9mx11ns1wddyqjr1xasjjkf6gaf0080" } diff --git a/haskell-overlays/ghcide.nix b/haskell-overlays/ghcide.nix deleted file mode 100644 index df8c15f8b..000000000 --- a/haskell-overlays/ghcide.nix +++ /dev/null @@ -1,40 +0,0 @@ -self: super: -let - pkgs = self.callPackage ({ pkgs }: pkgs) { }; - inherit (pkgs.haskell.lib) dontCheck justStaticExecutables; - inherit (pkgs.haskellPackages) callHackageDirect callHackage; - -in { - ghcide = justStaticExecutables (dontCheck (callHackageDirect { - pkg = "ghcide"; - ver = "0.2.0"; - sha256 = "199l4qzrghhz6wbfkgqdl4gll4wvgpr190kinzhv88idnn9pxm96"; - } rec { - ghc-check = callHackageDirect { - pkg = "ghc-check"; - ver = "0.3.0.1"; - sha256 = "1dj909m09m24315x51vxvcl28936ahsw4mavbc53danif3wy09ns"; - } { }; - lsp-test = dontCheck (callHackage "lsp-test" "0.6.1.0" { }); - haddock-library = dontCheck (callHackage "haddock-library" "1.8.0" { }); - haskell-lsp = dontCheck (callHackageDirect { - pkg = "haskell-lsp"; - ver = "0.22.0.0"; - sha256 = "1q3w46qcvzraxgmw75s7bl0qvb2fvff242r5vfx95sqska566b4m"; - } { inherit haskell-lsp-types; }); - haskell-lsp-types = dontCheck (callHackageDirect { - pkg = "haskell-lsp-types"; - ver = "0.22.0.0"; - sha256 = "1apjclphi2v6ggrdnbc0azxbb1gkfj3x1vkwpc8qd6lsrbyaf0n8"; - } { }); - regex-tdfa = dontCheck (callHackage "regex-tdfa" "1.3.1.0" { - regex-base = dontCheck (callHackage "regex-base" "0.94.0.0" { }); - }); - shake = dontCheck (callHackage "shake" "0.18.4" { }); - hie-bios = dontCheck (callHackageDirect { - pkg = "hie-bios"; - ver = "0.5.0"; - sha256 = "116nmpva5jmlgc2dgy8cm5wv6cinhzmga1l0432p305074w720r2"; - } { }); - })); -} diff --git a/haskell-overlays/misc-deps.nix b/haskell-overlays/misc-deps.nix index e6d60b87c..f2bd3f5a3 100644 --- a/haskell-overlays/misc-deps.nix +++ b/haskell-overlays/misc-deps.nix @@ -10,33 +10,32 @@ let in rec { - # Actually broken in current nixpkgs master due to MonadFail changes - # git = haskellLib.markUnbroken super.git; + resolv = haskellLib.dontCheck (self.callHackage "resolv" "0.1.2.0" {}); + cabal-install = haskellLib.doJailbreak ((self.callHackage "cabal-install" "3.4.1.0" {}).overrideScope (self: super: { Cabal = self.Cabal_3_4_0_0; })); # hpack requires cabal >= 3.0 but the ghc865 package set builds it with 2.4 by default - hpack = super.hpack.overrideScope (self: super: { Cabal = self.Cabal_3_2_0_0; }); + hpack = super.hpack.overrideScope (self: super: { Cabal = self.Cabal_3_2_1_0; }); + # These versions work with both the ghc865 and ghc8107 package sets git = self.callCabal2nix "git" (hackGet ../dep/hs-git) { }; - # hdevtools = haskellLib.markUnbroken super.hdevtools; - # reflex-ghci = haskellLib.markUnbroken super.reflex-ghci; - # reflex-process = haskellLib.markUnbroken super.reflex-process; - # reflex-vty = haskellLib.markUnbroken super.reflex-vty; - # reflex-fsnotify = haskellLib.markUnbroken super.reflex-fsnotify; - universe-base-810 = haskellLib.doJailbreak (self.callHackage "universe-base" "1.1.3" {}); + http-link-header = haskellLib.doJailbreak super.http-link-header; + universe-base-810 = haskellLib.doJailbreak (self.callHackage "universe-base" "1.1" {}); universe-dependent-sum-810 = self.callHackage "universe-dependent-sum" "1.3" {}; - universe-some-810 = haskellLib.dontHaddock (haskellLib.appendBuildFlags (haskellLib.doJailbreak (self.callHackage "universe-some" "1.2.1" { })) [ "--ghc-option=-Wno-inferred-safe-imports" "--ghc-option=-Wno-missing-safe-haskell-mode" ]); + universe-some-810 = haskellLib.dontHaddock (haskellLib.appendBuildFlags (haskellLib.doJailbreak (self.callHackage "universe-some" "1.2" { })) [ "--ghc-option=-Wno-inferred-safe-imports" "--ghc-option=-Wno-missing-safe-haskell-mode" ]); stylish-haskell = null; # FIXME + beam-migrate = self.callHackageDirect { + pkg = "beam-migrate"; + ver = "0.5.1.2"; + sha256 = "sha256-vEv/6DCvuEq6cmxoPKxZNIm5g6YUgrdvAK4YAoZQr/E="; + } {}; - universe-810 = self.callHackage "universe" "1.2.2" {}; - universe-instances-extended-810 = self.callHackage "universe-instances-extended" "1.1.3" {}; - universe-reverse-instances-810 = self.callHackage "universe-reverse-instances" "1.1.1" {}; + universe-810 = self.callHackage "universe" "1.2" {}; + universe-instances-extended-810 = self.callHackage "universe-instances-extended" "1.1.1" {}; + universe-reverse-instances-810 = self.callHackage "universe-reverse-instances" "1.1" {}; - hnix = haskellLib.overrideCabal super.hnix (drv: { - jailbreak = true; - preBuild = '' - substituteInPlace src/Nix/Expr/Types.hs --replace "instance Hashable1 NonEmpty" "" - '';}); + # We use our fork of hnix which has some compatibility patches on top of 0.12 from hackage + hnix = haskellLib.dontHaddock (haskellLib.dontCheck (self.callCabal2nix "hnix" (hackGet ../dep/hnix) {})); universe-86 = haskellLib.dontCheck (self.callHackage "universe" "1.2" {}); universe-instances-extended-86 = self.callHackage "universe-instances-extended" "1.1.1" {}; @@ -45,17 +44,11 @@ rec { universe = mkVersionset __useNewerCompiler universe-86 universe-810; universe-instances-extended = mkVersionset __useNewerCompiler universe-instances-extended-86 universe-instances-extended-810; universe-reverse-instances = mkVersionset __useNewerCompiler super.universe-reverse-instances universe-reverse-instances-810; - #hnix = mkVersionset version hnix-86 hnix-810; universe-base = haskellLib.dontCheck (mkVersionset __useNewerCompiler super.universe-base universe-base-810); universe-dependent-sum = mkVersionset __useNewerCompiler super.universe-dependent-sum universe-dependent-sum-810; universe-some-86 = self.callHackage "universe-some" "1.2" {}; universe-some = mkVersionset __useNewerCompiler universe-some-86 universe-some-810; - #th-abstraction-86 = self.callHackage "th-abstraction" "0.3.0.0" {}; - #th-abstraction-810 = self.callHackage "th-abstraction" "0.4.3.0" {}; - #th-abstraction = mkVersionset version th-abstraction-86 th-abstraction-810; - #bifunctors = self.callHackage "bifunctors" "5.5.11" { th-abstraction = th-abstraction-new; }; - #template-haskell = self.callHackage "template-haskell" "2.14.0.0" {}; regex-base = self.callHackage "regex-base" "0.94.0.0" { }; regex-posix = self.callHackage "regex-posix" "0.96.0.0" { }; regex-tdfa = self.callHackage "regex-tdfa" "1.3.1.0" { }; @@ -69,7 +62,6 @@ rec { heist = haskellLib.dontCheck (haskellLib.doJailbreak super.heist); # aeson 1.5 bump aeson-gadt-th = haskellLib.doJailbreak super.aeson-gadt-th; # requires aeson 1.5 for ghc8.10 support? deriving-compat = self.callHackage "deriving-compat" "0.6" { }; - #deriving-compat = mkVersionset version super.deriving-compat deriving-compat-810; http-api-data = haskellLib.doJailbreak super.http-api-data; nix-derivation = haskellLib.doJailbreak super.nix-derivation; algebraic-graphs = haskellLib.doJailbreak super.algebraic-graphs; @@ -82,7 +74,11 @@ rec { resourcet = self.callHackage "resourcet" "1.2.4.2" { }; unliftio-core = self.callHackage "unliftio-core" "0.2.0.1" { }; shelly = self.callHackage "shelly" "1.9.0" { }; + # version >= 0.2.5.2 has a Cabal version of 3.0, which nix doesn't like + vector-binary-instances = self.callHackage "vector-binary-instances" "0.2.5.1" {}; + modern-uri = haskellLib.doJailbreak super.modern-uri; monad-logger = self.callHackage "monad-logger" "0.3.36" { }; + neat-interpolation = haskellLib.doJailbreak super.neat-interpolation; nix-thunk = (import ../dep/nix-thunk { }).makeRunnableNixThunk (self.callCabal2nix "nix-thunk" (hackGet ../dep/nix-thunk) { }); cli-extras = self.callCabal2nix "cli-extras" (hackGet ../dep/cli-extras) { }; cli-git = haskellLib.overrideCabal (self.callCabal2nix "cli-git" (hackGet ../dep/cli-git) { }) { @@ -97,4 +93,6 @@ rec { nix-prefetch-git ]; }; + + haddock-library = haskellLib.doJailbreak (self.callHackage "haddock-library" "1.10.0" {}); } diff --git a/lib/asset/manifest/obelisk-asset-manifest.cabal b/lib/asset/manifest/obelisk-asset-manifest.cabal index 2dcc0d92a..a549d6564 100644 --- a/lib/asset/manifest/obelisk-asset-manifest.cabal +++ b/lib/asset/manifest/obelisk-asset-manifest.cabal @@ -8,9 +8,10 @@ Maintainer: maintainer@obsidian.systems Stability: Experimental Category: Web Build-type: Simple -Cabal-version: >= 1.8 +Cabal-version: >= 1.10 library + default-language: Haskell2010 hs-source-dirs: src build-depends: @@ -39,6 +40,7 @@ library -fno-warn-unused-do-bind -funbox-strict-fields -fprof-auto-calls executable obelisk-asset-manifest-generate + default-language: Haskell2010 hs-source-dirs: src-bin main-is: generate.hs build-depends: @@ -47,6 +49,7 @@ executable obelisk-asset-manifest-generate , text executable obelisk-asset-th-generate + default-language: Haskell2010 hs-source-dirs: src-bin main-is: static-th.hs build-depends: diff --git a/lib/asset/manifest/src/Obelisk/Asset/TH.hs b/lib/asset/manifest/src/Obelisk/Asset/TH.hs index fb7a2091b..bdb6e3dc0 100644 --- a/lib/asset/manifest/src/Obelisk/Asset/TH.hs +++ b/lib/asset/manifest/src/Obelisk/Asset/TH.hs @@ -62,8 +62,10 @@ staticAssetFilePathRaw staticAssetFilePathRaw root = staticAssetWorker root staticOutPath staticAssetFilePath :: FilePath -> FilePath -> Q Exp -staticAssetFilePath root fp = do - LitE . StringL . (root ) <$> hashedAssetFilePath root fp +staticAssetFilePath root relativePath = do + let fullPath = root relativePath + qAddDependentFile fullPath + pure $ LitE $ StringL fullPath -- | @'staticAssetWorker' root staticOut fp@. -- diff --git a/lib/asset/serve-snap/obelisk-asset-serve-snap.cabal b/lib/asset/serve-snap/obelisk-asset-serve-snap.cabal index 43aaf6bed..855f55e14 100644 --- a/lib/asset/serve-snap/obelisk-asset-serve-snap.cabal +++ b/lib/asset/serve-snap/obelisk-asset-serve-snap.cabal @@ -6,9 +6,10 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems category: Web build-type: Simple -cabal-version: >=1.2 +cabal-version: >=1.10 library + default-language: Haskell2010 hs-source-dirs: src build-depends: diff --git a/lib/command/src/Obelisk/Command/Project.hs b/lib/command/src/Obelisk/Command/Project.hs index 8069ae45d..3057a9ff3 100644 --- a/lib/command/src/Obelisk/Command/Project.hs +++ b/lib/command/src/Obelisk/Command/Project.hs @@ -29,7 +29,7 @@ module Obelisk.Command.Project ) where import Control.Concurrent.MVar (MVar, newMVar, withMVarMasked) -import Control.Lens ((.~), (?~), (<&>), (^.), _2, _3) +import Control.Lens ((.~), (?~), (<&>)) import Control.Monad import Control.Monad.Except import Control.Monad.IO.Class (liftIO) @@ -40,9 +40,10 @@ import qualified Data.ByteString.UTF8 as BSU import Data.Bits import qualified Data.ByteString.Lazy as BSL import Data.Default (def) +import qualified Data.Foldable as F (toList) import Data.Function ((&), on) import Data.Map (Map) -import Data.Maybe (isJust) +import qualified Data.Set as Set import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8, encodeUtf8) @@ -427,33 +428,67 @@ getHaskellManifestProjectPath root = fmap T.strip $ readProcessAndLogStderr Debu , "(let a = import ./. {}; in a.passthru.processedStatic.haskellManifest)" ] --- | Watch the project directory for file changes and check whether those file changes --- cause changes in the static files nix derivation. If so, rebuild it. +-- | Watch the common, backend, frontend, and static directories for file +-- changes and check whether those file changes cause changes in the static +-- files nix derivation. If so, rebuild it. watchStaticFilesDerivation :: (MonadIO m, MonadObelisk m) => FilePath -> m () watchStaticFilesDerivation root = do ob <- getObelisk - drv0 <- showDerivation liftIO $ runHeadlessApp $ do pb <- getPostBuild - checkForChanges <- batchOccurrences 0.25 =<< watchDirectoryTree - -- On macOS, use the polling backend due to https://github.com/luite/hfsevents/issues/13 - (defaultConfig { confUsePolling = SysInfo.os == "darwin", confPollInterval = 250000 }) - (root <$ pb) - ((/="static.out") . takeFileName . eventPath) - drv <- performEvent $ ffor checkForChanges $ \_ -> - liftIO $ runObelisk ob showDerivation - drvs <- foldDyn (\new (_, old, _) -> (old, new, old /= new)) (drv0, drv0, False) drv - void $ throttleBatchWithLag - (\e -> performEvent $ ffor e $ \_ -> liftIO $ runObelisk ob $ do + -- TODO: Instead of filtering like this, we should figure out what the + -- derivation actually relies on, or at least use the gitignore + let filterEvents x = + let fn = takeFileName x + dirs = Set.fromList $ splitDirectories x + ignoredFilenames = Set.fromList + [ "4913" -- Vim temporary file + ] + ignoredExtensions = Set.fromList + [ ".hi" + , ".o" + , ".swo" + , ".swp" + ] + in not $ + fn `Set.member` ignoredFilenames || + takeExtension fn `Set.member` ignoredExtensions + cfg = defaultConfig + -- On macOS, use the polling backend due to + -- https://github.com/luite/hfsevents/issues/13 + { confUsePolling = SysInfo.os == "darwin" + , confPollInterval = 250000 + } + watch' pkg = fmap (:[]) <$> watchDirectoryTree cfg (root pkg <$ pb) (filterEvents . eventPath) + rebuild <- batchOccurrences 0.25 =<< mergeWith (<>) <$> mapM watch' + [ "frontend" + , "backend" + , "common" + , "static" + ] + performEvent_ + $ liftIO + . runObelisk ob + . putLog Debug + . ("Regenerating static.out due to file changes: "<>) + . T.intercalate ", " + . Set.toList + . Set.fromList + . fmap (T.pack . eventPath) + . concat + . F.toList + <$> rebuild + void $ flip throttleBatchWithLag rebuild $ \e -> + performEvent $ ffor e $ \_ -> liftIO $ runObelisk ob $ do putLog Notice "Static assets being built..." buildStaticCatchErrors >>= \case Nothing -> pure () - Just _ -> putLog Notice "Static assets built and symlinked to static.out" - ) - ((() <$) . ffilter (\x -> isJust (x ^._2) && x ^._3) $ updated drvs) + Just n -> do + putLog Notice $ "Static assets built and symlinked to static.out" + putLog Debug $ "Generated static asset nix path: " <> n pure never where handleBuildFailure @@ -461,23 +496,14 @@ watchStaticFilesDerivation root = do => (ExitCode, String, String) -> m (Maybe Text) handleBuildFailure (ex, out, err) = case ex of - ExitSuccess -> pure $ Just $ T.pack out + ExitSuccess -> + let out' = T.strip $ T.pack out + in pure $ if T.null out' then Nothing else Just out' _ -> do putLog Error $ ("Static assets build failed: " <>) $ - T.unlines $ reverse $ take 10 $ reverse $ T.lines $ T.pack err + T.unlines $ reverse $ take 20 $ reverse $ T.lines $ T.pack err pure Nothing - showDerivation :: MonadObelisk m => m (Maybe Text) - showDerivation = - handleBuildFailure <=< readCreateProcessWithExitCode $ - setCwd (Just root) $ ProcessSpec - { _processSpec_createProcess = Proc.proc nixExePath - [ "show-derivation" - , "-f", "." - , "passthru.staticFilesImpure" - ] - , _processSpec_overrideEnv = Nothing - } buildStaticCatchErrors :: MonadObelisk m => m (Maybe Text) buildStaticCatchErrors = handleBuildFailure =<< buildStaticFilesDerivationAndSymlink diff --git a/lib/executable-config/default.nix b/lib/executable-config/default.nix index 99c972082..c6425e106 100644 --- a/lib/executable-config/default.nix +++ b/lib/executable-config/default.nix @@ -34,7 +34,7 @@ in (drv: { # Hack until https://github.com/NixOS/cabal2nix/pull/432 lands libraryHaskellDepends = (drv.libraryHaskellDepends or []) - ++ pkgs.stdenv.lib.optionals (with pkgs.stdenv.hostPlatform; isAndroid && is32bit) [ + ++ pkgs.lib.optionals (with pkgs.stdenv.hostPlatform; isAndroid && is32bit) [ self.android-activity ]; }); diff --git a/lib/route/src/Obelisk/Route.hs b/lib/route/src/Obelisk/Route.hs index bac168975..2f936af05 100644 --- a/lib/route/src/Obelisk/Route.hs +++ b/lib/route/src/Obelisk/Route.hs @@ -22,6 +22,7 @@ Types and functions for defining routes and 'Encoder's. {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-} module Obelisk.Route ( -- * Primary Types diff --git a/skeleton/backend/backend.cabal b/skeleton/backend/backend.cabal index 25f690346..46c0548ae 100644 --- a/skeleton/backend/backend.cabal +++ b/skeleton/backend/backend.cabal @@ -14,12 +14,26 @@ library , obelisk-route exposed-modules: Backend - ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O -fno-show-valid-hole-fits + ghc-options: -Wall -O -fno-show-valid-hole-fits + -- unsafe code + -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields + -- unneeded code + -Widentities -Wredundant-constraints + if impl(ghc >= 8.8) + ghc-options: + -Wmissing-deriving-strategies executable backend main-is: main.hs hs-source-dirs: src-bin - ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O -threaded -fno-show-valid-hole-fits + ghc-options: -Wall -O -fno-show-valid-hole-fits -threaded + -- unsafe code + -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields + -- unneeded code + -Widentities -Wredundant-constraints + if impl(ghc >= 8.8) + ghc-options: + -Wmissing-deriving-strategies if impl(ghcjs) buildable: False build-depends: base diff --git a/skeleton/common/common.cabal b/skeleton/common/common.cabal index 82b89916c..3a04644cb 100644 --- a/skeleton/common/common.cabal +++ b/skeleton/common/common.cabal @@ -12,4 +12,11 @@ library exposed-modules: Common.Api Common.Route - ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O -fno-show-valid-hole-fits + ghc-options: -Wall -O -fno-show-valid-hole-fits + -- unsafe code + -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields + -- unneeded code + -Widentities -Wredundant-constraints + if impl(ghc >= 8.8) + ghc-options: + -Wmissing-deriving-strategies diff --git a/skeleton/common/src/Common/Route.hs b/skeleton/common/src/Common/Route.hs index 1dce9a734..17dadaee5 100644 --- a/skeleton/common/src/Common/Route.hs +++ b/skeleton/common/src/Common/Route.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} diff --git a/skeleton/frontend/frontend.cabal b/skeleton/frontend/frontend.cabal index a9f7abafe..18db7578e 100644 --- a/skeleton/frontend/frontend.cabal +++ b/skeleton/frontend/frontend.cabal @@ -17,7 +17,14 @@ library , text exposed-modules: Frontend - ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O -fno-show-valid-hole-fits + ghc-options: -Wall -O -fno-show-valid-hole-fits + -- unsafe code + -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields + -- unneeded code + -Widentities -Wredundant-constraints + if impl(ghc >= 8.8) + ghc-options: + -Wmissing-deriving-strategies executable frontend main-is: main.hs @@ -29,7 +36,14 @@ executable frontend , reflex-dom , obelisk-generated-static , frontend - ghc-options: -threaded -O -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -fno-show-valid-hole-fits + ghc-options: -Wall -O -fno-show-valid-hole-fits -threaded + -- unsafe code + -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields + -- unneeded code + -Widentities -Wredundant-constraints + if impl(ghc >= 8.8) + ghc-options: + -Wmissing-deriving-strategies if impl(ghcjs) ghc-options: -dedupe cpp-options: -DGHCJS_BROWSER