From eae90867872bcd3d15db355fb5d1e7d5177243e7 Mon Sep 17 00:00:00 2001 From: Dmitry Kovanikov Date: Thu, 18 Jan 2018 20:09:31 +0300 Subject: [PATCH 1/3] [#45] Add support for AppVeyor CI --- CHANGELOG.md | 6 +++++ README.md | 10 ++++---- hs-init.hs | 67 ++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f06a0ca..35bec718 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +1.0.3 +===== + +* [#45](https://github.com/vrom911/hs-init/issues/45): + Support AppVeyor CI for created projects. + 1.0.2 ===== diff --git a/README.md b/README.md index 1e112a06..252c9296 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build status](https://secure.travis-ci.org/vrom911/hs-init.svg)](http://travis-ci.org/vrom911/hs-init) [![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/vrom911/hs-init/blob/master/LICENSE) -[![Version 1.0.2](https://img.shields.io/badge/version-v1.0.2-fabfff.svg)](https://github.com/vrom911/hs-init/blob/master/CHANGELOG.md) +[![Version 1.0.2](https://img.shields.io/badge/version-v1.0.3-fabfff.svg)](https://github.com/vrom911/hs-init/blob/master/CHANGELOG.md) This is tool for creating completely configured production Haskell projects. Consider that this script is using [`Stack`](http://haskellstack.org) for @@ -63,7 +63,8 @@ Available commands: Available command options: -g, --github Github integration - -c, --ci CI integration (Travis CI) + -c, --travis Travis CI integration + -w, --app-veyor AppVeyor CI integration -s, --script Build script -l, --library Library target -e, --exec Executable target @@ -79,11 +80,11 @@ the question will be asked during the work of the script. For example, ``` - hs-init newProject on -letgcsp off -b + hs-init newProject on -letgcspw off -b ``` will create fully functional project with library, executable file, tests, [build script](#build-script) and create private repository on [github](https://github.com) -integrated with `Travis-CI`, but benchmarks won't be attached to this one. +integrated with `Travis-CI`, `AppVeyor-CI`, but benchmarks won't be attached to this one. But when calling this command @@ -123,6 +124,7 @@ PROJECT_NAME ├── README.md ├── Setup.hs ├── stack.yaml +├── appveyor.yml ├── .git ├── .gitignore └── .travis.yml diff --git a/hs-init.hs b/hs-init.hs index 556147cc..bd93d17f 100755 --- a/hs-init.hs +++ b/hs-init.hs @@ -143,7 +143,8 @@ generateProject repo owner description Targets{..} = do -- Library/Executable/Tests/Benchmarks flags github <- decisionToBool githubFlag "github integration" - ci <- ifGithub github "CI integration" ciFlag + travis <- ifGithub github "Travis CI integration" travisFlag + appVey <- ifGithub github "AppVeyor CI integration" appVeyorFlag privat <- ifGithub github "Private repository" privateFlag script <- decisionToBool scriptFlag "build script" isLib <- decisionToBool isLibrary "library target" @@ -211,7 +212,8 @@ instance Monoid Decision where data Targets = Targets { githubFlag :: Decision - , ciFlag :: Decision + , travisFlag :: Decision + , appVeyorFlag :: Decision , privateFlag :: Decision , scriptFlag :: Decision , isLibrary :: Decision @@ -221,11 +223,12 @@ data Targets = Targets } instance Monoid Targets where - mempty = Targets mempty mempty mempty mempty mempty mempty mempty mempty + mempty = Targets mempty mempty mempty mempty mempty mempty mempty mempty mempty mappend t1 t2 = Targets { githubFlag = combine githubFlag - , ciFlag = combine ciFlag + , travisFlag = combine travisFlag + , appVeyorFlag = combine appVeyorFlag , privateFlag = combine privateFlag , scriptFlag = combine scriptFlag , isLibrary = combine isLibrary @@ -243,7 +246,8 @@ data InitOpts = InitOpts Text -- ^ Project name targetsP :: Decision -> Parser Targets targetsP d = do githubFlag <- githubP d - ciFlag <- ciP d + travisFlag <- travisP d + appVeyorFlag <- appVeyorP d privateFlag <- privateP d scriptFlag <- scriptP d isLibrary <- libraryP d @@ -258,11 +262,17 @@ githubP d = flag Idk d <> short 'g' <> help "GitHub integration" -ciP :: Decision -> Parser Decision -ciP d = flag Idk d - $ long "ci" - <> short 'c' - <> help "CI integration" +travisP :: Decision -> Parser Decision +travisP d = flag Idk d + $ long "travis" + <> short 'c' + <> help "Travis CI integration" + +appVeyorP :: Decision -> Parser Decision +appVeyorP d = flag Idk d + $ long "app-veyor" + <> short 'w' + <> help "AppVeyor CI integration" privateP :: Decision -> Parser Decision privateP d = flag Idk d @@ -382,7 +392,8 @@ data ProjectData = ProjectData , license :: Text -- ^ type of license , licenseText :: Text -- ^ license text , github :: Bool -- ^ github repository - , ci :: Bool -- ^ CI integration + , travis :: Bool -- ^ Travis CI integration + , appVey :: Bool -- ^ AppVeyor CI integration , script :: Bool -- ^ build script , isLib :: Bool -- ^ is library , isExe :: Bool -- ^ is executable @@ -571,7 +582,8 @@ createStackTemplate <> createCabalFiles <> readme <> emptyIfNot github gitignore - <> emptyIfNot ci travisYml + <> emptyIfNot travis travisYml + <> emptyIfNot appVey appVeyorYml <> emptyIfNot script scriptSh <> changelog <> createLicense @@ -750,6 +762,7 @@ createStackTemplate [![Hackage]($hackageShield)]($hackageLink) [![Build status](${travisShield})](${travisLink}) + [![Windows build status](${appVeyorShield})](${appVeyorLink}) [![$license license](${licenseShield})](${licenseLink}) $endLine |] @@ -762,6 +775,10 @@ createStackTemplate "https://secure.travis-ci.org/" <> owner <> "/" <> repo <> ".svg" travisLink :: Text = "https://travis-ci.org/" <> owner <> "/" <> repo + appVeyorShield :: Text = + "https://ci.appveyor.com/api/projects/status/github/" <> owner <> "/" <> repo <> "?branch=master&svg=true" + appVeyorLink :: Text = + "https://ci.appveyor.com/project/" <> owner <> "/" <> repo licenseShield :: Text = "https://img.shields.io/badge/license-" <> T.replace "-" "--" license <> "-blue.svg" licenseLink :: Text = @@ -884,6 +901,32 @@ createStackTemplate $endLine |] + -- create appveyor.yml template + appVeyorYml :: Text + appVeyorYml = + [text| + {-# START_FILE appveyor.yml #-} + build: off + + before_test: + # http://help.appveyor.com/discussions/problems/6312-curl-command-not-found + - set PATH=C:\Program Files\Git\mingw64\bin;%PATH% + + - curl -sS -ostack.zip -L --insecure http://www.stackage.org/stack/windows-i386 + - 7z x stack.zip stack.exe + + clone_folder: "c:\\stack" + environment: + global: + STACK_ROOT: "c:\\sr" + + test_script: + - stack setup > nul + # The ugly echo "" hack is to avoid complaints about 0 being an invalid file + # descriptor + - echo "" | stack --no-terminal build --bench --no-run-benchmarks --test + |] + scriptSh :: Text scriptSh = [text| From 91be389edf96ea64be43f01131c575eda5cc1480 Mon Sep 17 00:00:00 2001 From: Dmitry Kovanikov Date: Thu, 18 Jan 2018 21:11:14 +0300 Subject: [PATCH 2/3] Add Semigroup instances for monoids --- hs-init.hs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/hs-init.hs b/hs-init.hs index bd93d17f..9e9720c2 100755 --- a/hs-init.hs +++ b/hs-init.hs @@ -31,7 +31,7 @@ import Data.Aeson (FromJSON (..), decodeStrict, withObject, (.:)) import Data.ByteString.Char8 (pack) import Data.Foldable (fold) import Data.List (nub) -import Data.Semigroup ((<>)) +import Data.Semigroup (Semigroup (..)) import Data.String (IsString (..)) import Data.Text (Text) import Data.Time (getCurrentTime, toGregorian, utctDay) @@ -202,13 +202,15 @@ generateProject repo owner description Targets{..} = do data Decision = Yes | Nop | Idk -instance Monoid Decision where - mempty = Idk +instance Semigroup Decision where + (<>) :: Decision -> Decision -> Decision + Idk <> x = x + x <> Idk = x + _ <> x = x - mappend :: Decision -> Decision -> Decision - mappend Idk x = x - mappend x Idk = x - mappend _ x = x +instance Monoid Decision where + mempty = Idk + mappend = (<>) data Targets = Targets { githubFlag :: Decision @@ -222,10 +224,8 @@ data Targets = Targets , isBenchmark :: Decision } -instance Monoid Targets where - mempty = Targets mempty mempty mempty mempty mempty mempty mempty mempty mempty - - mappend t1 t2 = Targets +instance Semigroup Targets where + t1 <> t2 = Targets { githubFlag = combine githubFlag , travisFlag = combine travisFlag , appVeyorFlag = combine appVeyorFlag @@ -237,7 +237,12 @@ instance Monoid Targets where , isBenchmark = combine isBenchmark } where - combine field = field t1 `mappend` field t2 + combine field = field t1 <> field t2 + +instance Monoid Targets where + mempty = Targets mempty mempty mempty mempty mempty mempty mempty mempty mempty + mappend = (<>) + -- | Initial parsed options from cli data InitOpts = InitOpts Text -- ^ Project name From dd11ac8e09a4e0557d3908625f1390b5693217d2 Mon Sep 17 00:00:00 2001 From: Dmitry Kovanikov Date: Thu, 18 Jan 2018 21:22:07 +0300 Subject: [PATCH 3/3] [#45] Add AppVeyor config for hs-init itself --- README.md | 3 ++- appveyor.yml | 19 +++++++++++++++++++ hs-init.hs | 5 ++++- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 appveyor.yml diff --git a/README.md b/README.md index 252c9296..5f5027b9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # hs-init [![Build status](https://secure.travis-ci.org/vrom911/hs-init.svg)](http://travis-ci.org/vrom911/hs-init) +[![Windows build status](https://ci.appveyor.com/api/projects/status/github/vrom911/hs-init?branch=master&svg=true)](https://ci.appveyor.com/project/vrom911/hs-init) [![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/vrom911/hs-init/blob/master/LICENSE) -[![Version 1.0.2](https://img.shields.io/badge/version-v1.0.3-fabfff.svg)](https://github.com/vrom911/hs-init/blob/master/CHANGELOG.md) +[![Version 1.0.3](https://img.shields.io/badge/version-v1.0.3-fabfff.svg)](https://github.com/vrom911/hs-init/blob/master/CHANGELOG.md) This is tool for creating completely configured production Haskell projects. Consider that this script is using [`Stack`](http://haskellstack.org) for diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..46195b18 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,19 @@ +build: off + +before_test: +# http://help.appveyor.com/discussions/problems/6312-curl-command-not-found +- set PATH=C:\Program Files\Git\mingw64\bin;%PATH% + +- curl -sS -ostack.zip -L --insecure http://www.stackage.org/stack/windows-i386 +- 7z x stack.zip stack.exe + +clone_folder: "c:\\stack" +environment: + global: + STACK_ROOT: "c:\\sr" + +test_script: +- stack setup > nul +# The ugly echo "" hack is to avoid complaints about 0 being an invalid file +# descriptor +- echo "" | stack --no-terminal script --resolver lts-10.3 hs-init.hs -- --help diff --git a/hs-init.hs b/hs-init.hs index 9e9720c2..bf77f02a 100755 --- a/hs-init.hs +++ b/hs-init.hs @@ -45,6 +45,7 @@ import System.Console.ANSI (Color (Blue, Green, Red, Yellow), ColorIntensity (Vi SGR (Reset, SetColor, SetConsoleIntensity), setSGR) import System.Directory (doesPathExist, getCurrentDirectory, setCurrentDirectory) import System.FilePath (()) +import System.IO (hSetEncoding, stdout, utf8) import System.Process (callCommand, readProcess, showCommandForUser) import qualified Data.Text as T @@ -83,7 +84,9 @@ endLine = "\n" ---------------------------------------------------------------------------- main :: IO () -main = execParser prsr >>= runWithOptions +main = do + hSetEncoding stdout utf8 + execParser prsr >>= runWithOptions -- | Run 'hs-init' with cli options runWithOptions :: InitOpts -> IO ()