#!/usr/bin/env zsh autoload colors colors for COLOR in RED GREEN YELLOW BLUE MAGENTA CYAN BLACK WHITE; do eval $COLOR='$fg_no_bold[${(L)COLOR}]' eval BOLD_$COLOR='$fg_bold[${(L)COLOR}]' done eval RESET='$reset_color' # --- Function declaration and global variables answer="" # Capitalize a string capitalize(){ local str="$(print -- "$*" | sed 's/-/ /g')" print -- ${(C)str} | sed 's/ //g' } bk(){print -- "${GREEN}Bridgekeeper: $*${RESET}"} bkn(){print -n -- "${GREEN}Bridgekeeper: $*${RESET}"} you(){print -- "${YELLOW}You: $*${RESET}"} log(){print -- $*} err(){ { case $(( $RANDOM % 1 )); in 0) bk "What... is your favourite colour?" you "Blue. No, yel..." log "[You are thrown over the edge into the volcano]" you "You: Auuuuuuuuuuuugh" bk " Hee hee heh." ;; 1) bk "What is the capital of Assyria?" you "I don't know that!" log "[You are thrown over the edge into the volcano]" you "Auuuuuuuuuuuugh" ;; esac print -- "\n$*" }>&2 exit 1 } # Ask the user for some information # Search in .gitconfig some hints to provide default value ask(){ local elem=$1 local gitconfigelem bkn "What is your $elem?" [[ -e ~/.gitconfig ]] && { gitconfigelem="$(< ~/.gitconfig| awk '$1 == "'$elem'" {$1="";$2="";gsub("^ *","");print}')" [[ $gitconfigelem = "" ]] || { print -n -- " ($gitconfigelem)" } } print -n "\n> ";read answer [[ $answer = "" ]] && answer=$gitconfigelem } # Delete the project directory and show an error message reinit(){ cd .. [[ -e $project ]] && \rm -rf $project err "Something went wrong, I removed the project directory" } # --- Start asking questions bk "Stop!" bk "Who would cross the Bridge of Death" bk "must answer me these questions three," bk "ere the other side he see." you "Ask me the questions, bridgekeeper, I am not afraid.\n" # project name bk "What is the name of your project?" print -n "> ";read project project=${${project:gs/ /-/}:l} # use lowercase and replace spaces by dashes # Verify project has the right format if perl -e 'exit("'$project'" =~ /^[a-z][a-z0-9-]*$/)'; then err "The project must start with a letter and contains only letter, number, spaces or dashes" fi [[ $project = "" ]] && err "Can't use empty project name" [[ -e $project ]] && err "$project directory already exists" # Find the main module name from the project name module=$(capitalize $project) # author name ask name name="$answer" # email ask email email="$answer" # github bkn "What is your github user name?" githubname=( $( curl -sH 'Accept: application/vnd.github.v3.text-match+json' 'https://api.github.com/search/users?q='$email|grep '"login":'|perl -pe 's/.*"([^"]*)",/$1/' ) ) (( ${#githubname} == 1 )) && print -- " ($githubname)" print -n "> ";read github [[ $github = "" ]] && github=$githubname # synopsis bk "What is your project in less than ten words?" print -n "> ";read description # --- We start the creation of the project files here mkdir $project cd $project print -- "Initialize git" git init . print -- "Create files" print -- "\t.gitignore" >.gitignore cat < $project.cabal cat <=1.10 executable $project 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: $module , $module.Swallow , $module.Coconut -- other-modules: -- other-extensions: build-depends: base >=4.6 && <4.7 ghc-options: -Wall hs-source-dirs: src default-language: Haskell2010 executable test-$project 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 , $project , HUnit , QuickCheck , smallcheck , tasty , tasty-hunit , tasty-quickcheck , tasty-smallcheck END print -- "\tSetup.hs" > Setup.hs cat < LICENSE cat< test/Test.hs cat < test/$module/Swallow/Test.hs cat < src/$module/Swallow.hs cat < String -> String swallow prefix suffix = prefix ++ suffix END print -- "\ttest/$module/Coconut/Test.hs" > test/$module/Coconut/Test.hs cat < Serial m CoconutDataStruct where series = cons1 CoconutConstr -- Now we could test properties with smallcheck on CoconutDataStruct type. coconutSuite :: TestTree coconutSuite = testGroup "coconut" [ testCase "coconut" testCoconut , SC.testProperty "coconut property" prop_coconut ] testCoconut :: Assertion testCoconut = coconut @=? 10 prop_coconut :: Property IO prop_coconut = forAll $ \coconutStruct -> coconutfunc coconutStruct >= 0 END print -- "\tsrc/$module/Coconut.hs" > src/$module/Coconut.hs cat < Int coconutfunc (CoconutConstr l) = length l END print -- "\tsrc/$module.hs" > "src/$module.hs" cat < "src/Main.hs" cat <