on master help sign in
command: Add CLI option to export GHCi configuration
commite0a4f059b98aa56b5a414f05700ba118b47d87ca authorElliot Cameron <eacameron@gmail.com> dateWed 4 Mar 2020, 01:23 (7 years ago) parent1ecc90f
2 files changed+30−5
lib/command/src/Obelisk/Command.hs+9−1 lib/command/src/Obelisk/Command/Run.hs+21−4
lib/command/src/Obelisk/Command.hs+9−1
@@ -100,6 +100,7 @@ data ObInternal
100100 -- the preprocessor argument syntax is also handled outside
101101 -- optparse-applicative, but it shouldn't ever conflict with another syntax
102102 = ObInternal_ApplyPackages String String String [String]
103+ | ObInternal_ExportGhciConfig
103104 deriving Show
104105
105106obCommand :: ArgsConfig -> Parser ObCommand
@@ -118,8 +119,14 @@ obCommand cfg = hsubparser
118119 text "Hint: To open the documentation you can pipe the output of this command like"
119120 <$$> text "ob doc reflex reflex-dom-core | xargs -n1 xdg-open")
120121 , command "hoogle" $ info (ObCommand_Hoogle <$> shellFlags <*> portOpt 8080) $ progDesc "Run a hoogle server locally for your project's dependency tree"
122+ , command "internal" $ info (ObCommand_Internal <$> internalCommand) $ progDesc "Internal Obelisk commands with unstable APIs"
121123 ])
122124
125+internalCommand :: Parser ObInternal
126+internalCommand = hsubparser $ mconcat
127+ [ command "export-ghci-configuration" $ info (pure ObInternal_ExportGhciConfig) $ progDesc "Export the GHCi configuration used by ob run, etc.; useful for IDE integration"
128+ ]
129+
123130packageNames :: Parser [String]
124131packageNames = some (strArgument (metavar "PACKAGE-NAME..."))
125132
@@ -133,7 +140,7 @@ deployCommand cfg = hsubparser $ mconcat
133140 where
134141 platformP = hsubparser $ mconcat
135142 [ command "android" $ info (pure (Android, [])) mempty
136− , command "ios" $ info ((,) <$> pure IOS <*> (fmap pure $ strArgument (metavar "TEAMID" <> help "Your Team ID - found in the Apple developer portal"))) mempty
143+ , command "ios" $ info ((,) <$> pure IOS <*> fmap pure (strArgument (metavar "TEAMID" <> help "Your Team ID - found in the Apple developer portal"))) mempty
137144 ]
138145
139146 remoteBuilderParser :: Parser (Maybe RemoteBuilder)
@@ -381,6 +388,7 @@ ob = \case
381388 ObCommand_Internal icmd -> case icmd of
382389 ObInternal_ApplyPackages origPath inPath outPath packagePaths -> do
383390 liftIO $ Preprocessor.applyPackages origPath inPath outPath packagePaths
391+ ObInternal_ExportGhciConfig -> liftIO . putStrLn . unlines =<< exportGhciConfig
384392
385393haddockCommand :: [String] -> String
386394haddockCommand pkgs = unwords
lib/command/src/Obelisk/Command/Run.hs+21−4
@@ -115,6 +115,11 @@ runWatch = withProjectRoot "." $ \root -> do
115115 withGhciScript pkgs root $ \dotGhciPath ->
116116 runGhcid root True dotGhciPath pkgs Nothing
117117
118+exportGhciConfig :: MonadObelisk m => m [String]
119+exportGhciConfig = withProjectRoot "." $ \root -> do
120+ pkgs <- fmap toList . parsePackagesOrFail =<< getLocalPkgs root
121+ getGhciSessionSettings pkgs "."
122+
118123-- | Relative paths to local packages of an obelisk project.
119124--
120125-- These are a combination of the obelisk predefined local packages,
@@ -274,7 +279,7 @@ withGhciScript
274279 -> (FilePath -> m ()) -- ^ Action to run with the path to generated temporary .ghci
275280 -> m ()
276281withGhciScript packageInfos pathBase f = do
277− selfExe <- liftIO getExecutablePath
282+ ghciSettings <- getGhciSessionSettings packageInfos pathBase
278283 let
279284 packageNames = Set.fromList $ map _cabalPackageInfo_packageName packageInfos
280285 modulesToLoad = mconcat
@@ -283,9 +288,7 @@ withGhciScript packageInfos pathBase f = do
283288 , [ "Frontend" | "frontend" `Set.member` packageNames ]
284289 ]
285290 dotGhci = unlines
286− -- TODO: Shell escape
287− [ ":set -F -pgmF " <> selfExe <> " -optF " <> preprocessorIdentifier <> " " <> unwords (map (("-optF " <>) . makeRelative pathBase . _cabalPackageInfo_packageFile) packageInfos)
288− , ":set -i" <> intercalate ":" (packageInfos >>= rootedSourceDirs)
291+ [ ":set " <> unwords ghciSettings -- TODO: Shell escape
289292 , if null modulesToLoad then "" else ":load " <> unwords modulesToLoad
290293 , "import qualified Obelisk.Run"
291294 , "import qualified Frontend"
@@ -296,6 +299,20 @@ withGhciScript packageInfos pathBase f = do
296299 liftIO $ writeFile dotGhciPath dotGhci
297300 f dotGhciPath
298301
302+-- | Builds a list of options to pass to ghci or set in .ghci file that configures
303+-- the preprocessor and source includes.
304+getGhciSessionSettings
305+ :: MonadObelisk m
306+ => [CabalPackageInfo] -- ^ List of packages to load into ghci
307+ -> FilePath -- ^ All paths written to the .ghci file will be relative to this path
308+ -> m [String]
309+getGhciSessionSettings packageInfos pathBase = do
310+ selfExe <- liftIO getExecutablePath
311+ -- TODO: Shell escape
312+ pure
313+ $ ["-F", "-pgmF", selfExe, "-optF", preprocessorIdentifier]
314+ <> concatMap (\p -> ["-optF", makeRelative pathBase $ _cabalPackageInfo_packageFile p]) packageInfos
315+ <> [ "-i" <> intercalate ":" (packageInfos >>= rootedSourceDirs) ]
299316 where
300317 rootedSourceDirs pkg = NE.toList $
301318 makeRelative pathBase . (_cabalPackageInfo_packageRoot pkg </>) <$> _cabalPackageInfo_sourceDirs pkg