packages feed

hablo-1.0.0.0: src/Arguments.hs

module Arguments (
      Arguments(..)
    , get
  ) where

import Data.Monoid ((<>))
import Data.Version (showVersion)
import Control.Applicative ((<|>), (<**>), optional)
import Options.Applicative (Parser, ReadM, argument, auto, eitherReader, execParser, flag', fullDesc, header, help, helper, info, long, metavar, short, str, value)
import qualified Options.Applicative as Optparse (option)
import qualified Paths_hablo as Hablo (version)
import System.FilePath (dropTrailingPathSeparator, isValid)

data Arguments = BlogConfig {
      sourceDir :: FilePath
    , articlesPath :: FilePath
    , bannerPath :: Maybe FilePath
    , cardImage :: Maybe FilePath
    , commentsAt :: Maybe String
    , favicon :: Maybe FilePath
    , headPath :: Maybe FilePath
    , name :: Maybe String
    , pagesPath :: Maybe FilePath
    , previewArticlesCount :: Int
    , previewLinesCount :: Int
    , remarkableConfig :: Maybe FilePath
    , wording :: Maybe FilePath
  }
  | Version

option :: ReadM a -> Char -> String -> String -> String -> Parser (Maybe a)
option readM aShort aLong aMetavar aHelpMessage =
  Optparse.option (optional readM) (
        metavar aMetavar
      <> value Nothing
      <> short aShort
      <> long aLong
      <> help aHelpMessage
    )

blogConfig :: Parser Arguments
blogConfig = BlogConfig
  <$> argument filePath (value "." <> metavar "INPUT_DIR")
  <*> Optparse.option filePath (
          metavar "DIRECTORY"
        <> value "articles"
        <> short 'a'
        <> long "articles"
        <> help "relative path to the directory containing the articles within INPUT_DIR"
      )
  <*> option filePath 'b' "banner" "FILE" "path to the file to use for the blog's banner"
  <*> option filePath 'c' "card-image" "FILE" "relative path to the image to use for the blog's card"
  <*> option filePath 'C' "comments-at" "URL" "url of the instance where comments are stored"
  <*> option filePath 'f' "favicon" "FILE" "path to the image to use for the blog's favicon"
  <*> option filePath 'H' "head" "FILE" "path to the file to add in the blog's head"
  <*> option str 'n' "name" "BLOG_NAME" "name of the blog"
  <*> option filePath 'p' "pages"
        "DIRECTORY" "relative path to the directory containing the pages within INPUT_DIR"
  <*> Optparse.option auto (
          metavar "INTEGER"
        <> value 3
        <> short 'A'
        <> long "preview-articles"
        <> help "number of articles listed on the page of each category"
      )
  <*> Optparse.option auto (
          metavar "INTEGER"
        <> value 10
        <> short 'L'
        <> long "preview-lines"
        <> help "number of lines to display in articles preview"
      )
  <*> option filePath 'r' "remarkable-config" "FILE"
        "path to a file containing a custom RemarkableJS configuration"
  <*> option filePath 'w' "wording" "FILE" "path to the file containing the wording to use"

version :: Parser Arguments
version = flag' Version (
      long "version"
    <> short 'v'
    <> help "print the version number"
  )

arguments :: Parser Arguments
arguments = blogConfig <|> version

filePath :: ReadM FilePath
filePath = eitherReader $ \path ->
  if isValid path
    then Right $ dropTrailingPathSeparator path
    else Left "This string doesn't represent a valid path"

get :: IO Arguments
get = do
  execParser $
    info
      (arguments <**> helper)
      (fullDesc <> header ("Hablo v" ++ showVersion Hablo.version))