init-haskell-project/init-haskell-project.sh
2013-11-15 00:25:55 +01:00

250 lines
6.5 KiB
Bash
Executable file

#!/usr/bin/env zsh
answer=""
ask(){
local elem=$1
local gitconfigelem
print -n -- "What is your $elem?"
[[ -e ~/.gitconfig ]] && {
gitconfigelem="$(< ~/.gitconfig| awk '$1 == "'$elem'" {$1="";$2="";gsub("^ *","");print}')"
[[ $gitconfigelem = "" ]] || {
print -n -- " ($gitconfigelem)"
}
}
print -n ": "
read answer
[[ $answer = "" ]] && answer=$gitconfigelem
}
print -n -- "What is the name of your project? (start with a capital)"
read project
err(){print -- $*>&2;exit 1}
[[ $project = "" ]] && err "Can't use empty project name"
[[ -e $project ]] && err "$project already exists"
ask name
name="$answer"
ask email
email="$answer"
print -n -- "A short description of the project: "
read description
print -n -- "What is your github user name? "
read github
mkdir $project
cd $project
git init .
print -- ".gitignore"
>.gitignore cat <<END
.cabal-sandbox
cabal.sandbox.config
dist
*.swp
*~
.ghci
END
print -- "$project.cabal"
> $project.cabal cat <<END
-- Initial $project.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: $project
version: 0.1.0.0
synopsis: $description
-- description:
homepage: http://github.com/$github/$project
license: MIT
license-file: LICENSE
author: $name
maintainer: $email
-- copyright:
category: Unknown
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
executable yml
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >=4.6 && <4.7
hs-source-dirs: src
ghc-options: -Wall
default-language: Haskell2010
library
exposed-modules: $project
, $project.Foo
, $project.Bar
-- other-modules:
-- other-extensions:
build-depends: base >=4.6 && <4.7
ghc-options: -Wall
hs-source-dirs: src
default-language: Haskell2010
executable test-yml
hs-source-dirs: test
ghc-options: -Wall
main-is: Test.hs
default-language: Haskell2010
build-depends: base ==4.6.*, Cabal >= 1.16.0
, $project
, HUnit
, QuickCheck
, smallcheck
, tasty
, tasty-hunit
, tasty-quickcheck
, tasty-smallcheck
test-suite Tests
hs-source-dirs: test
ghc-options: -Wall
main-is: Test.hs
Type: exitcode-stdio-1.0
default-language: Haskell2010
build-depends: base ==4.6.*, Cabal >= 1.16.0
, vector
, $project
, HUnit
, QuickCheck
, smallcheck
, tasty
, tasty-hunit
, tasty-quickcheck
, tasty-smallcheck
END
print -- "Setup.hs"
> Setup.hs cat <<END
import Distribution.Simple
main = defaultMain
END
print -- "LICENSE"
> LICENSE cat<<END
The MIT License (MIT)
Copyright (c) $(date +%Y) $name
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
END
mkdir src test
print -- "test/Test.hs"
> test/Test.hs cat <<END
module Main where
import Test.Tasty (defaultMain,testGroup,TestTree)
import $project.Foo.Test
import $project.Bar.Test
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests = testGroup "All Tests"
[ fooSuite
, barSuite
]
END
mkdir -p src/$project
mkdir -p test/$project/{Foo,Bar}
print -- "test/$project/Foo/Test.hs"
> test/$project/Foo/Test.hs cat <<END
module $project.Foo.Test
(fooSuite)
where
import Test.Tasty (testGroup, TestTree)
import Test.Tasty.HUnit
import $project.Foo.Test
datasetSuite :: TestTree
datasetSuite = testGroup "Foo"
[testCase "foo test" testFoo]
testFoo :: Assertion
testFoo = "something" @=? foo "some" "thing"
END
print -- "src/$project/Foo.hs"
> src/$project/Foo.hs cat <<END
module $project.Foo (foo) where
foo :: String -> String -> String
foo prefix suffix = prefix ++ suffix
END
print -- "test/$project/Bar/Test.hs"
> test/$project/Bar/Test.hs cat <<END
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module YML.Bar.Test
(barSuite)
where
import Test.Tasty (testGroup, TestTree)
import Test.Tasty.HUnit
import Test.Tasty.SmallCheck as SC
import $project.Bar
-- Make instance of BarDataStruct
-- we simply use consN Constr where N is the arity of Constr (SmallCheck)
-- we also needed the
-- {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
import Test.SmallCheck.Series
instance Monad m => Serial m BarDataStruct where series = cons1 BarDataStruct
-- Now we could test properties with smallcheck on BarDataStruct type.
barSuite :: TestTree
barSuite = testGroup "bar"
[ testCase "bar" testBar
, SC.testProperty "bar property" prop_bar
]
testCost :: Assertion
testCost = bar @=? 10
prop_cost_positive :: Property IO
prop_cost_positive = forAll $ \barStruct -> barfunc barStruct >= 0
END
print -- "src/$project/Bar.hs"
> src/$project/Bar.hs cat <<END
module $project.Bar (bar,barfunc,BarDataStruct(..)) where
data BarDataStruct = BarConstr [Integer]
bar :: Integer
bar = 10
barfunc :: BarDataStruct -> Int
barfunc (BarConstr l) = length l
END
cabal sandbox init
cabal install
cabal test