on master help sign in
Merge branch 'develop' into db-app-cache-control
commit97254a1626d5d6290ab9a278f4b2c54ad9d33156 authorAli Abrar <aliabrar@gmail.com> dateThu 3 Oct 2019, 11:29 (7 years ago) parentbe7db050c66165
13 files changed+52−43
README.md+18−9 default.nix+1−1 dep/reflex-platform/github.json+3−3 lib/command/src/Obelisk/Command/Deploy.hs+1−1 lib/command/src/Obelisk/Command/Project.hs+1 lib/command/src/Obelisk/Command/Run.hs+9 lib/selftest/src/Obelisk/SelfTest.hs+4−8 release.nix+3−6 skeleton/backend/src/Backend.hs−2 skeleton/common/src/Common/Route.hs+4−6 skeleton/default.nix+6−6 skeleton/frontend/src/Frontend.hs+1−1 skeleton/shell.nix+1
README.md+18−9
@@ -99,14 +99,14 @@ In order to add package dependencies, declare them under the build-depends field
9999
100100### Adding package overrides
101101
102−To add a version override to any Haskell package, or to add a Haskell package that doesn't exist in the nixpkgs used by Obelisk, use the `overrides` attribute in your project's `default.nix`. For example, to use a specific version of the `aeson` package, your `default.nix` will look like:
102+To add a version override to any Haskell package, or to add a Haskell package that doesn't exist in the nixpkgs used by Obelisk, use the `overrides` attribute in your project's `default.nix`. For example, to use a specific version of the `aeson` package fetched from GitHub and a specific version of the `waargonaut` package fetched from Hackage, your `default.nix` will look like:
103103
104104```nix
105105# ...
106106project ./. ({ pkgs, ... }: {
107107# ...
108108 overrides = self: super: let
109− aeson = pkgs.fetchFromGitHub {
109+ aesonSrc = pkgs.fetchFromGitHub {
110110 owner = "obsidiansystems";
111111 repo = "aeson-gadt-th";
112112 rev = "ed573c2cccf54d72aa6279026752a3fecf9c1383";
@@ -114,7 +114,12 @@ project ./. ({ pkgs, ... }: {
114114 };
115115 in
116116 {
117− aeson = self.callCabal2nix "aeson" aeson {};
117+ aeson = self.callCabal2nix "aeson" aesonSrc {};
118+ waargonaut = self.callHackageDirect {
119+ pkg = "waargonaut";
120+ ver = "0.8.0.1";
121+ sha256 = "1zv28np3k3hg378vqm89v802xr0g8cwk7gy3mr77xrzy5jbgpa39";
122+ } {};
118123 };
119124# ...
120125```
@@ -128,14 +133,16 @@ For further information see [the Haskell section](https://nixos.org/nixpkgs/manu
128133Build everything:
129134
130135```
131−nix-build -A exe -o result-exe
136+nix-build -A exe --no-out-link
132137```
133138
134−Run the server:
139+Copy the result to a new directory, add configuration, and run!
135140
136141```
137−cd result-exe
138−./backend
142+mkdir test-app
143+ln -s $(nix-build -A exe --no-out-link)/* test-app/
144+cp -r config test-app
145+(cd test-app && ./backend)
139146```
140147
141148### EC2
@@ -167,9 +174,11 @@ ob deploy init \
167174 ~/code/myapp-deploy
168175```
169176
170−NOTE: HTTPS is enabled by default; to disable https, pass `--disable-https` to the `ob deploy init` command above.
177+HTTPS is enabled by default; to disable https, pass `--disable-https` to the `ob deploy init` command above.
171178
172−Then go to that created deployment configuration directory, and initiate the deployment:
179+This step will also require that you manually verify the authenticity of the host `$SERVER`. Obelisk will save the fingerprint in a deployment-specific configuration. **Obelisk deployments do *not* rely on the `known_hosts` of your local machine.** This is because, in the event that you need to switch from one deploy machine / bastion host to another, you want to be absolutely sure that you're still connecting to the machines you think you are, even if that deploy machine / bastion host has never connected to them before. Obelisk explicitly avoids a workflow that encourages people to accept host keys without checking them, since that could result in leaking production secrets to anyone who manages to MITM you, e.g. via DNS spoofing or cache poisoning. (Note that an active attack is a circumstance where you may need to quickly switch bastion hosts, e.g. because the attacker has taken one down or you have taken it down in case it was compromised. In this circumstance you might need to deploy to production to fix an exploit or rotate keys, etc.) When you run `ob deploy` later it will rely on the saved verification in this step.
180+
181+Next, go to the deployment directory that you just initialized and deploy!
173182
174183```
175184cd ~/code/myapp-deploy
default.nix+1−1
@@ -128,7 +128,7 @@ in rec {
128128 obelisk = ghcObelisk;
129129 obeliskEnvs = ghcObeliskEnvs;
130130 command = ghcObelisk.obelisk-command;
131− shell = pinBuildInputs "obelisk-shell" ([command] ++ commandRuntimeDeps pkgs) [];
131+ shell = pinBuildInputs "obelisk-shell" ([command] ++ commandRuntimeDeps pkgs);
132132
133133 selftest = pkgs.writeScript "selftest" ''
134134 #!/usr/bin/env bash
dep/reflex-platform/github.json+3−3
@@ -1,7 +1,7 @@
11{
22 "owner": "reflex-frp",
33 "repo": "reflex-platform",
4− "branch": "aa-split-these",
5− "rev": "4b4a2c8679d6f3042180d2974b31c43bfc506b91",
6− "sha256": "185i8ccqk0xc05ckd921fs7nnaj88gihmlazny1dk004hxq78cj2"
4+ "branch": "develop",
5+ "rev": "9e306f72ed0dbcdccce30a4ba0eb37aa03cf91e3",
6+ "sha256": "1crlwfw6zsx2izwsd57i5651p5pfyrpkfjwp6fc1yd4q4d4n7g2m"
77}
lib/command/src/Obelisk/Command/Deploy.hs+1−1
@@ -275,7 +275,7 @@ instance ToJSON KeytoolConfig
275275createKeystore :: MonadObelisk m => FilePath -> KeytoolConfig -> m ()
276276createKeystore root config = do
277277 let expr = "with (import " <> toImplDir root <> ").reflex-platform.nixpkgs; pkgs.mkShell { buildInputs = [ pkgs.jdk ]; }"
278− callProcessAndLogOutput (Notice,Notice) $ (proc "nix-shell" ["-E" , expr, "--run" , keytoolCmd]) { cwd = Just root }
278+ callProcessAndLogOutput (Notice,Notice) $ (proc "nix-shell" ["default.nix", "-E" , expr, "--run" , keytoolCmd]) { cwd = Just root }
279279 where
280280 keytoolCmd = processToShellString "keytool"
281281 [ "-genkeypair", "-noprompt"
lib/command/src/Obelisk/Command/Project.hs+1
@@ -205,6 +205,7 @@ inImpureProjectShell shellName command = withProjectRoot "." $ \root ->
205205projectShell :: MonadObelisk m => FilePath -> Bool -> String -> Maybe String -> m ()
206206projectShell root isPure shellName command = do
207207 (_, _, _, ph) <- createProcess_ "runNixShellAttr" $ setCtlc $ setCwd (Just root) $ proc "nix-shell" $
208+ [ "default.nix"] <>
208209 [ "--pure" | isPure ] <>
209210 [ "-A"
210211 , "shells." <> shellName
lib/command/src/Obelisk/Command/Run.hs+9
@@ -14,6 +14,7 @@ import qualified Data.List as L
1414import qualified Data.List.NonEmpty as NE
1515import Data.Maybe
1616import qualified Data.Text as T
17+import Distribution.Compiler (CompilerFlavor(..))
1718import Distribution.PackageDescription.Parsec (parseGenericPackageDescription)
1819import Distribution.Parsec.ParseResult (runParseResult)
1920import Distribution.Pretty
@@ -48,6 +49,8 @@ data CabalPackageInfo = CabalPackageInfo
4849 -- ^ List of globally enable extensions of the library component
4950 , _cabalPackageInfo_defaultLanguage :: Maybe Language
5051 -- ^ List of globally set languages of the library component
52+ , _cabalPackageInfo_compilerOptions :: [(CompilerFlavor, [String])]
53+ -- ^ List of compiler-specific options (e.g., the "ghc-options" field of the cabal file)
5154 }
5255
5356-- NOTE: `run` is not polymorphic like the rest because we use StaticPtr to invoke it.
@@ -143,6 +146,7 @@ parseCabalPackage dir = do
143146 defaultExtensions $ libBuildInfo lib
144147 , _cabalPackageInfo_defaultLanguage =
145148 defaultLanguage $ libBuildInfo lib
149+ , _cabalPackageInfo_compilerOptions = options $ libBuildInfo lib
146150 }
147151 Left (_, errors) -> do
148152 putLog Error $ T.pack $ "Failed to parse " <> cabalFp <> ":"
@@ -178,8 +182,13 @@ withGhciScript pkgs f = do
178182 extensionsLine = if extensions == mempty
179183 then ""
180184 else ":set " <> intercalate " " ((("-X" <>) . prettyShow) <$> extensions)
185+ ghcOptions = concat $ mapMaybe (\case (GHC, xs) -> Just xs; _ -> Nothing) $
186+ packageInfos >>= _cabalPackageInfo_compilerOptions
181187 dotGhci = unlines $
182188 [ ":set -i" <> intercalate ":" (packageInfos >>= rootedSourceDirs)
189+ , case ghcOptions of
190+ [] -> ""
191+ xs -> ":set " <> intercalate " " xs
183192 , extensionsLine
184193 , ":set " <> intercalate " " (("-X" <>) . prettyShow <$> language)
185194 , ":load Backend Frontend"
lib/selftest/src/Obelisk/SelfTest.hs+4−8
@@ -129,8 +129,8 @@ main = do
129129 ls tmp >>= liftIO . assertEqual "" []
130130
131131 it "produces a valid route config" $ inTmpObInit $ \tmp -> liftIO $ do
132− configs <- getConfigs
133− withCurrentDirectory (T.unpack $ toTextIgnore tmp) $
132+ withCurrentDirectory (T.unpack $ toTextIgnore tmp) $ do
133+ configs <- getConfigs
134134 return (either (const Nothing) Just $ getConfigRoute configs) `shouldNotReturn` Nothing
135135
136136 -- These tests fail with "Could not find module 'Obelisk.Generated.Static'"
@@ -145,8 +145,7 @@ main = do
145145 it "can build obelisk command" $ inTmpObInit $ \_ -> nixBuild ["-A", "command" , obeliskImpl]
146146 it "can build obelisk skeleton" $ inTmpObInit $ \_ -> nixBuild ["-A", "skeleton", obeliskImpl]
147147 it "can build obelisk shell" $ inTmpObInit $ \_ -> nixBuild ["-A", "shell", obeliskImpl]
148− -- See https://github.com/obsidiansystems/obelisk/issues/101
149− -- it "can build everything" $ shelly_ $ nixBuild [obeliskImpl]
148+ it "can build everything" $ inTmpObInit $ \_ -> nixBuild [obeliskImpl]
150149
151150 describe "blank initialized project" $ parallel $ do
152151
@@ -162,13 +161,10 @@ main = do
162161 forM_ ["ghc", "ghcjs"] $ \compiler -> do
163162 let
164163 shell = "shells." <> compiler
165− inShell cmd' = run "nix-shell" ["-A", fromString shell, "--run", cmd']
164+ inShell cmd' = run "nix-shell" ["default.nix", "-A", fromString shell, "--run", cmd']
166165 it ("can enter " <> shell) $ inTmpObInit $ \_ -> inShell "exit"
167166 it ("can build in " <> shell) $ inTmpObInit $ \_ -> inShell $ "cabal new-build --" <> fromString compiler <> " all"
168167
169− it "can build reflex project" $ inTmpObInit $ \_ -> do
170− nixBuild []
171−
172168 it "has idempotent thunk update" $ inTmpObInit $ \_ -> do
173169 u <- update
174170 uu <- update
release.nix+3−6
@@ -58,6 +58,7 @@ let
5858 (builtins.attrValues ghcjs)
5959 (concatDepends ghc)
6060 (concatDepends ghcjs)
61+ [command serverExeSkeleton iosSkeleton androidSkeleton]
6162 ];
6263 command = local-self.command;
6364 serverExeSkeleton = (import ./skeleton { obelisk = local-self; }).exe;
@@ -77,15 +78,11 @@ let
7778 serverExeSkeleton
7879 iosSkeleton
7980 androidSkeleton;
80− cache = reflex-platform.pinBuildInputs
81− "obelisk-${system}"
82− cachePackages
83− [command serverExeSkeleton iosSkeleton androidSkeleton];
81+ cache = reflex-platform.pinBuildInputs "obelisk-${system}" cachePackages;
8482 });
8583
8684 metaCache = local-self.pinBuildInputs
8785 "obelisk-everywhere"
88− (map (a: a.cache) (builtins.attrValues perPlatform))
89− [];
86+ (map (a: a.cache) (builtins.attrValues perPlatform));
9087
9188in perPlatform // { inherit metaCache; }
skeleton/backend/src/Backend.hs−2
@@ -1,6 +1,4 @@
1−{-# LANGUAGE EmptyCase #-}
21{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE LambdaCase #-}
42{-# LANGUAGE RankNTypes #-}
53{-# LANGUAGE TypeFamilies #-}
64module Backend where
skeleton/common/src/Common/Route.hs+4−6
@@ -1,15 +1,13 @@
11{-# LANGUAGE EmptyCase #-}
22{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE FlexibleInstances #-}
34{-# LANGUAGE GADTs #-}
4−{-# LANGUAGE LambdaCase #-}
5−{-# LANGUAGE RankNTypes #-}
6−{-# LANGUAGE TemplateHaskell #-}
75{-# LANGUAGE KindSignatures #-}
8−{-# LANGUAGE EmptyCase #-}
6+{-# LANGUAGE LambdaCase #-}
97{-# LANGUAGE MultiParamTypeClasses #-}
10−{-# LANGUAGE FlexibleInstances #-}
118{-# LANGUAGE OverloadedStrings #-}
12−
9+{-# LANGUAGE RankNTypes #-}
10+{-# LANGUAGE TemplateHaskell #-}
1311module Common.Route where
1412
1513{- -- You will probably want these imports for composing Encoders.
skeleton/default.nix+6−6
@@ -1,10 +1,10 @@
11{ obelisk ? import ./.obelisk/impl {
2− system = builtins.currentSystem;
3− iosSdkVersion = "10.2";
4− # You must accept the Android Software Development Kit License Agreement at
5− # https://developer.android.com/studio/terms in order to build Android apps.
6− # Uncomment and set this to `true` to indicate your acceptance:
7− # config.android_sdk.accept_license = false;
2+ system = builtins.currentSystem;
3+ iosSdkVersion = "10.2";
4+ # You must accept the Android Software Development Kit License Agreement at
5+ # https://developer.android.com/studio/terms in order to build Android apps.
6+ # Uncomment and set this to `true` to indicate your acceptance:
7+ # config.android_sdk.accept_license = false;
88 }
99}:
1010with obelisk;
skeleton/frontend/src/Frontend.hs+1−1
@@ -22,7 +22,7 @@ frontend = Frontend
2222 el "p" $ text $ T.pack commonStuff
2323 elAttr "img" ("src" =: static @"obelisk.jpg") blank
2424 el "div" $ do
25− exampleConfig <- getConfig "common/example"
25+ exampleConfig <- getConfig "common/example"
2626 case exampleConfig of
2727 Nothing -> text "No config file found in config/common/example"
2828 Just s -> text (T.decodeUtf8 s)
skeleton/shell.nixnew file+1
@@ -0,0 +1 @@
1+(import ./. {}).shells.ghc