{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE RecordWildCards #-} module Emanote.CLI ( Cli (..), Cmd (..), parseCli, cliParser, ) where import Data.Text qualified as T import Data.Version (showVersion) import Ema.CLI qualified import Options.Applicative hiding (action) import Paths_emanote qualified import Relude import UnliftIO.Directory (getCurrentDirectory) data Cli = Cli { Cli -> NonEmpty String layers :: NonEmpty FilePath, Cli -> Bool allowBrokenLinks :: Bool, Cli -> Cmd cmd :: Cmd } data Cmd = Cmd_Ema Ema.CLI.Cli | Cmd_Export cliParser :: FilePath -> Parser Cli cliParser :: String -> Parser Cli cliParser String cwd = do NonEmpty String layers <- NonEmpty String -> Parser (NonEmpty String) pathList (OneItem (NonEmpty String) -> NonEmpty String forall x. One x => OneItem x -> x one String OneItem (NonEmpty String) cwd) Bool allowBrokenLinks <- Mod FlagFields Bool -> Parser Bool switch (String -> Mod FlagFields Bool forall (f :: Type -> Type) a. HasName f => String -> Mod f a long String "allow-broken-links" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool forall a. Semigroup a => a -> a -> a <> String -> Mod FlagFields Bool forall (f :: Type -> Type) a. String -> Mod f a help String "Report but do not fail on broken links") Cmd cmd <- (Cli -> Cmd) -> Parser Cli -> Parser Cmd forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b fmap Cli -> Cmd Cmd_Ema Parser Cli Ema.CLI.cliParser Parser Cmd -> Parser Cmd -> Parser Cmd forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a <|> Mod CommandFields Cmd -> Parser Cmd forall a. Mod CommandFields a -> Parser a subparser (String -> ParserInfo Cmd -> Mod CommandFields Cmd forall a. String -> ParserInfo a -> Mod CommandFields a command String "export" (Parser Cmd -> InfoMod Cmd -> ParserInfo Cmd forall a. Parser a -> InfoMod a -> ParserInfo a info (Cmd -> Parser Cmd forall (f :: Type -> Type) a. Applicative f => a -> f a pure Cmd Cmd_Export) (String -> InfoMod Cmd forall a. String -> InfoMod a progDesc String "Export metadata JSON"))) pure Cli :: NonEmpty String -> Bool -> Cmd -> Cli Cli {Bool NonEmpty String Cmd cmd :: Cmd allowBrokenLinks :: Bool layers :: NonEmpty String cmd :: Cmd allowBrokenLinks :: Bool layers :: NonEmpty String ..} where pathList :: NonEmpty String -> Parser (NonEmpty String) pathList NonEmpty String defaultPath = do ReadM (NonEmpty String) -> Mod OptionFields (NonEmpty String) -> Parser (NonEmpty String) forall a. ReadM a -> Mod OptionFields a -> Parser a option ReadM (NonEmpty String) pathListReader (Mod OptionFields (NonEmpty String) -> Parser (NonEmpty String)) -> Mod OptionFields (NonEmpty String) -> Parser (NonEmpty String) forall a b. (a -> b) -> a -> b $ [Mod OptionFields (NonEmpty String)] -> Mod OptionFields (NonEmpty String) forall a. Monoid a => [a] -> a mconcat [ String -> Mod OptionFields (NonEmpty String) forall (f :: Type -> Type) a. HasName f => String -> Mod f a long String "layers", Char -> Mod OptionFields (NonEmpty String) forall (f :: Type -> Type) a. HasName f => Char -> Mod f a short Char 'L', String -> Mod OptionFields (NonEmpty String) forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a metavar String "LAYERS", NonEmpty String -> Mod OptionFields (NonEmpty String) forall (f :: Type -> Type) a. HasValue f => a -> Mod f a value NonEmpty String defaultPath, String -> Mod OptionFields (NonEmpty String) forall (f :: Type -> Type) a. String -> Mod f a help String "List of (semicolon delimited) notebook folders to 'union mount', with the left-side folders being overlaid on top of the right-side ones. The default layer is implicitly included at the end of this list." ] pathListReader :: ReadM (NonEmpty FilePath) pathListReader :: ReadM (NonEmpty String) pathListReader = (String -> Maybe (NonEmpty String)) -> ReadM (NonEmpty String) forall a. (String -> Maybe a) -> ReadM a maybeReader ((String -> Maybe (NonEmpty String)) -> ReadM (NonEmpty String)) -> (String -> Maybe (NonEmpty String)) -> ReadM (NonEmpty String) forall a b. (a -> b) -> a -> b $ \String paths -> [String] -> Maybe (NonEmpty String) forall a. [a] -> Maybe (NonEmpty a) nonEmpty ([String] -> Maybe (NonEmpty String)) -> [String] -> Maybe (NonEmpty String) forall a b. (a -> b) -> a -> b $ (Text -> String) -> [Text] -> [String] forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b fmap Text -> String forall a. ToString a => a -> String toString ([Text] -> [String]) -> [Text] -> [String] forall a b. (a -> b) -> a -> b $ (Char -> Bool) -> Text -> [Text] T.split (Char -> Char -> Bool forall a. Eq a => a -> a -> Bool == Char ';') (Text -> [Text]) -> (String -> Text) -> String -> [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Text forall a. ToText a => a -> Text toText (String -> [Text]) -> String -> [Text] forall a b. (a -> b) -> a -> b $ String paths parseCli' :: FilePath -> ParserInfo Cli parseCli' :: String -> ParserInfo Cli parseCli' String cwd = Parser Cli -> InfoMod Cli -> ParserInfo Cli forall a. Parser a -> InfoMod a -> ParserInfo a info (Parser (Cli -> Cli) forall {a}. Parser (a -> a) versionOption Parser (Cli -> Cli) -> Parser Cli -> Parser Cli forall (f :: Type -> Type) a b. Applicative f => f (a -> b) -> f a -> f b <*> String -> Parser Cli cliParser String cwd Parser Cli -> Parser (Cli -> Cli) -> Parser Cli forall (f :: Type -> Type) a b. Applicative f => f a -> f (a -> b) -> f b <**> Parser (Cli -> Cli) forall {a}. Parser (a -> a) helper) ( InfoMod Cli forall a. InfoMod a fullDesc InfoMod Cli -> InfoMod Cli -> InfoMod Cli forall a. Semigroup a => a -> a -> a <> String -> InfoMod Cli forall a. String -> InfoMod a progDesc String "Emanote - A spiritual successor to Neuron" InfoMod Cli -> InfoMod Cli -> InfoMod Cli forall a. Semigroup a => a -> a -> a <> String -> InfoMod Cli forall a. String -> InfoMod a header String "Emanote" ) where versionOption :: Parser (a -> a) versionOption = String -> Mod OptionFields (a -> a) -> Parser (a -> a) forall a. String -> Mod OptionFields (a -> a) -> Parser (a -> a) infoOption (Version -> String showVersion Version Paths_emanote.version) (String -> Mod OptionFields (a -> a) forall (f :: Type -> Type) a. HasName f => String -> Mod f a long String "version" Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a) forall a. Semigroup a => a -> a -> a <> String -> Mod OptionFields (a -> a) forall (f :: Type -> Type) a. String -> Mod f a help String "Show version") parseCli :: IO Cli parseCli :: IO Cli parseCli = ParserInfo Cli -> IO Cli forall a. ParserInfo a -> IO a execParser (ParserInfo Cli -> IO Cli) -> (String -> ParserInfo Cli) -> String -> IO Cli forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> ParserInfo Cli parseCli' (String -> IO Cli) -> IO String -> IO Cli forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b =<< IO String forall (m :: Type -> Type). MonadIO m => m String getCurrentDirectory