on master help sign in
Merge branch 'develop' into eac@config-deploy-module
02b7345Elliot Cameron
dep/reflex-platform/github.json+3−3
@@ -1,8 +1,8 @@
1{
1{
2 "owner": "reflex-frp",
2 "owner": "reflex-frp",
3 "repo": "reflex-platform",
3 "repo": "reflex-platform",
4− "branch": "master",
4+ "branch": "develop",
5 "private": false,
5 "private": false,
6− "rev": "5429278830e1555a577f2550e045ce7f7164aa65",
6+ "rev": "2df9a830193f551ff222ac6b0c739c622578ddc0",
7− "sha256": "1lp86cgccmim573rarsjny5vh0ygkfp5afq7006li0k9w2sw2d4c"
7+ "sha256": "17084xqhixk79av0gnjgwkhdigf9zwkd4axb6qp89dyyffy5s3hi"
8}
8}
lib/command/src/Obelisk/Command/Deploy.hs+33−42
@@ -8,22 +8,17 @@ module Obelisk.Command.Deploy where
8
8
9import Control.Lens
9import Control.Lens
10import Control.Monad
10import Control.Monad
11−import Control.Monad.Catch (Exception (displayException), MonadThrow, throwM, try, bracket_)
11+import Control.Monad.Catch (Exception (displayException), MonadThrow, bracket, throwM, try)
12import Control.Monad.IO.Class (liftIO)
12import Control.Monad.IO.Class (liftIO)
13import Data.Aeson (FromJSON, ToJSON, encode, eitherDecode)
13import Data.Aeson (FromJSON, ToJSON, encode, eitherDecode)
14import Data.Bits
14import Data.Bits
15import qualified Data.ByteString.Lazy as BSL
15import qualified Data.ByteString.Lazy as BSL
16import Data.Default
16import Data.Default
17−import qualified Data.HashMap.Strict as HM
18import qualified Data.Map as Map
17import qualified Data.Map as Map
19−import Data.Text (Text)
20import qualified Data.Set as Set
18import qualified Data.Set as Set
21import qualified Data.Text as T
19import qualified Data.Text as T
22import qualified Data.Text.IO as T
20import qualified Data.Text.IO as T
23import GHC.Generics
21import GHC.Generics
24−import Nix.Pretty
25−import Nix.String (principledMakeNixStringWithoutContext)
26−import Nix.Value
27import System.Directory
22import System.Directory
28import System.FilePath
23import System.FilePath
29import System.IO
24import System.IO
@@ -180,20 +175,6 @@ deployPush deployPath getNixBuilders = do
180deployUpdate :: MonadObelisk m => FilePath -> m ()
175deployUpdate :: MonadObelisk m => FilePath -> m ()
181deployUpdate deployPath = updateThunkToLatest (ThunkUpdateConfig Nothing (ThunkConfig Nothing)) (deployPath </> "src")
176deployUpdate deployPath = updateThunkToLatest (ThunkUpdateConfig Nothing (ThunkConfig Nothing)) (deployPath </> "src")
182
177
183−keytoolToAndroidConfig :: KeytoolConfig -> HM.HashMap Text (NValue t Identity m)
184−keytoolToAndroidConfig conf =
185− let path = nvPath $ _keytoolConfig_keystore conf
186− fromStr = nvStr . principledMakeNixStringWithoutContext . T.pack
187− storepass = fromStr $ _keytoolConfig_storepass conf
188− alias = fromStr $ _keytoolConfig_alias conf
189− keypass = fromStr $ _keytoolConfig_keypass conf
190− in HM.fromList
191− [ ("storeFile", path)
192− , ("storePassword", storepass)
193− , ("keyAlias", alias)
194− , ("keyPassword", keypass)
195− ]
196−
197data PlatformDeployment = Android | IOS
178data PlatformDeployment = Android | IOS
198 deriving (Show, Eq)
179 deriving (Show, Eq)
199
180
@@ -208,7 +189,7 @@ deployMobile platform mobileArgs = withProjectRoot "." $ \root -> do
208 configDir = root </> "config"
189 configDir = root </> "config"
209 exists <- liftIO $ doesDirectoryExist srcDir
190 exists <- liftIO $ doesDirectoryExist srcDir
210 unless exists $ failWith "ob test should be run inside of a deploy directory"
191 unless exists $ failWith "ob test should be run inside of a deploy directory"
211− nixBuildTarget <- case platform of
192+ (nixBuildTarget, extraArgs) <- case platform of
212 Android -> do
193 Android -> do
213 let keystorePath = root </> "android_keystore.jks"
194 let keystorePath = root </> "android_keystore.jks"
214 keytoolConfPath = root </> "android_keytool_config.json"
195 keytoolConfPath = root </> "android_keytool_config.json"
@@ -232,43 +213,53 @@ deployMobile platform mobileArgs = withProjectRoot "." $ \root -> do
232 checkKeytoolConfExist <- liftIO $ doesFileExist keytoolConfPath
213 checkKeytoolConfExist <- liftIO $ doesFileExist keytoolConfPath
233 unless checkKeytoolConfExist $ failWith "Missing android KeytoolConfig"
214 unless checkKeytoolConfExist $ failWith "Missing android KeytoolConfig"
234 keytoolConfContents <- liftIO $ BSL.readFile keytoolConfPath
215 keytoolConfContents <- liftIO $ BSL.readFile keytoolConfPath
235− liftIO $ print keytoolConfContents
236− releaseKey :: String <- case eitherDecode keytoolConfContents :: Either String KeytoolConfig of
216+ keyArgs <- case eitherDecode keytoolConfContents :: Either String KeytoolConfig of
237 Left err -> failWith $ T.pack err
217 Left err -> failWith $ T.pack err
238− Right conf -> return $
218+ Right conf -> pure [ "--sign"
239− (printNix :: MonadObelisk m => NValue t Identity m -> String) $
219+ , "--store-file", _keytoolConfig_keystore conf
240− nvSet (keytoolToAndroidConfig conf) HM.empty
220+ , "--store-password", _keytoolConfig_storepass conf
221+ , "--key-alias", _keytoolConfig_alias conf
222+ , "--key-password", _keytoolConfig_keypass conf]
241− let expr = mconcat
223+ let expr = unwords
242− [ "with (import ", srcDir, " {});"
224+ [ "with (import ", toNixPath srcDir, " {});"
243− , "android.frontend.override (drv: { "
225+ , "android.frontend.override (drv: {"
244− , "releaseKey = (if builtins.isNull drv.releaseKey then {} else drv.releaseKey) // " <> releaseKey <> "; "
226+ , "isRelease = true;"
227+ , "staticSrc = (passthru.__androidWithConfig ", configDir, ").frontend.staticSrc;"
245 , "assets = (passthru.__androidWithConfig ", configDir, ").frontend.assets;"
228 , "assets = (passthru.__androidWithConfig ", configDir, ").frontend.assets;"
246 , "})"
229 , "})"
247 ]
230 ]
248− return $ Target
231+ return (Target
249 { _target_path = Nothing
232 { _target_path = Nothing
250 , _target_attr = Nothing
233 , _target_attr = Nothing
251 , _target_expr = Just expr
234 , _target_expr = Just expr
252− }
235+ }, keyArgs)
253 IOS -> do
236 IOS -> do
254 let expr = mconcat
237 let expr = mconcat
255− [ "with (import ", srcDir, " {});"
238+ [ "with (import ", toNixPath srcDir, " {});"
256− , "ios.frontend.override (_: { staticSrc = (passthru.__iosWithConfig ", configDir, ").frontend.staticSrc; })"
239+ , "ios.frontend.override (_: { staticSrc = (passthru.__iosWithConfig ", toNixPath configDir, ").frontend.staticSrc; })"
257 ]
240 ]
258− return $ Target
241+ return (Target
259 { _target_path = Nothing
242 { _target_path = Nothing
260 , _target_attr = Nothing
243 , _target_attr = Nothing
261 , _target_expr = Just expr
244 , _target_expr = Just expr
262− }
245+ }, [])
263 result <- nixCmd $ NixCmd_Build $ def
246 result <- nixCmd $ NixCmd_Build $ def
264 & nixBuildConfig_outLink .~ OutLink_None
247 & nixBuildConfig_outLink .~ OutLink_None
265 & nixCmdConfig_target .~ nixBuildTarget
248 & nixCmdConfig_target .~ nixBuildTarget
249+ let mobileArtifact = case platform of
250+ IOS -> "iOS App"
251+ Android -> "Android APK"
266− putLog Notice $ T.pack $ "Your recently built android apk can be found at the following path: " <> show result
252+ putLog Notice $ T.pack $ unwords ["Your recently built", mobileArtifact, "can be found at the following path:", show result]
267− callProcessAndLogOutput (Notice, Error) $ proc (result </> "bin" </> "deploy") mobileArgs
253+ callProcessAndLogOutput (Notice, Error) $ proc (result </> "bin" </> "deploy") (mobileArgs ++ extraArgs)
268 where
254 where
269− withEcho showEcho f = do
255+ withEcho showEcho f = bracket
256+ (do
270− prevEcho <- hGetEcho stdin
257+ prevEcho <- hGetEcho stdin
271− bracket_ (hSetEcho stdin showEcho) (hSetEcho stdin prevEcho) f
258+ hSetEcho stdin showEcho
259+ pure prevEcho
260+ )
261+ (hSetEcho stdin)
262+ (const f)
272
263
273data KeytoolConfig = KeytoolConfig
264data KeytoolConfig = KeytoolConfig
274 { _keytoolConfig_keystore :: FilePath
265 { _keytoolConfig_keystore :: FilePath
@@ -283,7 +274,7 @@ instance ToJSON KeytoolConfig
283createKeystore :: MonadObelisk m => FilePath -> KeytoolConfig -> m ()
274createKeystore :: MonadObelisk m => FilePath -> KeytoolConfig -> m ()
284createKeystore root config = do
275createKeystore root config = do
285 let expr = "with (import " <> toImplDir root <> ").reflex-platform.nixpkgs; pkgs.mkShell { buildInputs = [ pkgs.jdk ]; }"
276 let expr = "with (import " <> toImplDir root <> ").reflex-platform.nixpkgs; pkgs.mkShell { buildInputs = [ pkgs.jdk ]; }"
286− callProcessAndLogOutput (Notice,Notice) $ setCwd (Just root) $ proc "nix-shell" ["default.nix", "-E" , expr, "--run" , keytoolCmd]
277+ callProcessAndLogOutput (Notice,Notice) $ setCwd (Just root) $ proc "nix-shell" ["-E" , expr, "--run" , keytoolCmd]
287 where
278 where
288 keytoolCmd = processToShellString "keytool"
279 keytoolCmd = processToShellString "keytool"
289 [ "-genkeypair", "-noprompt"
280 [ "-genkeypair", "-noprompt"