on 6a88430 help sign in
hakyll/src/Hakyll/Init.hs
96 lines 3.7 kB history raw
1--------------------------------------------------------------------------------
2module Main
3 ( main
4 ) where
7--------------------------------------------------------------------------------
8import Control.Arrow (first)
9import Control.Monad (forM_)
10import Data.Char (isAlphaNum, isNumber)
11import Data.List (foldl')
12import Data.List (intercalate, isPrefixOf)
13import Data.Version (Version (..))
14import System.Directory (canonicalizePath, copyFile)
15import System.Environment (getArgs, getProgName)
16import System.Exit (exitFailure)
17import System.FilePath (splitDirectories, (</>))
20--------------------------------------------------------------------------------
21import Hakyll.Core.Util.File
22import Paths_hakyll
25--------------------------------------------------------------------------------
26main :: IO ()
27main = do
28 progName <- getProgName
29 args <- getArgs
30 srcDir <- getDataFileName "example"
31 files <- getRecursiveContents (const $ return False) srcDir
33 case args of
34 -- When the argument begins with hyphens, it's more likely that the user
35 -- intends to attempt some arguments like ("--help", "-h", "--version", etc.)
36 -- rather than create directory with that name.
37 -- If dstDir begins with hyphens, the guard will prevent it from creating
38 -- directory with that name so we can fall to the second alternative
39 -- which prints a usage info for user.
40 [dstDir] | not ("-" `isPrefixOf` dstDir) -> do
41 forM_ files $ \file -> do
42 let dst = dstDir </> file
43 src = srcDir </> file
44 putStrLn $ "Creating " ++ dst
45 makeDirectories dst
46 copyFile src dst
48 name <- makeName dstDir
49 let cabalPath = dstDir </> name ++ ".cabal"
50 putStrLn $ "Creating " ++ cabalPath
51 createCabal cabalPath name
52 _ -> do
53 putStrLn $ "Usage: " ++ progName ++ " <directory>"
54 exitFailure
56-- | Figure out a good cabal package name from the given (existing) directory
57-- name
58makeName :: FilePath -> IO String
59makeName dstDir = do
60 canonical <- canonicalizePath dstDir
61 return $ case safeLast (splitDirectories canonical) of
62 Nothing -> fallbackName
63 Just "/" -> fallbackName
64 Just x -> repair (fallbackName ++) id x
65 where
66 -- Package name repair code comes from
67 -- cabal-install.Distribution.Client.Init.Heuristics
68 repair invalid valid x = case dropWhile (not . isAlphaNum) x of
69 "" -> repairComponent ""
70 x' -> let (c, r) = first repairComponent $ break (not . isAlphaNum) x'
71 in c ++ repairRest r
72 where repairComponent c | all isNumber c = invalid c
73 | otherwise = valid c
74 repairRest = repair id ('-' :)
75 fallbackName = "site"
77 safeLast = foldl' (\_ x -> Just x) Nothing
79createCabal :: FilePath -> String -> IO ()
80createCabal path name = do
81 writeFile path $ unlines [
82 "name: " ++ name
83 , "version: 0.1.0.0"
84 , "build-type: Simple"
85 , "cabal-version: >= 1.10"
86 , ""
87 , "executable site"
88 , " main-is: site.hs"
89 , " build-depends: base == 4.*"
90 , " , hakyll == " ++ version' ++ ".*"
91 , " ghc-options: -threaded"
92 , " default-language: Haskell2010"
93 ]
94 where
95 -- Major hakyll version
96 version' = intercalate "." . take 2 . map show $ versionBranch version