packages feed

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 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 $