Main.hs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Main where
  3. import qualified Data.Text as T
  4. import Lens.Family
  5. import qualified System.Console.GetOpt as Opt
  6. import qualified System.Environment as Sys
  7. import qualified System.Exit as Sys
  8. import qualified Charter as C
  9. data Option
  10. = AddBinary T.Text
  11. | SetCategory T.Text
  12. | SetSynopsis T.Text
  13. | SetDescription T.Text
  14. | SetLicense T.Text
  15. | SetRoot T.Text
  16. | AddDep T.Text
  17. | AddUsualDeps
  18. deriving (Eq, Show)
  19. options :: [Opt.OptDescr Option]
  20. options =
  21. [ Opt.Option ['b'] ["bin"]
  22. (Opt.ReqArg (AddBinary . T.pack) "PROGRAM NAME")
  23. "Add another binary target to this Cabal file"
  24. , Opt.Option ['r'] ["root"]
  25. (Opt.ReqArg (SetRoot . T.pack) "DIRECTORY")
  26. "Set the root directory for this project"
  27. , Opt.Option ['c'] ["category"]
  28. (Opt.ReqArg (SetCategory . T.pack) "CATEGORY")
  29. "Set the category for this project"
  30. , Opt.Option ['s'] ["synopsis"]
  31. (Opt.ReqArg (SetSynopsis . T.pack) "SYNOPSIS")
  32. "Set the synopsis for this project"
  33. , Opt.Option ['d'] ["description"]
  34. (Opt.ReqArg (SetDescription . T.pack) "DESCRIPTION")
  35. "Set the description for this project"
  36. , Opt.Option ['l'] ["license"]
  37. (Opt.ReqArg (SetLicense . T.pack) "LICENSE")
  38. "Set the license for this project"
  39. , Opt.Option ['a'] ["add-dep"]
  40. (Opt.ReqArg (AddDep . T.pack) "PACKAGE")
  41. "Add a dependency to this application"
  42. , Opt.Option ['A'] ["add-usual-deps"]
  43. (Opt.NoArg AddUsualDeps)
  44. "Add the typical set of dependencies to this application"
  45. ]
  46. usageInfo :: String
  47. usageInfo = Opt.usageInfo header options
  48. where header = "Usage: charter (quick|executable|library) [name]"
  49. process :: [Option] -> C.Project -> C.Project
  50. process opts p = foldr ($) p (map go opts)
  51. where
  52. go (AddBinary n) proj =
  53. proj & C.binDetails %~ (C.mkBinary n :)
  54. go (SetCategory s) proj =
  55. proj & C.projectDetails . C.projectCategory .~ Just s
  56. go (SetSynopsis s) proj =
  57. proj & C.projectDetails . C.projectSynopsis .~ Just s
  58. go (SetDescription s) proj =
  59. proj & C.projectDetails . C.projectDescription .~ Just s
  60. go (SetLicense s) proj =
  61. proj & C.projectDetails . C.projectLicense .~ Just s
  62. go (SetRoot _) proj = proj
  63. go (AddDep dep) proj =
  64. proj & C.binDetails %~ fmap (& C.execDeps %~ (dep :))
  65. & C.libDetails %~ fmap (& C.libDeps %~ (dep :))
  66. go (AddUsualDeps) proj =
  67. proj & C.binDetails %~ fmap (& C.execDeps %~ (C.usualDeps ++))
  68. & C.libDetails %~ fmap (& C.libDeps %~ (C.usualDeps ++))
  69. setupProject :: String -> String -> IO C.Project
  70. setupProject typ name = do
  71. details <- C.projectDefaults (T.pack name)
  72. case typ of
  73. "quick" -> return (C.quickBin details)
  74. "executable" -> return (C.projectBin details)
  75. "library" -> return (C.library details)
  76. _ -> Sys.die ("unknown project type: " ++ typ ++ "\n" ++ usageInfo)
  77. main :: IO ()
  78. main = do
  79. args <- Sys.getArgs
  80. case Opt.getOpt Opt.Permute options args of
  81. (os, [typ, name], []) -> do
  82. proj <- process os <$> setupProject typ name
  83. C.createProject proj
  84. (_, _, errs) -> do
  85. mapM_ putStrLn errs
  86. Sys.die usageInfo