git.iko.soy/typeable/compaREST
on 5e2eff7 help sign in
33 files changed+161−269
since splitsnapshots
unifiedsplit
.github/actions/common_setup/action.yaml+2−2 .github/workflows/github-actions-image.yaml+81−60 .gitmodules+3 CHANGELOG.md+1−5 README.md+3−1 action.yaml+1−1 app/Data/OpenApi/Compare/Options.hs−1 app/Main.hs−1 awsm-css+1 compaREST.cabal+4−6 css/awsm.min.css−1 default.nix+7−18 docs/Integration_guide.md+2 github-action/Main.hs+7−13 nix/ci.nix+1−6 nix/diff-yaml.nix−20 nix/shell.nix−11 nix/sources.json+13−13 nix/yq.nix−26 policeman.json+6 scripts/diff-yaml−35 src/Data/OpenApi/Compare/PathsPrefixTree.hs+4−5 src/Data/OpenApi/Compare/Report.hs+1−1 src/Data/OpenApi/Compare/Report/Html/Template.hs+1−1 src/Data/OpenApi/Compare/Validate/OpenApi.hs+1−2 src/Data/OpenApi/Compare/Validate/Schema.hs+1−1 src/Data/OpenApi/Compare/Validate/Schema/JsonFormula.hs+6−7 src/Data/OpenApi/Compare/Validate/Schema/Partition.hs+1−4 src/Data/OpenApi/Compare/Validate/Schema/Process.hs−2 stack.yaml+4−16 stack.yaml.lock+4−4 test/Spec/Golden/Extra.hs+2−2 test/golden/common/random-example/trace-tree.yaml+4−4
.github/actions/common_setup/action.yaml+2−2
@@ -30,13 +30,13 @@ runs:
3030 fi
3131
3232 - name: Install Nix
33− uses: cachix/install-nix-action@v27
33+ uses: cachix/install-nix-action@v16
3434 with:
3535 extra_nix_config: |
3636 system-features = kvm
3737 trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
3838 substituters = https://hydra.iohk.io https://cache.nixos.org/
39− - uses: cachix/cachix-action@v15
39+ - uses: cachix/cachix-action@v10
4040 with:
4141 name: typeable
4242 authToken: "${{ inputs.authToken }}"
.github/workflows/github-actions-image.yaml+81−60
@@ -9,23 +9,23 @@ on:
99 types: [prereleased]
1010
1111jobs:
12−# check-formatting:
13−# name: Check Haskell formatting
14−# runs-on: ubuntu-latest
15−# steps:
16−# - uses: actions/checkout@v2
17−#
18−# - name: Common setup
19−# uses: ./.github/actions/common_setup
20−# with:
21−# authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
22−#
23−# - name: Run fourmolu
24−# run: |
25−# nix-shell nix/ci.nix -j auto --run "git ls-files '*.hs' | xargs fourmolu -m inplace -o -XRecursiveDo -o -XTypeApplications -o -XPatternSynonyms -o -XBangPatterns"
26−# git diff --exit-code
12+ check-formatting:
13+ name: Check Haskell formatting
14+ runs-on: ubuntu-latest
15+ steps:
16+ - uses: actions/checkout@v2
2717
28− check_versions:
18+ - name: Common setup
19+ uses: ./.github/actions/common_setup
20+ with:
21+ authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
22+
23+ - name: Run fourmolu
24+ run: |
25+ nix-shell nix/ci.nix -j auto --run "git ls-files '*.hs' | xargs fourmolu -m inplace -o -XRecursiveDo -o -XTypeApplications -o -XPatternSynonyms -o -XBangPatterns"
26+ git diff --exit-code
27+
28+ policeman:
2929 runs-on: ubuntu-latest
3030 steps:
3131 - uses: actions/checkout@v2
@@ -37,6 +37,25 @@ jobs:
3737 with:
3838 authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
3939
40+ - name: Run policeman
41+ run: |
42+ jq --argjson msg "$( $(nix-build ci/policeman.nix)/bin/policeman | grep -v "⚙" | jq -aRs . )" ".[0].message = \$msg" <policeman.json >message.json
43+ cat message.json
44+
45+ - name: Post notice
46+ uses: yuzutech/annotations-action@v0.4.0
47+ with:
48+ title: 👮 Policeman
49+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
50+ input: "./message.json"
51+
52+ check_versions:
53+ runs-on: ubuntu-latest
54+ steps:
55+ - uses: actions/checkout@v2
56+ with:
57+ submodules: recursive
58+
4059 - name: Check library version
4160 if: github.event_name == 'release'
4261 run: |
@@ -108,6 +127,13 @@ jobs:
108127 name: compaREST Docker Image
109128 path: compaREST-image.tar.gz
110129
130+ - name: Install skopeo
131+ if: github.event_name == 'release'
132+ shell: bash
133+ run: |
134+ sudo apt-get -y update
135+ sudo apt-get -y install skopeo
136+
111137 - name: Login to DockerHub
112138 uses: docker/login-action@v1.10.0
113139 with:
@@ -159,18 +185,13 @@ jobs:
159185 tag: ${{ github.ref }}
160186
161187 dist:
162− needs: [check_versions, Linux]
188+ needs: check_versions
163189 runs-on: ubuntu-latest
164190 steps:
165191 - uses: actions/checkout@v2
166192 with:
167193 submodules: recursive
168194
169− - name: Common setup
170− uses: ./.github/actions/common_setup
171− with:
172− authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
173−
174195 - name: Cache
175196 uses: actions/cache@v1
176197 with:
@@ -189,7 +210,7 @@ jobs:
189210
190211 - name: Build dist
191212 run: |
192− stack sdist --pvp-bounds both
213+ stack sdist --pvp-bounds both --test-tarball
193214 echo "distPath=$(stack path | awk -F ": " '/dist-dir/ {print $2}')" >> $GITHUB_ENV
194215
195216 - name: Upload compaREST sources artifact
@@ -213,7 +234,7 @@ jobs:
213234 env:
214235 HACKAGE_KEY: ${{ secrets.HACKAGE_KEY }}
215236 run: |
216− stack upload --pvp-bounds both --candidate .
237+ stack upload --pvp-bounds both --test-tarball --candidate .
217238
218239 macOS:
219240 needs: check_versions
@@ -252,39 +273,39 @@ jobs:
252273 file: compaREST-macOS-x86.zip
253274 tag: ${{ github.ref }}
254275
255−# Linux-Windows:
256−# needs: check_versions
257−# runs-on: ubuntu-latest
258−# steps:
259−# - uses: actions/checkout@v2
260−# with:
261−# submodules: recursive
262−#
263−# - name: Common setup
264−# uses: ./.github/actions/common_setup
265−# with:
266−# authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
267−#
268−# - name: Build Windows binary
269−# run: |
270−# cp -LR $(nix-build -A WindowsCompaRESTBin -j auto --no-out-link)/bin compaREST
271−#
272−# - name: Upload Windows compaREST bundle
273−# uses: actions/upload-artifact@v2
274−# with:
275−# name: compaREST binary – Windows
276−# path: compaREST
277−#
278−# - name: Zip Release Assets
279−# if: github.event_name == 'release'
280−# shell: bash
281−# run: |
282−# zip -r compaREST-Windows.zip compaREST
283−#
284−# - name: Upload compaREST binary – Windows to release
285−# if: github.event_name == 'release'
286−# uses: svenstaro/upload-release-action@2.2.1
287−# with:
288−# repo_token: ${{ secrets.GITHUB_TOKEN }}
289−# file: compaREST-Windows.zip
290−# tag: ${{ github.ref }}
276+ Linux-Windows:
277+ needs: check_versions
278+ runs-on: ubuntu-latest
279+ steps:
280+ - uses: actions/checkout@v2
281+ with:
282+ submodules: recursive
283+
284+ - name: Common setup
285+ uses: ./.github/actions/common_setup
286+ with:
287+ authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
288+
289+ - name: Build Windows binary
290+ run: |
291+ cp -LR $(nix-build -A WindowsCompaRESTBin -j auto --no-out-link)/bin compaREST
292+
293+ - name: Upload Windows compaREST bundle
294+ uses: actions/upload-artifact@v2
295+ with:
296+ name: compaREST binary – Windows
297+ path: compaREST
298+
299+ - name: Zip Release Assets
300+ if: github.event_name == 'release'
301+ shell: bash
302+ run: |
303+ zip -r compaREST-Windows.zip compaREST
304+
305+ - name: Upload compaREST binary – Windows to release
306+ if: github.event_name == 'release'
307+ uses: svenstaro/upload-release-action@2.2.1
308+ with:
309+ repo_token: ${{ secrets.GITHUB_TOKEN }}
310+ file: compaREST-Windows.zip
311+ tag: ${{ github.ref }}
.gitmodulesnew file+3
@@ -0,0 +1,3 @@
1+[submodule "awsm-css"]
2+ path = awsm-css
3+ url = https://github.com/igoradamenko/awsm.css.git
CHANGELOG.md+1−5
@@ -1,10 +1,6 @@
11# Changelog
22
3−`compaREST` uses [PVP Versioning][1].
4−
5−## 0.1.0.1
6−
7−* Fixed an issue related to empty commit SHAs in GitHub Actions.
3+`comparest` uses [PVP Versioning][1].
84
95## 0.1.0.0
106
README.md+3−1
@@ -1,6 +1,8 @@
11# compaREST
22
3−[![Hackage](https://img.shields.io/hackage/v/compaREST.svg?logo=haskell)](https://hackage.haskell.org/package/compaREST)
3+[![Hackage](https://img.shields.io/hackage/v/compaREST.svg?logo=haskell)](https://hackage.haskell.org/package/comparest)
4+[![Stackage Lts](http://stackage.org/package/compaREST/badge/lts)](http://stackage.org/lts/package/comparest)
5+[![Stackage Nightly](http://stackage.org/package/comparest/badge/nightly)](http://stackage.org/nightly/package/comparest)
46[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
57
68Compatibility checker for OpenAPI
action.yaml+1−1
@@ -30,7 +30,7 @@ inputs:
3030 default: "${{ github.event.pull_request.head.sha }}"
3131runs:
3232 using: "docker"
33− image: "docker://typeable/comparest-github-action:0.1.0.1"
33+ image: "docker://typeable/comparest-github-action:0.1.0.0"
3434 env:
3535 GITHUB_TOKEN: "${{ inputs.GITHUB_TOKEN }}"
3636 REPO: "${{ inputs.repo }}"
app/Data/OpenApi/Compare/Options.hs−1
@@ -9,7 +9,6 @@ import Data.OpenApi.Compare.Report
99import GHC.Generics (Generic)
1010import Options.Applicative
1111import Options.Applicative.Help hiding (fullDesc)
12−import Text.PrettyPrint.ANSI.Leijen ((<$$>),string)
1312
1413parseOptions :: IO Options
1514parseOptions = customExecParser (prefs $ showHelpOnError) optionsParserInfo
app/Main.hs−1
@@ -2,7 +2,6 @@ module Main (main) where
22
33import Control.Monad
44import Control.Monad.Except
5−import Control.Monad.Trans (lift)
65import Data.Aeson
76import qualified Data.ByteString.Lazy as BSL
87import Data.Default
awsm-cssnew file+1

Submodule changed.

compaREST.cabal+4−6
@@ -1,6 +1,6 @@
11cabal-version: 2.4
22name: compaREST
3−version: 0.1.0.1
3+version: 0.1.0.0
44synopsis: Compatibility checker for OpenAPI
55description: Compatibility checker for OpenAPI.
66license: MIT
@@ -12,8 +12,8 @@ category: Web
1212build-type: Simple
1313extra-doc-files: README.md
1414 CHANGELOG.md
15−tested-with: GHC == 9.6
16−extra-source-files: css/awsm.min.css
15+tested-with: GHC == 8.10.4
16+extra-source-files: awsm-css/dist/awsm.min.css
1717extra-source-files:
1818 test/golden/**/*.yaml
1919 test/golden/**/*.md
@@ -26,14 +26,13 @@ common common-options
2626 -Wno-safe
2727 -Wno-prepositive-qualified-module
2828 -Wno-missing-import-lists
29− -Wno-missing-kind-signatures
3029 -Wno-partial-fields
3130 -Wno-all-missed-specialisations
3231 -Wno-missing-local-signatures
3332 -Wno-unsafe
3433 -fconstraint-solver-iterations=0
3534 default-language: Haskell2010
36− build-depends: base >= 4.12.0.0 && < 5
35+ build-depends: base >= 4.12.0.0 && < 4.16
3736 , text
3837
3938
@@ -166,7 +165,6 @@ executable compaREST
166165 , containers
167166 , doctemplates
168167 , pandoc-types
169− , prettyprinter-compat-ansi-wl-pprint
170168 ghc-options: -threaded
171169 -rtsopts
172170 -with-rtsopts=-N
css/awsm.min.cssdeleted−1
@@ -1 +0,0 @@
1−@charset "UTF-8";html{font-family:"PT Serif",Georgia,serif;font-size:100%;line-height:1.6;background:#fff;color:#000;-webkit-overflow-scrolling:touch}body{margin:1em;font-size:1rem}@media (min-width:20rem){body{font-size:calc(1rem + .0125*(100vw - 20rem))}}@media (min-width:40rem){body{font-size:1.25rem}}body article,body footer,body header,body main{position:relative;max-width:40rem;margin:0 auto}body>header{margin-bottom:3.5em}body>header h1{margin:0;font-size:1.5em}body>header p{margin:0;font-size:.85em}body>footer{margin-top:4.5em;padding-bottom:1.5em;text-align:center;font-size:.8rem;color:#aaa}details,nav,p{margin:1em 0}nav ul{list-style:none;margin:0;padding:0}nav li{display:inline-block;margin-right:1em;margin-bottom:.25em}nav a:visited{color:#0064c1}article header h1 a:visited:hover,article header h2 a:visited:hover,nav a:hover{color:#3000c1}ol,ul{margin-top:0;padding-top:0;padding-left:2.5em}p{-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}aside:first-child,p:first-child{margin-top:0}aside:last-child,p:last-child{margin-bottom:0}p+ol,p+ul{margin-top:-.75em}p img,p picture{float:right;margin-bottom:.5em;margin-left:.5em}p picture img{float:none;margin:0}blockquote,dd{padding-left:2.5em}dd{margin-bottom:1em;margin-left:0}dt{font-weight:700}blockquote{margin:0}aside{margin:.5em 0;font-style:italic;color:#aaa}@media (min-width:65rem){aside{position:absolute;right:-12.5rem;width:9.375rem;max-width:9.375rem;margin:0;padding-left:.5em;font-size:.8em;border-left:1px solid #f2f2f2}}section+section{margin-top:2em}h1,h2,h3,h4,h5,h6{margin:1.25em 0 0;line-height:1.2}h1:focus>a[href^="#"][id],h1:hover>a[href^="#"][id],h2:focus>a[href^="#"][id],h2:hover>a[href^="#"][id],h3:focus>a[href^="#"][id],h3:hover>a[href^="#"][id],h4:focus>a[href^="#"][id],h4:hover>a[href^="#"][id],h5:focus>a[href^="#"][id],h5:hover>a[href^="#"][id],h6:focus>a[href^="#"][id],h6:hover>a[href^="#"][id]{opacity:1;transition:opacity 0s,color 300ms ease-out}figure+p,h1+details,h1+p,h2+details,h2+p,h3+details,h3+p,h4+details,h4+p,h5+details,h5+p,h6+details,h6+p{margin-top:.5em}h1>a[href^="#"][id],h2>a[href^="#"][id],h3>a[href^="#"][id],h4>a[href^="#"][id],h5>a[href^="#"][id],h6>a[href^="#"][id]{position:absolute;left:-.5em;opacity:0;background:0 0;color:rgba(0,0,0,.5);transition:opacity 300ms ease-out}h1>a[href^="#"][id]:focus,h1>a[href^="#"][id]:hover,h1>a[href^="#"][id]:target,h2>a[href^="#"][id]:focus,h2>a[href^="#"][id]:hover,h2>a[href^="#"][id]:target,h3>a[href^="#"][id]:focus,h3>a[href^="#"][id]:hover,h3>a[href^="#"][id]:target,h4>a[href^="#"][id]:focus,h4>a[href^="#"][id]:hover,h4>a[href^="#"][id]:target,h5>a[href^="#"][id]:focus,h5>a[href^="#"][id]:hover,h5>a[href^="#"][id]:target,h6>a[href^="#"][id]:focus,h6>a[href^="#"][id]:hover,h6>a[href^="#"][id]:target{opacity:1;box-shadow:none;color:#000;transition:opacity 0s,color 0s}h1>a[href^="#"][id]:target:focus,h2>a[href^="#"][id]:target:focus,h3>a[href^="#"][id]:target:focus,h4>a[href^="#"][id]:target:focus,h5>a[href^="#"][id]:target:focus,h6>a[href^="#"][id]:target:focus{outline:0}h1>a[href^="#"][id]::before,h2>a[href^="#"][id]::before,h3>a[href^="#"][id]::before,h4>a[href^="#"][id]::before,h5>a[href^="#"][id]::before,h6>a[href^="#"][id]::before{content:"•"}h1{font-size:2em}h2{font-size:1.75em}h3{font-size:1.25em}h4{font-size:1.15em}h5,h6{font-size:1em}h6{margin-top:1em;color:#aaa}article+article{margin-top:5em}article header p{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:.6em;color:#aaa}article header p+h1,article header p+h2{margin-top:-.25em}article header h1+p,article header h2+p{margin-top:.25em}article header h1 a,article header h2 a{color:#000;background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="1"%3E%3Crect x="0" y="0.5" width="1" height="0.5" fill="rgba(0, 0, 0, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}@media screen and (-ms-high-contrast:active),(-ms-high-contrast:none){article header h1 a,article header h2 a{background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="2"%3E%3Crect x="0" y="1" width="1" height="1" fill="rgba(0, 0, 0, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}}article header h1 a:visited,article header h2 a:visited{color:#aaa;background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="1"%3E%3Crect x="0" y="0.5" width="1" height="0.5" fill="rgba(170, 170, 170, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}@media screen and (-ms-high-contrast:active),(-ms-high-contrast:none){article header h1 a:visited,article header h2 a:visited{background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="2"%3E%3Crect x="0" y="1" width="1" height="1" fill="rgba(170, 170, 170, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}}article>footer{margin-top:1.5em;font-size:.85em}a,abbr{text-decoration:none}a{color:#0064c1;transition:color 300ms ease-out,box-shadow 300ms ease-out;background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="1"%3E%3Crect x="0" y="0.5" width="1" height="0.5" fill="rgba(0, 100, 193, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}@media screen and (-ms-high-contrast:active),(-ms-high-contrast:none){a{background:url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="2"%3E%3Crect x="0" y="1" width="1" height="1" fill="rgba(0, 100, 193, 0.35)"/%3E%3C/svg%3E') left bottom repeat-x}}a:visited{color:#80b2e0}a:active,a:hover{outline-width:0}a:hover{box-shadow:inset 0 -1px #3000c1;color:#3000c1;transition:color 0s,box-shadow 0s}abbr{margin-right:-.075em;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;letter-spacing:.075em;font-size:.9em;border-bottom:1px dotted}img,picture{display:block;max-width:100%;margin:0 auto}audio,video{width:100%;max-width:100%}video{-o-object-position:0 -1px;object-position:0 -1px}figure{margin:1em 0 .5em;padding:0}figure figcaption{opacity:.65;font-size:.85em}table{display:inline-block;border-spacing:0;border-collapse:collapse;overflow-x:auto;max-width:100%;text-align:left;vertical-align:top;background:linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 0 0,linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 100% 0;background-attachment:scroll,scroll;background-size:1px 100%,1px 100%;background-repeat:no-repeat,no-repeat}table caption{font-size:.9em;background:#fff}table td,table th{padding:.35em .75em;vertical-align:top;font-size:.9em;border:1px solid #f2f2f2;border-top:0;border-left:0}table td:first-child,table th:first-child{padding-left:0;background-image:linear-gradient(to right,#fff 50%,rgba(255,255,255,0) 100%);background-size:2px 100%;background-repeat:no-repeat}table td:last-child,table th:last-child{padding-right:0;border-right:0;background-image:linear-gradient(to left,#fff 50%,rgba(255,255,255,0) 100%);background-position:100% 0;background-size:2px 100%;background-repeat:no-repeat}table td:only-child,table th:only-child{background-image:linear-gradient(to right,#fff 50%,rgba(255,255,255,0) 100%),linear-gradient(to left,#fff 50%,rgba(255,255,255,0) 100%);background-position:0 0,100% 0;background-size:2px 100%,2px 100%;background-repeat:no-repeat,no-repeat}table th{line-height:1.2}code,kbd,samp,var{font-family:Consolas,"Lucida Console",Monaco,monospace;font-style:normal}pre{overflow-x:auto;font-size:.8em;background:linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 0 0,linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 100% 0;background-attachment:scroll,scroll;background-size:1px 100%,1px 100%;background-repeat:no-repeat,no-repeat}pre>code,summary{display:inline-block}pre>code{overflow-x:visible;box-sizing:border-box;min-width:100%;border-right:3px solid #fff;border-left:1px solid #fff}hr{height:1px;margin:2em 0;border:0;background:#f2f2f2}details[open]{padding-bottom:.5em;border-bottom:1px solid #f2f2f2}summary{font-weight:700;border-bottom:1px dashed;cursor:pointer}summary::-webkit-details-marker{display:none}noscript{color:#d00000}::selection{background:rgba(0,100,193,.15)}
default.nix+7−18
@@ -1,13 +1,11 @@
11{ sources ? import ./nix/sources.nix
22, haskellNix ? import sources.haskellNix { inherit system; }
3−, pkgs ? import haskellNix.sources.nixpkgs-2311 (haskellNix.nixpkgsArgs // { inherit system; })
3+, pkgs ? import haskellNix.sources.nixpkgs-2105 (haskellNix.nixpkgsArgs // { inherit system; })
44, system ? builtins.currentSystem
55, nix-filter ? import sources.nix-filter
66}:
77let
88 masterPkgs = import sources.nixpkgs { inherit system; };
9− yq = import ./nix/yq.nix { pkgs = masterPkgs; };
10− diffYaml = import ./nix/diff-yaml.nix { pkgs = masterPkgs; };
119
1210 hsPkgs = pkgs.haskell-nix.stackProject {
1311 src = nix-filter {
@@ -40,7 +38,7 @@ let
4038 (inDirectory ./src)
4139 (inDirectory ./app)
4240 (inDirectory ./github-action)
43− ./css/awsm.min.css
41+ ./awsm-css/dist/awsm.min.css
4442 ./LICENSE
4543 ];
4644 };
@@ -99,18 +97,6 @@ let
9997 };
10098
10199 WindowsCompaRESTBin = hsPkgs.projectCross.mingwW64.hsPkgs.compaREST.components.exes.compaREST;
102−
103− # We use the static version so that we don't have to rebuild everything on CI.
104− # The only binaries build on CI are static.
105− test = hsPkgs.projectCross.musl64.hsPkgs.compaREST.components.tests.compaREST-tests.overrideAttrs (final: old: {
106− buildInputs = old.buildInputs ++ [ diffYaml yq ];
107− nativeBuildInputs = old.nativeBuildInputs ++ (with masterPkgs; [ makeWrapper ]);
108−
109− postInstall = ''
110− wrapProgram $out/bin/compaREST-tests \
111− --prefix PATH : ${masterPkgs.lib.makeBinPath [ diffYaml yq ]}
112− '';
113− });
114100in
115101{
116102 inherit
@@ -120,6 +106,9 @@ in
120106 compaRESTBin
121107 hsPkgs
122108 macOSCompaRESTBundle
123− WindowsCompaRESTBin
124− test;
109+ WindowsCompaRESTBin;
110+
111+ # We use the static version so that we don't have to rebuild everything on CI.
112+ # The only binaries build on CI are static.
113+ test = hsPkgs.projectCross.musl64.hsPkgs.compaREST.components.tests.compaREST-tests;
125114}
docs/Integration_guide.md+2
@@ -28,6 +28,8 @@ In our example we have already generated the two OpenAPI specs and placed them i
2828
2929We can now run our action:
3030
31+##### NOTE: will only work after public release
32+
3133```yaml
3234- uses: typeable/comparest
3335 with:
github-action/Main.hs+7−13
@@ -9,7 +9,6 @@ import Control.Monad.Freer.GitHub
99import Control.Monad.Freer.Reader
1010import Data.OpenApi.Compare.Run
1111import Data.Text (Text)
12−import qualified Data.Text as T
1312import qualified Data.Yaml.Aeson as Yaml
1413import qualified GitHub as GH
1514import System.Environment
@@ -23,18 +22,13 @@ import Text.Pandoc.Writers
2322main :: IO ()
2423main = do
2524 cfg <- decodeEnv >>= either error pure
26− case sha cfg of
27− x | T.null . T.strip . GH.untagName $ x -> do
28− putStrLn "SHA not specified. Exiting without doing anything."
29− pure ()
30− _ ->
31− getArgs >>= \case
32− ["pre"] -> runPre cfg
33− ["run"] -> do
34− oldFile <- getEnv "OLD"
35− newFile <- getEnv "NEW"
36− runRun cfg (root cfg </> oldFile) (root cfg </> newFile)
37− _ -> error "Invalid arguments."
25+ getArgs >>= \case
26+ ["pre"] -> runPre cfg
27+ ["run"] -> do
28+ oldFile <- getEnv "OLD"
29+ newFile <- getEnv "NEW"
30+ runRun cfg (root cfg </> oldFile) (root cfg </> newFile)
31+ _ -> error "Invalid arguments."
3832
3933runner :: Config -> Eff '[GitHub, Error GH.Error, Reader Config, IO] a -> IO a
4034runner cfg =
nix/ci.nix+1−6
@@ -1,11 +1,6 @@
11{ sources ? import ./sources.nix
22, pkgs ? import sources.nixpkgs { }
33}:
4−
5−let
6− yq = import ./yq.nix { inherit pkgs; };
7− diff-yaml = import ./diff-yaml.nix { inherit pkgs; };
8−in
94pkgs.mkShell {
10− packages = [ pkgs.haskellPackages.fourmolu diff-yaml yq ];
5+ packages = [ pkgs.haskellPackages.fourmolu ];
116}
nix/diff-yaml.nixdeleted−20
@@ -1,20 +0,0 @@
1−{ pkgs ? import <nixpkgs> {} }:
2−
3−let
4− inherit (pkgs) stdenv;
5− yq = import ./yq.nix { inherit pkgs; };
6−in
7−stdenv.mkDerivation {
8− name = "diff-yaml";
9−
10− src = ../scripts/diff-yaml;
11−
12− buildInputs = [ pkgs.bash yq ];
13−
14− phases = [ "installPhase" ];
15−
16− installPhase = ''
17− mkdir -p $out/bin
18− cp $src $out/bin/diff-yaml
19− '';
20−}
nix/shell.nixdeleted−11
@@ -1,11 +0,0 @@
1−{ sources ? import ./sources.nix
2−, pkgs ? import sources.nixpkgs { }
3−}:
4−
5−let
6− patched-yq = import ./yq.nix { inherit pkgs; };
7− diffYaml = import ./diff-yaml.nix { inherit pkgs; };
8−in
9−pkgs.mkShell {
10− buildInputs = with pkgs; [ pkg-config diffYaml patched-yq zlib ];
11−}
nix/sources.json+13−13
@@ -5,10 +5,10 @@
55 "homepage": "https://input-output-hk.github.io/haskell.nix",
66 "owner": "input-output-hk",
77 "repo": "haskell.nix",
8− "rev": "d7f95903c84a5a50d6fe0844280da82c3c81680a",
9− "sha256": "02870rk4sx44lwwa0k20iwdhqcx0ayz34yb3b0qy045p22q45815",
8+ "rev": "c8a8f57de3c14fcf1c5cda045ed885fb6d06a00e",
9+ "sha256": "0frzmvz8rhb4vgx20qms9xxqbkmg5pwivis4qis63ny5wxclzb34",
1010 "type": "tarball",
11− "url": "https://github.com/input-output-hk/haskell.nix/archive/d7f95903c84a5a50d6fe0844280da82c3c81680a.tar.gz",
11+ "url": "https://github.com/input-output-hk/haskell.nix/archive/c8a8f57de3c14fcf1c5cda045ed885fb6d06a00e.tar.gz",
1212 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
1313 },
1414 "niv": {
@@ -17,22 +17,22 @@
1717 "homepage": "https://github.com/nmattia/niv",
1818 "owner": "nmattia",
1919 "repo": "niv",
20− "rev": "f7c538837892dd2eb83567c9f380a11efb59b53f",
21− "sha256": "0xl33k24vfc29cg9lnp95kvcq69qbq5fzb7jk9ig4lgrhaarh651",
20+ "rev": "5830a4dd348d77e39a0f3c4c762ff2663b602d4c",
21+ "sha256": "1d3lsrqvci4qz2hwjrcnd8h5vfkg8aypq3sjd4g3izbc8frwz5sm",
2222 "type": "tarball",
23− "url": "https://github.com/nmattia/niv/archive/f7c538837892dd2eb83567c9f380a11efb59b53f.tar.gz",
23+ "url": "https://github.com/nmattia/niv/archive/5830a4dd348d77e39a0f3c4c762ff2663b602d4c.tar.gz",
2424 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
2525 },
2626 "nix-filter": {
27− "branch": "main",
27+ "branch": "master",
2828 "description": "a small self-container source filtering lib",
2929 "homepage": "",
3030 "owner": "numtide",
3131 "repo": "nix-filter",
32− "rev": "3342559a24e85fc164b295c3444e8a139924675b",
33− "sha256": "08xia32g5jzaiyhfl3kzxslzbr4w1i56i0mhy5gpfggv8gqy8sym",
32+ "rev": "3c9e33ed627e009428197b07216613206f06ed80",
33+ "sha256": "19w142crrkywxynmyw4rhz4nglrg64yjawfkw3j91qwkwbfjds84",
3434 "type": "tarball",
35− "url": "https://github.com/numtide/nix-filter/archive/3342559a24e85fc164b295c3444e8a139924675b.tar.gz",
35+ "url": "https://github.com/numtide/nix-filter/archive/3c9e33ed627e009428197b07216613206f06ed80.tar.gz",
3636 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
3737 },
3838 "nixpkgs": {
@@ -41,10 +41,10 @@
4141 "homepage": "",
4242 "owner": "NixOS",
4343 "repo": "nixpkgs",
44− "rev": "bf038bd724982de67a2ee9a6b2f1fcb7d6a87bd7",
45− "sha256": "0ivvwdmg9fipj6ylq5ipxqpb0xnz6hsx3lyn377jacfpiqi9w0cv",
44+ "rev": "f0fe5e9ba08e658474476317717aca7acacef4d4",
45+ "sha256": "1n5syynwmg3x8lj2kyb2ilbxw5nmw7f2kw6yxsi8qadx91hrvkwm",
4646 "type": "tarball",
47− "url": "https://github.com/NixOS/nixpkgs/archive/bf038bd724982de67a2ee9a6b2f1fcb7d6a87bd7.tar.gz",
47+ "url": "https://github.com/NixOS/nixpkgs/archive/f0fe5e9ba08e658474476317717aca7acacef4d4.tar.gz",
4848 "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
4949 }
5050}
nix/yq.nixdeleted−26
@@ -1,26 +0,0 @@
1−{ pkgs ? import <nixpkgs> {} }:
2−
3−# Make yq work inside whatever `stack test` launches.
4−# Nuke this when https://github.com/kislyuk/yq/pull/193 is merged
5−# and nixpkgs includes that fix.
6−
7−let
8− yq-patch = pkgs.writeText "yq-tty-fix.patch" ''
9−diff --git a/yq/__init__.py b/yq/__init__.py
10−index d95ac4b..ae7d59e 100644
11−--- a/yq/__init__.py
12−+++ b/yq/__init__.py
13−@@ -110,7 +110,7 @@ def cli(args=None, input_format="yaml", program_name="yq"):
14− in_place = args.in_place
15− delattr(args, "in_place")
16−
17−- if sys.stdin.isatty() and not args.input_streams:
18−+ if (sys.stdin is None or sys.stdin.isatty()) and not args.input_streams:
19− parser.print_help()
20− sys.exit(2)
21− elif not args.input_streams:
22− '';
23−in
24−pkgs.yq.overrideAttrs (final: old: {
25− patches = old.patches ++ [ yq-patch ];
26−})
policeman.jsonnew file+6
@@ -0,0 +1,6 @@
1+[{
2+ "file": "compaREST.cabal",
3+ "annotation_level": "notice",
4+ "end_line": 0,
5+ "start_line": 0
6+}]
scripts/diff-yamldeleted−35
@@ -1,35 +0,0 @@
1−#!/usr/bin/env bash
2−set -e
3−
4−# Normalise YAML files passed as inputs, then run diff on them.
5−
6−check_util() {
7− local util=$1
8−
9− if [ -z $util ]; then
10− echo "Error: $util not found in PATH"
11− exit 1
12− fi
13−}
14−
15−DIFF=`which diff`
16−check_util $DIFF
17−
18−YQ=`which yq`
19−check_util $YQ
20−
21−# Only normalise YAML files.
22−# Print anything else as is.
23−normalise() {
24− local file=$1
25− local contents=($YQ -y -S '.' $file)
26−
27− # if $contents contains actual YAML data, print it
28− if [[ $? == 0 ]]; then
29− echo $contents
30− else
31− cat $file
32− fi
33−}
34−
35−$DIFF -u <(normalise $1) <(normalise $2)
src/Data/OpenApi/Compare/PathsPrefixTree.hs+4−5
@@ -23,8 +23,7 @@ where
2323import Control.Monad
2424import Data.Aeson
2525import Data.Foldable hiding (null, toList)
26−import qualified Data.Aeson.Key as Key
27−import qualified Data.Aeson.KeyMap as KeyMap
26+import qualified Data.HashMap.Strict as HM
2827import Data.Kind
2928import qualified Data.Map as M
3029import Data.Monoid
@@ -257,7 +256,7 @@ newtype MergableObject = MergableObject {getMergableObject :: Object}
257256
258257instance Semigroup MergableObject where
259258 (MergableObject x) <> (MergableObject y) =
260− MergableObject $ KeyMap.unionWith mergeValue x y
259+ MergableObject $ HM.unionWith mergeValue x y
261260 where
262261 mergeValue :: Value -> Value -> Value
263262 mergeValue (Object a) (Object b) =
@@ -272,6 +271,6 @@ instance Monoid MergableObject where
272271
273272traceObject :: Paths q r a -> Value -> Object
274273traceObject Root (Object o) = o
275−traceObject Root v = KeyMap.singleton "root" v
274+traceObject Root v = HM.singleton "root" v
276275traceObject (root `Snoc` s) v =
277− traceObject root . Object $ KeyMap.singleton (Key.fromText . T.pack . show $ s) v
276+ traceObject root . Object $ HM.singleton (T.pack . show $ s) v
src/Data/OpenApi/Compare/Report.hs+1−1
@@ -198,7 +198,7 @@ showErrs x@(P.PathsPrefixNode currentIssues _) =
198198 let -- Extract this pattern if more cases like this arise
199199 ( removedPaths :: Maybe (Orientation, [Issue 'APILevel])
200200 , otherIssues :: Set (AnIssue a)
201− ) = case eqT @a @'APILevel of
201+ ) = case eqT @a @ 'APILevel of
202202 Just Refl
203203 | (S.toList -> p@((AnIssue ori _) : _), o) <-
204204 S.partition
src/Data/OpenApi/Compare/Report/Html/Template.hs+1−1
@@ -36,4 +36,4 @@ template =
3636 \</html>"
3737
3838awsmCss :: ByteString
39−awsmCss = $(makeRelativeToProject "css/awsm.min.css" >>= embedFile)
39+awsmCss = $(makeRelativeToProject "awsm-css/dist/awsm.min.css" >>= embedFile)
src/Data/OpenApi/Compare/Validate/OpenApi.hs+1−2
@@ -38,8 +38,7 @@ tracedSecuritySchemes :: Traced OpenApi -> Traced (Definitions SecurityScheme)
3838tracedSecuritySchemes oa =
3939 traced
4040 (ask oa >>> step ComponentsSecurityScheme)
41− (unSecurityDefinitions . _componentsSecuritySchemes . _openApiComponents . extract $ oa)
42− where unSecurityDefinitions (SecurityDefinitions ds) = ds
41+ (_componentsSecuritySchemes . _openApiComponents . extract $ oa)
4342
4443tracedResponses :: Traced OpenApi -> Traced (Definitions Response)
4544tracedResponses oa =
src/Data/OpenApi/Compare/Validate/Schema.hs+1−1
@@ -5,7 +5,7 @@ module Data.OpenApi.Compare.Validate.Schema
55 )
66where
77
8−import Control.Monad (when,unless)
8+import Control.Monad.Writer
99import qualified Data.Aeson as A
1010import Data.Coerce
1111import Data.Foldable (for_, toList)
src/Data/OpenApi/Compare/Validate/Schema/JsonFormula.hs+6−7
@@ -18,11 +18,10 @@ where
1818
1919import Algebra.Lattice
2020import qualified Data.Aeson as A
21−import qualified Data.Aeson.Key as Key
22−import qualified Data.Aeson.KeyMap as KeyMap
2321import qualified Data.ByteString.Lazy as BSL
2422import qualified Data.Foldable as F
2523import Data.Functor
24+import qualified Data.HashMap.Strict as HM
2625import Data.Int
2726import Data.Kind
2827import qualified Data.Map as M
@@ -40,7 +39,7 @@ import Data.Text (Text)
4039import qualified Data.Text as T
4140import qualified Data.Text.Encoding as T
4241import Data.Typeable
43−import Text.Pandoc.Builder hiding (Format)
42+import Text.Pandoc.Builder hiding (Format, Null)
4443import Text.Regex.Pcre2
4544
4645data Bound a = Exclusive !a | Inclusive !a
@@ -178,10 +177,10 @@ satisfiesTyped (TArray a) (MaxItems m) = fromIntegral (F.length a) <= m
178177satisfiesTyped (TArray a) (MinItems m) = fromIntegral (F.length a) >= m
179178satisfiesTyped (TArray a) UniqueItems = S.size (S.fromList $ F.toList a) == F.length a -- TODO: could be better #36
180179satisfiesTyped (TObject o) (Properties props additional _) =
181− all (`KeyMap.member` o) (map Key.fromText $ M.keys (M.filter propRequired props))
182− && all (\(k, v) -> satisfies v $ maybe additional propFormula $ M.lookup (Key.toText k) props) (KeyMap.toList o)
183−satisfiesTyped (TObject o) (MaxProperties m) = fromIntegral (KeyMap.size o) <= m
184−satisfiesTyped (TObject o) (MinProperties m) = fromIntegral (KeyMap.size o) >= m
180+ all (`HM.member` o) (M.keys (M.filter propRequired props))
181+ && all (\(k, v) -> satisfies v $ maybe additional propFormula $ M.lookup k props) (HM.toList o)
182+satisfiesTyped (TObject o) (MaxProperties m) = fromIntegral (HM.size o) <= m
183+satisfiesTyped (TObject o) (MinProperties m) = fromIntegral (HM.size o) >= m
185184
186185checkNumberFormat :: Format -> Scientific -> Bool
187186checkNumberFormat "int32" (toRational -> n) =
src/Data/OpenApi/Compare/Validate/Schema/Partition.hs+1−4
@@ -16,7 +16,6 @@ where
1616import Algebra.Lattice
1717import Algebra.Lattice.Lifted
1818import Control.Applicative
19−import Control.Monad (when)
2019import Control.Monad.Reader hiding (ask)
2120import qualified Control.Monad.Reader as R
2221import Control.Monad.State
@@ -32,7 +31,6 @@ import qualified Data.List as L
3231import qualified Data.List.NonEmpty as NE
3332import qualified Data.Map as M
3433import Data.Maybe
35−import Data.Monoid
3634import Data.OpenApi
3735import Data.OpenApi.Compare.Memo
3836import Data.OpenApi.Compare.References
@@ -45,8 +43,7 @@ import Data.Ord
4543import qualified Data.Set as S
4644import Data.Text (Text)
4745import qualified Data.Text as T
48−import Data.Traversable (forM)
49−import Text.Pandoc.Builder hiding (Format)
46+import Text.Pandoc.Builder hiding (Format, Null)
5047
5148data PartitionData
5249 = DByEnumValue (DNF (S.Set A.Value))
src/Data/OpenApi/Compare/Validate/Schema/Process.hs−2
@@ -13,7 +13,6 @@ import Data.Functor.Identity
1313import qualified Data.HashMap.Strict.InsOrd as IOHM
1414import qualified Data.Map as M
1515import Data.Maybe
16−import Data.Monoid
1716import Data.OpenApi hiding (get)
1817import Data.OpenApi.Compare.Behavior
1918import Data.OpenApi.Compare.Memo
@@ -29,7 +28,6 @@ import Data.OpenApi.Compare.Validate.Schema.Traced
2928import Data.OpenApi.Compare.Validate.Schema.TypedJson
3029import Data.Ord
3130import qualified Data.Set as S
32−import Data.Traversable (forM)
3331
3432-- | A fake writer monad that doesn't actually record anything and allows lazy recursion.
3533newtype Silent w a = Silent {runSilent :: a}
stack.yaml+4−16
@@ -1,23 +1,11 @@
1−resolver: lts-22.34
1+resolver: lts-18.16
22
33packages:
44 - .
55
66extra-deps:
7− - base16-bytestring-1.0.2.0
8− - freer-simple-1.2.1.2
9− - generics-sop-0.5.1.4
10− - github-0.29
11− - http-link-header-1.2.1
127 - open-union-0.4.0.0
13− - th-abstraction-0.7.0.0
148 - type-fun-0.1.3
15− - typerep-map-0.6.0.0
16−
17−# Required for freer-simple and typerep-map
18−allow-newer: true
19−
20−nix:
21−# packages: [pkg-config yq zlib]
22− shell-file: ./nix/shell.nix
23− pure: false
9+ - github-0.26
10+ - base16-bytestring-0.1.1.7
11+ - http-link-header-1.0.3.1
stack.yaml.lock+4−4
@@ -41,7 +41,7 @@ packages:
4141 hackage: http-link-header-1.0.3.1
4242snapshots:
4343- completed:
44− size: 587393
45− url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/25.yaml
46− sha256: 1b74fb5e970497b5aefae56703f1bd44aa648bd1a5ef95c1eb8c29775087e2bf
47− original: lts-18.25
44+ size: 586286
45+ url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/16.yaml
46+ sha256: cdead65fca0323144b346c94286186f4969bf85594d649c49c7557295675d8a5
47+ original: lts-18.16
test/Spec/Golden/Extra.hs+2−2
@@ -59,7 +59,7 @@ goldenInputsTree ::
5959 s ->
6060 (t -> IO BSL.ByteString) ->
6161 IO TestTree
62−goldenInputsTree name filepath golden inp f =
62+goldenInputsTree name filepath golden inp f = do
6363 runTestInputTree golden f <$> getGoldenInputs name filepath inp
6464
6565runTestInputTree ::
@@ -72,7 +72,7 @@ runTestInputTree golden f (TestInputNode name rest) =
7272runTestInputTree golden f (TestInputLeaf name t path) =
7373 goldenVsStringDiff
7474 name
75− (\ref new -> ["diff-yaml", ref, new])
75+ (\ref new -> ["diff", "-u", ref, new])
7676 (path </> golden)
7777 (f t)
7878
test/golden/common/random-example/trace-tree.yaml+4−4
@@ -23,10 +23,6 @@ forwardChanges:
2323backwardChanges:
2424 AtPath "/pets":
2525 InOperation GetMethod:
26− InParam "limit":
27− InParamSchema:
28− OfType Number: MatchingMaximumWeak (ProdCons {producer = Inclusive 30.0,
29− consumer = Inclusive 20.0})
3026 WithStatusCode 200:
3127 ResponsePayload:
3228 PayloadSchema:
@@ -37,6 +33,10 @@ backwardChanges:
3733 - TypesRestricted [Number]
3834 - AdditionalToProperty
3935 - OfType Number: NoMatchingMultipleOf 1.0
36+ InParam "limit":
37+ InParamSchema:
38+ OfType Number: MatchingMaximumWeak (ProdCons {producer = Inclusive 30.0,
39+ consumer = Inclusive 20.0})
4040 InOperation PostMethod:
4141 InRequest:
4242 InPayload: