summoner 2.0.1.1 → 2.1.0.0
raw patch · 85 files changed
+2095/−1332 lines, 85 filesdep +microaesondep −aesondep −containersdep −neat-interpolationdep ~basedep ~colouristadep ~filepathnew-component:exe:ggPVP ok
version bump matches the API change (PVP)
Dependencies added: microaeson
Dependencies removed: aeson, containers, neat-interpolation, text
Dependency ranges changed: base, colourista, filepath, generic-data, hedgehog, hspec-hedgehog, optparse-applicative, relude, shellmet, time, tree-diff, validation-selective
API changes (from Hackage documentation)
- Summoner.GhcVer: Ghc7103 :: GhcVer
- Summoner.GhcVer: Ghc883 :: GhcVer
- Summoner.License: instance Data.Aeson.Types.FromJSON.FromJSON Summoner.License.License
- Summoner.Text: endLine :: Text
- Summoner.Text: tconcatMap :: (a -> Text) -> [a] -> Text
+ Summoner.Default: defaultCabalVersion :: Text
+ Summoner.Default: defaultStack :: Text
+ Summoner.Default: ghcActionsCacheVersion :: Text
+ Summoner.Default: ghcActionsCheckoutVersion :: Text
+ Summoner.Default: ghcActionsSetupHaskellVersion :: Text
+ Summoner.GhcVer: Ghc8107 :: GhcVer
+ Summoner.GhcVer: Ghc884 :: GhcVer
+ Summoner.GhcVer: Ghc902 :: GhcVer
+ Summoner.GhcVer: Ghc9103 :: GhcVer
+ Summoner.GhcVer: Ghc9123 :: GhcVer
+ Summoner.GhcVer: Ghc928 :: GhcVer
+ Summoner.GhcVer: Ghc948 :: GhcVer
+ Summoner.GhcVer: Ghc967 :: GhcVer
+ Summoner.GhcVer: Ghc984 :: GhcVer
+ Summoner.Golden: cabalFull :: Settings
+ Summoner.Golden: cabalMinimal :: Settings
+ Summoner.Golden: fullBatteries :: Settings
+ Summoner.Golden: generateProjects :: IO ()
+ Summoner.Golden: generateScripts :: IO ()
+ Summoner.Golden: generateTomlConfig :: IO ()
+ Summoner.Golden: stackFull :: Settings
+ Summoner.License: instance Data.Aeson.Micro.FromJSON Summoner.License.License
+ Summoner.Text: quote :: Text -> Text
- Summoner.CLI: Config :: ConfigOpts -> Command
+ Summoner.CLI: Config :: !ConfigOpts -> Command
- Summoner.CLI: LicenseList :: Maybe String -> ShowOpts
+ Summoner.CLI: LicenseList :: !Maybe String -> ShowOpts
- Summoner.CLI: New :: NewOpts -> Command
+ Summoner.CLI: New :: !NewOpts -> Command
- Summoner.CLI: Script :: ScriptOpts -> Command
+ Summoner.CLI: Script :: !ScriptOpts -> Command
- Summoner.CLI: ShowInfo :: ShowOpts -> Command
+ Summoner.CLI: ShowInfo :: !ShowOpts -> Command
- Summoner.GhcVer: Pvp :: Int -> Int -> Int -> Int -> Pvp
+ Summoner.GhcVer: Pvp :: !Int -> !Int -> !Int -> !Int -> Pvp
- Summoner.GhcVer: [pvpFirst] :: Pvp -> Int
+ Summoner.GhcVer: [pvpFirst] :: Pvp -> !Int
- Summoner.GhcVer: [pvpFourth] :: Pvp -> Int
+ Summoner.GhcVer: [pvpFourth] :: Pvp -> !Int
- Summoner.GhcVer: [pvpSecond] :: Pvp -> Int
+ Summoner.GhcVer: [pvpSecond] :: Pvp -> !Int
- Summoner.GhcVer: [pvpThird] :: Pvp -> Int
+ Summoner.GhcVer: [pvpThird] :: Pvp -> !Int
- Summoner.Question: queryManyRepeatOnFail :: forall a. (Text -> Maybe a) -> IO [a]
+ Summoner.Question: queryManyRepeatOnFail :: (Text -> Maybe a) -> IO [a]
- Summoner.Tree: Dir :: FilePath -> [TreeFs] -> TreeFs
+ Summoner.Tree: Dir :: !FilePath -> ![TreeFs] -> TreeFs
- Summoner.Tree: File :: FilePath -> Text -> TreeFs
+ Summoner.Tree: File :: !FilePath -> !Text -> TreeFs
Files
- CHANGELOG.md +70/−0
- README.md +56/−49
- examples/cabal-full/.github/workflows/ci.yml +85/−16
- examples/cabal-full/.gitignore +1/−0
- examples/cabal-full/.travis.yml +15/−10
- examples/cabal-full/LICENSE +1/−1
- examples/cabal-full/README.md +2/−2
- examples/cabal-full/app/Main.hs +2/−2
- examples/cabal-full/appveyor.yml +12/−6
- examples/cabal-full/benchmark/Main.hs +2/−2
- examples/cabal-full/cabal-full.cabal +43/−11
- examples/cabal-full/src/CabalFull.hs +5/−5
- examples/cabal-full/test/Spec.hs +3/−1
- examples/cabal-minimal/app/Main.hs +1/−1
- examples/cabal-minimal/cabal-minimal.cabal +33/−9
- examples/full-batteries/.github/CODEOWNERS +1/−1
- examples/full-batteries/.github/workflows/ci.yml +138/−16
- examples/full-batteries/.gitignore +1/−0
- examples/full-batteries/.travis.yml +49/−17
- examples/full-batteries/LICENSE +1/−1
- examples/full-batteries/README.md +2/−2
- examples/full-batteries/app/Main.hs +2/−2
- examples/full-batteries/appveyor.yml +12/−6
- examples/full-batteries/benchmark/Main.hs +2/−2
- examples/full-batteries/full-batteries.cabal +18/−9
- examples/full-batteries/src/FullBatteries.hs +5/−5
- examples/full-batteries/stack-8.10.7.yaml +1/−0
- examples/full-batteries/stack-8.8.4.yaml +1/−0
- examples/full-batteries/stack-9.0.2.yaml +1/−0
- examples/full-batteries/stack-9.10.3.yaml +1/−0
- examples/full-batteries/stack-9.2.8.yaml +1/−0
- examples/full-batteries/stack-9.4.8.yaml +1/−0
- examples/full-batteries/stack-9.6.7.yaml +1/−0
- examples/full-batteries/stack-9.8.4.yaml +1/−0
- examples/full-batteries/stack.yaml +1/−1
- examples/full-batteries/test/Spec.hs +3/−1
- examples/stack-full/.gitignore +1/−0
- examples/stack-full/.travis.yml +32/−11
- examples/stack-full/LICENSE +1/−1
- examples/stack-full/README.md +3/−2
- examples/stack-full/app/Main.hs +2/−2
- examples/stack-full/appveyor.yml +6/−1
- examples/stack-full/benchmark/Main.hs +2/−2
- examples/stack-full/src/StackFull.hs +5/−5
- examples/stack-full/stack-8.10.7.yaml +1/−0
- examples/stack-full/stack-8.8.4.yaml +1/−0
- examples/stack-full/stack-9.0.2.yaml +1/−0
- examples/stack-full/stack-9.10.3.yaml +1/−0
- examples/stack-full/stack-9.2.8.yaml +1/−0
- examples/stack-full/stack-9.4.8.yaml +1/−0
- examples/stack-full/stack-9.6.7.yaml +1/−0
- examples/stack-full/stack-9.8.4.yaml +1/−0
- examples/stack-full/stack-full.cabal +43/−11
- examples/stack-full/stack.yaml +1/−1
- examples/stack-full/test/Spec.hs +3/−1
- examples/summoner-default.toml +3/−3
- golden/Main.hs +9/−0
- src/Summoner.hs +6/−3
- src/Summoner/CLI.hs +63/−64
- src/Summoner/Config.hs +7/−3
- src/Summoner/CustomPrelude.hs +6/−3
- src/Summoner/Decision.hs +6/−3
- src/Summoner/Default.hs +130/−99
- src/Summoner/GhcVer.hs +64/−35
- src/Summoner/Golden.hs +270/−0
- src/Summoner/License.hs +17/−15
- src/Summoner/Mode.hs +6/−3
- src/Summoner/Project.hs +32/−30
- src/Summoner/Question.hs +6/−4
- src/Summoner/Settings.hs +6/−5
- src/Summoner/Source.hs +7/−4
- src/Summoner/Template.hs +6/−3
- src/Summoner/Template/Cabal.hs +148/−121
- src/Summoner/Template/Doc.hs +8/−5
- src/Summoner/Template/GitHub.hs +406/−306
- src/Summoner/Template/Haskell.hs +45/−66
- src/Summoner/Template/Script.hs +28/−30
- src/Summoner/Template/Stack.hs +6/−3
- src/Summoner/Text.hs +12/−10
- src/Summoner/Tree.hs +17/−17
- summoner.cabal +66/−41
- test/Test/Golden.hs +7/−195
- test/Test/Script.hs +10/−33
- test/Test/Show.hs +14/−7
- test/Test/TomlSpec.hs +3/−6
CHANGELOG.md view
@@ -3,6 +3,76 @@ `summoner` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 2.1.0.0 — Jan 6, 2026++* Support GHC-9.12.3. Use GHC-9.12.3 as the default version for+ generated projects with `nightly-2026-01-04` Stack resolver.+* Support GHC-9.10.3 in generated projects with `lts-24.26`.+* Update GHC-9.8 to GHC-9.8.4 with `lts-23.28`.+* Update GHC-9.6 to GHC-9.6.7 with `lts-22.44`.+* Update `base` upper bound to `< 4.22`.+* Update GitHub Actions in generated projects: replace deprecated+ `haskell/actions/setup` with `haskell-actions/setup`.+* Update `optparse-applicative`, `shellmet`, `time`, `hedgehog`, `brick` upper bounds.+* Add new GHC warnings for GHC >= 9.10:+ `-Wincomplete-record-selectors`, `-Wdeprecated-type-abstractions`,+ `-Wdata-kinds-tc`, `-Wdefaulted-exception-context`.+* Add new GHC warning for GHC >= 9.12: `-Wview-pattern-signatures`.+* Fix encoding issues when reading source files by using `readFileBS`+ with `decodeUtf8` instead of `readFileText`.+* Update Stack resolver to `lts-24.26`. Update Stack version in CI to 3.3.++* [#564](https://github.com/kowainik/summoner/issues/564):+ Upgrade `brick` to version `>=1.0`.+* [#565](https://github.com/kowainik/summoner/issues/565):+ Build Summoner with GHC-9.2.+* [#539](https://github.com/kowainik/summoner/issues/539):+ Use GHC-9.0 as default version for generated projects.+* [#540](https://github.com/kowainik/summoner/issues/540):+ Build Summoner with GHC-9.0.+* [#520](https://github.com/kowainik/summoner/issues/520):+ Output the link to the GitHub project at the end of the process.+* [#476](https://github.com/kowainik/summoner/issues/476):+ Switch from `aeson` to `microaeson`.+* [#466](https://github.com/kowainik/summoner/issues/466):+ Add ` --test-show-details=direct` to `cabal test` on CI.+* [#444](https://github.com/kowainik/summoner/issues/444)+ [#547](https://github.com/kowainik/summoner/issues/547):+ Support GHC-8.10.1 in the generated projects.+ Use GHC-8.10.1 by default in the generated projects.+ Use `nightly-2020-06-29` for stack resolver.+ UPD: Use GHC-8.10.3 and `lts-17.0` instead.+ UPD: Use GHC-8.10.7 and `lts-18.10` instead.+* [#445](https://github.com/kowainik/summoner/issues/445):+ Add `-Wunused-packages` for GHC-8.10.+* [#477](https://github.com/kowainik/summoner/issues/477):+ Remove `neat-interpolation` from dependencies.+ As a result, remove some trailing spaces from the generated files.+* [#442](https://github.com/kowainik/summoner/issues/442):+ Get current year with the respect to the current timezone.+* [#446](https://github.com/kowainik/summoner/issues/446):+ Add README link in the `.cabal` file's description field.+* [#453](https://github.com/kowainik/summoner/issues/453):+ Drop support of `GHC-7.10` in the generated projects.+* [#482](https://github.com/kowainik/summoner/issues/482):+ Include `.hie` related GHC options to the generated files:+ `-fwrite-ide-info` and `-hiedir=.hie` for GHC >= 8.8.+ Also add `.hie` folder in the `.gitignore`.+* [#484](https://github.com/kowainik/summoner/issues/484):+ Improve generated files content.+* [#491](https://github.com/kowainik/summoner/issues/491):+ Support GHC-8.8.4 in the project.+* [#517](https://github.com/kowainik/summoner/issues/517):+ Switch to `main` initial branch when creating project.+* Require `git >= 2.28` for `--initial-branch=main` option.+* [#340](https://github.com/kowainik/summoner/issues/340):+ Use `cabal` version `3.0`.+* [#495](https://github.com/kowainik/summoner/issues/495):+ Generate `dependabot.yml` to update GitHub Actions automatically.+* __#TUI__ Upgrade `brick` allowed version. Bump up lower+ bound to `0.56` due to the new field `formFieldUpdate`+ addition to the `FormFieldState` data type.+ ## 2.0.1.1 — May 29, 2020 * [#467](https://github.com/kowainik/summoner/issues/467):
README.md view
@@ -1,11 +1,13 @@ # 🔮 Summoner + [](https://github.com/kowainik/summoner/actions)-[](http://travis-ci.org/kowainik/summoner)-[](https://ci.appveyor.com/project/kowainik/summoner)+ [](https://hackage.haskell.org/package/summoner)-[](https://github.com/kowainik/summoner/blob/master/LICENSE)+[](http://stackage.org/lts/package/summoner)+[](http://stackage.org/nightly/package/summoner)+[](https://github.com/kowainik/summoner/blob/main/LICENSE) > _So many of our dreams at first seem impossible, then they seem improbable, and > then, when we summon the will, they soon become inevitable._@@ -35,13 +37,13 @@ + [TUI: download binary](#tui-download-binary) + [TUI: Homebrew](#tui-homebrew) + [TUI: Ubuntu](#tui-ubuntu)- + [TUI: from Hackage/Stackage](#tui-from-hackagestackage)+ + [TUI: from Hackage](#tui-from-hackage) + [TUI: from source](#tui-from-source) + [Summon-CLI](#summon-cli) + [CLI: download binary](#cli-download-binary) + [CLI: Homebrew](#cli-homebrew) + [CLI: Ubuntu](#cli-ubuntu)- + [CLI: from Hackage/Stackage](#cli-from-hackagestackage)+ + [CLI: from Hackage](#cli-from-hackage) + [CLI: from source](#cli-from-source) + [Setup](#setup) * [Usage](#usage)@@ -78,18 +80,18 @@ You can also see complete examples in the following folder: -* [`summon-cli/examples/`: Examples of scaffolded projects](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/)+* [`summon-cli/examples/`: Examples of scaffolded projects](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/) The directory contains the following examples: -* [`cabal-minimal`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/cabal-minimal):+* [`cabal-minimal`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/cabal-minimal): Minimal Haskell project with the Cabal-only support, default settings and all of the integrations disabled.-* [`cabal-full`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/cabal-full):+* [`cabal-full`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/cabal-full): Cabal-only project with all integrations enabled.-* [`stack-full`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/stack-full):+* [`stack-full`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/stack-full): Stack-only project with all integrations enabled.-* [`full-batteries`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/full-batteries):+* [`full-batteries`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/full-batteries): All batteries-included project which supports both build tools and shows every Summoner feature. @@ -130,11 +132,20 @@ -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates- -Wredundant-constraints (GHC ⩾ 8.0)- -fhide-source-paths (GHC ⩾ 8.2)- -Wmissing-export-lists (GHC ⩾ 8.4)- -Wpartial-fields (GHC ⩾ 8.4)- -Wmissing-deriving-strategies (GHC ⩾ 8.8)+ -Wredundant-constraints+ -Wnoncanonical-monad-instances+ -fhide-source-paths (GHC ⩾ 8.2)+ -Wmissing-export-lists (GHC ⩾ 8.4)+ -Wpartial-fields (GHC ⩾ 8.4)+ -Wmissing-deriving-strategies (GHC ⩾ 8.8)+ -fwrite-ide-info (GHC ⩾ 8.8)+ -hiedir=.hie (GHC ⩾ 8.8)+ -Wunused-packages (GHC ⩾ 8.10)+ -Wincomplete-record-selectors (GHC ⩾ 9.10)+ -Wdeprecated-type-abstractions (GHC ⩾ 9.10)+ -Wdata-kinds-tc (GHC ⩾ 9.10)+ -Wdefaulted-exception-context (GHC ⩾ 9.10)+ -Wview-pattern-signatures (GHC ⩾ 9.12) ``` Besides, the following GHC options are added to the executable, tests and benchmark stanzas:@@ -223,13 +234,13 @@ To start using Summoner make sure that you have the following tools installed on your machine: -* [`git`](https://git-scm.com) – to initialize the GitHub repo.+* [`git`](https://git-scm.com) ⩾ 2.28 – to initialize the GitHub repo. * [`hub`](https://github.com/github/hub) – to upload the project to GitHub. * [`curl`](https://curl.haxx.se) – to download licenses. We also have minimal version requirements for build tools: -* [Cabal ⩾ 2.4](https://www.haskell.org/cabal/)+* [Cabal ⩾ 3.0](https://www.haskell.org/cabal/) * [Stack ⩾ 2.1.3](http://haskellstack.org) However, it is always recommended to use the newest versions of build tools.@@ -290,21 +301,15 @@ $ sudo apt install summoner-tui ``` -##### TUI: from Hackage/Stackage+##### TUI: from Hackage [[Back to the Table of Contents] ↑](#structure) Using `cabal`: ```shell-cabal v2-update-cabal v2-install summoner-tui-```--Using `stack`:--```shell-stack install summoner-tui+cabal update+cabal install summoner-tui ``` ##### TUI: from source@@ -332,7 +337,7 @@ Build and install using `cabal`: ```shell-cabal v2-install summoner-tui:exe:summon-tui+cabal install summoner-tui:exe:summon-tui ``` Build and install using `stack`:@@ -384,21 +389,15 @@ $ sudo apt install summoner-cli ``` -##### CLI: from Hackage/Stackage+##### CLI: from Hackage [[Back to the Table of Contents] ↑](#structure) Using `cabal`: ```shell-cabal v2-update-cabal v2-install summoner-```--Using `stack`:--```shell-stack install summoner+cabal update+cabal install summoner ``` ##### CLI: from source@@ -426,7 +425,7 @@ Build and install using `cabal`: ```shell-cabal v2-install summoner-cli:exe:summon+cabal install summoner-cli:exe:summon ``` Build and install using `stack`:@@ -476,7 +475,7 @@ | `fullName` | Text | Full name. | | `email` | Text | E-mail address. | | `license` | License | One of: `MIT`, `BSD2`, `BSD3`, `GPL-2`, `GPL-3`, `LGPL-2.1`, `LGPL-3`, `AGPL-3`, `Apache-2.0`, `MPL-2.0`, `None`. |-| `ghcVersions` | [GHC] | `summoner` uses default `GHC-8.8.3`. However, additionally you can specify other versions. For each version `x.y.z` the `stack-x.y.z.yaml` will be created. |+| `ghcVersions` | [GHC] | `summoner` uses default `GHC-9.12.3`. However, additionally you can specify other versions. For each version `x.y.z` the `stack-x.y.z.yaml` will be created. Use `summon show ghc` to see all supported GHC versions. | | `github` | Bool | Turn on `GitHub` integration by default? | | `gitignore` | [Text] | List of files you want added to the default `.gitignore`. (Ignored if `github = false`) | | `noUpload` | Bool | Do not upload to GitHub, but create all GitHub related files if specified (Ignored if `github = false`) |@@ -498,7 +497,7 @@ You can create default configuration using the `summon config` command. See [the default content here](summoner-cli/test/golden/summoner-default.toml). -For a real-life example of the configuration, see [the configuration for projects of the `Kowainik` organization](https://github.com/kowainik/org/blob/master/.summoner.toml).+For a real-life example of the configuration, see [the configuration for projects of the `Kowainik` organization](https://github.com/kowainik/org/blob/main/.summoner.toml). ### Command line arguments @@ -631,7 +630,7 @@ that can be used to scaffold future Haskell packages. It contains all options supported by Summoner with comments and examples. Though, all options would be turned off by default and to use them one will need-to uncomment the correspoding lines.+to uncomment the corresponding lines. See [the default content here](summoner-cli/test/golden/summoner-default.toml). Possible command usages:@@ -716,7 +715,7 @@ #!/usr/bin/env cabal {- cabal: build-depends:- , base ^>= 4.13.0.0+ , base ^>= 4.21.1.0 -} main :: IO ()@@ -728,7 +727,7 @@ ```haskell #!/usr/bin/env stack {- stack- --resolver lts-15.5+ --resolver nightly-2026-01-04 script --package base -}@@ -793,8 +792,8 @@ * Summoner is a multi-package project which has two packages inside: `summoner-cli` and `summoner-tui`. We are supporting the same functionality in both of them, so, if it's possible, you should add/change the code in both of the packages. * Summoner uses the custom prelude [`relude`](https://github.com/kowainik/relude).-* We are using the [Kowainik style guide](https://github.com/kowainik/org/blob/master/style-guide.md#haskell-style-guide).-* To sum up, [here is the Contributing guide](https://github.com/kowainik/.github/blob/master/CONTRIBUTING.md#contributing-to-the-kowainik-repositories) we use across the repositories.+* We are using the [Kowainik style guide](https://kowainik.github.io/posts/2019-02-06-style-guide).+* To sum up, [here is the Contributing guide](https://github.com/kowainik/.github/blob/main/CONTRIBUTING.md#contributing-to-the-kowainik-repositories) we use across the repositories. * This project is contributor-friendly, so be kind to other people working on the project. ### Dependencies@@ -810,7 +809,7 @@ To build the project you can use the following commands: ```shell=-cabal v2-build all+cabal build all ``` for Cabal and@@ -825,12 +824,12 @@ [[Back to the Table of Contents] ↑](#structure) -Summoner uses the golden tests technique for assuring the correctness of the generated files. For this purpose, we have [the `golden` folder](https://github.com/kowainik/summoner/tree/master/summoner-cli/test/golden) with two sample projects to test against.+Summoner uses the golden tests technique for assuring the correctness of the generated files. For this purpose, we have [the `golden` folder](https://github.com/kowainik/summoner/tree/main/summoner-cli/test/golden) with two sample projects to test against. To actually run tests you need to run: ```shell-cabal v2-test all+cabal test all ``` or, if using Stack@@ -846,8 +845,8 @@ Building Summoner with the recommended method creates two executables: `summon` and `summon-tui`. To run the compiled executable you can use the following commands: ```shell-cabal v2-exec summon -- SOME_COMMAND-cabal v2-exec summon-tui -- SOME_COMMAND+cabal exec summon -- SOME_COMMAND+cabal exec summon-tui -- SOME_COMMAND ``` or, if using Stack@@ -855,6 +854,14 @@ ```shell stack exec summon -- SOME_COMMAND stack exec summon-tui -- SOME_COMMAND+```++### Generate golden tests++To regenerate the content of all projects on disk, use the following command:++```shell+cabal run gg ``` ## Acknowledgments
examples/cabal-full/.github/workflows/ci.yml view
@@ -1,44 +1,113 @@ name: CI -# Trigger the workflow on push or pull request, but only for the master branch on: pull_request:+ types: [synchronize, opened, reopened] push:- branches: [master]+ branches: [main]+ schedule:+ # additionally run once per week (At 00:00 on Sunday) to maintain cache+ - cron: '0 0 * * 0' jobs:- build:- name: ghc ${{ matrix.ghc }}- runs-on: ubuntu-16.04+ cabal:+ name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}+ runs-on: ${{ matrix.os }} strategy: matrix:- cabal: ["2.4"]+ os: [ubuntu-latest, macOS-latest, windows-latest]+ cabal: ["3.14.2.0"] ghc: - "8.4.4" - "8.6.5"- - "8.8.3"+ - "8.8.4"+ - "8.10.7"+ - "9.0.2"+ - "9.2.8"+ - "9.4.8"+ - "9.6.7"+ - "9.8.4"+ - "9.10.3"+ - "9.12.3"+ exclude:+ - os: macOS-latest+ ghc: 9.10.3+ - os: macOS-latest+ ghc: 9.8.4+ - os: macOS-latest+ ghc: 9.6.7+ - os: macOS-latest+ ghc: 9.4.8+ - os: macOS-latest+ ghc: 9.2.8+ - os: macOS-latest+ ghc: 9.0.2+ - os: macOS-latest+ ghc: 8.10.7+ - os: macOS-latest+ ghc: 8.8.4+ - os: macOS-latest+ ghc: 8.6.5+ - os: macOS-latest+ ghc: 8.4.4+ - os: windows-latest+ ghc: 9.10.3+ - os: windows-latest+ ghc: 9.8.4+ - os: windows-latest+ ghc: 9.6.7+ - os: windows-latest+ ghc: 9.4.8+ - os: windows-latest+ ghc: 9.2.8+ - os: windows-latest+ ghc: 9.0.2+ - os: windows-latest+ ghc: 8.10.7+ - os: windows-latest+ ghc: 8.8.4+ - os: windows-latest+ ghc: 8.6.5+ - os: windows-latest+ ghc: 8.4.4 steps:- - uses: actions/checkout@v2- if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'+ - uses: actions/checkout@v4 - - uses: actions/setup-haskell@v1+ - uses: haskell-actions/setup@v2+ id: setup-haskell-cabal name: Setup Haskell with: ghc-version: ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} - - uses: actions/cache@v1+ - name: Configure+ run: |+ cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always++ - name: Freeze+ run: |+ cabal freeze++ - uses: actions/cache@v4 name: Cache ~/.cabal/store with:- path: ~/.cabal/store- key: ${{ runner.os }}-${{ matrix.ghc }}-cabal+ path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}+ key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }} + - name: Install dependencies+ run: |+ cabal build all --only-dependencies+ - name: Build run: |- cabal v2-update- cabal v2-build --enable-tests --enable-benchmarks+ cabal build all - name: Test run: |- cabal v2-test --enable-tests+ cabal test all++ - name: Documentation+ run: |+ cabal haddock+
examples/cabal-full/.gitignore view
@@ -21,6 +21,7 @@ cabal.project.local .ghc.environment.* .HTF/+.hie/ # Stack .stack-work/ stack.yaml.lock
examples/cabal-full/.travis.yml view
@@ -1,33 +1,38 @@-sudo: true language: haskell git: depth: 5 -cabal: "2.4"+cabal: "3.14.2.0" cache: directories: - "$HOME/.cabal/store"- -matrix:+jobs: include: - ghc: 8.4.4 - ghc: 8.6.5- - ghc: 8.8.3- - + - ghc: 8.8.4+ - ghc: 8.10.7+ - ghc: 9.0.2+ - ghc: 9.2.8+ - ghc: 9.4.8+ - ghc: 9.6.7+ - ghc: 9.8.4+ - ghc: 9.10.3+ - ghc: 9.12.3 install: # HLint check - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint . - - cabal v2-update- - cabal v2-build --enable-tests --enable-benchmarks+ - cabal update+ - cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always+ - cabal build all script:- - cabal v2-test --enable-tests+ - cabal test all notifications: email: false
examples/cabal-full/LICENSE view
@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2020, Kowainik+Copyright (c) 2022, Kowainik All rights reserved. Redistribution and use in source and binary forms, with or without
examples/cabal-full/README.md view
@@ -1,8 +1,8 @@ # cabal-full [](https://github.com/kowainik/cabal-full/actions)-[](https://travis-ci.org/kowainik/cabal-full)-[](https://ci.appveyor.com/project/kowainik/cabal-full)+[](https://travis-ci.com/kowainik/cabal-full)+[](https://ci.appveyor.com/project/kowainik/cabal-full) [](https://hackage.haskell.org/package/cabal-full) [](LICENSE)
examples/cabal-full/app/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import CabalFull (someFunc)+import CabalFull (projectName) main :: IO ()-main = someFunc+main = putStrLn ("Executable for " ++ projectName)
examples/cabal-full/appveyor.yml view
@@ -4,6 +4,11 @@ # Do not build feature branch with open Pull Requests skip_branch_with_pr: true +# build only main branch+branches:+ only:+ - main+ platform: - x86_64 @@ -16,19 +21,20 @@ CABOPTS: --store-dir=C:\\SR matrix:- - GHCVER: 8.8.3+ - GHCVER: 9.12.3 install: - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2- - choco install -y cabal --version 2.4.1.0- - choco install -y ghc --version 8.8.3+ - choco install -y cabal --version 3.6.2.0+ - choco install -y ghc --version 9.12.3 - refreshenv before_build: - cabal --version - ghc --version- - cabal %CABOPTS% v2-update+ - cabal %CABOPTS% update build_script:- - cabal %CABOPTS% v2-build --enable-tests- - cabal %CABOPTS% v2-test --enable-tests+ - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always+ - cabal %CABOPTS% build all+ - cabal %CABOPTS% test all
examples/cabal-full/benchmark/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import Gauge.Main+import CabalFull (projectName) main :: IO ()-main = defaultMain [bench "const" (whnf const ())]+main = putStrLn ("Benchmarks for " ++ projectName)
examples/cabal-full/cabal-full.cabal view
@@ -1,41 +1,51 @@-cabal-version: 2.4+cabal-version: 3.0 name: cabal-full version: 0.0.0.0 synopsis: Cabal-only example with all integrations-description: Cabal-only example with all integrations+description:+ Cabal-only example with all integrations.+ See [README.md](https://github.com/kowainik/cabal-full#cabal-full) for more details. homepage: https://github.com/kowainik/cabal-full bug-reports: https://github.com/kowainik/cabal-full/issues license: BSD-3-Clause license-file: LICENSE author: Kowainik maintainer: Kowainik <xrom.xkov@gmail.com>-copyright: 2020 Kowainik+copyright: 2022 Kowainik category: Testing build-type: Simple extra-doc-files: README.md CHANGELOG.md tested-with: GHC == 8.4.4 GHC == 8.6.5- GHC == 8.8.3+ GHC == 8.8.4+ GHC == 8.10.7+ GHC == 9.0.2+ GHC == 9.2.8+ GHC == 9.4.8+ GHC == 9.6.7+ GHC == 9.8.4+ GHC == 9.10.3+ GHC == 9.12.3 source-repository head type: git location: https://github.com/kowainik/cabal-full.git common common-options- build-depends: base >= 4.11.1.0 && < 4.14+ build-depends: base >= 4.11.1.0 && < 4.22 , relude- + mixins: base hiding (Prelude) , relude (Relude as Prelude)- + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates- if impl(ghc >= 8.0)- ghc-options: -Wredundant-constraints+ -Wredundant-constraints+ -Wnoncanonical-monad-instances if impl(ghc >= 8.2) ghc-options: -fhide-source-paths if impl(ghc >= 8.4)@@ -43,6 +53,29 @@ -Wpartial-fields if impl(ghc >= 8.8) ghc-options: -Wmissing-deriving-strategies+ -fwrite-ide-info+ -hiedir=.hie+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages+ if impl(ghc >= 9.0)+ ghc-options: -Winvalid-haddock+ if impl(ghc >= 9.2)+ ghc-options: -Wredundant-bang-patterns+ -Woperator-whitespace+ if impl(ghc >= 9.4 && < 9.10)+ ghc-options: -Wforall-identifier+ if impl(ghc >= 9.4)+ ghc-options: -Wredundant-strictness-flags+ if impl(ghc >= 9.8)+ ghc-options: -Wterm-variable-capture+ -Winconsistent-flags+ if impl(ghc >= 9.10)+ ghc-options: -Wincomplete-record-selectors+ -Wdeprecated-type-abstractions+ -Wdata-kinds-tc+ -Wdefaulted-exception-context+ if impl(ghc >= 9.12)+ ghc-options: -Wview-pattern-signatures default-language: Haskell2010 default-extensions: DeriveGeneric@@ -77,8 +110,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: benchmark main-is: Main.hs- build-depends: gauge- , cabal-full+ build-depends: cabal-full ghc-options: -threaded -rtsopts -with-rtsopts=-N
examples/cabal-full/src/CabalFull.hs view
@@ -1,5 +1,5 @@ {- |-Copyright: (c) 2020 Kowainik+Copyright: (c) 2022 Kowainik SPDX-License-Identifier: BSD-3-Clause Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -7,9 +7,9 @@ -} module CabalFull- ( someFunc- ) where+ ( projectName+ ) where -someFunc :: IO ()-someFunc = putStrLn ("someFunc" :: String)+projectName :: String+projectName = "cabal-full"
examples/cabal-full/test/Spec.hs view
@@ -1,5 +1,7 @@ module Main (main) where +import CabalFull (projectName) + main :: IO ()-main = putStrLn ("Test suite is not implemented" :: String)+main = putStrLn ("Tests for " ++ projectName)
examples/cabal-minimal/app/Main.hs view
@@ -2,4 +2,4 @@ main :: IO ()-main = putStrLn ("Hello, world!" :: String)+main = putStrLn ("Executable not implemented" :: String)
examples/cabal-minimal/cabal-minimal.cabal view
@@ -1,27 +1,29 @@-cabal-version: 2.4+cabal-version: 3.0 name: cabal-minimal version: 0.0.0.0 synopsis: Minimal cabal-only test project-description: Minimal cabal-only test project+description:+ Minimal cabal-only test project.+ See README.md for more details. license: NONE author: Kowainik maintainer: Kowainik <xrom.xkov@gmail.com>-copyright: 2020 Kowainik+copyright: 2022 Kowainik build-type: Simple extra-doc-files: README.md CHANGELOG.md-tested-with: GHC == 8.8.3+tested-with: GHC == 9.12.3 common common-options- build-depends: base ^>= 4.13.0.0- + build-depends: base ^>= 4.21.1.0+ ghc-options: -Wall -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates- if impl(ghc >= 8.0)- ghc-options: -Wredundant-constraints+ -Wredundant-constraints+ -Wnoncanonical-monad-instances if impl(ghc >= 8.2) ghc-options: -fhide-source-paths if impl(ghc >= 8.4)@@ -29,6 +31,29 @@ -Wpartial-fields if impl(ghc >= 8.8) ghc-options: -Wmissing-deriving-strategies+ -fwrite-ide-info+ -hiedir=.hie+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages+ if impl(ghc >= 9.0)+ ghc-options: -Winvalid-haddock+ if impl(ghc >= 9.2)+ ghc-options: -Wredundant-bang-patterns+ -Woperator-whitespace+ if impl(ghc >= 9.4 && < 9.10)+ ghc-options: -Wforall-identifier+ if impl(ghc >= 9.4)+ ghc-options: -Wredundant-strictness-flags+ if impl(ghc >= 9.8)+ ghc-options: -Wterm-variable-capture+ -Winconsistent-flags+ if impl(ghc >= 9.10)+ ghc-options: -Wincomplete-record-selectors+ -Wdeprecated-type-abstractions+ -Wdata-kinds-tc+ -Wdefaulted-exception-context+ if impl(ghc >= 9.12)+ ghc-options: -Wview-pattern-signatures default-language: Haskell2010 @@ -36,7 +61,6 @@ import: common-options hs-source-dirs: app main-is: Main.hs- ghc-options: -threaded -rtsopts -with-rtsopts=-N
examples/full-batteries/.github/CODEOWNERS view
@@ -1,1 +1,1 @@-* @chshersh @vrom911+* @vrom911
examples/full-batteries/.github/workflows/ci.yml view
@@ -1,46 +1,168 @@ name: CI -# Trigger the workflow on push or pull request, but only for the master branch on: pull_request:+ types: [synchronize, opened, reopened] push:- branches: [master]+ branches: [main]+ schedule:+ # additionally run once per week (At 00:00 on Sunday) to maintain cache+ - cron: '0 0 * * 0' jobs:- build:- name: ghc ${{ matrix.ghc }}- runs-on: ubuntu-16.04+ cabal:+ name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}+ runs-on: ${{ matrix.os }} strategy: matrix:- cabal: ["2.4"]+ os: [ubuntu-latest, macOS-latest, windows-latest]+ cabal: ["3.14.2.0"] ghc: - "8.0.2" - "8.2.2" - "8.4.4" - "8.6.5"- - "8.8.3"+ - "8.8.4"+ - "8.10.7"+ - "9.0.2"+ - "9.2.8"+ - "9.4.8"+ - "9.6.7"+ - "9.8.4"+ - "9.10.3"+ - "9.12.3"+ exclude:+ - os: macOS-latest+ ghc: 9.10.3+ - os: macOS-latest+ ghc: 9.8.4+ - os: macOS-latest+ ghc: 9.6.7+ - os: macOS-latest+ ghc: 9.4.8+ - os: macOS-latest+ ghc: 9.2.8+ - os: macOS-latest+ ghc: 9.0.2+ - os: macOS-latest+ ghc: 8.10.7+ - os: macOS-latest+ ghc: 8.8.4+ - os: macOS-latest+ ghc: 8.6.5+ - os: macOS-latest+ ghc: 8.4.4+ - os: macOS-latest+ ghc: 8.2.2+ - os: macOS-latest+ ghc: 8.0.2+ - os: windows-latest+ ghc: 9.10.3+ - os: windows-latest+ ghc: 9.8.4+ - os: windows-latest+ ghc: 9.6.7+ - os: windows-latest+ ghc: 9.4.8+ - os: windows-latest+ ghc: 9.2.8+ - os: windows-latest+ ghc: 9.0.2+ - os: windows-latest+ ghc: 8.10.7+ - os: windows-latest+ ghc: 8.8.4+ - os: windows-latest+ ghc: 8.6.5+ - os: windows-latest+ ghc: 8.4.4+ - os: windows-latest+ ghc: 8.2.2+ - os: windows-latest+ ghc: 8.0.2 steps:- - uses: actions/checkout@v2- if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'+ - uses: actions/checkout@v4 - - uses: actions/setup-haskell@v1+ - uses: haskell-actions/setup@v2+ id: setup-haskell-cabal name: Setup Haskell with: ghc-version: ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} - - uses: actions/cache@v1+ - name: Configure+ run: |+ cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always++ - name: Freeze+ run: |+ cabal freeze++ - uses: actions/cache@v4 name: Cache ~/.cabal/store with:- path: ~/.cabal/store- key: ${{ runner.os }}-${{ matrix.ghc }}-cabal+ path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}+ key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }} + - name: Install dependencies+ run: |+ cabal build all --only-dependencies+ - name: Build run: |- cabal v2-update- cabal v2-build --enable-tests --enable-benchmarks+ cabal build all - name: Test run: |- cabal v2-test --enable-tests+ cabal test all++ - name: Documentation+ run: |+ cabal haddock+++ stack:+ name: stack / ghc ${{ matrix.ghc }}+ runs-on: ubuntu-latest+ strategy:+ matrix:+ stack: ["3.3.1"]+ ghc:+ - "8.0.2"+ - "8.2.2"+ - "8.4.4"+ - "8.6.5"+ - "8.8.4"+ - "8.10.7"+ - "9.0.2"+ - "9.2.8"+ - "9.4.8"+ - "9.6.7"+ - "9.8.4"+ - "9.10.3"+ - "9.12.3"++ steps:+ - uses: actions/checkout@v4+ if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/main'++ - uses: haskell-actions/setup@v2+ name: Setup Haskell Stack+ with:+ ghc-version: ${{ matrix.ghc }}+ stack-version: ${{ matrix.stack }}++ - uses: actions/cache@v4+ name: Cache ~/.stack+ with:+ path: ~/.stack+ key: ${{ runner.os }}-${{ matrix.ghc }}-stack++ - name: Build+ run: |+ stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror++ - name: Test+ run: |+ stack test --system-ghc
examples/full-batteries/.gitignore view
@@ -21,6 +21,7 @@ cabal.project.local .ghc.environment.* .HTF/+.hie/ # Stack .stack-work/ stack.yaml.lock
examples/full-batteries/.travis.yml view
@@ -1,10 +1,9 @@-sudo: true language: haskell git: depth: 5 -cabal: "2.4"+cabal: "3.14.2.0" cache: directories:@@ -12,37 +11,69 @@ - "$HOME/.stack" - "$TRAVIS_BUILD_DIR/.stack-work" -matrix:+jobs: include: - ghc: 8.0.2 - ghc: 8.2.2 - ghc: 8.4.4 - ghc: 8.6.5- - ghc: 8.8.3- + - ghc: 8.8.4+ - ghc: 8.10.7+ - ghc: 9.0.2+ - ghc: 9.2.8+ - ghc: 9.4.8+ - ghc: 9.6.7+ - ghc: 9.8.4+ - ghc: 9.10.3+ - ghc: 9.12.3+ - ghc: 8.0.2 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.0.2.yaml"- + - ghc: 8.2.2 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml"- + - ghc: 8.4.4 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"- + - ghc: 8.6.5 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.6.5.yaml"- - - ghc: 8.8.3++ - ghc: 8.8.4+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.8.4.yaml"++ - ghc: 8.10.7+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.10.7.yaml"++ - ghc: 9.0.2+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.0.2.yaml"++ - ghc: 9.2.8+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.2.8.yaml"++ - ghc: 9.4.8+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.4.8.yaml"++ - ghc: 9.6.7+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.6.7.yaml"++ - ghc: 9.8.4+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.8.4.yaml"++ - ghc: 9.10.3+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.10.3.yaml"++ - ghc: 9.12.3 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"- + allow_failures:- + - ghc: 8.0.2 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.0.2.yaml"- + - ghc: 8.2.2 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml"- + - ghc: 8.4.4 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml" @@ -52,8 +83,9 @@ - | if [ -z "$STACK_YAML" ]; then- cabal v2-update- cabal v2-build --enable-tests --enable-benchmarks+ cabal update+ cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always+ cabal build all else curl -sSL https://get.haskellstack.org/ | sh stack --version@@ -63,7 +95,7 @@ script: - | if [ -z "$STACK_YAML" ]; then- cabal v2-test --enable-tests+ cabal test all else stack test --system-ghc fi
examples/full-batteries/LICENSE view
@@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Kowainik+Copyright (c) 2022 Kowainik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
examples/full-batteries/README.md view
@@ -1,8 +1,8 @@ # full-batteries [](https://github.com/kowainik/full-batteries/actions)-[](https://travis-ci.org/kowainik/full-batteries)-[](https://ci.appveyor.com/project/kowainik/full-batteries)+[](https://travis-ci.com/kowainik/full-batteries)+[](https://ci.appveyor.com/project/kowainik/full-batteries) [](https://hackage.haskell.org/package/full-batteries) [](http://stackage.org/lts/package/full-batteries) [](http://stackage.org/nightly/package/full-batteries)
examples/full-batteries/app/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import FullBatteries (someFunc)+import FullBatteries (projectName) main :: IO ()-main = someFunc+main = putStrLn ("Executable for " ++ projectName)
examples/full-batteries/appveyor.yml view
@@ -4,6 +4,11 @@ # Do not build feature branch with open Pull Requests skip_branch_with_pr: true +# build only main branch+branches:+ only:+ - main+ platform: - x86_64 @@ -16,19 +21,20 @@ CABOPTS: --store-dir=C:\\SR matrix:- - GHCVER: 8.8.3+ - GHCVER: 9.12.3 install: - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2- - choco install -y cabal --version 2.4.1.0- - choco install -y ghc --version 8.8.3+ - choco install -y cabal --version 3.6.2.0+ - choco install -y ghc --version 9.12.3 - refreshenv before_build: - cabal --version - ghc --version- - cabal %CABOPTS% v2-update+ - cabal %CABOPTS% update build_script:- - cabal %CABOPTS% v2-build --enable-tests- - cabal %CABOPTS% v2-test --enable-tests+ - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always+ - cabal %CABOPTS% build all+ - cabal %CABOPTS% test all
examples/full-batteries/benchmark/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import Gauge.Main+import FullBatteries (projectName) main :: IO ()-main = defaultMain [bench "const" (whnf const ())]+main = putStrLn ("Benchmarks for " ++ projectName)
examples/full-batteries/full-batteries.cabal view
@@ -1,15 +1,17 @@-cabal-version: 2.4+cabal-version: 3.0 name: full-batteries version: 0.0.0.0 synopsis: Full-featured test project-description: Full-featured test project+description:+ Full-featured test project.+ See [README.md](https://github.com/kowainik/full-batteries#full-batteries) for more details. homepage: https://github.com/kowainik/full-batteries bug-reports: https://github.com/kowainik/full-batteries/issues license: MIT license-file: LICENSE author: Kowainik maintainer: Kowainik <xrom.xkov@gmail.com>-copyright: 2020 Kowainik+copyright: 2022 Kowainik category: Testing build-type: Simple extra-doc-files: README.md@@ -18,19 +20,27 @@ GHC == 8.2.2 GHC == 8.4.4 GHC == 8.6.5- GHC == 8.8.3+ GHC == 8.8.4+ GHC == 8.10.7+ GHC == 9.0.2+ GHC == 9.2.8+ GHC == 9.4.8+ GHC == 9.6.7+ GHC == 9.8.4+ GHC == 9.10.3+ GHC == 9.12.3 source-repository head type: git location: https://github.com/kowainik/full-batteries.git common common-options- build-depends: base >= 4.9.1.0 && < 4.14+ build-depends: base >= 4.9.1.0 && < 4.22 , relude- + mixins: base hiding (Prelude) , relude (Relude as Prelude)- + ghc-options: -Wcompat -Widentities @@ -68,8 +78,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: benchmark main-is: Main.hs- build-depends: gauge- , full-batteries+ build-depends: full-batteries ghc-options: -threaded -rtsopts -with-rtsopts=-N
examples/full-batteries/src/FullBatteries.hs view
@@ -1,5 +1,5 @@ {- |-Copyright: (c) 2020 Kowainik+Copyright: (c) 2022 Kowainik SPDX-License-Identifier: MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -7,9 +7,9 @@ -} module FullBatteries- ( someFunc- ) where+ ( projectName+ ) where -someFunc :: IO ()-someFunc = putStrLn ("someFunc" :: String)+projectName :: String+projectName = "full-batteries"
+ examples/full-batteries/stack-8.10.7.yaml view
@@ -0,0 +1,1 @@+resolver: lts-18.28
+ examples/full-batteries/stack-8.8.4.yaml view
@@ -0,0 +1,1 @@+resolver: lts-16.31
+ examples/full-batteries/stack-9.0.2.yaml view
@@ -0,0 +1,1 @@+resolver: lts-19.33
+ examples/full-batteries/stack-9.10.3.yaml view
@@ -0,0 +1,1 @@+resolver: lts-24.26
+ examples/full-batteries/stack-9.2.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-20.26
+ examples/full-batteries/stack-9.4.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-21.25
+ examples/full-batteries/stack-9.6.7.yaml view
@@ -0,0 +1,1 @@+resolver: lts-22.44
+ examples/full-batteries/stack-9.8.4.yaml view
@@ -0,0 +1,1 @@+resolver: lts-23.28
examples/full-batteries/stack.yaml view
@@ -1,1 +1,1 @@-resolver: lts-15.5+resolver: nightly-2026-01-04
examples/full-batteries/test/Spec.hs view
@@ -1,5 +1,7 @@ module Main (main) where +import FullBatteries (projectName) + main :: IO ()-main = putStrLn ("Test suite is not implemented" :: String)+main = putStrLn ("Tests for " ++ projectName)
examples/stack-full/.gitignore view
@@ -21,6 +21,7 @@ cabal.project.local .ghc.environment.* .HTF/+.hie/ # Stack .stack-work/ stack.yaml.lock
examples/stack-full/.travis.yml view
@@ -1,32 +1,53 @@-sudo: true language: haskell git: depth: 5 -cabal: "2.4"+cabal: "3.14.2.0" cache: directories:- - "$HOME/.stack" - "$TRAVIS_BUILD_DIR/.stack-work" -matrix:+jobs: include:- - + - ghc: 8.4.4 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"- + - ghc: 8.6.5 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.6.5.yaml"- - - ghc: 8.8.3++ - ghc: 8.8.4+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.8.4.yaml"++ - ghc: 8.10.7+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.10.7.yaml"++ - ghc: 9.0.2+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.0.2.yaml"++ - ghc: 9.2.8+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.2.8.yaml"++ - ghc: 9.4.8+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.4.8.yaml"++ - ghc: 9.6.7+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.6.7.yaml"++ - ghc: 9.8.4+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.8.4.yaml"++ - ghc: 9.10.3+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.10.3.yaml"++ - ghc: 9.12.3 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"- + allow_failures:- + - ghc: 8.4.4 env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
examples/stack-full/LICENSE view
@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2020, Kowainik+Copyright (c) 2022, Kowainik All rights reserved. Redistribution and use in source and binary forms, with or without
examples/stack-full/README.md view
@@ -1,7 +1,8 @@ # stack-full -[](https://travis-ci.org/kowainik/stack-full)-[](https://ci.appveyor.com/project/kowainik/stack-full)+[](https://github.com/kowainik/stack-full/actions)+[](https://travis-ci.com/kowainik/stack-full)+[](https://ci.appveyor.com/project/kowainik/stack-full) [](https://hackage.haskell.org/package/stack-full) [](http://stackage.org/lts/package/stack-full) [](http://stackage.org/nightly/package/stack-full)
examples/stack-full/app/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import StackFull (someFunc)+import StackFull (projectName) main :: IO ()-main = someFunc+main = putStrLn ("Executable for " ++ projectName)
examples/stack-full/appveyor.yml view
@@ -3,9 +3,14 @@ # Do not build feature branch with open Pull Requests skip_branch_with_pr: true +# build only main branch+branches:+ only:+ - main+ environment: STACK_ROOT: C:\sr- STACK_VERSION: 2.1.1+ STACK_VERSION: 3.3.1 # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386 # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story
examples/stack-full/benchmark/Main.hs view
@@ -1,7 +1,7 @@ module Main (main) where -import Gauge.Main+import StackFull (projectName) main :: IO ()-main = defaultMain [bench "const" (whnf const ())]+main = putStrLn ("Benchmarks for " ++ projectName)
examples/stack-full/src/StackFull.hs view
@@ -1,5 +1,5 @@ {- |-Copyright: (c) 2020 Kowainik+Copyright: (c) 2022 Kowainik SPDX-License-Identifier: BSD-3-Clause Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -7,9 +7,9 @@ -} module StackFull- ( someFunc- ) where+ ( projectName+ ) where -someFunc :: IO ()-someFunc = putStrLn ("someFunc" :: String)+projectName :: String+projectName = "stack-full"
+ examples/stack-full/stack-8.10.7.yaml view
@@ -0,0 +1,1 @@+resolver: lts-18.28
+ examples/stack-full/stack-8.8.4.yaml view
@@ -0,0 +1,1 @@+resolver: lts-16.31
+ examples/stack-full/stack-9.0.2.yaml view
@@ -0,0 +1,1 @@+resolver: lts-19.33
+ examples/stack-full/stack-9.10.3.yaml view
@@ -0,0 +1,1 @@+resolver: lts-24.26
+ examples/stack-full/stack-9.2.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-20.26
+ examples/stack-full/stack-9.4.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-21.25
+ examples/stack-full/stack-9.6.7.yaml view
@@ -0,0 +1,1 @@+resolver: lts-22.44
+ examples/stack-full/stack-9.8.4.yaml view
@@ -0,0 +1,1 @@+resolver: lts-23.28
examples/stack-full/stack-full.cabal view
@@ -1,41 +1,51 @@-cabal-version: 2.4+cabal-version: 3.0 name: stack-full version: 0.0.0.0 synopsis: Stack-only example with all integrations-description: Stack-only example with all integrations+description:+ Stack-only example with all integrations.+ See [README.md](https://github.com/kowainik/stack-full#stack-full) for more details. homepage: https://github.com/kowainik/stack-full bug-reports: https://github.com/kowainik/stack-full/issues license: BSD-3-Clause license-file: LICENSE author: Kowainik maintainer: Kowainik <xrom.xkov@gmail.com>-copyright: 2020 Kowainik+copyright: 2022 Kowainik category: Testing build-type: Simple extra-doc-files: README.md CHANGELOG.md tested-with: GHC == 8.4.4 GHC == 8.6.5- GHC == 8.8.3+ GHC == 8.8.4+ GHC == 8.10.7+ GHC == 9.0.2+ GHC == 9.2.8+ GHC == 9.4.8+ GHC == 9.6.7+ GHC == 9.8.4+ GHC == 9.10.3+ GHC == 9.12.3 source-repository head type: git location: https://github.com/kowainik/stack-full.git common common-options- build-depends: base >= 4.11.1.0 && < 4.14+ build-depends: base >= 4.11.1.0 && < 4.22 , relude- + mixins: base hiding (Prelude) , relude (Relude as Prelude)- + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates- if impl(ghc >= 8.0)- ghc-options: -Wredundant-constraints+ -Wredundant-constraints+ -Wnoncanonical-monad-instances if impl(ghc >= 8.2) ghc-options: -fhide-source-paths if impl(ghc >= 8.4)@@ -43,6 +53,29 @@ -Wpartial-fields if impl(ghc >= 8.8) ghc-options: -Wmissing-deriving-strategies+ -fwrite-ide-info+ -hiedir=.hie+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages+ if impl(ghc >= 9.0)+ ghc-options: -Winvalid-haddock+ if impl(ghc >= 9.2)+ ghc-options: -Wredundant-bang-patterns+ -Woperator-whitespace+ if impl(ghc >= 9.4 && < 9.10)+ ghc-options: -Wforall-identifier+ if impl(ghc >= 9.4)+ ghc-options: -Wredundant-strictness-flags+ if impl(ghc >= 9.8)+ ghc-options: -Wterm-variable-capture+ -Winconsistent-flags+ if impl(ghc >= 9.10)+ ghc-options: -Wincomplete-record-selectors+ -Wdeprecated-type-abstractions+ -Wdata-kinds-tc+ -Wdefaulted-exception-context+ if impl(ghc >= 9.12)+ ghc-options: -Wview-pattern-signatures default-language: Haskell2010 default-extensions: DeriveGeneric@@ -77,8 +110,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: benchmark main-is: Main.hs- build-depends: gauge- , stack-full+ build-depends: stack-full ghc-options: -threaded -rtsopts -with-rtsopts=-N
examples/stack-full/stack.yaml view
@@ -1,1 +1,1 @@-resolver: lts-15.5+resolver: nightly-2026-01-04
examples/stack-full/test/Spec.hs view
@@ -1,5 +1,7 @@ module Main (main) where +import StackFull (projectName) + main :: IO ()-main = putStrLn ("Test suite is not implemented" :: String)+main = putStrLn ("Tests for " ++ projectName)
examples/summoner-default.toml view
@@ -48,9 +48,9 @@ # travis = true # Travis CI # appveyor = true # AppVeyor CI -# List of additional GHC versions to support besides 8.8.3.+# List of additional GHC versions to support besides 9.12.3. # Run the 'summon show ghc' command to see the list of all supported GHC versions.-# ghcVersions = ["8.4.4", "8.6.5"]+# ghcVersions = ["9.8.4", "9.10.3"] # List of default-extensions in the .cabal file # extensions = [ "ConstraintKinds"@@ -71,7 +71,7 @@ # List of additional files to add after creating the project # files = # [ { path = ".stylish-haskell.yaml"-# , url = "https://raw.githubusercontent.com/kowainik/org/master/.stylish-haskell.yaml"+# , url = "https://raw.githubusercontent.com/kowainik/org/main/.stylish-haskell.yaml" # } # , { path = ".github/CODEOWNERS" # , raw = "* @kowainik"
+ golden/Main.hs view
@@ -0,0 +1,9 @@+module Main (main) where++import Summoner.Golden (generateProjects, generateScripts, generateTomlConfig)++main :: IO ()+main = do+ generateScripts+ generateTomlConfig+ generateProjects
src/Summoner.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Main module that reexports all library components of the @summoner@. -}
src/Summoner/CLI.hs view
@@ -1,47 +1,47 @@ {-# LANGUAGE ApplicativeDo #-}-{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.CLI+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains functions and data types to parse CLI inputs. -} module Summoner.CLI- ( -- * CLI data types- Command (..)- , NewOpts (..)- , ShowOpts (..)+ ( -- * CLI data types+ Command (..)+ , NewOpts (..)+ , ShowOpts (..) - -- * Functions to parse CLI arguments and run @summoner@- , summon- , summonCli+ -- * Functions to parse CLI arguments and run @summoner@+ , summon+ , summonCli - -- * Runners- , runConfig- , runScript+ -- * Runners+ , runConfig+ , runScript - -- * Common helper functions- , getFinalConfig- , getCustomLicenseText- ) where+ -- * Common helper functions+ , getFinalConfig+ , getCustomLicenseText+ ) where import Colourista (blue, bold, errorMessage, formatWith, infoMessage, successMessage, warningMessage) import Data.Version (Version, showVersion) import Development.GitRev (gitCommitDate, gitHash)-import NeatInterpolation (text) import Options.Applicative (Parser, ParserInfo, ParserPrefs, argument, command, customExecParser, flag, fullDesc, help, helpLongEquals, helper, info, infoFooter, infoHeader, infoOption, long, maybeReader, metavar, option, prefs, progDesc, short, showDefault, showHelpOnEmpty, strArgument, strOption, subparser, subparserInline, switch, value) import Options.Applicative.Help.Chunk (stringChunk)-import Relude.Extra.Enum (universe) import System.Directory (doesFileExist) import System.Info (os) import Validation (Validation (..))@@ -58,7 +58,6 @@ import Summoner.Project (generateProject) import Summoner.Settings (Tool, parseTool) import Summoner.Template.Script (scriptFile)-import Summoner.Text (endLine) import qualified Data.Text as T import qualified Paths_summoner as Meta (version)@@ -84,10 +83,10 @@ -- | Run 'summoner' with @CLI@ command runCliCommand :: Command -> IO () runCliCommand = \case- New opts -> runNew opts- Script opts -> runScript opts+ New opts -> runNew opts+ Script opts -> runScript opts ShowInfo opts -> runShow opts- Config opts -> runConfig opts+ Config opts -> runConfig opts {- | Runs @config@ command@@ -254,13 +253,13 @@ -- | Represent all available commands data Command -- | @new@ command creates a new project- = New NewOpts+ = New !NewOpts -- | @script@ command creates Haskell script- | Script ScriptOpts+ | Script !ScriptOpts -- | @show@ command shows supported licenses or GHC versions- | ShowInfo ShowOpts+ | ShowInfo !ShowOpts -- | @config@ command creates the TOML configuration file- | Config ConfigOpts+ | Config !ConfigOpts -- | Options parsed with the @new@ command data NewOpts = NewOpts@@ -282,7 +281,7 @@ -- | Commands parsed with @show@ command data ShowOpts = GhcList- | LicenseList (Maybe String)+ | LicenseList !(Maybe String) -- | Options parsed with the @config@ command newtype ConfigOpts = ConfigOpts@@ -424,7 +423,7 @@ cExe <- execP d cTest <- testP d cBench <- benchmarkP d- pure mempty+ pure (mempty :: PartialConfig) { cGitHub = cGitHub , cGhActions = cGhActions , cTravis = cTravis@@ -583,39 +582,39 @@ modifyFooter p = p {infoFooter = stringChunk $ toString artFooter} artHeader :: Text-artHeader = [text|-$endLine- ___- ╱ . ╲- │╲_/│ │- │ │ ╱│- ___________________________________________________-' │- ╱ │-╱ .-. │-│ ╱ ╲ │-│ │\_. │ Summoner — tool for creating Haskell projects │-│\│ │ ╱│ │-│ `-_-' │ ╱-│ │_____________________________________________╱-│ │- ╲ ╱- `-_-'-|]+artHeader = unlines+ [ ""+ , " ___"+ , " ╱ . ╲"+ , " │╲_/│ │"+ , " │ │ ╱│"+ , " ___________________________________________________-' │"+ , " ╱ │"+ , "╱ .-. │"+ , "│ ╱ ╲ │"+ , "│ │\\_. │ Summoner — tool for creating Haskell projects │"+ , "│\\│ │ ╱│ │"+ , "│ `-_-' │ ╱"+ , "│ │_____________________________________________╱"+ , "│ │"+ , " ╲ ╱"+ , " `-_-'"+ ] artFooter :: Text-artFooter = [text|-$endLine- , * +- + o * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓- * @ ╭─╮ . ________┃ ┃_______- ╱| . │λ│ @ ' ╲ ┃ λ Haskell's summon scroll λ ┃ ╱- _╱ ╰─ ╰╥╯ O ╲ ┃ ┃ ╱- .─╲"╱. * ║ + ╱ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ╲- ╱ ( ) ╲_ ║ ╱__________) (_________╲- ╲ ╲(')╲__(╱- ╱╱`)╱ `╮ ║- `╲. ╱╱ ( │ ║- ╲.╲╱ │ ║- `╰══════════╯-$endLine-|]+artFooter = unlines+ [ ""+ , " , * +"+ , " + o * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"+ , " * @ ╭─╮ . ________┃ ┃_______"+ , " ╱| . │λ│ @ ' ╲ ┃ λ Haskell's summon scroll λ ┃ ╱"+ , " _╱ ╰─ ╰╥╯ O ╲ ┃ ┃ ╱"+ , " .─╲\"╱. * ║ + ╱ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ╲"+ , " ╱ ( ) ╲_ ║ ╱__________) (_________╲"+ , " ╲ ╲(')╲__(╱"+ , " ╱╱`)╱ `╮ ║"+ , " `╲. ╱╱ ( │ ║"+ , " ╲.╲╱ │ ║"+ , " `╰══════════╯"+ , ""+ ]
src/Summoner/Config.hs view
@@ -7,9 +7,12 @@ {-# LANGUAGE UndecidableInstances #-} {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Config+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Summoner configurations. -}@@ -29,6 +32,7 @@ import Data.List (lookup) import Generic.Data (gmappend, gmempty)+import Generic.Data.Orphans () import Shellmet (($?), ($|)) import Toml (Key, TomlBiMap, TomlCodec, (.=)) import Validation (Validation (..))
src/Summoner/CustomPrelude.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.CustomPrelude+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module implements data type for representing custom alternative preludes. -}
src/Summoner/Decision.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Decision+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Decision data type. -}
src/Summoner/Default.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE QuasiQuotes #-}- {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Default+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains some default values to use. -}@@ -11,6 +12,8 @@ module Summoner.Default ( defaultGHC , defaultCabal+ , defaultCabalVersion+ , defaultStack , defaultLicenseName , defaultOwner , defaultFullName@@ -20,15 +23,22 @@ , defaultConfigFileContent , defaultDescription , currentYear++ -- * GitHub Actions defaults+ , ghcActionsCacheVersion+ , ghcActionsCheckoutVersion+ , ghcActionsSetupHaskellVersion ) where -import Data.Time (getCurrentTime, toGregorian, utctDay)-import NeatInterpolation (text)+import Relude.Extra.Enum (prev)++import Data.Time (getCurrentTime, getCurrentTimeZone, localDay, toGregorian, utcToLocalTime) import System.Directory (getHomeDirectory) import System.FilePath ((</>)) import Summoner.GhcVer (GhcVer, showGhcVer) import Summoner.License (LicenseName (MIT))+import Summoner.Text (quote) -- | Default GHC version is the latest available.@@ -37,8 +47,16 @@ -- | Default version of the Cabal. defaultCabal :: Text-defaultCabal = "2.4"+defaultCabal = "3.14.2.0" +-- | Default version of the Cabal specified in the *.cabal* file.+defaultCabalVersion :: Text+defaultCabalVersion = "3.0"++-- | Default version of the Stack.+defaultStack :: Text+defaultStack = "3.3.1"+ defaultLicenseName :: LicenseName defaultLicenseName = MIT @@ -60,108 +78,121 @@ defaultDescription :: Text defaultDescription = "See README for more info" +ghcActionsCheckoutVersion :: Text+ghcActionsCheckoutVersion = "@v4"++ghcActionsSetupHaskellVersion :: Text+ghcActionsSetupHaskellVersion = "@v2"++ghcActionsCacheVersion :: Text+ghcActionsCacheVersion = "@v4"+ currentYear :: IO Text currentYear = do now <- getCurrentTime- let (year, _, _) = toGregorian $ utctDay now+ zone <- getCurrentTimeZone+ let localNow = utcToLocalTime zone now+ let (year, _, _) = toGregorian $ localDay localNow pure $ show year {- | Default content of the @~/summoner.toml@ file to be generated by the @summon config@ command. -} defaultConfigFileContent :: Text-defaultConfigFileContent = [text|- # This file is automatically generated by Summoner.- # Edit required fields, uncomment additional settings or delete irrelevant- # lines for the personalized configuration.-- # GitHub user name- owner = "$defaultOwner"-- # First and last name- fullName = "$defaultFullName"-- # Email used at GitHub- email = "$defaultEmail"-- # Default OSS license for your projects.- # Run the 'summon show license' command to see the list of supported licenses.- license = "$licenseName"-- # Create projects with the Cabal support- # cabal = true-- # Create projects with the Stack support- # stack = true-- # Should your projects have the library stanza by default?- # lib = true-- # Should your projects have an executable stanza by default?- # exe = true-- # Should your projects have the test-suite stanza by default?- # test = true-- # Should your projects have the benchmark stanza by default?- # bench = true-- # Summoner suports 'git' version control system and GitHub as a platform for- # hosting 'git' repos. The following set of flags controls integration with GitHub.- # github = true # enabled GitHub integration- # noUpload = true # Init git repo, but don't create it on GitHub- # private = true # create private repos by default- # gitignore = # list of additional entries to be added in .gitignore- # [ "build"- # , "result"- # ]-- # Summoner supports various CI services. Uncomment those you want to use by default.- # githubActions = true # GitHub Actions CI- # travis = true # Travis CI- # appveyor = true # AppVeyor CI-- # List of additional GHC versions to support besides $defaultGhcVer.- # Run the 'summon show ghc' command to see the list of all supported GHC versions.- # ghcVersions = ["8.4.4", "8.6.5"]-- # List of default-extensions in the .cabal file- # extensions = [ "ConstraintKinds"- # , "DeriveGeneric"- # , "GeneralizedNewtypeDeriving"- # , "InstanceSigs"- # , "KindSignatures"- # , "LambdaCase"- # , "OverloadedStrings"- # , "RecordWildCards"- # , "ScopedTypeVariables"- # , "StandaloneDeriving"- # , "TupleSections"- # , "TypeApplications"- # , "ViewPatterns"- # ]-- # List of additional files to add after creating the project- # files =- # [ { path = ".stylish-haskell.yaml"- # , url = "https://raw.githubusercontent.com/kowainik/org/master/.stylish-haskell.yaml"- # }- # , { path = ".github/CODEOWNERS"- # , raw = "* @$defaultOwner"- # }- # , { path = "src/Foo.hs"- # , local = "/home/user/.default/Foo.hs"- # }- # ]-- # Alternative Prelude to be used instead of the default one if you prefer- # [prelude]- # package = "relude"- # module = "Relude"-|]+defaultConfigFileContent = unlines+ [ "# This file is automatically generated by Summoner."+ , "# Edit required fields, uncomment additional settings or delete irrelevant"+ , "# lines for the personalized configuration."+ , ""+ , "# GitHub user name"+ , "owner = " <> quote defaultOwner+ , ""+ , "# First and last name"+ , "fullName = " <> quote defaultFullName+ , ""+ , "# Email used at GitHub"+ , "email = " <> quote defaultEmail+ , ""+ , "# Default OSS license for your projects."+ , "# Run the 'summon show license' command to see the list of supported licenses."+ , "license = " <> quote licenseName+ , ""+ , "# Create projects with the Cabal support"+ , "# cabal = true"+ , ""+ , "# Create projects with the Stack support"+ , "# stack = true"+ , ""+ , "# Should your projects have the library stanza by default?"+ , "# lib = true"+ , ""+ , "# Should your projects have an executable stanza by default?"+ , "# exe = true"+ , ""+ , "# Should your projects have the test-suite stanza by default?"+ , "# test = true"+ , ""+ , "# Should your projects have the benchmark stanza by default?"+ , "# bench = true"+ , ""+ , "# Summoner suports 'git' version control system and GitHub as a platform for"+ , "# hosting 'git' repos. The following set of flags controls integration with GitHub."+ , "# github = true # enabled GitHub integration"+ , "# noUpload = true # Init git repo, but don't create it on GitHub"+ , "# private = true # create private repos by default"+ , "# gitignore = # list of additional entries to be added in .gitignore"+ , "# [ " <> quote "build"+ , "# , " <> quote "result"+ , "# ]"+ , ""+ , "# Summoner supports various CI services. Uncomment those you want to use by default."+ , "# githubActions = true # GitHub Actions CI"+ , "# travis = true # Travis CI"+ , "# appveyor = true # AppVeyor CI"+ , ""+ , "# List of additional GHC versions to support besides " <> defaultGhcVer <> "."+ , "# Run the 'summon show ghc' command to see the list of all supported GHC versions."+ , "# ghcVersions = [" <> quote defaultGhcPrevPrev <> ", " <> quote defaultGhcPrev <> "]"+ , ""+ , "# List of default-extensions in the .cabal file"+ , "# extensions = [ " <> quote "ConstraintKinds"+ , "# , " <> quote "DeriveGeneric"+ , "# , " <> quote "GeneralizedNewtypeDeriving"+ , "# , " <> quote "InstanceSigs"+ , "# , " <> quote "KindSignatures"+ , "# , " <> quote "LambdaCase"+ , "# , " <> quote "OverloadedStrings"+ , "# , " <> quote "RecordWildCards"+ , "# , " <> quote "ScopedTypeVariables"+ , "# , " <> quote "StandaloneDeriving"+ , "# , " <> quote "TupleSections"+ , "# , " <> quote "TypeApplications"+ , "# , " <> quote "ViewPatterns"+ , "# ]"+ , ""+ , "# List of additional files to add after creating the project"+ , "# files ="+ , "# [ { path = " <> quote ".stylish-haskell.yaml"+ , "# , url = " <> quote "https://raw.githubusercontent.com/kowainik/org/main/.stylish-haskell.yaml"+ , "# }"+ , "# , { path = " <> quote ".github/CODEOWNERS"+ , "# , raw = " <> quote ("* @" <> defaultOwner)+ , "# }"+ , "# , { path = " <> quote "src/Foo.hs"+ , "# , local = " <> quote "/home/user/.default/Foo.hs"+ , "# }"+ , "# ]"+ , ""+ , "# Alternative Prelude to be used instead of the default one if you prefer"+ , "# [prelude]"+ , "# package = " <> quote "relude"+ , "# module = " <> quote "Relude"+ ] where licenseName :: Text licenseName = show defaultLicenseName - defaultGhcVer :: Text+ defaultGhcVer, defaultGhcPrev, defaultGhcPrevPrev :: Text defaultGhcVer = showGhcVer defaultGHC+ defaultGhcPrev = showGhcVer $ prev defaultGHC+ defaultGhcPrevPrev = showGhcVer $ prev $ prev defaultGHC
src/Summoner/GhcVer.hs view
@@ -1,28 +1,28 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.GhcVer+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Contains data type for GHC versions supported by Summoner and some useful functions for manipulation with them. -} module Summoner.GhcVer- ( GhcVer (..)- , GhcMeta (..)- , Pvp (..)- , showGhcVer- , parseGhcVer- , latestLts- , baseVer- , cabalBaseVersions- , ghcTable-- , oldGhcs- ) where+ ( GhcVer (..)+ , GhcMeta (..)+ , Pvp (..)+ , showGhcVer+ , parseGhcVer+ , latestLts+ , baseVer+ , cabalBaseVersions+ , ghcTable -import Data.List (maximum, minimum)-import Relude.Extra.Enum (inverseMap, universe)+ , oldGhcs+ ) where import qualified Data.Text as T import qualified Text.Show as Show@@ -30,23 +30,37 @@ -- | Represents some selected set of GHC versions. data GhcVer- = Ghc7103- | Ghc802+ = Ghc802 | Ghc822 | Ghc844 | Ghc865- | Ghc883+ | Ghc884+ | Ghc8107+ | Ghc902+ | Ghc928+ | Ghc948+ | Ghc967+ | Ghc984+ | Ghc9103+ | Ghc9123 deriving stock (Eq, Ord, Show, Enum, Bounded) -- | Converts 'GhcVer' into dot-separated string. showGhcVer :: GhcVer -> Text showGhcVer = \case- Ghc7103 -> "7.10.3" Ghc802 -> "8.0.2" Ghc822 -> "8.2.2" Ghc844 -> "8.4.4" Ghc865 -> "8.6.5"- Ghc883 -> "8.8.3"+ Ghc884 -> "8.8.4"+ Ghc8107 -> "8.10.7"+ Ghc902 -> "9.0.2"+ Ghc928 -> "9.2.8"+ Ghc948 -> "9.4.8"+ Ghc967 -> "9.6.7"+ Ghc984 -> "9.8.4"+ Ghc9103 -> "9.10.3"+ Ghc9123 -> "9.12.3" {- | These are old GHC versions that are not working with default GHC versions when using Stack.@@ -60,19 +74,26 @@ -- | Returns latest known LTS resolver for all GHC versions except default one. latestLts :: GhcVer -> Text latestLts = \case- Ghc7103 -> "lts-6.35" Ghc802 -> "lts-9.21" Ghc822 -> "lts-11.22" Ghc844 -> "lts-12.26" Ghc865 -> "lts-14.27"- Ghc883 -> "lts-15.5"+ Ghc884 -> "lts-16.31"+ Ghc8107 -> "lts-18.28"+ Ghc902 -> "lts-19.33"+ Ghc928 -> "lts-20.26"+ Ghc948 -> "lts-21.25"+ Ghc967 -> "lts-22.44"+ Ghc984 -> "lts-23.28"+ Ghc9103 -> "lts-24.26"+ Ghc9123 -> "nightly-2026-01-04" -- | Represents PVP versioning (4 numbers). data Pvp = Pvp- { pvpFirst :: Int- , pvpSecond :: Int- , pvpThird :: Int- , pvpFourth :: Int+ { pvpFirst :: !Int+ , pvpSecond :: !Int+ , pvpThird :: !Int+ , pvpFourth :: !Int } -- | Show PVP version in a standard way: @1.2.3.4@@@ -82,12 +103,19 @@ -- | Returns base version by 'GhcVer' as 'Pvp'. baseVerPvp :: GhcVer -> Pvp baseVerPvp = \case- Ghc7103 -> Pvp 4 8 0 2 Ghc802 -> Pvp 4 9 1 0 Ghc822 -> Pvp 4 10 1 0 Ghc844 -> Pvp 4 11 1 0 Ghc865 -> Pvp 4 12 0 0- Ghc883 -> Pvp 4 13 0 0+ Ghc884 -> Pvp 4 13 0 0+ Ghc8107 -> Pvp 4 14 3 0+ Ghc902 -> Pvp 4 15 1 0+ Ghc928 -> Pvp 4 16 4 0+ Ghc948 -> Pvp 4 17 2 1+ Ghc967 -> Pvp 4 18 3 1+ Ghc984 -> Pvp 4 19 2 0+ Ghc9103 -> Pvp 4 20 2 0+ Ghc9123 -> Pvp 4 21 1 0 -- | Returns corresponding @base@ version of the given GHC version. baseVer :: GhcVer -> Text@@ -103,12 +131,13 @@ -} cabalBaseVersions :: [GhcVer] -> Text-cabalBaseVersions [] = ""-cabalBaseVersions [v] = "^>= " <> baseVer v-cabalBaseVersions ghcs = ">= " <> baseVer (minimum ghcs) <> " && < " <> upperBound+cabalBaseVersions ghcVers = case sort ghcVers of+ [] -> ""+ [v] -> "^>= " <> baseVer v+ minGhc:x:xs -> ">= " <> baseVer minGhc <> " && < " <> upperBound (x :| xs) where- upperBound :: Text- upperBound = let Pvp{..} = baseVerPvp $ maximum ghcs in+ upperBound :: NonEmpty GhcVer -> Text+ upperBound ghcs = let Pvp{..} = baseVerPvp $ last ghcs in show pvpFirst <> "." <> show (pvpSecond + 1) -- | Data type to keep meta information for every 'GhcVer'.
+ src/Summoner/Golden.hs view
@@ -0,0 +1,270 @@+{- |+Module : Summoner.Golden+Copyright : (c) 2021-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable++This module contains test data for golden examples.+It is used for both purposes:++ * To test new implementation against the old one+ * In the @gg@ executable to generate new golden examples boilerplate+-}++module Summoner.Golden+ ( -- * Executable scripts+ generateScripts+ -- * Default TOML config+ , generateTomlConfig+ -- * Projects+ -- ** Generator+ , generateProjects+ -- ** Project settings+ , cabalMinimal+ , cabalFull+ , stackFull+ , fullBatteries+ ) where++import Colourista (infoMessage)+import Colourista.Short (b)+import System.Directory (withCurrentDirectory)++import Summoner.CustomPrelude (CustomPrelude (..))+import Summoner.Default (defaultConfigFileContent, defaultGHC)+import Summoner.GhcVer (GhcVer (..))+import Summoner.License (License (..), LicenseName (..))+import Summoner.Settings (Settings (..), Tool (..))+import Summoner.Template (createProjectTemplate)+import Summoner.Template.Script (scriptFile)+import Summoner.Text (quote)+import Summoner.Tree (TreeFs (..), traverseTree)+++generateScripts :: IO ()+generateScripts = do+ generateCabalScript+ generateStackScript++generateCabalScript :: IO ()+generateCabalScript = do+ let path = "summoner-cli/examples/cabalScript.hs"+ infoMessage $ "Writing Cabal script to: " <> toText path+ writeFileText path $ scriptFile defaultGHC Cabal++generateStackScript :: IO ()+generateStackScript = do+ let path = "summoner-cli/examples/stackScript.hs"+ infoMessage $ "Writing Stack script to: " <> toText path+ writeFileText path $ scriptFile defaultGHC Stack++generateTomlConfig :: IO ()+generateTomlConfig = do+ let path = "summoner-cli/examples/summoner-default.toml"+ infoMessage $ "Writing default TOML config to: " <> toText path+ writeFileText path defaultConfigFileContent++----------------------------------------------------------------------------+-- Entire projects+----------------------------------------------------------------------------++generateProjects :: IO ()+generateProjects = withCurrentDirectory "summoner-cli/examples" $ do+ mkProject cabalMinimal+ mkProject cabalFull+ mkProject stackFull+ mkProject fullBatteries++mkProject :: Settings -> IO ()+mkProject settings = do+ infoMessage $ "Creating project: " <> b (settingsRepo settings)+ traverseTree $ createProjectTemplate settings++cabalMinimal :: Settings+cabalMinimal = Settings+ { settingsRepo = "cabal-minimal"+ , settingsOwner = "kowainik"+ , settingsDescription = "Minimal cabal-only test project"+ , settingsFullName = "Kowainik"+ , settingsEmail = "xrom.xkov@gmail.com"+ , settingsYear = "2022"+ , settingsCategories = ""+ , settingsLicenseName = NONE+ , settingsLicenseText = ""+ , settingsGitHub = False+ , settingsGhActions = False+ , settingsPrivate = False+ , settingsTravis = False+ , settingsAppVeyor = False+ , settingsIsLib = False+ , settingsIsExe = True+ , settingsTest = False+ , settingsBench = False+ , settingsTestedVersions = [defaultGHC]+ , settingsPrelude = Nothing+ , settingsExtensions = []+ , settingsGhcOptions = []+ , settingsGitignore = []+ , settingsCabal = True+ , settingsStack = False+ , settingsNoUpload = True+ , settingsFiles = mempty+ }++cabalFull :: Settings+cabalFull = Settings+ { settingsRepo = "cabal-full"+ , settingsOwner = "kowainik"+ , settingsDescription = "Cabal-only example with all integrations"+ , settingsFullName = "Kowainik"+ , settingsEmail = "xrom.xkov@gmail.com"+ , settingsYear = "2022"+ , settingsCategories = "Testing"+ , settingsLicenseName = BSD3+ , settingsLicenseText = bsd3License+ , settingsGitHub = True+ , settingsGhActions = True+ , settingsPrivate = False+ , settingsTravis = True+ , settingsAppVeyor = True+ , settingsIsLib = True+ , settingsIsExe = True+ , settingsTest = True+ , settingsBench = True+ , settingsTestedVersions = [Ghc844 .. defaultGHC]+ , settingsPrelude = Just $ CustomPrelude "relude" "Relude"+ , settingsExtensions = ["DeriveGeneric", "TypeApplications"]+ , settingsGitignore = []+ , settingsGhcOptions = []+ , settingsCabal = True+ , settingsStack = False+ , settingsNoUpload = False+ , settingsFiles = []+ }++stackFull :: Settings+stackFull = Settings+ { settingsRepo = "stack-full"+ , settingsOwner = "kowainik"+ , settingsDescription = "Stack-only example with all integrations"+ , settingsFullName = "Kowainik"+ , settingsEmail = "xrom.xkov@gmail.com"+ , settingsYear = "2022"+ , settingsCategories = "Testing"+ , settingsLicenseName = BSD3+ , settingsLicenseText = bsd3License+ , settingsGitHub = True+ , settingsGhActions = True+ , settingsPrivate = False+ , settingsTravis = True+ , settingsAppVeyor = True+ , settingsIsLib = True+ , settingsIsExe = True+ , settingsTest = True+ , settingsBench = True+ , settingsTestedVersions = [Ghc844 .. defaultGHC]+ , settingsPrelude = Just $ CustomPrelude "relude" "Relude"+ , settingsExtensions = ["DeriveGeneric", "TypeApplications"]+ , settingsGitignore = []+ , settingsGhcOptions = []+ , settingsCabal = False+ , settingsStack = True+ , settingsNoUpload = False+ , settingsFiles = []+ }++fullBatteries :: Settings+fullBatteries = Settings+ { settingsRepo = "full-batteries"+ , settingsOwner = "kowainik"+ , settingsDescription = "Full-featured test project"+ , settingsFullName = "Kowainik"+ , settingsEmail = "xrom.xkov@gmail.com"+ , settingsYear = "2022"+ , settingsCategories = "Testing"+ , settingsLicenseName = MIT+ , settingsLicenseText = mitLicense+ , settingsGitHub = True+ , settingsGhActions = True+ , settingsPrivate = True+ , settingsTravis = True+ , settingsAppVeyor = True+ , settingsIsLib = True+ , settingsIsExe = True+ , settingsTest = True+ , settingsBench = True+ , settingsTestedVersions = [minBound .. defaultGHC]+ , settingsPrelude = Just $ CustomPrelude "relude" "Relude"+ , settingsExtensions = ["ConstraintKinds", "LambdaCase", "OverloadedStrings"]+ , settingsGitignore = [".secret"]+ , settingsGhcOptions = ["-Wcompat", "-Widentities"]+ , settingsCabal = True+ , settingsStack = True+ , settingsNoUpload = True+ , settingsFiles =+ [ File "extra.txt" "See full content of the file [here](@github)\n"+ , Dir ".github" [File "CODEOWNERS" "* @vrom911\n"]+ , File ".stylish-haskell.yaml" "This is stylish-haskell.yaml\n"+ , File "CONTRIBUTING.md" "This is contributing guide\n"+ ]+ }+ where+ mitLicense :: License+ mitLicense = License $ unlines+ [ "MIT License"+ , ""+ , "Copyright (c) 2022 Kowainik"+ , ""+ , "Permission is hereby granted, free of charge, to any person obtaining a copy"+ , "of this software and associated documentation files (the " <> quote "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 " <> quote "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."+ ]++bsd3License :: License+bsd3License = License $ unlines+ [ "BSD 3-Clause License"+ , ""+ , "Copyright (c) 2022, Kowainik"+ , "All rights reserved."+ , ""+ , "Redistribution and use in source and binary forms, with or without"+ , "modification, are permitted provided that the following conditions are met:"+ , ""+ , "1. Redistributions of source code must retain the above copyright notice, this"+ , " list of conditions and the following disclaimer."+ , ""+ , "2. Redistributions in binary form must reproduce the above copyright notice,"+ , " this list of conditions and the following disclaimer in the documentation"+ , " and/or other materials provided with the distribution."+ , ""+ , "3. Neither the name of the copyright holder nor the names of its"+ , " contributors may be used to endorse or promote products derived from"+ , " this software without specific prior written permission."+ , ""+ , "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " <> quote "AS IS"+ , "AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"+ , "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"+ , "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE"+ , "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"+ , "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"+ , "SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"+ , "CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,"+ , "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE"+ , "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."+ ]
src/Summoner/License.hs view
@@ -1,27 +1,29 @@ {- |-Copyright: (c) 2017-2020 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.License+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Data types that represent license names and license content and functions to work with them. -} module Summoner.License- ( LicenseName(..)- , License(..)- , customizeLicense- , githubLicenseQueryNames- , parseLicenseName- , fetchLicense- , fetchLicenseCustom- , licenseShortDesc- , showLicenseWithDesc- ) where+ ( LicenseName (..)+ , License (..)+ , customizeLicense+ , githubLicenseQueryNames+ , parseLicenseName+ , fetchLicense+ , fetchLicenseCustom+ , licenseShortDesc+ , showLicenseWithDesc+ ) where import Colourista (errorMessage)-import Data.Aeson (FromJSON (..), decodeStrict, withObject, (.:))-import Relude.Extra.Enum (inverseMap)+import Data.Aeson.Micro (FromJSON (..), decodeStrict, withObject, (.:)) import Shellmet (($|)) import qualified Data.Text as T
src/Summoner/Mode.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2020 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Mode+Copyright : (c) 2020-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module introduces different modes in which the command-line interface could be.
src/Summoner/Project.hs view
@@ -1,15 +1,16 @@-{-# LANGUAGE QuasiQuotes #-}--{- HLINT ignore "Reduce duplication" -}- {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Project+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module introduces functions for the project creation. -} +{- HLINT ignore "Reduce duplication" -}+ module Summoner.Project ( generateProject , generateProjectInteractive@@ -20,8 +21,6 @@ import Colourista (bold, errorMessage, formattedMessage, green, infoMessage, skipMessage, successMessage, warningMessage) import Data.List.NonEmpty ((<|))-import NeatInterpolation (text)-import Relude.Extra.Enum (universe, universeNonEmpty) import Shellmet (($?)) import System.Directory (findExecutable, setCurrentDirectory) @@ -98,7 +97,7 @@ (settingsGitHub && not settingsNoUpload) (YesNoPrompt "private repository" "Create as a private repository (Requires a GitHub private repo plan)?") cPrivate- settingsGhActions <- decisionIf (settingsCabal && settingsGitHub) (mkDefaultYesNoPrompt "GitHub Actions CI integration") cGhActions+ settingsGhActions <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "GitHub Actions CI integration") cGhActions settingsTravis <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "Travis CI integration") cTravis settingsAppVeyor <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "AppVeyor CI integration") cAppVey settingsIsLib <- promptDecisionToBool cLib (mkDefaultYesNoPrompt "library target")@@ -137,24 +136,23 @@ else falseMessage (yesNoTarget ynPrompt) categoryText :: Text- categoryText =- [text|- List of categories to choose from:-- * Control * Concurrency- * Codec * Graphics- * Data * Sound- * Math * System- * Parsing * Network- * Text-- * Application * Development- * Compilers/Interpreters * Testing- * Web- * Game- * Utility-- |]+ categoryText = unlines+ [ "List of categories to choose from:"+ , ""+ , " * Control * Concurrency"+ , " * Codec * Graphics"+ , " * Data * Sound"+ , " * Math * System"+ , " * Parsing * Network"+ , " * Text"+ , ""+ , " * Application * Development"+ , " * Compilers/Interpreters * Testing"+ , " * Web"+ , " * Game"+ , " * Utility"+ , ""+ ] licenseText :: Text licenseText = "List of licenses to choose from:\n\n"@@ -287,7 +285,7 @@ doGithubCommands :: Settings -> IO () doGithubCommands Settings{..} = do -- Create git repostitory and do a commit.- "git" ["init"]+ "git" ["init", "--initial-branch=main"] "git" ["add", "."] "git" ["commit", "-m", "Create the project"] unless settingsNoUpload $ do@@ -297,7 +295,11 @@ Just _ -> do isHubSuccess <- runHub repo if isHubSuccess- then "git" ["push", "-u", "origin", "master"]+ then do+ "git" ["push", "-u", "origin", "main"]+ "git" ["remote", "set-head", "origin", "-a"]+ successMessage "Project created:"+ infoMessage $ " https://github.com/" <> repo else do warningMessage "Error running 'hub'. Possible reason: incorrect password." hubHelp repo
src/Summoner/Question.hs view
@@ -3,9 +3,12 @@ {-# LANGUAGE ViewPatterns #-} {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Question+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains function to proper questioning in terminal. -}@@ -40,7 +43,6 @@ warningMessage) import System.Directory (doesPathExist, getCurrentDirectory) import System.FilePath ((</>))-import System.IO (hFlush) import Summoner.Text (headToUpper, intercalateMap)
src/Summoner/Settings.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Settings+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Complete settings required for the project creation. -}@@ -13,8 +16,6 @@ , showTool , parseTool ) where--import Relude.Extra.Enum (inverseMap) import Summoner.CustomPrelude (CustomPrelude) import Summoner.GhcVer (GhcVer)
src/Summoner/Source.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Source+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains the 'Source' data that describes how to fetch custom files. -}@@ -89,7 +92,7 @@ -} fetchSource :: ConnectMode -> Source -> IO (Maybe Text) fetchSource connectMode = \case- Local path -> catch (Just <$> readFileText path) (localError path)+ Local path -> catch (Just . decodeUtf8 <$> readFileBS path) (localError path) Url url -> if isOffline connectMode then Nothing <$ infoMessage ("Ignoring fetching from URL in offline mode from source: " <> url) else fetchUrl url `catch` urlError url
src/Summoner/Template.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains functions for the Haskell project template creation. -}
src/Summoner/Template/Cabal.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE QuasiQuotes #-}- {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template.Cabal+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable @.cabal@ file template. -}@@ -12,14 +13,14 @@ ( cabalFile ) where -import NeatInterpolation (text)+import Colourista (indent) import Summoner.CustomPrelude (CustomPrelude (..))-import Summoner.Default (defaultCabal)+import Summoner.Default (defaultCabalVersion) import Summoner.GhcVer (cabalBaseVersions, showGhcVer) import Summoner.License (LicenseName (..)) import Summoner.Settings (Settings (..))-import Summoner.Text (endLine, intercalateMap, packageToModule)+import Summoner.Text (intercalateMap, packageToModule) import Summoner.Tree (TreeFs (..)) import qualified Data.Text as T@@ -37,17 +38,17 @@ , memptyIfFalse settingsIsLib libraryStanza , memptyIfFalse settingsIsExe executableStanza , memptyIfFalse settingsTest testSuiteStanza- , memptyIfFalse settingsBench $ benchmarkStanza $ memptyIfFalse settingsIsLib $ ", " <> settingsRepo+ , memptyIfFalse settingsBench benchmarkStanza ] - -- TODO: do something to not have empty lines cabalHeader :: Text cabalHeader = unlines $- [ "cabal-version: " <> defaultCabal+ [ "cabal-version: " <> defaultCabalVersion , "name: " <> settingsRepo , "version: 0.0.0.0" , "synopsis: " <> settingsDescription- , "description: " <> settingsDescription ] +++ , "description:"+ ] <> fullDescription <> [ "homepage: " <> githubUrl | settingsGitHub ] ++ [ "bug-reports: " <> githubBugReports | settingsGitHub ] ++ ( "license: " <> licenseName) :@@ -62,6 +63,23 @@ , "tested-with: " <> testedGhcs ] + fullDescription :: [Text]+ fullDescription =+ [ " " <> addDot settingsDescription+ , " See " <> readme <> " for more details."+ ]+ where+ readme :: Text+ readme = if settingsGitHub+ then "[README.md](" <> githubUrl <> "#" <> settingsRepo <> ")"+ else "README.md"++ addDot :: Text -> Text+ addDot "" = ""+ addDot txt = case T.last txt of+ '.' -> txt+ _otherChar -> txt <> "."+ githubUrl, githubBugReports :: Text githubUrl = "https://github.com/" <> settingsOwner <> "/" <> settingsRepo githubBugReports = githubUrl <> "/issues"@@ -77,136 +95,145 @@ settingsTestedVersions sourceRepository :: Text- sourceRepository =- [text|- $endLine- source-repository head- type: git- location: ${githubUrl}.git- |]+ sourceRepository = unlines+ [ ""+ , "source-repository head"+ , " type: git"+ , " location: " <> githubUrl <> ".git"+ ] commonStanza :: Text- commonStanza =- [text|- $endLine- common common-options- build-depends: base $baseBounds- $customPrelude- $ghcOptions-- default-language: Haskell2010- |] <> defaultExtensions+ commonStanza = unlines $+ [ ""+ , "common common-options"+ , " build-depends: base " <> baseBounds+ ]+ <> customPrelude+ <> ghcOptions+ <>+ ( ""+ : " default-language: Haskell2010"+ : defaultExtensions+ ) baseBounds :: Text baseBounds = cabalBaseVersions settingsTestedVersions - ghcOptions :: Text- ghcOptions = case settingsGhcOptions of- [] -> defaultGhcOptions- x:xs ->- let customGhcOptions = T.intercalate "\n" $ x : map (T.replicate 21 " " <>) xs in- [text|- ghc-options: $customGhcOptions- |]+ ghcOptions :: [Text]+ ghcOptions = "" : case settingsGhcOptions of+ [] -> defaultGhcOptions+ x:xs -> " ghc-options: " <> x : map (indent 23 <>) xs - defaultGhcOptions :: Text+ defaultGhcOptions :: [Text] defaultGhcOptions =- [text|- ghc-options: -Wall- -Wcompat- -Widentities- -Wincomplete-uni-patterns- -Wincomplete-record-updates- if impl(ghc >= 8.0)- ghc-options: -Wredundant-constraints- if impl(ghc >= 8.2)- ghc-options: -fhide-source-paths- if impl(ghc >= 8.4)- ghc-options: -Wmissing-export-lists- -Wpartial-fields- if impl(ghc >= 8.8)- ghc-options: -Wmissing-deriving-strategies- |]+ [ " ghc-options: -Wall"+ , " -Wcompat"+ , " -Widentities"+ , " -Wincomplete-uni-patterns"+ , " -Wincomplete-record-updates"+ , " -Wredundant-constraints"+ , " -Wnoncanonical-monad-instances"+ , " if impl(ghc >= 8.2)"+ , " ghc-options: -fhide-source-paths"+ , " if impl(ghc >= 8.4)"+ , " ghc-options: -Wmissing-export-lists"+ , " -Wpartial-fields"+ , " if impl(ghc >= 8.8)"+ , " ghc-options: -Wmissing-deriving-strategies"+ , " -fwrite-ide-info"+ , " -hiedir=.hie"+ , " if impl(ghc >= 8.10)"+ , " ghc-options: -Wunused-packages"+ , " if impl(ghc >= 9.0)"+ , " ghc-options: -Winvalid-haddock"+ , " if impl(ghc >= 9.2)"+ , " ghc-options: -Wredundant-bang-patterns"+ , " -Woperator-whitespace"+ , " if impl(ghc >= 9.4 && < 9.10)"+ , " ghc-options: -Wforall-identifier"+ , " if impl(ghc >= 9.4)"+ , " ghc-options: -Wredundant-strictness-flags"+ , " if impl(ghc >= 9.8)"+ , " ghc-options: -Wterm-variable-capture"+ , " -Winconsistent-flags"+ , " if impl(ghc >= 9.10)"+ , " ghc-options: -Wincomplete-record-selectors"+ , " -Wdeprecated-type-abstractions"+ , " -Wdata-kinds-tc"+ , " -Wdefaulted-exception-context"+ , " if impl(ghc >= 9.12)"+ , " ghc-options: -Wview-pattern-signatures"+ ] libraryStanza :: Text- libraryStanza =- [text|- $endLine- library- import: common-options- hs-source-dirs: src- exposed-modules: $libModuleName- |]+ libraryStanza = unlines+ [ ""+ , "library"+ , " import: common-options"+ , " hs-source-dirs: src"+ , " exposed-modules: " <> libModuleName+ ] executableStanza :: Text- executableStanza =- [text|- $endLine- executable $settingsRepo- import: common-options- hs-source-dirs: app- main-is: Main.hs- $buildDepends- $rtsOptions- |]+ executableStanza = unlines $+ [ ""+ , "executable " <> settingsRepo+ , " import: common-options"+ , " hs-source-dirs: app"+ , " main-is: Main.hs"+ ]+ <> buildDepends+ <> rtsOptions testSuiteStanza :: Text- testSuiteStanza =- [text|- $endLine- test-suite ${settingsRepo}-test- import: common-options- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Spec.hs- $buildDepends- $rtsOptions- |]+ testSuiteStanza = unlines $+ [ ""+ , "test-suite " <> settingsRepo <> "-test"+ , " import: common-options"+ , " type: exitcode-stdio-1.0"+ , " hs-source-dirs: test"+ , " main-is: Spec.hs"+ ]+ <> buildDepends+ <> rtsOptions - benchmarkStanza :: Text -> Text- benchmarkStanza commaRepo =- [text|- $endLine- benchmark ${settingsRepo}-benchmark- import: common-options- type: exitcode-stdio-1.0- hs-source-dirs: benchmark- main-is: Main.hs- build-depends: gauge- $commaRepo- $rtsOptions- |]+ benchmarkStanza :: Text+ benchmarkStanza = unlines $+ [ ""+ , "benchmark " <> settingsRepo <> "-benchmark"+ , " import: common-options"+ , " type: exitcode-stdio-1.0"+ , " hs-source-dirs: benchmark"+ , " main-is: Main.hs"+ ]+ <> buildDepends+ <> rtsOptions -- | @build-depends@ for the repo, only if the library is on.- buildDepends :: Text- buildDepends =- if settingsIsLib- then "build-depends: " <> settingsRepo- else ""+ buildDepends :: [Text]+ buildDepends = memptyIfFalse settingsIsLib+ [" build-depends: " <> settingsRepo] - rtsOptions :: Text+ rtsOptions :: [Text] rtsOptions =- [text|- ghc-options: -threaded- -rtsopts- -with-rtsopts=-N- |]+ [ " ghc-options: -threaded"+ , " -rtsopts"+ , " -with-rtsopts=-N"+ ] - customPrelude :: Text+ customPrelude :: [Text] customPrelude = case settingsPrelude of- Nothing -> ""+ Nothing -> [] Just CustomPrelude{..} ->- " , " <> cpPackage <> "\n" <>- [text|- $endLine- mixins: base hiding (Prelude)- , $cpPackage ($cpModule as Prelude)- $endLine- |]+ [ " , " <> cpPackage+ , ""+ , " mixins: base hiding (Prelude)"+ , " , " <> cpPackage <> " (" <> cpModule <> " as Prelude)"+ ] - defaultExtensions :: Text+ defaultExtensions :: [Text] defaultExtensions = case settingsExtensions of- [] -> ""- xs -> " default-extensions: "- <> T.intercalate "\n " xs- <> "\n"+ [] -> []+ x:xs ->+ " default-extensions: " <> x+ : map (indent 23 <>) xs
src/Summoner/Template/Doc.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template.Doc+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Templates for various documentation files: @@ -79,12 +82,12 @@ travisShield, travisLink, travisBadge :: Text travisShield = shieldsIo <> "travis/" <> ownerRepo <> ".svg?logo=travis"- travisLink = "https://travis-ci.org/" <> ownerRepo+ travisLink = "https://travis-ci.com/" <> ownerRepo travisBadge = makeBadge "Build status" travisShield travisLink appVeyorCom, appVeyorShield, appVeyorLink, appVeyorBadge :: Text appVeyorCom = "https://ci.appveyor.com/"- appVeyorShield = appVeyorCom <> "api/projects/status/github/" <> ownerRepo <> "?branch=master&svg=true"+ appVeyorShield = appVeyorCom <> "api/projects/status/github/" <> ownerRepo <> "?branch=main&svg=true" appVeyorLink = appVeyorCom <> "project/" <> ownerRepo appVeyorBadge = makeBadge "Windows build status" appVeyorShield appVeyorLink
src/Summoner/Template/GitHub.hs view
@@ -1,10 +1,12 @@-{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE ViewPatterns #-} -{-|-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+{- |+Module : Summoner.Template.GitHub+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable This module contains template for GitHub related docs: @@ -21,86 +23,92 @@ -} module Summoner.Template.GitHub- ( gitHubFiles- ) where+ ( gitHubFiles+ ) where +import Colourista (indent) import Data.List (delete, intersect)-import NeatInterpolation (text) -import Summoner.Default (defaultCabal, defaultGHC)+import Summoner.Default (defaultCabal, defaultGHC, defaultStack, ghcActionsCacheVersion,+ ghcActionsCheckoutVersion, ghcActionsSetupHaskellVersion) import Summoner.GhcVer (GhcVer (..), oldGhcs, showGhcVer) import Summoner.Settings (Settings (..))-import Summoner.Text (endLine, intercalateMap, tconcatMap)+import Summoner.Text (quote) import Summoner.Tree (TreeFs (..)) gitHubFiles :: Settings -> [TreeFs] gitHubFiles Settings{..} = concat [ [File ".gitignore" (gitignoreDefault <> gitignoreCustom) | settingsGitHub]- , [Dir ".github" [ Dir "workflows" [ File "ci.yml" ghActionsYml ]] | settingsGhActions ]+ , [ Dir ".github"+ [ Dir "workflows" [ File "ci.yml" ghActionsYml ]+ , File "dependabot.yml" dependabotYml+ ]+ | settingsGhActions+ ] , [File ".travis.yml" travisYml | settingsTravis] , [File "appveyor.yml" appVeyorYml | settingsAppVeyor] ] where -- default .gitignore template gitignoreDefault :: Text- gitignoreDefault =- [text|- ### Haskell- dist- dist-*- cabal-dev- *.o- *.hi- *.chi- *.chs.h- *.dyn_o- *.dyn_hi- *.prof- *.aux- *.hp- *.eventlog- .virtualenv- .hsenv- .hpc- .cabal-sandbox/- cabal.sandbox.config- cabal.config- cabal.project.local- .ghc.environment.*- .HTF/- # Stack- .stack-work/- stack.yaml.lock-- ### IDE/support- # Vim- [._]*.s[a-v][a-z]- [._]*.sw[a-p]- [._]s[a-v][a-z]- [._]sw[a-p]- *~- tags-- # IntellijIDEA- .idea/- .ideaHaskellLib/- *.iml-- # Atom- .haskell-ghc-mod.json-- # VS- .vscode/-- # Emacs- *#- .dir-locals.el- TAGS-- # other- .DS_Store- |]+ gitignoreDefault = unlines+ [ "### Haskell"+ , "dist"+ , "dist-*"+ , "cabal-dev"+ , "*.o"+ , "*.hi"+ , "*.chi"+ , "*.chs.h"+ , "*.dyn_o"+ , "*.dyn_hi"+ , "*.prof"+ , "*.aux"+ , "*.hp"+ , "*.eventlog"+ , ".virtualenv"+ , ".hsenv"+ , ".hpc"+ , ".cabal-sandbox/"+ , "cabal.sandbox.config"+ , "cabal.config"+ , "cabal.project.local"+ , ".ghc.environment.*"+ , ".HTF/"+ , ".hie/"+ , "# Stack"+ , ".stack-work/"+ , "stack.yaml.lock"+ , ""+ , "### IDE/support"+ , "# Vim"+ , "[._]*.s[a-v][a-z]"+ , "[._]*.sw[a-p]"+ , "[._]s[a-v][a-z]"+ , "[._]sw[a-p]"+ , "*~"+ , "tags"+ , ""+ , "# IntellijIDEA"+ , ".idea/"+ , ".ideaHaskellLib/"+ , "*.iml"+ , ""+ , "# Atom"+ , ".haskell-ghc-mod.json"+ , ""+ , "# VS"+ , ".vscode/"+ , ""+ , "# Emacs"+ , "*#"+ , ".dir-locals.el"+ , "TAGS"+ , ""+ , "# other"+ , ".DS_Store"+ ] -- additional .gitignore gitignoreCustom :: Text@@ -109,303 +117,395 @@ else unlines ("\n# User specific" : settingsGitignore) ghActionsYml :: Text- ghActionsYml = [text|- name: CI-- # Trigger the workflow on push or pull request, but only for the master branch- on:- pull_request:- push:- branches: [master]-- jobs:- build:- name: ghc ${{ matrix.ghc }}- runs-on: ubuntu-16.04- strategy:- matrix:- cabal: ["${defaultCabal}"]- ghc:- ${ghActionsVersions}-- steps:- - uses: actions/checkout@v2- if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'-- - uses: actions/setup-haskell@v1- name: Setup Haskell- with:- ghc-version: ${{ matrix.ghc }}- cabal-version: ${{ matrix.cabal }}-- - uses: actions/cache@v1- name: Cache ~/.cabal/store- with:- path: ~/.cabal/store- key: ${{ runner.os }}-${{ matrix.ghc }}-cabal+ ghActionsYml = unlines $+ [ "name: CI"+ , ""+ , "on:"+ , " pull_request:"+ , " types: [synchronize, opened, reopened]"+ , " push:"+ , " branches: [main]"+ , " schedule:"+ , " # additionally run once per week (At 00:00 on Sunday) to maintain cache"+ , " - cron: '0 0 * * 0'"+ , ""+ , "jobs:" - - name: Build- run: |- $cabalUpdate- $cabalBuild+ ]+ <> memptyIfFalse settingsCabal ghActionsCabal+ <> memptyIfFalse (settingsCabal && settingsStack) [""]+ <> memptyIfFalse settingsStack ghActionsStack - - name: Test- run: |- ${cabalTest}- |]+ ghActionsCabal :: [Text]+ ghActionsCabal =+ [ " cabal:"+ , " name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}"+ , " runs-on: ${{ matrix.os }}"+ , " strategy:"+ , " matrix:"+ , " os: [ubuntu-latest, macOS-latest, windows-latest]"+ , " cabal: [" <> quote defaultCabal <> "]"+ , " ghc:"+ ]+ <> map (indent 10 <>) ghActionsVersions+ <> ghActionsExcludes+ <>+ [ ""+ , " steps:"+ , " - uses: actions/checkout" <> ghcActionsCheckoutVersion+ , ""+ , " - uses: haskell-actions/setup" <> ghcActionsSetupHaskellVersion+ , " id: setup-haskell-cabal"+ , " name: Setup Haskell"+ , " with:"+ , " ghc-version: ${{ matrix.ghc }}"+ , " cabal-version: ${{ matrix.cabal }}"+ , ""+ , " - name: Configure"+ , " run: |"+ , " " <> cabalConfigure+ , ""+ , " - name: Freeze"+ , " run: |"+ , " cabal freeze"+ , ""+ , " - uses: actions/cache" <> ghcActionsCacheVersion+ , " name: Cache ~/.cabal/store"+ , " with:"+ , " path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}"+ , " key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}"+ , ""+ , " - name: Install dependencies"+ , " run: |"+ , " " <> cabalBuild <> " --only-dependencies"+ , ""+ , " - name: Build"+ , " run: |"+ , " " <> cabalBuild+ , ""+ , " - name: Test"+ , " run: |"+ , " " <> cabalTest+ , ""+ , " - name: Documentation"+ , " run: |"+ , " " <> cabalDocumentation+ , ""+ ] + ghActionsStack :: [Text]+ ghActionsStack =+ [ " stack:"+ , " name: stack / ghc ${{ matrix.ghc }}"+ , " runs-on: ubuntu-latest"+ , " strategy:"+ , " matrix:"+ , " stack: [" <> quote defaultStack <> "]"+ , " ghc:"+ ]+ <> map (indent 10 <>) ghActionsVersions+ <>+ [ ""+ , " steps:"+ , " - uses: actions/checkout" <> ghcActionsCheckoutVersion+ , " if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/main'"+ , ""+ , " - uses: haskell-actions/setup" <> ghcActionsSetupHaskellVersion+ , " name: Setup Haskell Stack"+ , " with:"+ , " ghc-version: ${{ matrix.ghc }}"+ , " stack-version: ${{ matrix.stack }}"+ , ""+ , " - uses: actions/cache" <> ghcActionsCacheVersion+ , " name: Cache ~/.stack"+ , " with:"+ , " path: ~/.stack"+ , " key: ${{ runner.os }}-${{ matrix.ghc }}-stack"+ , ""+ , " - name: Build"+ , " run: |"+ , " " <> stackBuild+ , ""+ , " - name: Test"+ , " run: |"+ , " " <> stackTest+ ] - ghActionsVersions :: Text- ghActionsVersions = intercalateMap- "\n"- (\ghc -> "- " <> ghActionsMatrixItem ghc)+ ghActionsVersions :: [Text]+ ghActionsVersions = map+ (\ghc -> "- " <> quote (showGhcVer ghc)) settingsTestedVersions - ghActionsMatrixItem :: GhcVer -> Text- ghActionsMatrixItem v = "\"" <> showGhcVer v <> "\""+ ghActionsExcludes :: [Text]+ ghActionsExcludes =+ let versionsToExclude = -- all but the latest version+ drop 1 $ sortWith Down settingsTestedVersions+ osesToExclude = ["macOS-latest", "windows-latest"]+ excludes = do+ os <- osesToExclude+ version <- versionsToExclude+ [ "- os: " <> os+ , " ghc: " <> showGhcVer version+ ]+ in case excludes of+ [] -> []+ xs ->+ " exclude:"+ : map (indent 10 <>) xs + dependabotYml :: Text+ dependabotYml = unlines+ [ "updates:"+ , " - package-ecosystem: \"github-actions\""+ , " directory: \"/\""+ , " schedule:"+ , " interval: \"daily\""+ , " commit-message:"+ , " prefix: \"GA\""+ , " include: \"scope\""+ , " labels:"+ , " - \"CI\""+ , " - \"dependencies\""+ ]+ -- create travis.yml template travisYml :: Text- travisYml =- [text|- sudo: true- language: haskell-- git:- depth: 5-- cabal: "${defaultCabal}"-- cache:- directories:- $travisCabalCache- $travisStackCache-- matrix:- include:- $travisCabalMtr- $travisStackMtr- $travisStackAllowFailuresMtr-- $installAndScript-- notifications:- email: false- |]+ travisYml = unlines $+ [ "language: haskell"+ , ""+ , "git:"+ , " depth: 5"+ , ""+ , "cabal: " <> quote defaultCabal+ , ""+ , "cache:"+ , " directories:"+ ]+ <> travisCabalCache+ <> travisStackCache+ <>+ [ ""+ , "jobs:"+ , " include:"+ ]+ <> travisCabalMtr+ <> travisStackMtr+ <> travisStackAllowFailuresMtr+ <> installAndScript+ <>+ [ ""+ , "notifications:"+ , " email: false"+ ] - travisCabalCache, travisStackCache :: Text- travisCabalCache = memptyIfFalse settingsCabal "- \"$HOME/.cabal/store\""+ travisCabalCache, travisStackCache :: [Text]+ travisCabalCache = memptyIfFalse settingsCabal [" - " <> quote "$HOME/.cabal/store"] travisStackCache = memptyIfFalse settingsStack- [text|- - "$$HOME/.stack"- - "$$TRAVIS_BUILD_DIR/.stack-work"- |]+ [ " - " <> quote "$HOME/.stack"+ , " - " <> quote "$TRAVIS_BUILD_DIR/.stack-work"+ ] - travisCabalMtr :: Text+ travisCabalMtr :: [Text] travisCabalMtr = memptyIfFalse settingsCabal $- tconcatMap travisCabalMatrixItem settingsTestedVersions+ map travisCabalMatrixItem settingsTestedVersions travisCabalMatrixItem :: GhcVer -> Text- travisCabalMatrixItem (showGhcVer -> ghcV) = [text|- ghc: $ghcV|]+ travisCabalMatrixItem (showGhcVer -> ghcV) = " - ghc: " <> ghcV -- Due to the Stack issues with newer Cabal versions TravisCI for 'oldGhcs' -- can fail. Possible failure jobs are added to the @allow-failures@ section.- travisStackMtr :: Text- travisStackMtr = memptyIfFalse settingsStack $ tconcatMap- travisStackMatrixItem (delete defaultGHC settingsTestedVersions)+ travisStackMtr :: [Text]+ travisStackMtr = memptyIfFalse settingsStack $+ concatMap travisStackMatrixItem (delete defaultGHC settingsTestedVersions) <> travisStackMatrixDefaultItem - travisStackAllowFailuresMtr :: Text- travisStackAllowFailuresMtr = memptyIfFalse (settingsStack && not (null old))- [text|- $endLine- allow_failures:- $matrix- |]+ travisStackAllowFailuresMtr :: [Text]+ travisStackAllowFailuresMtr = memptyIfFalse (settingsStack && not (null old)) $+ [ ""+ , " allow_failures:"+ ]+ <> concatMap travisStackMatrixItem old where old :: [GhcVer] old = settingsTestedVersions `intersect` oldGhcs - matrix :: Text- matrix = tconcatMap travisStackMatrixItem old-- travisStackMatrixItem :: GhcVer -> Text+ travisStackMatrixItem :: GhcVer -> [Text] travisStackMatrixItem (showGhcVer -> ghcV) =- [text|- $endLine- - ghc: ${ghcV}- env: STACK_YAML="$$TRAVIS_BUILD_DIR/stack-$ghcV.yaml"- |]+ [ ""+ , " - ghc: " <> ghcV+ , " env: STACK_YAML=" <> quote ("$TRAVIS_BUILD_DIR/stack-" <> ghcV <> ".yaml")+ ] - travisStackMatrixDefaultItem :: Text- travisStackMatrixDefaultItem = let defGhc = showGhcVer defaultGHC in- [text|- $endLine- - ghc: ${defGhc}- env: STACK_YAML="$$TRAVIS_BUILD_DIR/stack.yaml"- |]+ travisStackMatrixDefaultItem :: [Text]+ travisStackMatrixDefaultItem =+ [ ""+ , " - ghc: " <> showGhcVer defaultGHC+ , " env: STACK_YAML=" <> quote "$TRAVIS_BUILD_DIR/stack.yaml"+ ] - installAndScript :: Text+ installAndScript :: [Text] installAndScript =+ ""+ : "install:"+ : hlintCheck+ <> if settingsCabal then if settingsStack then installScriptBoth else installScriptCabal else installScriptStack - installScriptBoth :: Text+ installScriptBoth :: [Text] installScriptBoth =- [text|- install:- $hlintCheck-- - |- if [ -z "$$STACK_YAML" ]; then- $cabalUpdate- $cabalBuild- else- curl -sSL https://get.haskellstack.org/ | sh- stack --version- $stackBuild- fi-- script:- - |- if [ -z "$$STACK_YAML" ]; then- ${cabalTest}- else- $stackTest- fi- |]+ [ " - |"+ , " if [ -z " <> quote "$STACK_YAML" <> " ]; then"+ , " " <> cabalUpdate+ , " " <> cabalConfigure+ , " " <> cabalBuild+ , " else"+ , " curl -sSL https://get.haskellstack.org/ | sh"+ , " stack --version"+ , " " <> stackBuild+ , " fi"+ , ""+ , "script:"+ , " - |"+ , " if [ -z " <> quote "$STACK_YAML" <> " ]; then"+ , " " <> cabalTest+ , " else"+ , " " <> stackTest+ , " fi"+ ] - installScriptCabal :: Text+ installScriptCabal :: [Text] installScriptCabal =- [text|- install:- $hlintCheck-- - $cabalUpdate- - $cabalBuild-- script:- - ${cabalTest}- |]+ [ " - " <> cabalUpdate+ , " - " <> cabalConfigure+ , " - " <> cabalBuild+ , ""+ , "script:"+ , " - " <> cabalTest+ ] - installScriptStack :: Text+ installScriptStack :: [Text] installScriptStack =- [text|- install:- $hlintCheck-- - curl -sSL https://get.haskellstack.org/ | sh- - stack --version- - $stackBuild-- script:- - $stackTest- |]+ [ " - curl -sSL https://get.haskellstack.org/ | sh"+ , " - stack --version"+ , " - " <> stackBuild+ , ""+ , "script:"+ , " - " <> stackTest+ ] cabalUpdate :: Text- cabalUpdate = "cabal v2-update"+ cabalUpdate = "cabal update" + cabalConfigure :: Text+ cabalConfigure = "cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always"+ cabalBuild :: Text- cabalBuild = "cabal v2-build --enable-tests --enable-benchmarks"+ cabalBuild = "cabal build all" cabalTest :: Text- cabalTest = if settingsTest- then "cabal v2-test --enable-tests"- else "echo 'No tests'"+ cabalTest = "cabal test all" + cabalDocumentation :: Text+ cabalDocumentation = "cabal haddock"+ stackBuild :: Text stackBuild = "stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror" stackTest :: Text stackTest = "stack test --system-ghc" - hlintCheck :: Text+ hlintCheck :: [Text] hlintCheck =- [text|- # HLint check- - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint .- |]+ [ " # HLint check"+ , " - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint ."+ , ""+ ] appVeyorYml :: Text- appVeyorYml =+ appVeyorYml = unlines $ if settingsCabal then appVeyorYmlCabal else appVeyorYmlStack - appVeyorYmlCabal :: Text- appVeyorYmlCabal = let defGhc = showGhcVer defaultGHC in- [text|- clone_folder: "c:\\WORK"- clone_depth: 5-- # Do not build feature branch with open Pull Requests- skip_branch_with_pr: true-- platform:- - x86_64-- cache:- - "C:\\SR"- - dist-newstyle-- environment:- global:- CABOPTS: --store-dir=C:\\SR-- matrix:- - GHCVER: $defGhc-- install:- - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2- - choco install -y cabal --version 2.4.1.0- - choco install -y ghc --version $defGhc- - refreshenv-- before_build:- - cabal --version- - ghc --version- - cabal %CABOPTS% v2-update+ appVeyorYmlCommon :: [Text]+ appVeyorYmlCommon =+ [ "clone_depth: 5"+ , ""+ , "# Do not build feature branch with open Pull Requests"+ , "skip_branch_with_pr: true"+ , ""+ , "# build only main branch"+ , "branches:"+ , " only:"+ , " - main"+ , ""+ ] - build_script:- - cabal %CABOPTS% v2-build --enable-tests- - cabal %CABOPTS% v2-test --enable-tests- |]+ appVeyorYmlCabal :: [Text]+ appVeyorYmlCabal = let defGhc = showGhcVer defaultGHC in+ ( "clone_folder: " <> quote "c:\\\\WORK" )+ : appVeyorYmlCommon +++ [ "platform:"+ , " - x86_64"+ , ""+ , "cache:"+ , " - " <> quote "C:\\\\SR"+ , " - dist-newstyle"+ , ""+ , "environment:"+ , " global:"+ , " CABOPTS: --store-dir=C:\\\\SR"+ , ""+ , " matrix:"+ , " - GHCVER: " <> defGhc+ , ""+ , "install:"+ , " - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2"+ , " - choco install -y cabal --version 3.6.2.0"+ , " - choco install -y ghc --version " <> defGhc+ , " - refreshenv"+ , ""+ , "before_build:"+ , " - cabal --version"+ , " - ghc --version"+ , " - cabal %CABOPTS% update"+ , ""+ , "build_script:"+ , " - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always"+ , " - cabal %CABOPTS% build all"+ , " - cabal %CABOPTS% test all"+ ] -- create appveyor.yml template- appVeyorYmlStack :: Text- appVeyorYmlStack =- [text|- clone_depth: 5-- # Do not build feature branch with open Pull Requests- skip_branch_with_pr: true-- environment:- STACK_ROOT: C:\sr- STACK_VERSION: 2.1.1-- # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386- # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story- # TODO: check if it's fixed once we switch to lst-13 and GHC 8.6- TMP: "c:\\tmp"-- matrix:- - STACK_YAML: stack.yaml-- cache:- - "%STACK_ROOT% -> %STACK_YAML%, appveyor.yml"- - ".stack-work -> %STACK_YAML%, appveyor.yml"-- install:- - choco install -y haskell-stack --version %STACK_VERSION%- - stack setup > nul-- build_script:- - stack build --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror-- test_script:- - stack test- |]+ appVeyorYmlStack :: [Text]+ appVeyorYmlStack = appVeyorYmlCommon +++ [ "environment:"+ , " STACK_ROOT: C:\\sr"+ , " STACK_VERSION: " <> defaultStack+ , ""+ , " # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386"+ , " # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story"+ , " # TODO: check if it's fixed once we switch to lst-13 and GHC 8.6"+ , " TMP: " <> quote "c:\\\\tmp"+ , ""+ , " matrix:"+ , " - STACK_YAML: stack.yaml"+ , ""+ , "cache:"+ , " - " <> quote "%STACK_ROOT% -> %STACK_YAML%, appveyor.yml"+ , " - " <> quote ".stack-work -> %STACK_YAML%, appveyor.yml"+ , ""+ , "install:"+ , " - choco install -y haskell-stack --version %STACK_VERSION%"+ , " - stack setup > nul"+ , ""+ , "build_script:"+ , " - stack build --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror"+ , ""+ , "test_script:"+ , " - stack test"+ ]
src/Summoner/Template/Haskell.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE QuasiQuotes #-}- {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template.Haskell+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Templates for generated Haskell source code files. -}@@ -12,10 +13,8 @@ ( haskellFiles ) where -import NeatInterpolation (text)- import Summoner.Settings (Settings (..))-import Summoner.Text (packageToModule)+import Summoner.Text (packageToModule, quote) import Summoner.Tree (TreeFs (..)) @@ -28,24 +27,23 @@ ] where libFile :: TreeFs- libFile = File (toString libModuleName <> ".hs")- [text|- {- |- Copyright: (c) $settingsYear $settingsFullName- SPDX-License-Identifier: $licenseName- Maintainer: $settingsFullName <$settingsEmail>-- $settingsDescription- -}-- module $libModuleName- ( someFunc- ) where--- someFunc :: IO ()- someFunc = putStrLn ("someFunc" :: String)- |]+ libFile = File (toString libModuleName <> ".hs") $ unlines+ [ "{- |"+ , "Copyright: (c) " <> settingsYear <> " " <> settingsFullName+ , "SPDX-License-Identifier: " <> licenseName+ , "Maintainer: " <> settingsFullName <> " <" <> settingsEmail <> ">"+ , ""+ , settingsDescription+ , "-}"+ , ""+ , "module " <> libModuleName+ , " ( projectName"+ , " ) where"+ , ""+ , ""+ , "projectName :: String"+ , "projectName = " <> quote settingsRepo+ ] libModuleName :: Text libModuleName = packageToModule settingsRepo@@ -54,48 +52,29 @@ licenseName = show settingsLicenseName exeFile :: TreeFs- exeFile = File "Main.hs" $ if settingsIsLib then createExe else createOnlyExe-- createOnlyExe :: Text- createOnlyExe =- [text|- module Main (main) where--- main :: IO ()- main = putStrLn ("Hello, world!" :: String)- |]-- createExe :: Text- createExe =- [text|- module Main (main) where-- import $libModuleName (someFunc)--- main :: IO ()- main = someFunc- |]+ exeFile = File "Main.hs" $ stanza "Executable" testFile :: TreeFs- testFile = File "Spec.hs"- [text|- module Main (main) where--- main :: IO ()- main = putStrLn ("Test suite is not implemented" :: String)- |]+ testFile = File "Spec.hs" $ stanza "Tests" benchmarkFile :: TreeFs- benchmarkFile = File "Main.hs"- [text|- module Main (main) where-- import Gauge.Main-+ benchmarkFile = File "Main.hs" $ stanza "Benchmarks" - main :: IO ()- main = defaultMain [bench "const" (whnf const ())]- |]+ stanza :: Text -> Text+ stanza st = unlines $+ "module Main (main) where"+ : memptyIfFalse settingsIsLib+ [ ""+ , "import " <> libModuleName <> " (projectName)"+ ]+ <>+ [ ""+ , ""+ , "main :: IO ()"+ , mainContent+ ]+ where+ mainContent :: Text+ mainContent = if settingsIsLib+ then "main = putStrLn (" <> quote (st <> " for ") <> " ++ projectName)"+ else "main = putStrLn (" <> quote (st <> " not implemented") <> " :: String)"
src/Summoner/Template/Script.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE QuasiQuotes #-}- {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template.Script+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable File templates for @cabal@ and @stack@ scripts. -}@@ -12,38 +13,35 @@ ( scriptFile ) where -import NeatInterpolation (text)- import Summoner.GhcVer (GhcVer, baseVer, latestLts) import Summoner.Settings (Tool (..))+import Summoner.Text (quote) -- | 'Text' content for a single script file. scriptFile :: GhcVer -> Tool -> Text scriptFile ghcVer = \case- Cabal ->- [text|- #!/usr/bin/env cabal- {- cabal:- build-depends:- , base ^>= $baseVersion- -}-- main :: IO ()- main = putStrLn "Hello, World!"- |]- Stack ->- [text|- #!/usr/bin/env stack- {- stack- --resolver ${ltsVersion}- script- --package base- -}-- main :: IO ()- main = putStrLn "Hello, World!"- |]+ Cabal -> unlines+ [ "#!/usr/bin/env cabal"+ , "{- cabal:"+ , "build-depends:"+ , " , base ^>= " <> baseVersion+ , "-}"+ , ""+ , "main :: IO ()"+ , "main = putStrLn " <> quote "Hello, World!"+ ]+ Stack -> unlines+ [ "#!/usr/bin/env stack"+ , "{- stack"+ , " --resolver " <> ltsVersion+ , " script"+ , " --package base"+ , "-}"+ , ""+ , "main :: IO ()"+ , "main = putStrLn " <> quote "Hello, World!"+ ] where baseVersion, ltsVersion :: Text baseVersion = baseVer ghcVer
src/Summoner/Template/Stack.hs view
@@ -1,7 +1,10 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Template.Stack+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Templates for @stack.yaml@ files. -}
src/Summoner/Text.hs view
@@ -1,29 +1,27 @@ {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Text+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Various helpful functions to work with 'Text' -} module Summoner.Text- ( endLine- , packageToModule+ ( packageToModule , packageNameValid , moduleNameValid , intercalateMap , headToUpper- , tconcatMap+ , quote ) where import qualified Data.Char as C import qualified Data.Text as T --- | Endline symbol to use with @neat-interpolation@.-endLine :: Text-endLine = "\n"- -- | Creates module name from the name of the package -- Ex: @my-lovely-project@ — @MyLovelyProject@ packageToModule :: Text -> Text@@ -63,3 +61,7 @@ -- | Convert every element of a list into text, and squash the results tconcatMap :: (a -> Text) -> [a] -> Text tconcatMap f = T.concat . map f++-- | Wrap the given text into quotes.+quote :: Text -> Text+quote t = "\"" <> t <> "\""
src/Summoner/Tree.hs view
@@ -1,23 +1,26 @@ {-# LANGUAGE ViewPatterns #-} {- |-Copyright: (c) 2017-2019 Kowainik-SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>+Module : Summoner.Tree+Copyright : (c) 2017-2026 Kowainik+SPDX-License-Identifier : MPL-2.0+Maintainer : Kowainik <xrom.xkov@gmail.com>+Stability : Stable+Portability : Portable Data type for representing filesystem structure via tree. -} module Summoner.Tree- ( TreeFs (..)- , traverseTree- , pathToTree- , insertTree- , showBoldTree- , showTree- ) where+ ( TreeFs (..)+ , traverseTree+ , pathToTree+ , insertTree+ , showBoldTree+ , showTree+ ) where -import Colourista (bold, reset)+import Colourista.Short (b) import System.Directory (createDirectoryIfMissing, withCurrentDirectory) import System.FilePath (splitDirectories) @@ -25,9 +28,9 @@ -- | Describes simple structure of filesystem tree. data TreeFs -- | Name of directory (relative) and its containing entries- = Dir FilePath [TreeFs]+ = Dir !FilePath ![TreeFs] -- | File name (relative) and file content- | File FilePath Text+ | File !FilePath !Text deriving stock (Generic, Show, Eq, Ord) -- | Walks through directory tree and write file contents, creating all@@ -100,10 +103,7 @@ nodeRep = leader <> arm <> tie <> boldDir (fp <> "/") where boldDir :: FilePath -> Text- boldDir str = toText $- if isBold- then bold <> str <> reset- else str+ boldDir str = toText $ if isBold then b str else str extension :: Text extension = case arm of "" -> ""; "└" -> " "; _ -> "│ "
summoner.cabal view
@@ -1,6 +1,6 @@-cabal-version: 2.4+cabal-version: 3.4 name: summoner-version: 2.0.1.1+version: 2.1.0.0 synopsis: Tool for scaffolding fully configured batteries-included production-level Haskell projects. description: Tool for scaffolding fully configured batteries-included production-level Haskell projects. See [README.md](https://github.com/kowainik/summoner#-summoner) for details.@@ -10,7 +10,7 @@ license-file: LICENSE author: Veronika Romashkina, Dmitrii Kovanikov maintainer: Kowainik <xrom.xkov@gmail.com>-copyright: 2018-2020 Kowainik+copyright: 2018-2026 Kowainik category: CLI, CLI Tool, Development build-type: Simple stability: stable@@ -18,8 +18,15 @@ CHANGELOG.md tested-with: GHC == 8.4.4 GHC == 8.6.5- GHC == 8.8.3- GHC == 8.10.1+ GHC == 8.8.4+ GHC == 8.10.7+ GHC == 9.0.2+ GHC == 9.2.8+ GHC == 9.4.7+ GHC == 9.6.7+ GHC == 9.8.4+ GHC == 9.10.3+ GHC == 9.12.3 extra-source-files: examples/summoner-default.toml @@ -72,31 +79,49 @@ location: git@github.com:kowainik/summoner.git common common-options- build-depends: base >= 4.11 && < 4.15- , relude ^>= 0.7.0.0+ build-depends: base >= 4.11 && < 4.22+ , relude >= 1.0.0.0 && < 1.3 mixins: base hiding (Prelude)- , relude (Relude as Prelude- , Relude.Extra.Enum- )+ , relude (Relude as Prelude)+ , relude ghc-options: -Wall -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates- if impl(ghc >= 8.0)- ghc-options: -Wredundant-constraints- if impl(ghc >= 8.2)- ghc-options: -fhide-source-paths- if impl(ghc >= 8.4)- ghc-options: -Wmissing-export-lists+ -Wredundant-constraints+ -Wnoncanonical-monad-instances+ -fhide-source-paths+ -Wmissing-export-lists -Wpartial-fields if impl(ghc >= 8.8) ghc-options: -Wmissing-deriving-strategies -Werror=missing-deriving-strategies+ -fwrite-ide-info+ -hiedir=../.hie if impl(ghc >= 8.10) ghc-options: -Wunused-packages+ if impl(ghc >= 9.0)+ ghc-options: -Winvalid-haddock+ if impl(ghc >= 9.2)+ ghc-options: -Wredundant-bang-patterns+ -Woperator-whitespace+ if impl(ghc >= 9.4 && < 9.10)+ ghc-options: -Wforall-identifier+ if impl(ghc >= 9.4)+ ghc-options: -Wredundant-strictness-flags+ if impl(ghc >= 9.8)+ ghc-options: -Wterm-variable-capture+ -Winconsistent-flags+ if impl(ghc >= 9.10)+ ghc-options: -Wincomplete-record-selectors+ -Wdeprecated-type-abstractions+ -Wdata-kinds-tc+ -Wdefaulted-exception-context+ if impl(ghc >= 9.12)+ ghc-options: -Wview-pattern-signatures default-extensions: DeriveGeneric DerivingStrategies@@ -110,6 +135,11 @@ default-language: Haskell2010 +common exe-options+ ghc-options: -threaded+ -rtsopts+ -with-rtsopts=-N+ library import: common-options hs-source-dirs: src@@ -120,6 +150,7 @@ Summoner.Decision Summoner.Default Summoner.GhcVer+ Summoner.Golden Summoner.License Summoner.Mode Summoner.Project@@ -139,34 +170,34 @@ autogen-modules: Paths_summoner other-modules: Paths_summoner - build-depends: aeson >= 1.2.4.0 && < 1.6- , colourista ^>= 0.1- , containers ^>= 0.6+ build-depends: colourista ^>= 0.1.0.1 , directory ^>= 1.3.0.2- , filepath ^>= 1.4.1.2- , generic-data ^>= 0.8.0.0+ , filepath >= 1.4.1.2 && < 1.6+ , generic-data >= 0.8.0.0 && < 1.2 , gitrev ^>= 1.3.1- , neat-interpolation ^>= 0.3.2.2- , optparse-applicative ^>= 0.15+ , microaeson ^>= 0.1.0.0+ , optparse-applicative >= 0.16 && < 0.20 , process ^>= 1.6.1.0- , shellmet ^>= 0.0.3.0- , text ^>= 1.2.3.0- , time >= 1.8 && < 1.11+ , shellmet >= 0.0.3.0 && < 0.0.7+ , time >= 1.8 && < 1.16 , tomland ^>= 1.3.0.0- , validation-selective >= 0.0.0.0 && < 0.2+ , validation-selective >= 0.1.0.0 && < 0.3 executable summon- import: common-options+ import: common-options, exe-options hs-source-dirs: app main-is: Cli.hs build-depends: summoner - ghc-options: -threaded- -rtsopts- -with-rtsopts=-N+executable gg+ import: common-options, exe-options+ hs-source-dirs: golden+ main-is: Main.hs+ build-depends: summoner + test-suite summoner-test- import: common-options+ import: common-options, exe-options type: exitcode-stdio-1.0 hs-source-dirs: test @@ -181,16 +212,10 @@ build-depends: directory , filepath- , hedgehog >= 0.5.3 && < 1.1+ , hedgehog >= 0.5.3 && < 1.8 , hspec >= 2.4.8- , hspec-hedgehog ^>= 0.0.1.1- , neat-interpolation- , text+ , hspec-hedgehog >= 0.0.1.1 && < 0.4 , tomland- , tree-diff >= 0.0.2 && < 0.2+ , tree-diff >= 0.0.2 && < 0.4 , summoner , validation-selective-- ghc-options: -threaded- -rtsopts- -with-rtsopts=-N
test/Test/Golden.hs view
@@ -1,7 +1,5 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# LANGUAGE QuasiQuotes #-}- {- | Golden tests for @summoner@. In the @test/golden@ folder we now have two projects that are created by@@ -20,17 +18,18 @@ ) where import Data.TreeDiff (ToExpr, ansiWlEditExprCompact, ediff)-import NeatInterpolation (text) import System.Directory (doesDirectoryExist, listDirectory) import System.FilePath (takeFileName, (</>)) import Test.Hspec (Spec, describe, expectationFailure, it) -import Summoner (CustomPrelude (..), GhcVer (..), License (..), LicenseName (..), Settings (..),- defaultGHC)+import Summoner (Settings)+import Summoner.Golden (cabalFull, cabalMinimal, fullBatteries, stackFull) import Summoner.Template (createProjectTemplate) import Summoner.Tree (TreeFs (..)) +import qualified Data.Text as T + goldenSpec :: Spec goldenSpec = describe "golden tests" $ do it "correctly scaffolds the 'cabal-minimal' project" $@@ -56,201 +55,14 @@ dirs <- listDirectory filePath Dir (takeFileName filePath) <$> traverse (\dir -> readTreeFs $ filePath </> dir) dirs False -> do- content <- readFileText filePath+ -- Normalize line endings (CRLF -> LF) for cross-platform compatibility+ content <- T.filter (/= '\r') . decodeUtf8 <$> readFileBS filePath pure $ File (takeFileName filePath) content sortTree :: TreeFs -> TreeFs sortTree = \case file@(File _ _) -> file- Dir path fs -> Dir path $ sort $ map sortTree fs---fullBatteries :: Settings-fullBatteries = Settings- { settingsRepo = "full-batteries"- , settingsOwner = "kowainik"- , settingsDescription = "Full-featured test project"- , settingsFullName = "Kowainik"- , settingsEmail = "xrom.xkov@gmail.com"- , settingsYear = "2020"- , settingsCategories = "Testing"- , settingsLicenseName = MIT- , settingsLicenseText = mitLicense- , settingsGitHub = True- , settingsGhActions = True- , settingsPrivate = True- , settingsTravis = True- , settingsAppVeyor = True- , settingsIsLib = True- , settingsIsExe = True- , settingsTest = True- , settingsBench = True- , settingsTestedVersions = [Ghc802 .. defaultGHC]- , settingsPrelude = Just $ CustomPrelude "relude" "Relude"- , settingsExtensions = ["ConstraintKinds", "LambdaCase", "OverloadedStrings"]- , settingsGitignore = [".secret"]- , settingsGhcOptions = ["-Wcompat", "-Widentities"]- , settingsCabal = True- , settingsStack = True- , settingsNoUpload = True- , settingsFiles =- [ File "extra.txt" "See full content of the file [here](@github)\n"- , Dir ".github" [File "CODEOWNERS" "* @chshersh @vrom911\n"]- , File ".stylish-haskell.yaml" "This is stylish-haskell.yaml\n"- , File "CONTRIBUTING.md" "This is contributing guide\n"- ]- }- where- mitLicense :: License- mitLicense = License [text|-MIT License--Copyright (c) 2018 Kowainik--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.-|]--stackFull :: Settings-stackFull = Settings- { settingsRepo = "stack-full"- , settingsOwner = "kowainik"- , settingsDescription = "Stack-only example with all integrations"- , settingsFullName = "Kowainik"- , settingsEmail = "xrom.xkov@gmail.com"- , settingsYear = "2020"- , settingsCategories = "Testing"- , settingsLicenseName = BSD3- , settingsLicenseText = bsd3License- , settingsGitHub = True- , settingsGhActions = False- , settingsPrivate = False- , settingsTravis = True- , settingsAppVeyor = True- , settingsIsLib = True- , settingsIsExe = True- , settingsTest = True- , settingsBench = True- , settingsTestedVersions = [Ghc844 .. defaultGHC]- , settingsPrelude = Just $ CustomPrelude "relude" "Relude"- , settingsExtensions = ["DeriveGeneric", "TypeApplications"]- , settingsGitignore = []- , settingsGhcOptions = []- , settingsCabal = False- , settingsStack = True- , settingsNoUpload = False- , settingsFiles = []- }--cabalFull :: Settings-cabalFull = Settings- { settingsRepo = "cabal-full"- , settingsOwner = "kowainik"- , settingsDescription = "Cabal-only example with all integrations"- , settingsFullName = "Kowainik"- , settingsEmail = "xrom.xkov@gmail.com"- , settingsYear = "2020"- , settingsCategories = "Testing"- , settingsLicenseName = BSD3- , settingsLicenseText = bsd3License- , settingsGitHub = True- , settingsGhActions = True- , settingsPrivate = False- , settingsTravis = True- , settingsAppVeyor = True- , settingsIsLib = True- , settingsIsExe = True- , settingsTest = True- , settingsBench = True- , settingsTestedVersions = [Ghc844 .. defaultGHC]- , settingsPrelude = Just $ CustomPrelude "relude" "Relude"- , settingsExtensions = ["DeriveGeneric", "TypeApplications"]- , settingsGitignore = []- , settingsGhcOptions = []- , settingsCabal = True- , settingsStack = False- , settingsNoUpload = False- , settingsFiles = []- }--cabalMinimal :: Settings-cabalMinimal = Settings- { settingsRepo = "cabal-minimal"- , settingsOwner = "kowainik"- , settingsDescription = "Minimal cabal-only test project"- , settingsFullName = "Kowainik"- , settingsEmail = "xrom.xkov@gmail.com"- , settingsYear = "2020"- , settingsCategories = ""- , settingsLicenseName = NONE- , settingsLicenseText = ""- , settingsGitHub = False- , settingsGhActions = False- , settingsPrivate = False- , settingsTravis = False- , settingsAppVeyor = False- , settingsIsLib = False- , settingsIsExe = True- , settingsTest = False- , settingsBench = False- , settingsTestedVersions = [defaultGHC]- , settingsPrelude = Nothing- , settingsExtensions = []- , settingsGhcOptions = []- , settingsGitignore = []- , settingsCabal = True- , settingsStack = False- , settingsNoUpload = True- , settingsFiles = mempty- }--bsd3License :: License-bsd3License = License [text|-BSD 3-Clause License--Copyright (c) 2020, Kowainik-All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:--1. Redistributions of source code must retain the above copyright notice, this- list of conditions and the following disclaimer.--2. Redistributions in binary form must reproduce the above copyright notice,- this list of conditions and the following disclaimer in the documentation- and/or other materials provided with the distribution.--3. Neither the name of the copyright holder nor the names of its- contributors may be used to endorse or promote products derived from- this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-|]+ Dir path fs -> Dir path $ sort $ map sortTree fs -- Orphan instances
test/Test/Script.hs view
@@ -1,45 +1,22 @@-{-# LANGUAGE QuasiQuotes #-}- module Test.Script- ( scriptSpec- ) where+ ( scriptSpec+ ) where -import NeatInterpolation (text)-import Test.Hspec (Spec, describe, it, shouldBe)+import Test.Hspec (Spec, describe, it, shouldReturn) -import Summoner.GhcVer (GhcVer (..))+import Summoner.Default (defaultGHC) import Summoner.Settings (Tool (..)) import Summoner.Template.Script (scriptFile) +import qualified Data.Text as T scriptSpec :: Spec scriptSpec = describe "script golden tests" $ do it "correctly creates cabal script" $- scriptFile Ghc844 Cabal `shouldBe` cabalScript+ readScript "examples/cabalScript.hs" `shouldReturn` scriptFile defaultGHC Cabal it "correctly creates stack script" $- scriptFile Ghc865 Stack `shouldBe` stackScript--cabalScript :: Text-cabalScript = [text|-#!/usr/bin/env cabal-{- cabal:-build-depends:- , base ^>= 4.11.1.0--}--main :: IO ()-main = putStrLn "Hello, World!"-|]--stackScript :: Text-stackScript = [text|-#!/usr/bin/env stack-{- stack- --resolver lts-14.27- script- --package base--}+ readScript "examples/stackScript.hs" `shouldReturn` scriptFile defaultGHC Stack -main :: IO ()-main = putStrLn "Hello, World!"-|]+-- | Read a script file, normalizing line endings (CRLF -> LF) for cross-platform compatibility+readScript :: FilePath -> IO Text+readScript path = T.filter (/= '\r') . decodeUtf8 <$> readFileBS path
test/Test/Show.hs view
@@ -14,10 +14,17 @@ goldenGhcTable :: [Text] goldenGhcTable =- [ "GHC-7.10.3 base-4.8.0.2 lts-6.35"- , "GHC-8.0.2 base-4.9.1.0 lts-9.21"- , "GHC-8.2.2 base-4.10.1.0 lts-11.22"- , "GHC-8.4.4 base-4.11.1.0 lts-12.26"- , "GHC-8.6.5 base-4.12.0.0 lts-14.27"- , "GHC-8.8.3 base-4.13.0.0 lts-15.5"- ]+ [ "GHC-8.0.2 base-4.9.1.0 lts-9.21"+ , "GHC-8.2.2 base-4.10.1.0 lts-11.22"+ , "GHC-8.4.4 base-4.11.1.0 lts-12.26"+ , "GHC-8.6.5 base-4.12.0.0 lts-14.27"+ , "GHC-8.8.4 base-4.13.0.0 lts-16.31"+ , "GHC-8.10.7 base-4.14.3.0 lts-18.28"+ , "GHC-9.0.2 base-4.15.1.0 lts-19.33"+ , "GHC-9.2.8 base-4.16.4.0 lts-20.26"+ , "GHC-9.4.8 base-4.17.2.1 lts-21.25"+ , "GHC-9.6.7 base-4.18.3.1 lts-22.44"+ , "GHC-9.8.4 base-4.19.2.0 lts-23.28"+ , "GHC-9.10.3 base-4.20.2.0 lts-24.26"+ , "GHC-9.12.3 base-4.21.1.0 nightly-2026-01-04"+ ]
test/Test/TomlSpec.hs view
@@ -3,11 +3,10 @@ ) where import Hedgehog (MonadGen, forAll, tripping)-import Relude.Extra.Enum (universe) import Test.Hspec (Spec, describe, it, shouldReturn, shouldSatisfy) import Test.Hspec.Hedgehog (hedgehog) import Toml.Codec.Code (decode, encode)-import Validation (Validation (..))+import Validation (isSuccess) import Summoner.Config (ConfigP (..), PartialConfig, configCodec, defaultConfig, finalise) import Summoner.CustomPrelude (CustomPrelude (..))@@ -34,11 +33,9 @@ it "parses default configuration" $ decode configCodec defaultConfigFileContent `shouldSatisfy` isRight it "default configuration is up-to-date" $- readFileText "examples/summoner-default.toml"+ -- Normalize line endings (CRLF -> LF) for cross-platform compatibility+ T.filter (/= '\r') . decodeUtf8 <$> readFileBS "examples/summoner-default.toml" `shouldReturn` defaultConfigFileContent- where- isSuccess :: Validation e a -> Bool- isSuccess = \case { Success _ -> True; _ -> False } tomlProp :: Spec tomlProp = describe "TOML property tests" $