diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 92d3748..bbf33cf 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -2,22 +2,18 @@ name: Haskell CI on: push: - branches: - - '*' - pull_request: - branches: [ "master" ] + workflow_dispatch: permissions: contents: read jobs: fourmolu: - runs-on: ubuntu-latest - + steps: - - uses: actions/checkout@v3 - - uses: haskell-actions/run-fourmolu@v9 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: haskell-actions/run-fourmolu@3b7702b41516aa428dfe6e295dc73476ae58f69e # v11 with: version: "0.14.0.0" build: @@ -27,104 +23,58 @@ jobs: fail-fast: false matrix: os: [windows-latest, macos-latest, ubuntu-latest] - ghc-version: ['9.6', '9.4', '9.2', '9.0'] + ghc-version: ["9.12", "9.10", "9.8", "9.6", "9.4", "9.2"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up GHC ${{ matrix.ghc-version }} - uses: haskell/actions/setup@v2 + uses: haskell-actions/setup@96f3dafd067155f32643c2a0757ab71d2910e2c2 # v2.8.0 id: setup with: ghc-version: ${{ matrix.ghc-version }} - enable-stack: true - name: Installed minor versions of GHC, Cabal, and Stack shell: bash run: | GHC_VERSION=$(ghc --numeric-version) CABAL_VERSION=$(cabal --numeric-version) - STACK_VERSION=$(stack --numeric-version) echo "GHC_VERSION=${GHC_VERSION}" >> "${GITHUB_ENV}" echo "CABAL_VERSION=${CABAL_VERSION}" >> "${GITHUB_ENV}" - echo "STACK_VERSION=${STACK_VERSION}" >> "${GITHUB_ENV}" + + - name: Check cabal file + run: cabal check - name: Configure the build run: | - # cabal configure --enable-tests --enable-benchmarks --disable-documentation - # cabal build --dry-run - stack build --test --bench --no-haddock --dry-run - # The last step generates dist-newstyle/cache/plan.json for the cache key. - - - name: Restore .stack-work cache - uses: actions/cache/restore@v3 - id: cache-restore-stack-work - with: - path: .stack-work - key: ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-work-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}-${{ hashFiles('**/*.hs') }} - restore-keys: | - ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-work- - - - name: Restore ~/.stack cache (Unix) - uses: actions/cache/restore@v3 - id: cache-restore-stack-global-unix - if: runner.os == 'Linux' || runner.os == 'macOS' - with: - path: ~/.stack - key: ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} - restore-keys: | - ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-global- - - - name: Restore %APPDATA%\stack, %LOCALAPPDATA%\Programs\stack cache (Windows) - uses: actions/cache/restore@v3 - id: cache-restore-stack-global-windows - if: runner.os == 'Windows' + cabal configure --enable-tests --enable-benchmarks --disable-documentation + cabal build --dry-run + + - name: Restore cached dependencies + uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + id: cache + env: + key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-cabal-${{ steps.setup.outputs.cabal-version }} with: - path: | - ~\AppData\Roaming\stack - ~\AppData\Local\Programs\stack - key: ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }} - restore-keys: | - ${{ runner.os }}-ghc-${{ env.GHC_VERSION }}-stack-${{ env.STACK_VERSION }}-stack-global- + path: ${{ steps.setup.outputs.cabal-store }} + key: ${{ env.key }}-plan-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ env.key }}- - name: Build dependencies - run: stack build --only-dependencies + run: cabal build --only-dependencies - - name: Build the package - run: stack build - - - name: Save .stack-work cache - uses: actions/cache/save@v3 - id: cache-save-stack-work - if: steps.cache-restore-stack-work.outputs.cache-hit != 'true' - with: - path: .stack-work - key: ${{ steps.cache-restore-stack-work.outputs.cache-primary-key }} - - - name: Save %APPDATA%\stack, %LOCALAPPDATA%\Programs\stack cache (Windows) - uses: actions/cache/save@v3 - if: runner.os == 'Windows' - && steps.cache-restore-stack-global-windows.outputs.cache-hit != 'true' + - name: Save cached dependencies + uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + if: steps.cache.outputs.cache-hit != 'true' with: - path: | - ~\AppData\Roaming\stack - ~\AppData\Local\Programs\stack - key: ${{ steps.cache-restore-stack-global-windows.outputs.cache-primary-key }} - - - name: Save ~/.stack cache (Unix) - uses: actions/cache/save@v3 - id: cache-save-stack-global - if: (runner.os == 'Linux' || runner.os == 'macOS') - && steps.cache-restore-stack-global-unix.outputs.cache-hit != 'true' - with: - path: ~/.stack - key: ${{ steps.cache-restore-stack-global-unix.outputs.cache-primary-key }} + path: ${{ steps.setup.outputs.cabal-store }} + key: ${{ steps.cache.outputs.cache-primary-key }} - - name: Run tests - run: stack test + - name: Build the package + run: cabal build all - - name: Check cabal file - run: cabal check + - name: Run tests + run: cabal test all - name: Build documentation - run: stack haddock \ No newline at end of file + run: cabal haddock all --disable-documentation diff --git a/ChangeLog.md b/ChangeLog.md index 5e6fb45..62325e2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,9 @@ ## Unreleased changes +- Use Hspec for tests +- Add nix flake + ## [v0.2.0.0](https://github.com/rasheedja/LPPaver/tree/v0.2.0.0) - Setup CI diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7d8c09d --- /dev/null +++ b/flake.lock @@ -0,0 +1,633 @@ +{ + "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1645834128, + "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=", + "owner": "haskell", + "repo": "cabal", + "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1669081697, + "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=", + "owner": "haskell", + "repo": "cabal", + "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1672831974, + "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=", + "owner": "input-output-hk", + "repo": "flake-compat", + "rev": "45f2638735f8cdc40fe302742b79f248d23eb368", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "hkm/gitlab-fix", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1758846310, + "narHash": "sha256-kVnn9TScof8n41p7LqwvBvoLlfFhLDkjrP+aOAhmQ9k=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "173aca690d454916a2d1ab5a7d13b593240fa0f5", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage-for-stackage": { + "flake": false, + "locked": { + "lastModified": 1758846300, + "narHash": "sha256-uS0e51ny5rGdI5HiOttTYMjGyOqBSoraXDWCY7gFc9g=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "813f87b29c01a70bf479ff7c72b240d7d6a3fe16", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "for-stackage", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage-internal": { + "flake": false, + "locked": { + "lastModified": 1750307553, + "narHash": "sha256-iiafNoeLHwlSLQTyvy8nPe2t6g5AV4PPcpMeH/2/DLs=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "f7867baa8817fab296528f4a4ec39d1c7c4da4f3", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskellNix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-compat": "flake-compat", + "hackage": "hackage", + "hackage-for-stackage": "hackage-for-stackage", + "hackage-internal": "hackage-internal", + "hls": "hls", + "hls-1.10": "hls-1.10", + "hls-2.0": "hls-2.0", + "hls-2.10": "hls-2.10", + "hls-2.11": "hls-2.11", + "hls-2.2": "hls-2.2", + "hls-2.3": "hls-2.3", + "hls-2.4": "hls-2.4", + "hls-2.5": "hls-2.5", + "hls-2.6": "hls-2.6", + "hls-2.7": "hls-2.7", + "hls-2.8": "hls-2.8", + "hls-2.9": "hls-2.9", + "hpc-coveralls": "hpc-coveralls", + "iserv-proxy": "iserv-proxy", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ], + "nixpkgs-2305": "nixpkgs-2305", + "nixpkgs-2311": "nixpkgs-2311", + "nixpkgs-2405": "nixpkgs-2405", + "nixpkgs-2411": "nixpkgs-2411", + "nixpkgs-2505": "nixpkgs-2505", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1758847890, + "narHash": "sha256-rGX7RF8Au5ZJJSqlQivsl4seyEslI/K3OnEC9ulLwNM=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "46abef90b4101ff9253a574cf6fbdc74b78a5863", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "hls": { + "flake": false, + "locked": { + "lastModified": 1741604408, + "narHash": "sha256-tuq3+Ip70yu89GswZ7DSINBpwRprnWnl6xDYnS4GOsc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "682d6894c94087da5e566771f25311c47e145359", + "type": "github" + }, + "original": { + "owner": "haskell", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-1.10": { + "flake": false, + "locked": { + "lastModified": 1680000865, + "narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.0": { + "flake": false, + "locked": { + "lastModified": 1687698105, + "narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "783905f211ac63edf982dd1889c671653327e441", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.0.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.10": { + "flake": false, + "locked": { + "lastModified": 1743069404, + "narHash": "sha256-q4kDFyJDDeoGqfEtrZRx4iqMVEC2MOzCToWsFY+TOzY=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "2318c61db3a01e03700bd4b05665662929b7fe8b", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.11": { + "flake": false, + "locked": { + "lastModified": 1747306193, + "narHash": "sha256-/MmtpF8+FyQlwfKHqHK05BdsxC9LHV70d/FiMM7pzBM=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "46ef4523ea4949f47f6d2752476239f1c6d806fe", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.11.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.2": { + "flake": false, + "locked": { + "lastModified": 1693064058, + "narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.2.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.3": { + "flake": false, + "locked": { + "lastModified": 1695910642, + "narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.3.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.4": { + "flake": false, + "locked": { + "lastModified": 1699862708, + "narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.4.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.5": { + "flake": false, + "locked": { + "lastModified": 1701080174, + "narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "27f8c3d3892e38edaef5bea3870161815c4d014c", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.5.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.6": { + "flake": false, + "locked": { + "lastModified": 1705325287, + "narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.6.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.7": { + "flake": false, + "locked": { + "lastModified": 1708965829, + "narHash": "sha256-LfJ+TBcBFq/XKoiNI7pc4VoHg4WmuzsFxYJ3Fu+Jf+M=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "50322b0a4aefb27adc5ec42f5055aaa8f8e38001", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.7.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.8": { + "flake": false, + "locked": { + "lastModified": 1715153580, + "narHash": "sha256-Vi/iUt2pWyUJlo9VrYgTcbRviWE0cFO6rmGi9rmALw0=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "dd1be1beb16700de59e0d6801957290bcf956a0a", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.8.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.9": { + "flake": false, + "locked": { + "lastModified": 1719993701, + "narHash": "sha256-wy348++MiMm/xwtI9M3vVpqj2qfGgnDcZIGXw8sF1sA=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "90319a7e62ab93ab65a95f8f2bcf537e34dae76a", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.9.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "iserv-proxy": { + "flake": false, + "locked": { + "lastModified": 1755243078, + "narHash": "sha256-GLbl1YaohKdpzZVJFRdcI1O1oE3F3uBer4lFv3Yy0l8=", + "owner": "stable-haskell", + "repo": "iserv-proxy", + "rev": "150605195cb7183a6fb7bed82f23fedf37c6f52a", + "type": "github" + }, + "original": { + "owner": "stable-haskell", + "ref": "iserv-syms", + "repo": "iserv-proxy", + "type": "github" + } + }, + "nixpkgs-2305": { + "locked": { + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2311": { + "locked": { + "lastModified": 1719957072, + "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2405": { + "locked": { + "lastModified": 1735564410, + "narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2411": { + "locked": { + "lastModified": 1748037224, + "narHash": "sha256-92vihpZr6dwEMV6g98M5kHZIttrWahb9iRPBm1atcPk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f09dede81861f3a83f7f06641ead34f02f37597f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2505": { + "locked": { + "lastModified": 1754477006, + "narHash": "sha256-suIgZZHXdb4ca9nN4MIcmdjeN+ZWsTwCtYAG4HExqAo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4896699973299bffae27d0d9828226983544d9e9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-25.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1754393734, + "narHash": "sha256-fbnmAwTQkuXHKBlcL5Nq1sMAzd3GFqCOQgEQw6Hy0Ak=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a683adc19ff5228af548c6539dbc3440509bfed3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "haskellNix": "haskellNix", + "nixpkgs": [ + "haskellNix", + "nixpkgs-2505" + ] + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1758845522, + "narHash": "sha256-SgkvlWF9a+Qrkn791ZOiUVt3wuZXRJ06YjpTZMRy+R8=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "e2f097d435e38fb6e649efa4a95e214a506a1da5", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + }, + "systems": { + "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..69be272 --- /dev/null +++ b/flake.nix @@ -0,0 +1,45 @@ +{ + inputs = { + haskellNix.url = "github:input-output-hk/haskell.nix"; + nixpkgs.follows = "haskellNix/nixpkgs-2505"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, haskellNix }: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ haskellNix.overlay ]; + pkgs = import nixpkgs { + inherit system overlays; + inherit (haskellNix) config; + }; + + project = pkgs.haskell-nix.cabalProject' { + src = ./.; + compiler-nix-name = "ghc967"; + shell = { + tools = { + cabal = "3.16.0.0"; + hlint = "3.8"; + haskell-language-server = "2.11.0.0"; + fourmolu = "0.17.0.0"; + }; + buildInputs = with pkgs; [ + # system dependencies go here + ]; + }; + }; + + flake = project.flake {}; + in flake); + + # --- Flake Local Nix Configuration --- + nixConfig = { + # This sets the flake to use the IOG nix cache. + # Nix should ask for permission before using it, + # but remove it here if you do not want it to. + extra-substituters = ["https://cache.iog.io"]; + extra-trusted-public-keys = ["hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="]; + allow-import-from-derivation = "true"; + }; +} diff --git a/package.yaml b/package.yaml deleted file mode 100644 index f4ba4bc..0000000 --- a/package.yaml +++ /dev/null @@ -1,56 +0,0 @@ -name: simplex-method -version: 0.2.0.0 -github: "rasheedja/simplex-method" -license: BSD3 -author: "Junaid Rasheed" -maintainer: "jrasheed178@gmail.com" -copyright: "BSD-3" - -extra-source-files: -- README.md -- ChangeLog.md - -# Metadata used when publishing your package -synopsis: Implementation of the two-phase simplex method in exact rational arithmetic -category: Math, Maths, Mathematics, Optimisation, Optimization, Linear Programming - -# To avoid duplicated efforts in documentation and dealing with the -# complications of embedding Haddock markup inside cabal files, it is -# common to point users to the README.md file. -description: Please see the README on GitHub at - -dependencies: -- base >= 4.14 && < 5 -- containers >= 0.6.5.1 && < 0.7 -- generic-lens >= 2.2.0 && < 2.3 -- lens >= 5.2.2 && < 5.3 -- monad-logger >= 0.3.40 && < 0.4 -- text >= 2.0.2 && < 2.1 -- time >= 1.12.2 && < 1.13 - -default-extensions: - DataKinds - DeriveFunctor - DeriveGeneric - DisambiguateRecordFields - DuplicateRecordFields - FlexibleContexts - LambdaCase - OverloadedLabels - OverloadedRecordDot - OverloadedStrings - RecordWildCards - TemplateHaskell - TupleSections - TypeApplications - NamedFieldPuns - -library: - source-dirs: src - -tests: - simplex-haskell-test: - main: Spec.hs - source-dirs: test - dependencies: - - simplex-method diff --git a/simplex-method.cabal b/simplex-method.cabal index 3078198..f3e9673 100644 --- a/simplex-method.cabal +++ b/simplex-method.cabal @@ -1,9 +1,3 @@ -cabal-version: 1.12 - --- This file has been generated from package.yaml by hpack version 0.36.0. --- --- see: https://github.com/sol/hpack - name: simplex-method version: 0.2.0.0 synopsis: Implementation of the two-phase simplex method in exact rational arithmetic @@ -16,6 +10,7 @@ maintainer: jrasheed178@gmail.com copyright: BSD-3 license: BSD3 license-file: LICENSE +cabal-version: 1.12 build-type: Simple extra-source-files: README.md @@ -36,34 +31,77 @@ library hs-source-dirs: src default-extensions: - DataKinds DeriveFunctor DeriveGeneric DisambiguateRecordFields DuplicateRecordFields FlexibleContexts LambdaCase OverloadedLabels OverloadedRecordDot OverloadedStrings RecordWildCards TemplateHaskell TupleSections TypeApplications NamedFieldPuns + DataKinds + DeriveFunctor + DeriveGeneric + DerivingStrategies + DisambiguateRecordFields + DuplicateRecordFields + ExtendedDefaultRules + FlexibleContexts + GeneralizedNewtypeDeriving + LambdaCase + NamedFieldPuns + OverloadedLabels + OverloadedRecordDot + OverloadedStrings + RecordWildCards + TemplateHaskell + TupleSections + TypeApplications + QuasiQuotes build-depends: base >=4.14 && <5 - , containers >=0.6.5.1 && <0.7 - , generic-lens >=2.2.0 && <2.3 - , lens >=5.2.2 && <5.3 - , monad-logger >=0.3.40 && <0.4 - , text >=2.0.2 && <2.1 - , time >=1.12.2 && <1.13 + , containers >= 0.6.5.1 && < 0.8 + , generic-lens >= 2.2 && < 2.3 + , lens >= 5.2.2 && < 5.4 + , text >= 2.0.2 && < 2.2 + , time >= 1.12.2 && < 1.15 + , monad-logger >= 0.3.40 && < 0.4 + , QuickCheck >= 2.16.0 && < 2.17 default-language: Haskell2010 test-suite simplex-haskell-test type: exitcode-stdio-1.0 main-is: Spec.hs other-modules: - TestFunctions + Linear.Simplex.Solver.TwoPhaseSpec Paths_simplex_method hs-source-dirs: test default-extensions: - DataKinds DeriveFunctor DeriveGeneric DisambiguateRecordFields DuplicateRecordFields FlexibleContexts LambdaCase OverloadedLabels OverloadedRecordDot OverloadedStrings RecordWildCards TemplateHaskell TupleSections TypeApplications NamedFieldPuns + DataKinds + DeriveFunctor + DeriveGeneric + DerivingStrategies + DisambiguateRecordFields + DuplicateRecordFields + ExtendedDefaultRules + FlexibleContexts + GeneralizedNewtypeDeriving + LambdaCase + NamedFieldPuns + OverloadedLabels + OverloadedRecordDot + OverloadedStrings + RecordWildCards + TemplateHaskell + TupleSections + TypeApplications + QuasiQuotes build-depends: base >=4.14 && <5 - , containers >=0.6.5.1 && <0.7 - , generic-lens >=2.2.0 && <2.3 - , lens >=5.2.2 && <5.3 - , monad-logger >=0.3.40 && <0.4 , simplex-method - , text >=2.0.2 && <2.1 - , time >=1.12.2 && <1.13 + , containers >= 0.6.5.1 && < 0.8 + , generic-lens >= 2.2 && < 2.3 + , lens >= 5.2.2 && < 5.4 + , text >= 2.0.2 && < 2.2 + , time >= 1.12.2 && < 1.15 + , monad-logger >= 0.3.40 && < 0.4 + , QuickCheck >= 2.16.0 && < 2.17 + , hspec >= 2.11.12 && < 2.12 + , hspec-expectations >= 0.8.3 && < 0.9 + , interpolatedstring-perl6 >= 1.0.2 && < 1.1 + build-tool-depends: + hspec-discover:hspec-discover >= 2.11.12 && < 2.12 default-language: Haskell2010 diff --git a/stack.yaml b/stack.yaml deleted file mode 100644 index eab5650..0000000 --- a/stack.yaml +++ /dev/null @@ -1,68 +0,0 @@ -# This file was automatically generated by 'stack init' -# -# Some commonly used options have been documented as comments in this file. -# For advanced use and comprehensive documentation of the format, please see: -# https://docs.haskellstack.org/en/stable/yaml_configuration/ - -# Resolver to choose a 'specific' stackage snapshot or a compiler version. -# A snapshot resolver dictates the compiler version and the set of packages -# to be used for project dependencies. For example: -# -# resolver: lts-3.5 -# resolver: nightly-2015-09-21 -# resolver: ghc-7.10.2 -# -# The location of a snapshot can be provided as a file or url. Stack assumes -# a snapshot provided as a file might change, whereas a url resource does not. -# -# resolver: ./custom-snapshot.yaml -# resolver: https://example.com/snapshots/2018-01-01.yaml -resolver: lts-21.22 - -# User packages to be built. -# Various formats can be used as shown in the example below. -# -# packages: -# - some-directory -# - https://example.com/foo/bar/baz-0.0.2.tar.gz -# subdirs: -# - auto-update -# - wai -packages: -- . -# Dependency packages to be pulled from upstream that are not in the resolver. -# These entries can reference officially published versions as well as -# forks / in-progress versions pinned to a git hash. For example: -# -# extra-deps: -# - acme-missiles-0.3 -# - git: https://github.com/commercialhaskell/stack.git -# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# -# extra-deps: {} - -# Override default flag values for local packages and extra-deps -# flags: {} - -# Extra package databases containing global packages -# extra-package-dbs: [] - -# Control whether we use the GHC we find on the path -# system-ghc: true -# -# Require a specific version of stack, using version ranges -# require-stack-version: -any # Default -# require-stack-version: ">=2.5" -# -# Override the architecture used by stack, especially useful on Windows -# arch: i386 -# arch: x86_64 -# -# Extra directories used by stack for building -# extra-include-dirs: [/path/to/dir] -# extra-lib-dirs: [/path/to/dir] -# -# Allow a newer minor version of GHC than the snapshot specifies -# compiler-check: newer-minor - -system-ghc: true diff --git a/stack.yaml.lock b/stack.yaml.lock deleted file mode 100644 index e8d3cc7..0000000 --- a/stack.yaml.lock +++ /dev/null @@ -1,12 +0,0 @@ -# This file was autogenerated by Stack. -# You should not edit this file by hand. -# For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files - -packages: [] -snapshots: -- completed: - sha256: afd5ba64ab602cabc2d3942d3d7e7dd6311bc626dcb415b901eaf576cb62f0ea - size: 640060 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/22.yaml - original: lts-21.22 diff --git a/test/TestFunctions.hs b/test/Linear/Simplex/Solver/TwoPhaseSpec.hs similarity index 95% rename from test/TestFunctions.hs rename to test/Linear/Simplex/Solver/TwoPhaseSpec.hs index b2af317..06b98d9 100644 --- a/test/TestFunctions.hs +++ b/test/Linear/Simplex/Solver/TwoPhaseSpec.hs @@ -1,9 +1,21 @@ -module TestFunctions where +module Linear.Simplex.Solver.TwoPhaseSpec where +import Prelude hiding (EQ) + +import Control.Monad +import Control.Monad.IO.Class +import Control.Monad.Logger import qualified Data.Map as M import Data.Ratio +import Text.InterpolatedString.Perl6 + +import Test.Hspec +import Test.Hspec.Expectations.Contrib (annotate) + +import Linear.Simplex.Prettify +import Linear.Simplex.Solver.TwoPhase import Linear.Simplex.Types -import Prelude hiding (EQ) +import Linear.Simplex.Util testsList :: [((ObjectiveFunction, [PolyConstraint]), Maybe Result)] testsList = @@ -1046,3 +1058,35 @@ testQuickCheck3 = , GEQ (M.fromList [(1, -5), (2, -1), (2, 1)]) (-5) ] ) + +spec :: Spec +spec = describe "twoPhaseSimplex" $ do + it "Check golden tests" $ do + forM_ testsList $ + \((obj, constraints), expectedResult) -> do + actualResult <- + runStdoutLoggingT $ + filterLogger (\_logSource logLevel -> logLevel > LevelInfo) $ + twoPhaseSimplex obj constraints + let prettyObj = prettyShowObjectiveFunction obj + prettyConstraints = map prettyShowPolyConstraint constraints + + expectedObjVal = extractObjectiveValue expectedResult + actualObjVal = extractObjectiveValue actualResult + annotate + [qc| + +Objective Function (Non-prettified): {obj} +Constraints (Non-prettified): {constraints} +==================================== +Objective Function (Prettified): {prettyObj} +Constraints (Prettified): {prettyConstraints} +==================================== +Expected Solution (Full): {expectedResult} +Actual Solution (Full): {actualResult} +Expected Solution (Objective): {expectedObjVal} +Actual Solution (Objective): {actualObjVal} + + |] + $ do + actualResult `shouldBe` expectedResult diff --git a/test/Spec.hs b/test/Spec.hs index 4a8ad55..a824f8c 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1,42 +1 @@ -module Main where - -import Control.Monad -import Control.Monad.IO.Class -import Control.Monad.Logger - -import Linear.Simplex.Prettify -import Linear.Simplex.Solver.TwoPhase -import Linear.Simplex.Types -import Linear.Simplex.Util - -import TestFunctions - -main :: IO () -main = runStdoutLoggingT $ filterLogger (\_logSource logLevel -> logLevel > LevelInfo) $ runTests testsList - -runTests :: (MonadLogger m, MonadFail m, MonadIO m) => [((ObjectiveFunction, [PolyConstraint]), Maybe Result)] -> m () -runTests [] = do - liftIO $ putStrLn "All tests passed" - pure () -runTests (((testObjective, testConstraints), expectedResult) : tests) = - do - testResult <- twoPhaseSimplex testObjective testConstraints - if testResult == expectedResult - then runTests tests - else do - let msg = - "\nThe following test failed: " - <> ("\nObjective Function (Non-prettified): " ++ show testObjective) - <> ("\nConstraints (Non-prettified): " ++ show testConstraints) - <> "\n====================================" - <> ("\nObjective Function (Prettified): " ++ prettyShowObjectiveFunction testObjective) - <> "\nConstraints (Prettified): " - <> "\n" - <> concatMap (\c -> "\t" ++ prettyShowPolyConstraint c ++ "\n") testConstraints - <> "\n====================================" - <> ("\nExpected Solution (Full): " ++ show expectedResult) - <> ("\nActual Solution (Full): " ++ show testResult) - <> ("\nExpected Solution (Objective): " ++ show (extractObjectiveValue expectedResult)) - <> ("\nActual Solution (Objective): " ++ show (extractObjectiveValue testResult)) - <> "\n" - fail msg +{-# OPTIONS_GHC -F -pgmF hspec-discover #-}