Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#48] Add configurations, read from the file #59

Merged
merged 5 commits into from
May 25, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change the logic of toml files, refactor coloring
  • Loading branch information
vrom911 committed May 25, 2018
commit f9444fc4ce1d1fd9cae8910a5751daff03a95130
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ Here is the list of the options that could be configured for your needs:
If not specified it would be asked during each run of the `summoner`.
* `bscript` – `true` if you want to include [build script](#build-script) by default,
`false` if you don't. If not specified it would be asked during each run of the `summoner`.
* `lib` – `true` if you want to create `src` folder by default,
* `lib` – `true` if you want to create `src` folder with dummy `Lib.hs` file and library target by default,
`false` if you don't. If not specified it would be asked during each run of the `summoner`.
* `exe` – `true` if you want to create `app` folder by default,
* `exe` – `true` if you want to create `app` folder with dummy `Main.hs` file and executable target by default,
`false` if you don't. If not specified it would be asked during each run of the `summoner`.
* `test` – `true` if you want to create `test` folder by default,
* `test` – `true` if you want to create `test` folder with dummy `Spec.hs` file and test target by default,
`false` if you don't. If not specified it would be asked during each run of the `summoner`.
* `bench` – `true` if you want to create `benchmark` folder by default with `gauge` library usage,
* `bench` – `true` if you want to create `benchmark` folder with `Main.hs` file with dummy `gauge` library usage example by default,
`false` if you don't. If not specified it would be asked during each run of the `summoner`.


See example of [configuration for projects of `Kowainik` organization]().
See example of [configuration for projects of `Kowainik` organization](https://github.com/kowainik/org/blob/master/summoner.toml).


By default the `summoner` will look for the configuration file (`summoner.toml`) in home directory.
Expand Down
8 changes: 6 additions & 2 deletions src/Summoner/Ansi.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ module Summoner.Ansi
, successMessage
, warningMessage
, errorMessage
, infoMessage
, skipMessage
) where

import Data.Semigroup (Semigroup (..))
import Data.Text (Text)
import System.Console.ANSI (Color (Blue, Green, Red, Yellow), ColorIntensity (Vivid),
import System.Console.ANSI (Color (Blue, Cyan, Green, Red, Yellow), ColorIntensity (Vivid),
ConsoleIntensity (BoldIntensity), ConsoleLayer (Foreground),
SGR (Reset, SetColor, SetConsoleIntensity), setSGR)
import System.IO (hFlush, stdout)
Expand Down Expand Up @@ -63,7 +65,9 @@ colorMessage color message = do
T.putStrLn $ " " <> message
reset

errorMessage, warningMessage, successMessage :: Text -> IO ()
errorMessage, warningMessage, successMessage, infoMessage, skipMessage :: Text -> IO ()
errorMessage = colorMessage Red
warningMessage = colorMessage Yellow
successMessage = colorMessage Green
infoMessage = colorMessage Blue
skipMessage = colorMessage Cyan
37 changes: 24 additions & 13 deletions src/Summoner/CLI.hs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TupleSections #-}

-- | This module contains functions and data types to parse CLI inputs.

module Summoner.CLI
( summon
) where

import Data.Foldable (fold)
import Data.Foldable (fold, for_)
import Data.Semigroup (Semigroup (..))
import Data.Text (Text)
import NeatInterpolation (text)
import Options.Applicative (Parser, ParserInfo, command, execParser, flag, fullDesc, help, helper,
info, infoFooter, infoHeader, long, metavar, optional, progDesc, short,
strArgument, strOption, subparser)
import Options.Applicative.Help.Chunk (stringChunk)
import System.Directory (doesFileExist, getHomeDirectory)
import System.FilePath ((</>))
import System.Directory (doesFileExist)
import System.Exit (exitFailure)

import Summoner.Ansi (boldText)
import Summoner.Ansi (boldText, errorMessage, infoMessage, warningMessage)
import Summoner.Config (ConfigP (..), PartialConfig, defaultConfig, finalise, loadFileConfig)
import Summoner.Default (endLine)
import Summoner.Default (defaultConfigFile, endLine)
import Summoner.Project (generateProject)
import Summoner.ProjectData (Decision (..))
import Summoner.Validation (Validation (..))
Expand All @@ -37,20 +38,30 @@ summon = execParser prsr >>= runWithOptions
-- | Run 'hs-init' with cli options
runWithOptions :: InitOpts -> IO ()
runWithOptions (InitOpts projectName cliConfig maybeFile) = do
file <- case maybeFile of
Nothing -> (</> "summoner.toml") <$> getHomeDirectory
Just x -> pure x
(isDefault, file) <- case maybeFile of
Nothing -> (True,) <$> defaultConfigFile
Just x -> pure (False, x)
isFile <- doesFileExist file
fileConfig <-
if isFile
then loadFileConfig file
else pure mempty
then do
infoMessage $ "Configurations from " <> T.pack file <> " will be used."
loadFileConfig file
else if isDefault
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space here..

then do
warningMessage "Default config file is missing."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can add path defaultTomlFile path to this message just in case. So stupid people won't complain in a way like It says to me that default config file is missing but I don't know where default config file should be.

pure mempty
else do
errorMessage $ "Specified configuration file " <> T.pack file <> " is not found."
exitFailure
-- union all possible configs
let unionConfig = defaultConfig <> fileConfig <> cliConfig
-- get the final config
let finalConfig = case finalise unionConfig of
Failure msgs -> error $ T.unpack $ T.intercalate "\n" msgs
Success c -> c
finalConfig <- case finalise unionConfig of
Failure msgs -> do
for_ msgs $ \msg -> errorMessage msg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can eta-reduce lambda here

exitFailure
Success c -> pure c
-- Generate the project.
generateProject projectName finalConfig

Expand Down
10 changes: 10 additions & 0 deletions src/Summoner/Default.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

module Summoner.Default
( defaultGHC
, defaultTomlFile
, defaultConfigFile
, currentYear
, endLine
) where

import Data.Text (Text)
import Data.Time (getCurrentTime, toGregorian, utctDay)
import System.Directory (getHomeDirectory)
import System.FilePath ((</>))

import Summoner.ProjectData (GhcVer (Ghc822))

Expand All @@ -20,6 +24,12 @@ import qualified Data.Text as T
defaultGHC :: GhcVer
defaultGHC = Ghc822

defaultTomlFile :: String
defaultTomlFile = "summoner.toml"

defaultConfigFile :: IO FilePath
defaultConfigFile = (</> defaultTomlFile) <$> getHomeDirectory

currentYear :: IO Text
currentYear = do
now <- getCurrentTime
Expand Down
12 changes: 6 additions & 6 deletions src/Summoner/Project.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import NeatInterpolation (text)
import System.Info (os)
import System.Process (readProcess)

import Summoner.Ansi (successMessage, warningMessage)
import Summoner.Ansi (infoMessage, skipMessage, successMessage)
import Summoner.Config (Config, ConfigP (..))
import Summoner.Default (currentYear, defaultGHC)
import Summoner.License (License (..), customizeLicense, githubLicenseQueryNames, licenseNames)
Expand All @@ -42,7 +42,7 @@ decisionToBool decision target = case decision of

trueMessage, falseMessage :: Text -> IO Bool
trueMessage target = True <$ successMessage (T.toTitle target <> " will be added to the project")
falseMessage target = False <$ warningMessage (T.toTitle target <> " won't be added to the project")
falseMessage target = False <$ skipMessage (T.toTitle target <> " won't be added to the project")


-- | Generate the project.
Expand Down Expand Up @@ -88,12 +88,12 @@ generateProject projectName Config{..} = do
test <- decisionToBool cTest "tests"
bench <- decisionToBool cBench "benchmarks"

T.putStrLn $ "Supported by 'summoner' GHCs: " <> T.intercalate " " (map showGhcVer supportedGhcVers)
T.putStrLn $ "The project will be created with the latest resolver for default GHC-" <> showGhcVer defaultGHC
testedVersions <- case cGhcVer of
[] -> queryManyRepeatOnFail
parseGhcVer
"Additionally you can specify versions of GHC to test with (space-separated): "
[] -> do
T.putStrLn "Additionally you can specify versions of GHC to test with (space-separated): "
infoMessage $ "Supported by 'summoner' GHCs: " <> T.intercalate " " (map showGhcVer supportedGhcVers)
queryManyRepeatOnFail parseGhcVer
vers -> do
T.putStrLn $ "Also these GHC versions will be added: " <> T.intercalate " " (map showGhcVer vers)
pure vers
Expand Down
9 changes: 4 additions & 5 deletions src/Summoner/Question.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Data.Text (Text)
import System.Directory (doesPathExist, getCurrentDirectory)
import System.FilePath ((</>))

import Summoner.Ansi (boldDefault, errorMessage, prompt, putStrFlush)
import Summoner.Ansi (boldDefault, errorMessage, prompt, putStrFlush, warningMessage)

import qualified Data.Text as T
import qualified Data.Text.IO as T
Expand Down Expand Up @@ -63,9 +63,8 @@ queryDef question defAnswer = do
if | T.null answer -> pure defAnswer
| otherwise -> pure answer

queryManyRepeatOnFail :: forall a . (Text -> Maybe a) -> Text -> IO [a]
queryManyRepeatOnFail parser question = do
T.putStrLn question
queryManyRepeatOnFail :: forall a . (Text -> Maybe a) -> IO [a]
queryManyRepeatOnFail parser = do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need do here and you can put promptLoop on the same line as queryManyRepeatOnFail

promptLoop
where
promptLoop :: IO [a]
Expand Down Expand Up @@ -97,7 +96,7 @@ checkUniqueName nm = do
curPath <- getCurrentDirectory
exist <- doesPathExist $ curPath </> T.unpack nm
if exist then do
errorMessage "Project with this name is already exist. Please choose another one"
warningMessage "Project with this name is already exist. Please choose another one"
newNm <- query "Project name: "
checkUniqueName newNm
else
Expand Down
2 changes: 1 addition & 1 deletion src/Summoner/Template.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ createStackTemplate
build-type: Simple
extra-doc-files: README.md
cabal-version: 1.24
testedWith: $testedGhcs
tested-with: $testedGhcs
$endLine
|]

Expand Down