@@ -8,12 +8,13 @@ module Main
8import Control.Arrow (first)
8import Control.Arrow (first)
9import Control.Monad (forM_)
9import Control.Monad (forM_)
10import Data.Char (isAlphaNum, isNumber)
10import Data.Char (isAlphaNum, isNumber)
11+import Data.List (foldl')
11import Data.List (intercalate)
12import Data.List (intercalate)
12−import Data.Version (Version(..))
13+import Data.Version (Version (..))
13−import System.Directory (copyFile, canonicalizePath)
14+import System.Directory (canonicalizePath, copyFile)
14import System.Environment (getArgs, getProgName)
15import System.Environment (getArgs, getProgName)
15import System.Exit (exitFailure)
16import System.Exit (exitFailure)
16−import System.FilePath ((</>), splitDirectories)
17+import System.FilePath (splitDirectories, (</>))
19--------------------------------------------------------------------------------
20--------------------------------------------------------------------------------
@@ -37,38 +38,25 @@ main = do
37 putStrLn $ "Creating " ++ dst
38 putStrLn $ "Creating " ++ dst
38 makeDirectories dst
39 makeDirectories dst
39 copyFile src dst
40 copyFile src dst
40− -- canonicalizePath is safe because the destination
41+
41− -- directory should exist at this point
42+ name <- makeName dstDir
42− canonicalizePath dstDir >>= createCabal
43+ let cabalPath = dstDir </> name ++ ".cabal"
44+ putStrLn $ "Creating " ++ cabalPath
45+ createCabal cabalPath name
44 putStrLn $ "Usage: " ++ progName ++ " <directory>"
47 putStrLn $ "Usage: " ++ progName ++ " <directory>"
45 exitFailure
48 exitFailure
47−
50+-- | Figure out a good cabal package name from the given (existing) directory
48−createCabal :: FilePath -> IO ()
52+makeName :: FilePath -> IO String
49−createCabal dstDir = do
53+makeName dstDir = do
50− putStrLn $ "Creating " ++ name ++ ".cabal"
54+ canonical <- canonicalizePath dstDir
51− writeFile (dstDir </> name ++ ".cabal") $ unlines [
55+ return $ case safeLast (splitDirectories canonical) of
52− "name: " ++ name
56+ Nothing -> fallbackName
53− , "version: 0.1.0.0"
57+ Just "/" -> fallbackName
54− , "build-type: Simple"
58+ Just x -> repair (fallbackName ++) id x
55− , "cabal-version: >= 1.10"
58− , " main-is: site.hs"
59− , " build-depends: base == 4.*"
60− , " , hakyll == " ++ version' ++ ".*"
61− , " ghc-options: -threaded"
62− , " default-language: Haskell2010"
65− -- Major hakyll version
66− version' = intercalate "." . take 2 . map show $ versionBranch version
67− -- last is safe here as the path is canonicalised and "/" is just
68− -- a very rare but possible corner case
69− name = case last (splitDirectories dstDir) of
71− x -> repair (fallbackName ++) id x
72 -- Package name repair code comes from
60 -- Package name repair code comes from
73 -- cabal-install.Distribution.Client.Init.Heuristics
61 -- cabal-install.Distribution.Client.Init.Heuristics
74 repair invalid valid x = case dropWhile (not . isAlphaNum) x of
62 repair invalid valid x = case dropWhile (not . isAlphaNum) x of
@@ -79,3 +67,24 @@ createCabal dstDir = do
79 | otherwise = valid c
67 | otherwise = valid c
80 repairRest = repair id ('-' :)
68 repairRest = repair id ('-' :)
81 fallbackName = "site"
69 fallbackName = "site"
71+ safeLast = foldl' (\_ x -> Just x) Nothing
73+createCabal :: FilePath -> String -> IO ()
74+createCabal path name = do
75+ writeFile (path ++ ".cabal") $ unlines [
78+ , "build-type: Simple"
79+ , "cabal-version: >= 1.10"
82+ , " main-is: site.hs"
83+ , " build-depends: base == 4.*"
84+ , " , hakyll == " ++ version' ++ ".*"
85+ , " ghc-options: -threaded"
86+ , " default-language: Haskell2010"
89+ -- Major hakyll version
90+ version' = intercalate "." . take 2 . map show $ versionBranch version