commit d45d07b39b20095aa4785f03dc2fada004598cf9 Author: Alexander Kobjolke Date: Wed Nov 29 21:29:32 2023 +0100 Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6622ec1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.pre-commit-config.yaml +result +.direnv diff --git a/aoc.cabal b/aoc.cabal new file mode 100644 index 0000000..dc8e04a --- /dev/null +++ b/aoc.cabal @@ -0,0 +1,128 @@ +cabal-version: 2.0 + +-- This file has been generated from package.yaml by hpack version 0.35.2. +-- +-- see: https://github.com/sol/hpack + +name: aoc +version: 0.0.1.0 +description: Advent-Of-Code +author: Alexander Kobjolke +maintainer: alex@jakalx.net +copyright: Alexander Kobjolke 2023 +license: MIT +build-type: Simple +extra-source-files: + README.org + +library + exposed-modules: + AoC + AoC.Internal + other-modules: + Paths_aoc + autogen-modules: + Paths_aoc + hs-source-dirs: + src + default-extensions: + BlockArguments + OverloadedStrings + ImportQualifiedPost + ghc-options: -Weverything -Wno-implicit-prelude -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -fdefer-typed-holes + build-depends: + base + , containers + , megaparsec + , relude + , text + mixins: + base hiding (Prelude) + , relude (Relude as Prelude) + default-language: GHC2021 + +executable aoc + main-is: aoc.hs + other-modules: + Paths_aoc + autogen-modules: + Paths_aoc + hs-source-dirs: + app + default-extensions: + BlockArguments + OverloadedStrings + ImportQualifiedPost + ghc-options: -Weverything -Wno-implicit-prelude -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -fdefer-typed-holes + build-depends: + aoc + , base + , containers + , megaparsec + , relude + , text + mixins: + base hiding (Prelude) + , relude (Relude as Prelude) + default-language: GHC2021 + +test-suite doctest + type: exitcode-stdio-1.0 + main-is: Doctest.hs + other-modules: + Paths_aoc + autogen-modules: + Paths_aoc + hs-source-dirs: + test/doctest + default-extensions: + BlockArguments + OverloadedStrings + ImportQualifiedPost + ghc-options: -Weverything -Wno-implicit-prelude -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -fdefer-typed-holes + build-tool-depends: + doctest:doctest + build-depends: + base + , containers + , megaparsec + , process + , relude + , text + mixins: + base hiding (Prelude) + , relude (Relude as Prelude) + default-language: Haskell2010 + +test-suite spec + type: exitcode-stdio-1.0 + main-is: Spec.hs + other-modules: + AoCSpec + Paths_aoc + autogen-modules: + Paths_aoc + hs-source-dirs: + test/spec + default-extensions: + BlockArguments + OverloadedStrings + ImportQualifiedPost + ghc-options: -Weverything -Wno-implicit-prelude -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -fdefer-typed-holes + cpp-options: -DTEST + build-tool-depends: + hspec-discover:hspec-discover + build-depends: + QuickCheck + , aoc + , base + , containers + , hspec + , megaparsec + , quickcheck-instances + , relude + , text + mixins: + base hiding (Prelude) + , relude (Relude as Prelude) + default-language: GHC2021 diff --git a/app/aoc.hs b/app/aoc.hs new file mode 100644 index 0000000..0d613fd --- /dev/null +++ b/app/aoc.hs @@ -0,0 +1,6 @@ +module Main (main) where + +import AoC qualified + +main :: IO () +main = AoC.defaultMain diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..38bb947 --- /dev/null +++ b/flake.lock @@ -0,0 +1,171 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1701290038, + "narHash": "sha256-mcbPGHxG9c7Og+SkKYTAtOJwDERGx5kvTVH0BH1PNXE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "231ffe19425544deb8da37b1362b545ef90bcb40", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils_2", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1700922917, + "narHash": "sha256-ej2fch/T584b5K9sk1UhmZF7W6wEfDHuoUYpFN8dtvM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "e5ee5c5f3844550c01d2131096c7271cec5e9b78", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8af83c9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,76 @@ +{ + description = "Advent-Of-Code"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; + + flake-utils.url = "github:numtide/flake-utils"; + + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { self, nixpkgs, flake-utils, pre-commit-hooks }: + flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + + overlay = final: prev: { aoc = final.callCabal2nix "aoc" ./. { }; }; + + haskellPackages = pkgs.haskell.packages.ghc942.extend overlay; + in { + packages.default = haskellPackages.aoc; + + apps = { + # run with: nix run #.aoc + aoc = { + type = "app"; + program = "${self.packages.${system}.default}/bin/aoc"; + }; + + # run with: nix run + default = self.apps.${system}.aoc; + }; + + checks = { + pre-commit-check = pre-commit-hooks.lib.${system}.run { + src = ./.; + settings = { ormolu.defaultExtensions = [ "GHC2021" ]; }; + tools.fourmolu = haskellPackages.fourmolu; + hooks = { + nixfmt.enable = true; + fourmolu.enable = true; + hpack.enable = true; + hlint.enable = true; + doctest = { + enable = false; + name = "Run documentation tests"; + entry = "${haskellPackages.doctest}/bin/doctest src app"; + files = "\\.l?hs$"; + pass_filenames = false; + }; + }; + }; + }; + + devShells.default = haskellPackages.shellFor { + inherit (self.checks.${system}.pre-commit-check) shellHook; + + packages = p: [ p.aoc ]; + + withHoogle = true; + + nativeBuildInputs = with pkgs; [ + haskellPackages.haskell-language-server + haskellPackages.fourmolu + haskellPackages.hspec-discover + haskellPackages.doctest + cabal-install + ghcid + nixfmt + hpack + hlint + ]; + }; + }); +} diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 0000000..d8c5559 --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,2 @@ +haddock-style: single-line +indentation: 2 diff --git a/package.yaml b/package.yaml new file mode 100644 index 0000000..321ed2a --- /dev/null +++ b/package.yaml @@ -0,0 +1,74 @@ +name: aoc +version: 0.0.1.0 +license: MIT +author: "Alexander Kobjolke" +maintainer: "alex@jakalx.net" +copyright: "Alexander Kobjolke 2023" +description: "Advent-Of-Code" + +extra-source-files: + - README.org + +dependencies: + - name: base + mixin: + - hiding (Prelude) + - name: relude + mixin: + - (Relude as Prelude) + - containers + - text + - megaparsec + +ghc-options: + - -Weverything + - -Wno-implicit-prelude + - -Wno-missing-import-lists # Requires explicit imports of _every_ function (e.g. ‘$’); too strict + - -Wno-missed-specialisations # When GHC can’t specialize a polymorphic function. No big deal and requires fixing underlying libraries to solve. + - -Wno-all-missed-specialisations # See missed-specialisations + - -Wno-unsafe # Don’t use Safe Haskell warnings + - -Wno-safe # Don’t use Safe Haskell warnings + - -Wno-missing-local-signatures # Warning for polymorphic local bindings; nothing wrong with those. + - -Wno-monomorphism-restriction # Don’t warn if the monomorphism restriction is used + - -fdefer-typed-holes + +default-extensions: + - BlockArguments + - OverloadedStrings + - ImportQualifiedPost + +library: + source-dirs: src + verbatim: + default-language: GHC2021 + +executables: + aoc: + source-dirs: app + main: aoc.hs + dependencies: + - aoc + verbatim: + default-language: GHC2021 + +tests: + spec: + cpp-options: -DTEST + main: Spec.hs + source-dirs: + - test/spec + dependencies: + - aoc + - hspec + - QuickCheck + - quickcheck-instances + build-tools: hspec-discover + verbatim: + default-language: GHC2021 + doctest: + main: Doctest.hs + dependencies: + - process + source-dirs: + - test/doctest + build-tools: doctest diff --git a/src/AoC.hs b/src/AoC.hs new file mode 100644 index 0000000..7a3c6dc --- /dev/null +++ b/src/AoC.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE OverloadedStrings #-} + +module AoC ( + defaultMain, +) where + +import Control.Exception qualified as Exception +import System.IO (hPutStrLn) +import System.IO.Error qualified as IOError + +runAoC :: [String] -> IO () +runAoC _args = putStrLn "Hello" + +handleError :: IOError.IOError -> IO () +handleError e = do + hPutStrLn stderr $ "I ran into an issue: " <> show e + +defaultMain :: IO () +defaultMain = do + args <- getArgs + Exception.catch (runAoC args) handleError diff --git a/src/AoC/Internal.hs b/src/AoC/Internal.hs new file mode 100644 index 0000000..160a7af --- /dev/null +++ b/src/AoC/Internal.hs @@ -0,0 +1,2 @@ +-- | Internal module in order to facilitate testability. +module AoC.Internal where diff --git a/test/doctest/Doctest.hs b/test/doctest/Doctest.hs new file mode 100644 index 0000000..72c84cf --- /dev/null +++ b/test/doctest/Doctest.hs @@ -0,0 +1,10 @@ +-- | Rn the doctest executable +module Main where + +import System.Process (callProcess) + +doctest :: [String] -> IO () +doctest = callProcess "doctest" + +main :: IO () +main = doctest ["--fast", "src"] diff --git a/test/spec/AoCSpec.hs b/test/spec/AoCSpec.hs new file mode 100644 index 0000000..303f6ae --- /dev/null +++ b/test/spec/AoCSpec.hs @@ -0,0 +1,12 @@ +module AoCSpec (spec) where + +import AoC.Internal + +import Test.Hspec +import Test.Hspec.QuickCheck (prop) + +spec :: Spec +spec = do + describe "parseArgs" do + it "returns the filename if given a single argument" do + True `shouldBe` True diff --git a/test/spec/Spec.hs b/test/spec/Spec.hs new file mode 100644 index 0000000..a824f8c --- /dev/null +++ b/test/spec/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover #-}