templatise 0.1.1.0 → 0.1.2.0
raw patch · 21 files changed
+501/−45 lines, 21 filesdep ~timePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: time
API changes (from Hackage documentation)
+ Git: root :: IO Text
+ Initialise: defaultInitialiser :: Initialise ()
Files
- .devcontainer/devcontainer.json +36/−0
- .github/workflows/bounds-bump.yml +17/−0
- .github/workflows/dependency-review.yml +20/−0
- .github/workflows/haskell-ci.yml +199/−0
- .github/workflows/pre-commit.yml +17/−0
- .github/workflows/publish.yml +19/−0
- .github/workflows/stale.yml +27/−0
- bin/initialise/Main.hs +3/−16
- lib/initialise/Cabal.hs +2/−2
- lib/initialise/File.hs +1/−1
- lib/initialise/Git.hs +4/−1
- lib/initialise/Initialise.hs +3/−12
- lib/initialise/Initialise/Initialisers.hs +23/−0
- lib/initialise/Initialise/Types.hs +13/−0
- lib/initialise/Licence.hs +2/−2
- templatise.cabal +10/−3
- test/initialise/ConfigurationSpec.hs +21/−3
- test/initialise/DefaultsSpec.hs +6/−1
- test/initialise/Hooks.hs +14/−2
- test/initialise/InitialiseSpec.hs +58/−0
- test/initialise/Main.hs +6/−2
+ .devcontainer/devcontainer.json view
@@ -0,0 +1,36 @@+{+ "name": "template.hs",+ "image": "mcr.microsoft.com/devcontainers/base:ubuntu",+ // Features to add to the dev container. More info: https://containers.dev/features.+ "features": {+ "ghcr.io/devcontainers-contrib/features/haskell:2": {+ "globalPackages": "cabal-fmt ormolu"+ },+ "ghcr.io/devcontainers-contrib/features/pre-commit:2": {},+ "ghcr.io/devcontainers/features/git:1": {},+ "ghcr.io/devcontainers/features/github-cli:1": {}+ },+ // Use 'forwardPorts' to make a list of ports inside the container available locally.+ // "forwardPorts": [],+ // Use 'postCreateCommand' to run commands after the container is created.+ // "postCreateCommand": "",+ // Configure tool-specific properties.+ "customizations": {+ "vscode": {+ "settings": {+ "haskell.manageHLS": "GHCup"+ },+ "extensions": [+ "berberman.vscode-cabal-fmt",+ "DavidAnson.vscode-markdownlint",+ "eamodio.gitlens",+ "github.vscode-github-actions",+ "GitHub.vscode-pull-request-github",+ "haskell.haskell",+ "ms-azuretools.vscode-docker"+ ]+ }+ },+ // Comment out to connect as root instead. To add a non-root user, see: https://aka.ms/vscode-remote/containers/non-root.+ "remoteUser": "vscode"+}
+ .github/workflows/bounds-bump.yml view
@@ -0,0 +1,17 @@+name: Create Dependency Bump PR+on:+ workflow_dispatch:+ schedule:+ - cron: '0 8 * * 4'++permissions:+ contents: write+ pull-requests: write++jobs:+ bump-bounds:+ runs-on: ubuntu-latest+ steps:+ - uses: nomeata/haskell-bounds-bump-action@main+ with:+ test: true
+ .github/workflows/dependency-review.yml view
@@ -0,0 +1,20 @@+# Dependency Review Action+#+# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.+#+# Source repository: https://github.com/actions/dependency-review-action+# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement+name: 'Dependency Review'+on: [pull_request]++permissions:+ contents: read++jobs:+ dependency-review:+ runs-on: ubuntu-latest+ steps:+ - name: 'Checkout Repository'+ uses: actions/checkout@v3+ - name: 'Dependency Review'+ uses: actions/dependency-review-action@v2
+ .github/workflows/haskell-ci.yml view
@@ -0,0 +1,199 @@+# This GitHub workflow config has been generated by a script via+#+# haskell-ci 'github' '--haddock' 'templatise.cabal'+#+# To regenerate the script (for example after adjusting tested-with) run+#+# haskell-ci regenerate+#+# For more information, see https://github.com/haskell-CI/haskell-ci+#+# version: 0.16.3+#+# REGENDATA ("0.16.3",["github","--haddock","templatise.cabal"])+#+name: Haskell-CI+on:+ - push+ - pull_request+jobs:+ linux:+ name: Haskell-CI - Linux - ${{ matrix.compiler }}+ runs-on: ubuntu-20.04+ timeout-minutes:+ 60+ container:+ image: buildpack-deps:bionic+ continue-on-error: ${{ matrix.allow-failure }}+ strategy:+ matrix:+ include:+ - compiler: ghc-9.6.2+ compilerKind: ghc+ compilerVersion: 9.6.2+ setup-method: ghcup+ allow-failure: false+ - compiler: ghc-9.4.5+ compilerKind: ghc+ compilerVersion: 9.4.5+ setup-method: ghcup+ allow-failure: false+ - compiler: ghc-9.2.4+ compilerKind: ghc+ compilerVersion: 9.2.4+ setup-method: ghcup+ allow-failure: false+ fail-fast: false+ steps:+ - name: apt+ run: |+ apt-get update+ apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5+ mkdir -p "$HOME/.ghcup/bin"+ curl -sL https://downloads.haskell.org/ghcup/0.1.19.2/x86_64-linux-ghcup-0.1.19.2 > "$HOME/.ghcup/bin/ghcup"+ chmod a+x "$HOME/.ghcup/bin/ghcup"+ "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)+ "$HOME/.ghcup/bin/ghcup" install cabal 3.10.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)+ env:+ HCKIND: ${{ matrix.compilerKind }}+ HCNAME: ${{ matrix.compiler }}+ HCVER: ${{ matrix.compilerVersion }}+ - name: Set PATH and environment variables+ run: |+ echo "$HOME/.cabal/bin" >> $GITHUB_PATH+ echo "LANG=C.UTF-8" >> "$GITHUB_ENV"+ echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"+ echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"+ HCDIR=/opt/$HCKIND/$HCVER+ HC=$HOME/.ghcup/bin/$HCKIND-$HCVER+ echo "HC=$HC" >> "$GITHUB_ENV"+ echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV"+ echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV"+ echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"+ HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')+ echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"+ echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"+ echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"+ echo "HEADHACKAGE=false" >> "$GITHUB_ENV"+ echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"+ echo "GHCJSARITH=0" >> "$GITHUB_ENV"+ env:+ HCKIND: ${{ matrix.compilerKind }}+ HCNAME: ${{ matrix.compiler }}+ HCVER: ${{ matrix.compilerVersion }}+ - name: env+ run: |+ env+ - name: write cabal config+ run: |+ mkdir -p $CABAL_DIR+ cat >> $CABAL_CONFIG <<EOF+ remote-build-reporting: anonymous+ write-ghc-environment-files: never+ remote-repo-cache: $CABAL_DIR/packages+ logs-dir: $CABAL_DIR/logs+ world-file: $CABAL_DIR/world+ extra-prog-path: $CABAL_DIR/bin+ symlink-bindir: $CABAL_DIR/bin+ installdir: $CABAL_DIR/bin+ build-summary: $CABAL_DIR/logs/build.log+ store-dir: $CABAL_DIR/store+ install-dirs user+ prefix: $CABAL_DIR+ repository hackage.haskell.org+ url: http://hackage.haskell.org/+ EOF+ cat >> $CABAL_CONFIG <<EOF+ program-default-options+ ghc-options: $GHCJOBS +RTS -M3G -RTS+ EOF+ cat $CABAL_CONFIG+ - name: versions+ run: |+ $HC --version || true+ $HC --print-project-git-commit-id || true+ $CABAL --version || true+ - name: update cabal index+ run: |+ $CABAL v2-update -v+ - name: install cabal-plan+ run: |+ mkdir -p $HOME/.cabal/bin+ curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz+ echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -+ xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan+ rm -f cabal-plan.xz+ chmod a+x $HOME/.cabal/bin/cabal-plan+ cabal-plan --version+ - name: checkout+ uses: actions/checkout@v3+ with:+ path: source+ - name: initial cabal.project for sdist+ run: |+ touch cabal.project+ echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project+ cat cabal.project+ - name: sdist+ run: |+ mkdir -p sdist+ $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist+ - name: unpack+ run: |+ mkdir -p unpacked+ find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \;+ - name: generate cabal.project+ run: |+ PKGDIR_templatise="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/templatise-[0-9.]*')"+ echo "PKGDIR_templatise=${PKGDIR_templatise}" >> "$GITHUB_ENV"+ rm -f cabal.project cabal.project.local+ touch cabal.project+ touch cabal.project.local+ echo "packages: ${PKGDIR_templatise}" >> cabal.project+ echo "package templatise" >> cabal.project+ echo " ghc-options: -Werror=missing-methods" >> cabal.project+ cat >> cabal.project <<EOF+ EOF+ $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(templatise)$/; }' >> cabal.project.local+ cat cabal.project+ cat cabal.project.local+ - name: dump install plan+ run: |+ $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all+ cabal-plan+ - name: restore cache+ uses: actions/cache/restore@v3+ with:+ key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}+ path: ~/.cabal/store+ restore-keys: ${{ runner.os }}-${{ matrix.compiler }}-+ - name: install dependencies+ run: |+ $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all+ $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all+ - name: build w/o tests+ run: |+ $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all+ - name: build+ run: |+ $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always+ - name: tests+ run: |+ $CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct+ - name: cabal check+ run: |+ cd ${PKGDIR_templatise} || false+ ${CABAL} -vnormal check+ - name: haddock+ run: |+ $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all+ - name: unconstrained build+ run: |+ rm -f cabal.project.local+ $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all+ - name: save cache+ uses: actions/cache/save@v3+ if: always()+ with:+ key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}+ path: ~/.cabal/store
+ .github/workflows/pre-commit.yml view
@@ -0,0 +1,17 @@+name: pre-commit++on:+ pull_request:+ push:+ branches: [main]++jobs:+ pre-commit:+ runs-on: ubuntu-latest+ steps:+ - uses: actions/checkout@v3+ - uses: actions/setup-python@v3+ - uses: haskell-actions/setup@v2+ with:+ ghc-version: '9.4.7'+ - uses: pre-commit/action@v3.0.0
+ .github/workflows/publish.yml view
@@ -0,0 +1,19 @@+name: Publish to Hackage++on:+ release:+ types: [published]++permissions:+ contents: read++jobs:+ publish:+ runs-on: ubuntu-latest+ steps:+ - uses: actions/checkout@v3+ - uses: haskell-actions/setup@v2+ - name: cabal sdist+ run: cabal sdist+ - name: cabal upload+ run: cabal upload --publish --username=${{ secrets.HACKAGE_USERNAME }} --password=${{ secrets.HACKAGE_PASSWORD }} dist-newstyle/sdist/*.tar.gz
+ .github/workflows/stale.yml view
@@ -0,0 +1,27 @@+# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.+#+# You can adjust the behavior by modifying this file.+# For more information, see:+# https://github.com/actions/stale+name: Mark stale issues and pull requests++on:+ schedule:+ - cron: '18 10 * * *'++jobs:+ stale:++ runs-on: ubuntu-latest+ permissions:+ issues: write+ pull-requests: write++ steps:+ - uses: actions/stale@v5+ with:+ repo-token: ${{ secrets.GITHUB_TOKEN }}+ stale-issue-message: 'Stale issue message'+ stale-pr-message: 'Stale pull request message'+ stale-issue-label: 'no-issue-activity'+ stale-pr-label: 'no-pr-activity'
bin/initialise/Main.hs view
@@ -1,10 +1,10 @@-module Main (main, main') where+module Main (main) where import qualified Cabal (replace) import qualified Configuration (parser) import qualified Defaults (getDefaults) import qualified File (replace)-import Initialise (Initialise, runInitialise)+import Initialise (Initialise, defaultInitialiser, runInitialise) import qualified Licence (replace) import Options.Applicative (execParser, fullDesc, helper, info, progDesc, (<**>)) import System.FilePath ((</>))@@ -25,17 +25,4 @@ ) ) - execParser options >>= runInitialise main'--main' :: Initialise ()-main' = do- mapM_- File.replace- [ ".devcontainer" </> "devcontainer.json",- ".github" </> "workflows" </> "haskell-ci.yml",- "CHANGELOG.md"- ]- Licence.replace "LICENSE"- Cabal.replace "templatise.cabal"---- TODO README+ execParser options >>= runInitialise defaultInitialiser
lib/initialise/Cabal.hs view
@@ -28,7 +28,7 @@ import Distribution.Fields.Field (fieldLineAnn) import Distribution.Parsec.Position (Position) import Distribution.SPDX (licenseId)-import Initialise (Initialise)+import Initialise.Types (Initialise) import System.Directory.Extra (createDirectoryIfMissing, removeDirectoryRecursive, removeFile) import System.FilePath (replaceBaseName, (</>)) import Text.Parsec.Error (ParseError)@@ -46,7 +46,7 @@ replaceCabal :: FilePath -> Initialise () replaceCabal path = do -- TODO handle in replaceWith- path' <- asks (flip replaceBaseName path . T.unpack . name)+ path' <- asks (replaceBaseName path . T.unpack . name) -- TODO replaceWith convert contents <- liftIO $ readFile path contents' <- convert contents
lib/initialise/File.hs view
@@ -8,7 +8,7 @@ import Data.Text (Text) import qualified Data.Text as T (replace) import Data.Text.IO (readFile, writeFile)-import Initialise (Initialise)+import Initialise.Types (Initialise) import Prelude hiding (readFile, writeFile) replace :: FilePath -> Initialise ()
lib/initialise/Git.hs view
@@ -1,7 +1,10 @@-module Git (config) where+module Git (config, root) where import Data.Text (Text, pack, unpack) import System.Process (readProcess) config :: Text -> IO Text config key = pack . head . lines <$> readProcess "git" ["config", unpack key] ""++root :: IO Text+root = pack . head . lines <$> readProcess "git" ["rev-parse", "--show-toplevel"] ""
lib/initialise/Initialise.hs view
@@ -1,13 +1,4 @@-module Initialise- ( Initialise,- runInitialise,- )-where--import Configuration (Configuration)-import Control.Monad.Reader (ReaderT, runReaderT)--type Initialise = ReaderT Configuration IO+module Initialise (Initialise, runInitialise, defaultInitialiser) where -runInitialise :: Initialise a -> Configuration -> IO a-runInitialise = runReaderT+import Initialise.Initialisers+import Initialise.Types
+ lib/initialise/Initialise/Initialisers.hs view
@@ -0,0 +1,23 @@+module Initialise.Initialisers+ ( defaultInitialiser,+ )+where++import qualified Cabal (replace)+import qualified File (replace)+import Initialise.Types+import qualified Licence (replace)+import System.FilePath ((</>))++defaultInitialiser :: Initialise ()+defaultInitialiser = do+ mapM_+ File.replace+ [ ".devcontainer" </> "devcontainer.json",+ ".github" </> "workflows" </> "haskell-ci.yml",+ "CHANGELOG.md"+ ]+ Licence.replace "LICENSE"+ Cabal.replace "templatise.cabal"++-- TODO README
+ lib/initialise/Initialise/Types.hs view
@@ -0,0 +1,13 @@+module Initialise.Types+ ( Initialise,+ runInitialise,+ )+where++import Configuration (Configuration)+import Control.Monad.Reader (ReaderT, runReaderT)++type Initialise = ReaderT Configuration IO++runInitialise :: Initialise a -> Configuration -> IO a+runInitialise = runReaderT
lib/initialise/Licence.hs view
@@ -7,7 +7,7 @@ import Control.Monad.Reader (ask, liftIO) import Data.ByteString.Lazy (ByteString, writeFile) import Distribution.SPDX.LicenseId (LicenseId (Unlicense), licenseId)-import Initialise (Initialise)+import Initialise.Types (Initialise) import Network.HTTP.Client (responseBody) import Network.HTTP.Simple (httpLBS, parseRequest) import System.FilePath ((</>))@@ -17,7 +17,7 @@ replace p = do Configuration {..} <- ask unless (licence == Unlicense) $- liftIO (writeFile (p </> path) =<< contents licence)+ liftIO (writeFile (path </> p) =<< contents licence) contents :: LicenseId -> IO ByteString contents l = do
templatise.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: templatise-version: 0.1.1.0+version: 0.1.2.0 license: Unlicense license-file: LICENSE copyright: (c) 2023 Alex Brandt@@ -26,9 +26,12 @@ || ==9.4.8 || ==9.6.2 || ==9.6.3+ || ==9.6.4 || ==9.8.1 extra-source-files:+ .devcontainer/devcontainer.json+ .github/workflows/*.yml CHANGELOG.md README.md @@ -53,6 +56,7 @@ , optparse-applicative ^>=0.18.1.0 , process ^>=1.6.13.2 , text ^>=1.2.5.0 || ^>=2.0.2 || ^>=2.1+ , time ^>=1.11.1.1 || ^>=1.12.2 || ^>=1.13 library initialise-library import: initialise-common@@ -66,14 +70,16 @@ Licence -- TODO Make Git private.- --other-modules: Git+ other-modules:+ Initialise.Initialisers+ Initialise.Types+ build-depends: , exceptions ^>=0.10.4 , extra ^>=1.7.14 , http-client ^>=0.7.14 , http-conduit ^>=2.3.8.3 , parsec ^>=3.1.15.0- , time ^>=1.11.1.1 || ^>=1.12.2 hs-source-dirs: lib/initialise @@ -104,6 +110,7 @@ FileGolden GitSpec Hooks+ InitialiseSpec hs-source-dirs: test/initialise
test/initialise/ConfigurationSpec.hs view
@@ -6,7 +6,19 @@ import Data.Maybe (fromJust) import Defaults (Defaults (..)) import Network.URI (parseURI)-import Options.Applicative (ParserResult (CompletionInvoked, Failure, Success), defaultPrefs, execParserPure, helper, info, renderFailure, (<**>))+import Options.Applicative+ ( ParserResult+ ( CompletionInvoked,+ Failure,+ Success+ ),+ defaultPrefs,+ execParserPure,+ helper,+ info,+ renderFailure,+ (<**>),+ ) import System.Exit (ExitCode (ExitFailure)) import Test.Hspec (Expectation, Spec, describe, expectationFailure, it, shouldBe) @@ -15,9 +27,15 @@ describe "Configuration" $ do describe "parser" $ do it "should error if homepage isn't a URI" $- parse ["--homepage", "not-a-url"] `shouldFailWith` ("", ExitFailure 1)+ parse ["--homepage", "not-a-url"]+ `shouldFailWith` ( "option --homepage: cannot parse value `not-a-url'\n\nUsage: [--name NAME] [--homepage URL] [--author AUTHOR] \n [--maintainer MAINTAINER] [--licence LICENCE]",+ ExitFailure 1+ ) it "should error if licence isn't an SPDX licence ID" $ do- parse ["--licence", "not-a-licence"] `shouldFailWith` ("", ExitFailure 1)+ parse ["--licence", "not-a-licence"]+ `shouldFailWith` ( "option --licence: cannot parse value `not-a-licence'\n\nUsage: [--name NAME] [--homepage URL] [--author AUTHOR] \n [--maintainer MAINTAINER] [--licence LICENCE]",+ ExitFailure 1+ ) parse :: [String] -> ParserResult SUT.Configuration parse =
test/initialise/DefaultsSpec.hs view
@@ -3,6 +3,8 @@ module DefaultsSpec (spec) where import Data.Maybe (fromJust)+import Data.Time (LocalTime (localDay), getCurrentTime, getCurrentTimeZone, utcToLocalTime)+import Data.Time.Calendar.OrdinalDate (toOrdinalDate) import qualified Defaults as SUT import Hooks (withGitRepo) import Network.URI (parseURI)@@ -19,13 +21,16 @@ describe "getDefaults" $ around withGitRepo $ do it "inspects the current repository" $ \p -> do ds <- SUT.getDefaults+ -- TODO resolve code duplication with SUT.+ timezone <- getCurrentTimeZone+ (dYear, _day) <- toOrdinalDate . localDay . utcToLocalTime timezone <$> getCurrentTime ds `shouldBe` SUT.Defaults { SUT.dOrigin = fromJust (parseURI "https://github.com/sentinel/sentinel.git"), SUT.dAuthor = "Sentinel", SUT.dMaintainer = "sentinel@example.com", SUT.dPath = p,- SUT.dYear = 2023+ SUT.dYear = dYear } defaults :: SUT.Defaults
test/initialise/Hooks.hs view
@@ -1,7 +1,11 @@-module Hooks (withGitRepo) where+module Hooks (withGitRepo, withProjectCopy) where +import Control.Applicative ((<|>)) import Control.Monad (void)-import System.Directory (withCurrentDirectory)+import Data.Text (unpack)+import Git (root)+import System.Directory (getCurrentDirectory, withCurrentDirectory)+import System.FilePath (takeFileName, (</>)) import System.IO.Temp (withSystemTempDirectory) import System.Process (readProcess) @@ -14,3 +18,11 @@ void $ readProcess "git" ["config", "user.email", "sentinel@example.com"] "" void $ readProcess "git" ["remote", "add", "origin", "https://github.com/sentinel/sentinel.git"] "" action p++withProjectCopy :: (FilePath -> IO ()) -> IO ()+withProjectCopy action = do+ withSystemTempDirectory "initialise" $ \p -> do+ r <- unpack <$> root <|> getCurrentDirectory+ void $ readProcess "cp" ["-a", r, p] ""+ let p' = p </> takeFileName r+ withCurrentDirectory p' $ action p'
+ test/initialise/InitialiseSpec.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE OverloadedStrings #-}++module InitialiseSpec (spec) where++import Configuration (Configuration (..))+import Data.Maybe (fromJust)+import Data.Text (Text, pack)+import Distribution.SPDX (LicenseId (MIT))+import Hooks (withProjectCopy)+import qualified Initialise as SUT+import Network.URI (parseURI)+import System.Directory (doesFileExist)+import System.FilePath ((</>))+import System.Process (readProcess)+import Test.Hspec (Spec, describe, runIO, shouldNotReturn, shouldReturn)++spec :: Spec+spec = describe "Initialisers" $ do+ describe "defaultInitialiser" $ do+ runIO $ withProjectCopy $ \p -> do+ let configuration =+ Configuration+ { name = "sentinel",+ homepage = fromJust (parseURI "https://github.com/sentinel/sentinel.git"),+ author = "Sentinel",+ maintainer = "sentinel@example.com",+ licence = MIT,+ path = p,+ year = 1970+ }++ SUT.runInitialise SUT.defaultInitialiser configuration++ doesFileExist (p </> "templatise.cabal") `shouldReturn` False+ doesFileExist (p </> "sentinel.cabal") `shouldReturn` True++ grep ["MIT"] [p </> "LICENSE"] `shouldNotReturn` []++ let ps =+ [ "initialise",+ "template-hs",+ "template.hs",+ "templatise"+ ]++ let fs =+ map+ (p </>)+ [ ".devcontainer" </> "devcontainer.json",+ ".github" </> "workflows" </> "haskell-ci.yml",+ "CHANGELOG.md",+ "sentinel.cabal"+ ]++ grep ps fs `shouldReturn` []++grep :: [String] -> [FilePath] -> IO [Text]+grep ps fs = map pack . lines <$> readProcess "grep" ("-o" : unlines ps : fs) ""
test/initialise/Main.hs view
@@ -1,9 +1,11 @@ module Main (main) where import qualified CabalGolden (golden)+import qualified ConfigurationSpec (spec) import qualified DefaultsSpec (spec) import qualified FileGolden (golden) import qualified GitSpec (spec)+import qualified InitialiseSpec (spec) import Test.Tasty (defaultMain, testGroup) import Test.Tasty.Hspec (testSpecs) @@ -13,8 +15,10 @@ concat <$> mapM testSpecs- [ DefaultsSpec.spec,- GitSpec.spec+ [ ConfigurationSpec.spec,+ DefaultsSpec.spec,+ GitSpec.spec,+ InitialiseSpec.spec ] goldens <- sequence [CabalGolden.golden, FileGolden.golden] defaultMain $