packages feed

elm-init 1.0.0.0 → 1.0.0.1

raw patch · 5 files changed

+240/−2 lines, 5 files

Files

elm-init.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                elm-init-version:             1.0.0.0+version:             1.0.0.1 synopsis:            Set up basic structure for an elm project description:   Initialize a new empty elm project with some basic scaffolding according to 'https://github.com/evancz/elm-architecture-tutorial'.@@ -28,7 +28,11 @@  executable elm-init   main-is:             Main.hs-  -- other-modules:+  other-modules:+    ElmInit+    ElmInit.Types+    ElmInit.Interact+    ElmInit.Util   -- other-extensions:   build-depends:       base >=4.8 && <5.0,
+ src/ElmInit.hs view
@@ -0,0 +1,15 @@+module ElmInit+  ( UserDecisions(..)+  , CmdArgs(..)+  , Result+  , askChoices+  , askChoicesWithOther+  , exists+  , verifyElmVersion+  , makePackage+  , flattenMaybe+  ) where++import ElmInit.Interact+import ElmInit.Types+import ElmInit.Util
+ src/ElmInit/Interact.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE OverloadedStrings #-}++module ElmInit.Interact+  ( askChoicesWithOther+  , askChoices+  ) where+++import qualified Control.Arrow            as Arrow (first)+import           Control.Applicative      ((<$>), (<*>))+import           Data.Text                (append)+import           Data.Bool                (bool)+import           ElmInit.Util             (getOr, enumerate)+import           Data.Text                as Text (Text, intercalate, pack)+import           Data.Text.IO             as TextIO (getLine, putStrLn)+import           Prelude                  hiding (getLine, putStrLn)+++askChoices :: Text -> Int -> [Text] -> IO Text+askChoices =+  ((fmap <$> (!!) <*>) .) . askChoices'+++askChoices' :: Text -> Int -> [Text] -> IO Int+askChoices' message selected choices =+  putStrLn message >>+  ask out++  where+    (l1, selectedElem : l2tail) = splitAt selected choices+    out =+      intercalate+        "\n"+        (normFormat 1 l1+          ++ (selectedFormat selected selectedElem : normFormat (selected + 1) l2tail))++    enumF = flip append " )  " . pack . show+    enumFn = append "    " . enumF+    enumFs = append "  * " . enumF+    normFormat = (map (uncurry append . Arrow.first enumFn) .) . enumerate+    selectedFormat x y = (flip append y . enumFs) x++    ask a =+      putStrLn a >>+      getOr selected >>=+        (bool+          (putStrLn "invalid choice, please choose again" >>+          ask a)+          <$> return+          <*> (<= length choices))+++askChoicesWithOther :: Text -> Int -> (Text -> Either Text a) -> [Text] -> IO a+askChoicesWithOther m s trans l =+    askChoices' m s (l ++ ["other (specify)"])+    >>= (flip bool getAlternative+          <$> either (const $ error "No parse") return . trans . (l !!)+          <*> (== length l))++  where+    getAlternative =+      putStrLn "please enter an alternative" >>+      getLine >>=+        (either+          (\message ->+            putStrLn "Invalid input:" >>+            putStrLn message >>+            getAlternative+          )+          return+          . trans)
+ src/ElmInit/Types.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE OverloadedStrings #-}++module ElmInit.Types+  ( Result+  , CmdArgs(..)+  , UserDecisions(..)+  , ElmPackage(..)+  , readVersion+  , makePackage+  , verifyElmVersion+  , readOneVersion+  ) where+++import           Data.Aeson                   as Aeson (ToJSON, object, (.=),+                                              toJSON, Value)+import           Control.Applicative          ((<*>), (<$>))+import           Control.Monad                ((<=<))+import           Data.Version                 (Version(Version), makeVersion,+                                              showVersion, parseVersion)+import           Data.Text                    (pack, Text)+import           Text.ParserCombinators.ReadP (readP_to_S)++++type Result = Either Text ()+++data CmdArgs = CmdArgs { workingDirectory :: FilePath }+++data UserDecisions = Default { projectName  :: Text+                             , sourceFolder :: FilePath+                             , version      :: Version+                             , summary      :: Text+                             , repository   :: Text+                             , license      :: Text+                             , elmVersion   :: Text+                             , mainFileName :: String+                             , addIndex     :: Bool+                             }+++data ElmPackage = ElmPackage { pkgVersion        :: Version+                             , pkgSummary        :: Text+                             , pkgRepository     :: Text+                             , pkgLicense        :: Text+                             , pkgDependencies   :: Aeson.Value+                             , pkgExposedModules :: [Text]+                             , pkgElmVersion     :: Text+                             , pkgSourceDirs     :: [Text]+                             }+++readVersion :: String -> [(Version, String)]+readVersion = readP_to_S parseVersion+++instance Aeson.ToJSON ElmPackage where+  toJSON = object . sequenceA+    [ ("version" .=)          . showVersion . pkgVersion+    , ("summary" .=)          . pkgSummary+    , ("repository" .=)       . pkgRepository+    , ("license" .=)          . pkgLicense+    , ("dependencies" .=)     . pkgDependencies+    , ("exposed-modules" .=)  . pkgExposedModules+    , ("elm-version" .=)      . pkgElmVersion+    , ("source-directories".=). pkgSourceDirs+    ]+++emptyDecisions :: UserDecisions+emptyDecisions =+  Default { summary       = ""+          , repository    = ""+          , version       = makeVersion [0, 0, 0]+          , license       = ""+          , sourceFolder  = ""+          , projectName   = ""+          , elmVersion    = ""+          , mainFileName  = "Main.elm"+          , addIndex      = True+          }+++makePackage :: UserDecisions -> ElmPackage+makePackage = ElmPackage+  <$> version+  <*> summary+  <*> repository+  <*> license+  <*> const (object [("elm-lang/core", "2.0.0 <= v < 3.0.0")])+  <*> const []+  <*> elmVersion+  <*> (:[]) . pack . sourceFolder+++readOneVersion :: String -> Either Text Version+readOneVersion = verif . readVersion+  where+    verif ((v, []):_) = return v+    verif []          = Left "Version must have this structure: 1.2.3"+    verif (_:xs)      = verif xs+++verifyElmVersion :: String -> Either Text Version+verifyElmVersion = hasElmStructure <=< readOneVersion+  where+    hasElmStructure v@(Version [ _, _, _ ] []) = Right v+    hasElmStructure _                          = Left "Version must have this structure: 1.2.3"
+ src/ElmInit/Util.hs view
@@ -0,0 +1,38 @@+module ElmInit.Util+  ( flattenMaybe+  , exists+  , getOr+  , enumerate+  ) where+++import           Control.Applicative ((<$>), (<*>))+import           Data.Maybe          (fromMaybe)+import           Data.Bool           (bool)+import           System.Directory    (doesFileExist, doesDirectoryExist)+import           Control.Exception   (catch, IOException)+++flattenMaybe :: Maybe (Maybe a) -> Maybe a+flattenMaybe = fromMaybe Nothing+++exists :: FilePath -> IO Bool+exists =+  (>>=)+  <$> doesFileExist+  <*> (flip bool+        (return True)+        . doesDirectoryExist)+++getOr :: Read a => a -> IO a+getOr =+  catch readLn . handler+  where+    handler :: a -> IOException -> IO a+    handler = const . return+++enumerate :: Int -> [a] -> [(Int,a)]+enumerate from l = zip [from..(length l)] l