on 2cea75b help sign in
21 files changed+385−368
since splitsnapshots
unifiedsplit
.github/workflows/haskell-ci-bench.yml+43−107 .github/workflows/haskell-ci.yml+51−117 cabal.haskell-ci−6 cabal.project+1−1 gen-ci.sh → haskell-ci.sh uuid-bench/bench/uuid-benchmark.hs+1 uuid-bench/uuid-bench.cabal+20−27 uuid-types/ChangeLog.md−9 uuid-types/src/Data/UUID/Types.hs+4 uuid-types/src/Data/UUID/Types/Internal.hs+43−15 uuid-types/src/Data/UUID/Types/Internal/Builder.hs+3 uuid-types/tests/TestUUID.hs−7 uuid-types/uuid-types.cabal+21−28 uuid/CHANGES.md+1−15 uuid/src/Data/UUID.hs+3−2 uuid/src/Data/UUID/Util.hs+11 uuid/src/Data/UUID/V1.hs+135 uuid/src/Data/UUID/V3.hs+1−1 uuid/src/Data/UUID/V4.hs+4−5 uuid/tests/TestUUID.hs+20−4 uuid/uuid.cabal+23−24
.github/workflows/haskell-ci-bench.yml+43−107
@@ -8,9 +8,9 @@
88#
99# For more information, see https://github.com/haskell-CI/haskell-ci
1010#
11−# version: 0.19.20240702
11+# version: 0.11.20210214
1212#
13−# REGENDATA ("0.19.20240702",["github","--project","cabal.bench.project","-o",".github/workflows/haskell-ci-bench.yml","--github-action-name","Benchmarks"])
13+# REGENDATA ("0.11.20210214",["github","--project","cabal.bench.project","-o",".github/workflows/haskell-ci-bench.yml","--github-action-name","Benchmarks"])
1414#
1515name: Benchmarks
1616on:
@@ -22,101 +22,57 @@ on:
2222 - master
2323jobs:
2424 linux:
25− name: Benchmarks - Linux - ${{ matrix.compiler }}
26− runs-on: ubuntu-20.04
27− timeout-minutes:
28− 60
25+ name: Benchmarks - Linux - GHC ${{ matrix.ghc }}
26+ runs-on: ubuntu-18.04
2927 container:
30− image: buildpack-deps:jammy
28+ image: buildpack-deps:bionic
3129 continue-on-error: ${{ matrix.allow-failure }}
3230 strategy:
3331 matrix:
3432 include:
35− - compiler: ghc-9.10.1
36− compilerKind: ghc
37− compilerVersion: 9.10.1
38− setup-method: ghcup
33+ - ghc: 8.10.3
3934 allow-failure: false
40− - compiler: ghc-9.8.2
41− compilerKind: ghc
42− compilerVersion: 9.8.2
43− setup-method: ghcup
35+ - ghc: 8.8.4
4436 allow-failure: false
45− - compiler: ghc-9.6.6
46− compilerKind: ghc
47− compilerVersion: 9.6.6
48− setup-method: ghcup
37+ - ghc: 8.6.4
4938 allow-failure: false
50− - compiler: ghc-9.4.8
51− compilerKind: ghc
52− compilerVersion: 9.4.8
53− setup-method: ghcup
39+ - ghc: 8.4.4
5440 allow-failure: false
55− - compiler: ghc-9.2.8
56− compilerKind: ghc
57− compilerVersion: 9.2.8
58− setup-method: ghcup
41+ - ghc: 8.2.2
5942 allow-failure: false
60− - compiler: ghc-9.0.2
61− compilerKind: ghc
62− compilerVersion: 9.0.2
63− setup-method: ghcup
64− allow-failure: false
65− - compiler: ghc-8.10.7
66− compilerKind: ghc
67− compilerVersion: 8.10.7
68− setup-method: ghcup
69− allow-failure: false
70− - compiler: ghc-8.8.4
71− compilerKind: ghc
72− compilerVersion: 8.8.4
73− setup-method: ghcup
74− allow-failure: false
75− - compiler: ghc-8.6.5
76− compilerKind: ghc
77− compilerVersion: 8.6.5
78− setup-method: ghcup
43+ - ghc: 8.0.2
7944 allow-failure: false
8045 fail-fast: false
8146 steps:
8247 - name: apt
8348 run: |
8449 apt-get update
85− apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
86− mkdir -p "$HOME/.ghcup/bin"
87− curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
88− chmod a+x "$HOME/.ghcup/bin/ghcup"
89− "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
90− "$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
50+ apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common
51+ apt-add-repository -y 'ppa:hvr/ghc'
52+ apt-get update
53+ apt-get install -y ghc-$GHC_VERSION cabal-install-3.2
9154 env:
92− HCKIND: ${{ matrix.compilerKind }}
93− HCNAME: ${{ matrix.compiler }}
94− HCVER: ${{ matrix.compilerVersion }}
55+ GHC_VERSION: ${{ matrix.ghc }}
9556 - name: Set PATH and environment variables
9657 run: |
9758 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
98− echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
99− echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
100− echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
101− HCDIR=/opt/$HCKIND/$HCVER
102− HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
103− HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
104− HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
105− echo "HC=$HC" >> "$GITHUB_ENV"
106− echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
107− echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
108− echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"
59+ echo "LANG=C.UTF-8" >> $GITHUB_ENV
60+ echo "CABAL_DIR=$HOME/.cabal" >> $GITHUB_ENV
61+ echo "CABAL_CONFIG=$HOME/.cabal/config" >> $GITHUB_ENV
62+ HC=/opt/ghc/$GHC_VERSION/bin/ghc
63+ echo "HC=$HC" >> $GITHUB_ENV
64+ echo "HCPKG=/opt/ghc/$GHC_VERSION/bin/ghc-pkg" >> $GITHUB_ENV
65+ echo "HADDOCK=/opt/ghc/$GHC_VERSION/bin/haddock" >> $GITHUB_ENV
66+ echo "CABAL=/opt/cabal/3.2/bin/cabal -vnormal+nowrap" >> $GITHUB_ENV
10967 HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
110− echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
111− echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
112− echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
113− echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
114− echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
115− echo "GHCJSARITH=0" >> "$GITHUB_ENV"
68+ echo "HCNUMVER=$HCNUMVER" >> $GITHUB_ENV
69+ echo "ARG_TESTS=--enable-tests" >> $GITHUB_ENV
70+ echo "ARG_BENCH=--enable-benchmarks" >> $GITHUB_ENV
71+ echo "HEADHACKAGE=false" >> $GITHUB_ENV
72+ echo "ARG_COMPILER=--ghc --with-compiler=/opt/ghc/$GHC_VERSION/bin/ghc" >> $GITHUB_ENV
73+ echo "GHCJSARITH=0" >> $GITHUB_ENV
11674 env:
117− HCKIND: ${{ matrix.compilerKind }}
118− HCNAME: ${{ matrix.compiler }}
119− HCVER: ${{ matrix.compilerVersion }}
75+ GHC_VERSION: ${{ matrix.ghc }}
12076 - name: env
12177 run: |
12278 env
@@ -139,10 +95,6 @@ jobs:
13995 repository hackage.haskell.org
14096 url: http://hackage.haskell.org/
14197 EOF
142− cat >> $CABAL_CONFIG <<EOF
143− program-default-options
144− ghc-options: $GHCJOBS +RTS -M3G -RTS
145− EOF
14698 cat $CABAL_CONFIG
14799 - name: versions
148100 run: |
@@ -155,14 +107,14 @@ jobs:
155107 - name: install cabal-plan
156108 run: |
157109 mkdir -p $HOME/.cabal/bin
158− curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz
159− echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -
110+ curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz
111+ echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
160112 xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
161113 rm -f cabal-plan.xz
162114 chmod a+x $HOME/.cabal/bin/cabal-plan
163115 cabal-plan --version
164116 - name: checkout
165− uses: actions/checkout@v4
117+ uses: actions/checkout@v2
166118 with:
167119 path: source
168120 - name: initial cabal.project for sdist
@@ -181,28 +133,27 @@ jobs:
181133 - name: generate cabal.project
182134 run: |
183135 PKGDIR_uuid_bench="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/uuid-bench-[0-9.]*')"
184− echo "PKGDIR_uuid_bench=${PKGDIR_uuid_bench}" >> "$GITHUB_ENV"
185− rm -f cabal.project cabal.project.local
136+ echo "PKGDIR_uuid_bench=${PKGDIR_uuid_bench}" >> $GITHUB_ENV
186137 touch cabal.project
187138 touch cabal.project.local
188139 echo "packages: ${PKGDIR_uuid_bench}" >> cabal.project
189− echo "package uuid-bench" >> cabal.project
190− echo " ghc-options: -Werror=missing-methods" >> cabal.project
140+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package uuid-bench" >> cabal.project ; fi
141+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
191142 cat >> cabal.project <<EOF
192143 EOF
193− $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: any.$_ installed\n" unless /^(uuid-bench)$/; }' >> cabal.project.local
144+ $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(uuid-bench)$/; }' >> cabal.project.local
194145 cat cabal.project
195146 cat cabal.project.local
196147 - name: dump install plan
197148 run: |
198149 $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
199150 cabal-plan
200− - name: restore cache
201− uses: actions/cache/restore@v4
151+ - name: cache
152+ uses: actions/cache@v2
202153 with:
203− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
154+ key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
204155 path: ~/.cabal/store
205− restore-keys: ${{ runner.os }}-${{ matrix.compiler }}-
156+ restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
206157 - name: install dependencies
207158 run: |
208159 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all
@@ -219,23 +170,8 @@ jobs:
219170 ${CABAL} -vnormal check
220171 - name: haddock
221172 run: |
222− $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
173+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
223174 - name: unconstrained build
224175 run: |
225176 rm -f cabal.project.local
226177 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
227− - name: prepare for constraint sets
228− run: |
229− rm -f cabal.project.local
230− - name: constraint set random-1.2
231− run: |
232− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' all --dry-run
233− cabal-plan topo | sort
234− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' --dependencies-only -j2 all
235− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' all
236− - name: save cache
237− uses: actions/cache/save@v4
238− if: always()
239− with:
240− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
241− path: ~/.cabal/store
.github/workflows/haskell-ci.yml+51−117
@@ -8,9 +8,9 @@
88#
99# For more information, see https://github.com/haskell-CI/haskell-ci
1010#
11−# version: 0.19.20241223
11+# version: 0.11.20210214
1212#
13−# REGENDATA ("0.19.20241223",["github","cabal.project"])
13+# REGENDATA ("0.11.20210214",["github","cabal.project"])
1414#
1515name: Haskell-CI
1616on:
@@ -22,111 +22,65 @@ on:
2222 - master
2323jobs:
2424 linux:
25− name: Haskell-CI - Linux - ${{ matrix.compiler }}
26− runs-on: ubuntu-20.04
27− timeout-minutes:
28− 60
25+ name: Haskell-CI - Linux - GHC ${{ matrix.ghc }}
26+ runs-on: ubuntu-18.04
2927 container:
30− image: buildpack-deps:jammy
28+ image: buildpack-deps:bionic
3129 continue-on-error: ${{ matrix.allow-failure }}
3230 strategy:
3331 matrix:
3432 include:
35− - compiler: ghc-9.12.1
36− compilerKind: ghc
37− compilerVersion: 9.12.1
38− setup-method: ghcup
33+ - ghc: 8.10.3
3934 allow-failure: false
40− - compiler: ghc-9.10.1
41− compilerKind: ghc
42− compilerVersion: 9.10.1
43− setup-method: ghcup
35+ - ghc: 8.8.4
4436 allow-failure: false
45− - compiler: ghc-9.8.4
46− compilerKind: ghc
47− compilerVersion: 9.8.4
48− setup-method: ghcup
37+ - ghc: 8.6.4
4938 allow-failure: false
50− - compiler: ghc-9.6.6
51− compilerKind: ghc
52− compilerVersion: 9.6.6
53− setup-method: ghcup
39+ - ghc: 8.4.4
5440 allow-failure: false
55− - compiler: ghc-9.4.8
56− compilerKind: ghc
57− compilerVersion: 9.4.8
58− setup-method: ghcup
41+ - ghc: 8.2.2
5942 allow-failure: false
60− - compiler: ghc-9.2.8
61− compilerKind: ghc
62− compilerVersion: 9.2.8
63− setup-method: ghcup
43+ - ghc: 8.0.2
6444 allow-failure: false
65− - compiler: ghc-9.0.2
66− compilerKind: ghc
67− compilerVersion: 9.0.2
68− setup-method: ghcup
45+ - ghc: 7.10.3
6946 allow-failure: false
70− - compiler: ghc-8.10.7
71− compilerKind: ghc
72− compilerVersion: 8.10.7
73− setup-method: ghcup
47+ - ghc: 7.8.4
7448 allow-failure: false
75− - compiler: ghc-8.8.4
76− compilerKind: ghc
77− compilerVersion: 8.8.4
78− setup-method: ghcup
49+ - ghc: 7.6.3
7950 allow-failure: false
80− - compiler: ghc-8.6.5
81− compilerKind: ghc
82− compilerVersion: 8.6.5
83− setup-method: ghcup
51+ - ghc: 7.4.2
8452 allow-failure: false
8553 fail-fast: false
8654 steps:
87− - name: apt-get install
55+ - name: apt
8856 run: |
8957 apt-get update
90− apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
91− - name: Install GHCup
92− run: |
93− mkdir -p "$HOME/.ghcup/bin"
94− curl -sL https://downloads.haskell.org/ghcup/0.1.30.0/x86_64-linux-ghcup-0.1.30.0 > "$HOME/.ghcup/bin/ghcup"
95− chmod a+x "$HOME/.ghcup/bin/ghcup"
96− - name: Install cabal-install
97− run: |
98− "$HOME/.ghcup/bin/ghcup" install cabal 3.14.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
99− echo "CABAL=$HOME/.ghcup/bin/cabal-3.14.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"
100− - name: Install GHC (GHCup)
101− if: matrix.setup-method == 'ghcup'
102− run: |
103− "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
104− HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
105− HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
106− HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
107− echo "HC=$HC" >> "$GITHUB_ENV"
108− echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
109− echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
58+ apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common
59+ apt-add-repository -y 'ppa:hvr/ghc'
60+ apt-get update
61+ apt-get install -y ghc-$GHC_VERSION cabal-install-3.2
11062 env:
111− HCKIND: ${{ matrix.compilerKind }}
112− HCNAME: ${{ matrix.compiler }}
113− HCVER: ${{ matrix.compilerVersion }}
63+ GHC_VERSION: ${{ matrix.ghc }}
11464 - name: Set PATH and environment variables
11565 run: |
11666 echo "$HOME/.cabal/bin" >> $GITHUB_PATH
117− echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
118− echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
119− echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
67+ echo "LANG=C.UTF-8" >> $GITHUB_ENV
68+ echo "CABAL_DIR=$HOME/.cabal" >> $GITHUB_ENV
69+ echo "CABAL_CONFIG=$HOME/.cabal/config" >> $GITHUB_ENV
70+ HC=/opt/ghc/$GHC_VERSION/bin/ghc
71+ echo "HC=$HC" >> $GITHUB_ENV
72+ echo "HCPKG=/opt/ghc/$GHC_VERSION/bin/ghc-pkg" >> $GITHUB_ENV
73+ echo "HADDOCK=/opt/ghc/$GHC_VERSION/bin/haddock" >> $GITHUB_ENV
74+ echo "CABAL=/opt/cabal/3.2/bin/cabal -vnormal+nowrap" >> $GITHUB_ENV
12075 HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
121− echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
122− echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
123− echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
124− echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
125− echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
76+ echo "HCNUMVER=$HCNUMVER" >> $GITHUB_ENV
77+ echo "ARG_TESTS=--enable-tests" >> $GITHUB_ENV
78+ echo "ARG_BENCH=--enable-benchmarks" >> $GITHUB_ENV
79+ echo "HEADHACKAGE=false" >> $GITHUB_ENV
80+ echo "ARG_COMPILER=--ghc --with-compiler=/opt/ghc/$GHC_VERSION/bin/ghc" >> $GITHUB_ENV
81+ echo "GHCJSARITH=0" >> $GITHUB_ENV
12682 env:
127− HCKIND: ${{ matrix.compilerKind }}
128− HCNAME: ${{ matrix.compiler }}
129− HCVER: ${{ matrix.compilerVersion }}
83+ GHC_VERSION: ${{ matrix.ghc }}
13084 - name: env
13185 run: |
13286 env
@@ -149,10 +103,6 @@ jobs:
149103 repository hackage.haskell.org
150104 url: http://hackage.haskell.org/
151105 EOF
152− cat >> $CABAL_CONFIG <<EOF
153− program-default-options
154− ghc-options: $GHCJOBS +RTS -M3G -RTS
155− EOF
156106 cat $CABAL_CONFIG
157107 - name: versions
158108 run: |
@@ -165,14 +115,14 @@ jobs:
165115 - name: install cabal-plan
166116 run: |
167117 mkdir -p $HOME/.cabal/bin
168− curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz
169− echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -
118+ curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz
119+ echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
170120 xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
171121 rm -f cabal-plan.xz
172122 chmod a+x $HOME/.cabal/bin/cabal-plan
173123 cabal-plan --version
174124 - name: checkout
175− uses: actions/checkout@v4
125+ uses: actions/checkout@v2
176126 with:
177127 path: source
178128 - name: initial cabal.project for sdist
@@ -192,33 +142,32 @@ jobs:
192142 - name: generate cabal.project
193143 run: |
194144 PKGDIR_uuid_types="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/uuid-types-[0-9.]*')"
195− echo "PKGDIR_uuid_types=${PKGDIR_uuid_types}" >> "$GITHUB_ENV"
145+ echo "PKGDIR_uuid_types=${PKGDIR_uuid_types}" >> $GITHUB_ENV
196146 PKGDIR_uuid="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/uuid-[0-9.]*')"
197− echo "PKGDIR_uuid=${PKGDIR_uuid}" >> "$GITHUB_ENV"
198− rm -f cabal.project cabal.project.local
147+ echo "PKGDIR_uuid=${PKGDIR_uuid}" >> $GITHUB_ENV
199148 touch cabal.project
200149 touch cabal.project.local
201150 echo "packages: ${PKGDIR_uuid_types}" >> cabal.project
202151 echo "packages: ${PKGDIR_uuid}" >> cabal.project
203− echo "package uuid-types" >> cabal.project
204− echo " ghc-options: -Werror=missing-methods" >> cabal.project
205− echo "package uuid" >> cabal.project
206− echo " ghc-options: -Werror=missing-methods" >> cabal.project
152+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package uuid-types" >> cabal.project ; fi
153+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
154+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package uuid" >> cabal.project ; fi
155+ if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
207156 cat >> cabal.project <<EOF
208157 EOF
209− $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: any.$_ installed\n" unless /^(uuid|uuid-types)$/; }' >> cabal.project.local
158+ $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(uuid|uuid-types)$/; }' >> cabal.project.local
210159 cat cabal.project
211160 cat cabal.project.local
212161 - name: dump install plan
213162 run: |
214163 $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
215164 cabal-plan
216− - name: restore cache
217− uses: actions/cache/restore@v4
165+ - name: cache
166+ uses: actions/cache@v2
218167 with:
219− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
168+ key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }}
220169 path: ~/.cabal/store
221− restore-keys: ${{ runner.os }}-${{ matrix.compiler }}-
170+ restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
222171 - name: install dependencies
223172 run: |
224173 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all
@@ -240,23 +189,8 @@ jobs:
240189 ${CABAL} -vnormal check
241190 - name: haddock
242191 run: |
243− $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
192+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
244193 - name: unconstrained build
245194 run: |
246195 rm -f cabal.project.local
247196 $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
248− - name: prepare for constraint sets
249− run: |
250− rm -f cabal.project.local
251− - name: constraint set random-1.2
252− run: |
253− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' all --dry-run
254− cabal-plan topo | sort
255− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' --dependencies-only -j2 all
256− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='random==1.2.*' all
257− - name: save cache
258− if: always()
259− uses: actions/cache/save@v4
260− with:
261− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
262− path: ~/.cabal/store
cabal.haskell-ci−6
@@ -1,7 +1 @@
11branches: master
2−-- jobs-selection: any
3−head-hackage: False
4−
5−constraint-set random-1.2
6− ghc: >=7.10
7− constraints: random==1.2.*
cabal.project+1−1
@@ -2,7 +2,7 @@
22-- for more details
33
44packages: uuid-types/
5−packages: uuid/
5+ uuid/
66
77package uuid-types
88 tests: True
gen-ci.sh → haskell-ci.shrenamed

The content is the same.

uuid-bench/bench/uuid-benchmark.hs+1
@@ -3,6 +3,7 @@ import Data.Char (ord)
33import Data.IORef
44import Data.Word
55import qualified Data.UUID as U
6+import qualified Data.UUID.V1 as U
67import qualified Data.UUID.V4 as U
78import qualified Data.UUID.V3 as U3
89import qualified Data.UUID.V5 as U5
uuid-bench/uuid-bench.cabal+20−27
@@ -14,15 +14,7 @@ build-type: Simple
1414
1515-- Benchmarking with older GHCs is not meaningful
1616tested-with:
17− GHC ==8.6.5
18− || ==8.8.4
19− || ==8.10.7
20− || ==9.0.2
21− || ==9.2.8
22− || ==9.4.8
23− || ==9.6.6
24− || ==9.8.2
25− || ==9.10.1
17+ GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.4 || ==8.8.4 || ==8.10.3
2618
2719synopsis: UUID benchmarks
2820description:
@@ -40,24 +32,25 @@ source-repository head
4032
4133library
4234 build-depends:
43− base >=4.12.0.0 && <5
44− , binary >=0.8.6.0 && <0.9
45− , bytestring >=0.10.8.2 && <0.13
46− , cryptohash-md5 >=0.11.100 && <0.12
47− , cryptohash-sha1 >=0.11.100 && <0.12
48− , deepseq >=1.4.4.0 && <1.6
49− , entropy >=0.3.7 && <0.5
50− , hashable >=1.4.4.0 && <1.6
51− , network-info >=0.2 && <0.3
52− , random >=1.2.1.2 && <1.3
53− , template-haskell >=2.14.0.0 && <2.23
54− , text >=1.2.3.0 && <1.3 || >=2.0 && <2.2
55− , time >=1.4 && <1.13
35+ base >=4.9 && <5
36+ , binary >=0.4 && <0.9
37+ , bytestring >=0.9 && <0.11
38+ , cryptohash-md5 >=0.11.100 && <0.12
39+ , cryptohash-sha1 >=0.11.100 && <0.12
40+ , deepseq >=1.3 && <1.5
41+ , entropy >=0.3.7 && <0.5
42+ , hashable >=1.2.7.0 && <1.4
43+ , network-info >=0.2 && <0.3
44+ , random >=1.0.1 && <1.2
45+ , text >=1.2.3 && <1.3
46+ , time >=1.1 && <1.12
47+ , uuid-types >=1.0.2 && <2
5648
5749 -- uuid modules
5850 exposed-modules:
5951 Data.UUID
6052 Data.UUID.Util
53+ Data.UUID.V1
6154 Data.UUID.V3
6255 Data.UUID.V4
6356 Data.UUID.V5
@@ -99,13 +92,13 @@ benchmark uuid-types-benchmark
9992
10093 -- deps w/o inherited constraints
10194 build-depends:
102− containers >=0.5 && <0.8
103− , criterion >=1.5 && <1.7
95+ containers >=0.5 && <0.7
96+ , criterion >=1.5 && <1.6
10497 , unordered-containers >=0.2.7 && <0.3
10598
10699benchmark uuid-benchmark
107100 type: exitcode-stdio-1.0
108− main-is: uuid-benchmark.hs
101+ main-is: uuid-benchmark.hs
109102 hs-source-dirs: bench
110103 default-language: Haskell2010
111104 default-extensions:
@@ -118,9 +111,9 @@ benchmark uuid-benchmark
118111 build-depends:
119112 base
120113 , random
121− , uuid-bench
114+ , uuid
122115
123116 -- deps w/o inherited constraints
124117 build-depends:
125− criterion >=1.5 && <1.7
118+ criterion >=1.5 && <1.6
126119 , mersenne-random-pure64 >=0.2 && <0.3
uuid-types/ChangeLog.md−9
@@ -1,18 +1,9 @@
1−## 1.0.6 (2023-04-16)
2−
3−- Support GHC-8.6.5..GHC-9.10.1
4−
5−## 1.0.5 (2021-05-03)
6−
7−- Add (Template Haskell) `Lift UUID` instance
8−
91## 1.0.4.0
102
113- Declare `Data.UUID.Types` module "`Trustworthy`" with respect to SafeHaskell.
124- Use more compact heap object representation which saves 16 bytes on 64bit platforms.
135- Add `toWords64`/`fromWords64` functions
146- Drop support for GHC < 7.
15−- Add support for `random-1.2`, i.e. idiomatic `Random` and added `Uniform` instances.
167
178## 1.0.3
189
uuid-types/src/Data/UUID/Types.hs+4
@@ -1,4 +1,8 @@
1+{-# LANGUAGE CPP #-}
2+
3+#if __GLASGOW_HASKELL__ >= 702
14{-# LANGUAGE Trustworthy #-}
5+#endif
26
37{- |
48Module : Data.UUID.Types
uuid-types/src/Data/UUID/Types/Internal.hs+43−15
@@ -2,9 +2,10 @@
22{-# LANGUAGE DeriveDataTypeable #-}
33{-# LANGUAGE TypeFamilies #-}
44{-# LANGUAGE ViewPatterns #-}
5+#if __GLASGOW_HASKELL__ >= 704
56{-# LANGUAGE Unsafe #-}
6−{-# LANGUAGE DeriveLift #-}
7−{-# LANGUAGE StandaloneDeriving #-}
7+#endif
8+
89{-# OPTIONS_HADDOCK hide #-}
910
1011-- |
@@ -46,11 +47,13 @@ module Data.UUID.Types.Internal
4647
4748import Prelude hiding (null)
4849
50+import Control.Applicative ((<*>))
4951import Control.DeepSeq (NFData (..))
5052import Control.Monad (guard, liftM2)
5153import Data.Bits
5254import Data.Char
5355import Data.Data
56+import Data.Functor ((<$>))
5457import Data.Hashable
5558import Data.List (elemIndices)
5659import Foreign.Ptr (Ptr)
@@ -69,15 +72,13 @@ import qualified Data.Text.Encoding as T
6972
7073import Data.UUID.Types.Internal.Builder
7174
72−import System.Random (Random (..), uniform)
73−import System.Random.Stateful (Uniform (..), uniformWord64)
75+import System.Random
7476
75−import Language.Haskell.TH.Syntax (Lift)
7677
7778-- | Type representing <https://en.wikipedia.org/wiki/UUID Universally Unique Identifiers (UUID)> as specified in
7879-- <http://tools.ietf.org/html/rfc4122 RFC 4122>.
7980data UUID = UUID {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64
80− deriving (Eq, Ord)
81+ deriving (Eq, Ord, Typeable)
8182{-
8283 Prior to uuid-types-1.0.4:
8384 !Word32 !Word32 !Word32 !Word32
@@ -455,13 +456,23 @@ fromASCIIBytes bs = do
455456-- | Similar to `toASCIIBytes` except we produce a lazy `BL.ByteString`.
456457toLazyASCIIBytes :: UUID -> BL.ByteString
457458toLazyASCIIBytes =
459+#if MIN_VERSION_bytestring(0,10,0)
458460 BL.fromStrict
461+#else
462+ BL.fromChunks . return
463+#endif
459464 . toASCIIBytes
460465
461466-- | Similar to `fromASCIIBytes` except parses from a lazy `BL.ByteString`.
462467fromLazyASCIIBytes :: BL.ByteString -> Maybe UUID
463468fromLazyASCIIBytes bs =
464− if BL.length bs == 36 then fromASCIIBytes (BL.toStrict bs) else Nothing
469+ if BL.length bs == 36 then fromASCIIBytes (
470+#if MIN_VERSION_bytestring(0,10,0)
471+ BL.toStrict bs
472+#else
473+ B.concat $ BL.toChunks bs
474+#endif
475+ ) else Nothing
465476
466477--
467478-- Class Instances
@@ -470,15 +481,26 @@ fromLazyASCIIBytes bs =
470481-- | This 'Random' instance produces __insecure__ version 4 UUIDs as
471482-- specified in <http://tools.ietf.org/html/rfc4122 RFC 4122>.
472483instance Random UUID where
473− random = uniform
484+ random g = (fromGenNext w0 w1 w2 w3 w4, g4)
485+ where (w0, g0) = next g
486+ (w1, g1) = next g0
487+ (w2, g2) = next g1
488+ (w3, g3) = next g2
489+ (w4, g4) = next g3
474490 randomR _ = random -- range is ignored
475491
476−-- @since 1.0.4
477−instance Uniform UUID where
478− uniformM gen = do
479− w0 <- uniformWord64 gen
480− w1 <- uniformWord64 gen
481− pure $ buildFromBytes 4 /-/ w0 /-/ w1
492+-- |Build a UUID from the results of five calls to next on a StdGen.
493+-- While next on StdGet returns an Int, it doesn't provide 32 bits of
494+-- randomness. This code relies on at last 28 bits of randomness in the
495+-- and optimizes its use so as to make only five random values, not six.
496+fromGenNext :: Int -> Int -> Int -> Int -> Int -> UUID
497+fromGenNext w0 w1 w2 w3 w4 =
498+ buildFromBytes 4 /-/ (ThreeByte w0)
499+ /-/ (ThreeByte w1)
500+ /-/ w2 -- use all 4 bytes because we know the version
501+ -- field will "cover" the upper, non-random bits
502+ /-/ (ThreeByte w3)
503+ /-/ (ThreeByte w4)
482504
483505-- |A ByteSource to extract only three bytes from an Int, since next on StdGet
484506-- only returns 31 bits of randomness.
@@ -572,4 +594,10 @@ instance Data UUID where
572594uuidType :: DataType
573595uuidType = mkNoRepType "Data.UUID.Types.UUID"
574596
575−deriving instance Lift UUID
597+#if !MIN_VERSION_base(4,5,0)
598+unsafeShiftR, unsafeShiftL :: Bits w => w -> Int -> w
599+{-# INLINE unsafeShiftR #-}
600+unsafeShiftR = shiftR
601+{-# INLINE unsafeShiftL #-}
602+unsafeShiftL = shiftL
603+#endif
uuid-types/src/Data/UUID/Types/Internal/Builder.hs+3
@@ -1,5 +1,8 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE TypeFamilies #-}
3+#if __GLASGOW_HASKELL__ >= 704
24{-# LANGUAGE Unsafe #-}
5+#endif
36
47{-# OPTIONS_HADDOCK hide #-}
58
uuid-types/tests/TestUUID.hs−7
@@ -1,5 +1,4 @@
11{-# LANGUAGE ViewPatterns #-}
2−{-# LANGUAGE TemplateHaskell #-}
32
43{-# OPTIONS_GHC -fno-warn-orphans #-}
54
@@ -41,11 +40,6 @@ test_nil = testGroup "nil" [
4140 testCase "nil bytes" $ U.toByteString U.nil @?= BL.pack (replicate 16 0)
4241 ]
4342
44−test_lift :: Test
45−test_lift = testCase "TH.Lift" $ do
46− let uuid = U.fromWords64 123456789 987654321
47− uuid @?= $( [| uuid |] )
48−
4943test_conv :: Test
5044test_conv = testGroup "conversions" [
5145 testCase "conv bytes to string" $
@@ -182,7 +176,6 @@ main = do
182176 [ [
183177 test_null,
184178 test_nil,
185− test_lift,
186179 test_conv,
187180 test_fromByteString,
188181 test_fromWords,
uuid-types/uuid-types.cabal+21−28
@@ -1,7 +1,6 @@
11cabal-version: 1.12
22name: uuid-types
3−version: 1.0.6
4−x-revision: 2
3+version: 1.0.4.0
54copyright:
65 (c) 2017-2018 Herbert Valerio Riedel
76 (c) 2008-2014 Antoine Latter
@@ -13,16 +12,16 @@ license-file: LICENSE
1312category: Data
1413build-type: Simple
1514tested-with:
16− GHC ==8.6.5
15+ GHC ==7.4.2
16+ || ==7.6.3
17+ || ==7.8.4
18+ || ==7.10.3
19+ || ==8.0.2
20+ || ==8.2.2
21+ || ==8.4.4
22+ || ==8.6.4
1723 || ==8.8.4
18− || ==8.10.7
19− || ==9.0.2
20− || ==9.2.8
21− || ==9.4.8
22− || ==9.6.6
23− || ==9.8.4
24− || ==9.10.1
25− || ==9.12.1
24+ || ==8.10.3
2625
2726synopsis: Type definitions for Universally Unique Identifiers
2827description:
@@ -46,14 +45,13 @@ source-repository head
4645
4746library
4847 build-depends:
49− base >=4.12.0.0 && <5
50− , binary >=0.8.6.0 && <0.9
51− , bytestring >=0.10.8.2 && <0.13
52− , deepseq >=1.4.4.0 && <1.6
53− , hashable >=1.4.4.0 && <1.6
54− , random >=1.2.1.2 && <1.3
55− , template-haskell >=2.14.0.0 && <2.24
56− , text >=1.2.3.0 && <1.3 || >=2.0 && <2.2
48+ base >=4.3 && <5
49+ , binary >=0.4 && <0.9
50+ , bytestring >=0.9 && <0.11
51+ , deepseq >=1.3 && <1.5
52+ , hashable >=1.2.7.0 && <1.4
53+ , random >=1.1 && <1.2
54+ , text >=1.2.3 && <1.3
5755
5856 exposed-modules: Data.UUID.Types
5957
@@ -77,23 +75,18 @@ test-suite testuuid
7775 default-language: Haskell2010
7876 other-extensions: ViewPatterns
7977 ghc-options: -Wall
80− if impl(ghc >= 8.10)
81− ghc-options: -Wunused-packages
8278
8379 -- inherited constraints
8480 build-depends:
8581 base
8682 , binary
8783 , bytestring
88− , template-haskell
8984 , uuid-types
9085
9186 -- deps w/o inherited constraints
9287 build-depends:
93− QuickCheck >=2.14.2 && <2.16
94− , tasty >=1.4.0.1 && <1.6
88+ ghc-byteorder >=4.11 && <4.12
89+ , QuickCheck >=2.14.2 && <2.15
90+ , tasty >=1.4.0.1 && <1.5
9591 , tasty-hunit >=0.10 && <0.11
96− , tasty-quickcheck >=0.10 && <0.12
97−
98− if !impl(ghc >=8.4)
99− build-depends: ghc-byteorder >=4.11 && <4.12
92+ , tasty-quickcheck >=0.10 && <0.11
uuid/CHANGES.md+1−15
@@ -1,23 +1,9 @@
1−1.3.16
2−
3−- Support GHC-8.6.5...9.10.1
4−
5−1.3.15
6−
7−- Add (Template Haskell) `Lift UUID` instance
8−
9−1.3.14
10−
11−- Use more compact heap object representation which saves 16 bytes on 64bit platforms.
12−- Add `toWords64`/`fromWords64` functions
13−
1411.3.13
152
163- Optimize `V4.nextRandom` (~3x speed increase)
174- Optimize UUID V3 & V5 generation (~2x speed increase)
185- Use `cryptohash-md5`/`cryptohash-sha1`/`entropy` instead
19− of `memory`/`cryptonite` for better performance and stability,
20− but GHCJS is now no longer supported.
6+ of `memory`/`cryptonite` for better performance and stability.
217- Update cabal-spec to version 1.10
228
2391.3.12
uuid/src/Data/UUID.hs+3−2
@@ -18,6 +18,9 @@ See <http://tools.ietf.org/html/rfc4122> for the specification.
1818favorite instance of 'System.Random.Random' for faster but insecure
1919generation of UUIDs.
2020
21+* We have an implementation of generating a UUID from the hardware
22+MAC address and current system time in "Data.UUID.V1".
23+
2124* For name-based generation of UUIDs using SHA-1 hashing see
2225"Data.UUID.V5".
2326-}
@@ -34,8 +37,6 @@ module Data.UUID(UUID
3437 ,fromByteString
3538 ,toWords
3639 ,fromWords
37− ,toWords64
38− ,fromWords64
3940 ,null
4041 ,nil
4142 ) where
uuid/src/Data/UUID/Util.hs+11
@@ -3,6 +3,7 @@ module Data.UUID.Util (
33 UnpackedUUID(..)
44 , unpack, pack
55 , version
6+ , extractMac
67 , extractTime
78 , setTime
89 ) where
@@ -12,6 +13,7 @@ import Data.Word
1213import Data.Word.Util
1314import Data.Bits
1415import Data.UUID.Types.Internal
16+import Network.Info
1517import Data.Int (Int64)
1618
1719version :: UUID -> Int
@@ -40,3 +42,12 @@ extractTime uuid =
4042
4143timeAndVersionToTime :: Word16 -> Word16
4244timeAndVersionToTime tv = tv .&. 0x0FFF
45+
46+extractMac :: UUID -> Maybe MAC
47+extractMac uuid =
48+ if version uuid == 1
49+ then Just $
50+ MAC (node_0 unpacked) (node_1 unpacked) (node_2 unpacked) (node_3 unpacked) (node_4 unpacked) (node_5 unpacked)
51+ else Nothing
52+ where
53+ unpacked = unpack uuid
uuid/src/Data/UUID/V1.hsnew file+135
@@ -0,0 +1,135 @@
1+{-# OPTIONS_GHC -fno-cse #-}
2+{-# LANGUAGE TypeFamilies #-}
3+
4+{- |
5+Module : Data.UUID.V1
6+Copyright : (c) 2008 Jason Dusek
7+ (c) 2009 Mark Lentczner
8+ (c) 2009-2010,2012 Antoine Latter
9+
10+License : BSD-style
11+
12+Maintainer : aslatter@gmail.com
13+Stability : experimental
14+Portability : portable
15+
16+RFC 4122 Version 1 UUID state machine.
17+
18+The generated UUID is based on the hardware MAC
19+address and the system clock.
20+
21+If we cannot lookup the MAC address we seed the
22+generator with a psuedo-random number.
23+-}
24+
25+module Data.UUID.V1(nextUUID)
26+where
27+
28+
29+import Data.Bits
30+import Data.Maybe
31+import Data.Time
32+import Data.Word
33+
34+import Control.Applicative ((<$>),(<*>))
35+import Control.Concurrent.MVar
36+import System.IO.Unsafe
37+
38+import qualified System.Random as R
39+
40+import Network.Info
41+
42+import Data.UUID.Types.Internal.Builder
43+import Data.UUID.Types.Internal
44+
45+-- | Returns a new UUID derived from the local hardware MAC
46+-- address and the current system time.
47+-- Is generated according to the Version 1 UUID specified in
48+-- RFC 4122.
49+--
50+-- Returns 'Nothing' if you request UUIDs too quickly.
51+nextUUID :: IO (Maybe UUID)
52+nextUUID = do
53+ res <- stepTime
54+ case res of
55+ Just (mac', c, t) -> return $ Just $ makeUUID t c mac'
56+ _ -> return Nothing
57+
58+
59+makeUUID :: Word64 -> Word16 -> MAC -> UUID
60+makeUUID time clock mac' =
61+ buildFromBytes 1 /-/ tLow /-/ tMid /-/ tHigh /-/ clock /-/ (MACSource mac')
62+ where tLow = (fromIntegral time) :: Word32
63+ tMid = (fromIntegral (time `shiftR` 32)) :: Word16
64+ tHigh = (fromIntegral (time `shiftR` 48)) :: Word16
65+
66+newtype MACSource = MACSource MAC
67+instance ByteSource MACSource where
68+ z /-/ (MACSource (MAC a b c d e f)) = z a b c d e f
69+type instance ByteSink MACSource g = Takes3Bytes (Takes3Bytes g)
70+
71+
72+-- |Approximates the clock algorithm in RFC 4122, section 4.2
73+-- Isn't system wide or thread safe, nor does it properly randomize
74+-- the clock value on initialization.
75+stepTime :: IO (Maybe (MAC, Word16, Word64))
76+stepTime = do
77+ h1 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
78+ modifyMVar state $ \s@(State mac' c0 h0) ->
79+ if h1 > h0
80+ then
81+ return (State mac' c0 h1, Just (mac', c0, h1))
82+ else
83+ let
84+ c1 = succ c0
85+ in if c1 <= 0x3fff -- when clock is initially randomized,
86+ -- then this test will need to change
87+ then
88+ return (State mac' c1 h1, Just (mac', c1, h1))
89+ else
90+ return (s, Nothing)
91+
92+
93+{-# NOINLINE state #-}
94+state :: MVar State
95+state = unsafePerformIO $ do
96+ h0 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
97+ mac' <- getMac
98+ newMVar $ State mac' 0 h0 -- the 0 should be a random number
99+
100+-- SysMAC.mac can fail on some machines.
101+-- In those cases we fake it with a random
102+-- 6 bytes seed.
103+getMac :: IO MAC
104+getMac =
105+ getNetworkInterfaces >>=
106+ return . listToMaybe . filter (minBound /=) . map mac >>=
107+ \macM -> case macM of
108+ Just m -> return m
109+ Nothing -> randomMac
110+
111+randomMac :: IO MAC
112+randomMac =
113+ -- I'm too lazy to thread through
114+ -- the random state ...
115+ MAC
116+ <$> (R.randomIO >>= return . (1 .|.)) -- We must set the multicast bit to True. See section 4.5 of the RFC.
117+ <*> R.randomIO
118+ <*> R.randomIO
119+ <*> R.randomIO
120+ <*> R.randomIO
121+ <*> R.randomIO
122+
123+data State = State
124+ {-# UNPACK #-} !MAC
125+ {-# UNPACK #-} !Word16
126+ {-# UNPACK #-} !Word64
127+ deriving (Show)
128+
129+
130+
131+hundredsOfNanosSinceGregorianReform :: UTCTime -> Word64
132+hundredsOfNanosSinceGregorianReform t = floor $ 10000000 * dt
133+ where
134+ gregorianReform = UTCTime (fromGregorian 1582 10 15) 0
135+ dt = t `diffUTCTime` gregorianReform
uuid/src/Data/UUID/V3.hs+1−1
@@ -8,7 +8,7 @@ Maintainer : aslatter@gmail.com
88Stability : experimental
99Portability : portable
1010
11−NOTE\: This module uses MD5 hashing. Unless you know
11+NOTE: This module uses MD5 hashing. Unless you know
1212you need to use this module, you should probably be
1313using "Data.UUID.V5", which offers the same sort of
1414functionality as this module except implemented with
uuid/src/Data/UUID/V4.hs+4−5
@@ -11,8 +11,8 @@
1111 This module implements Version 4 UUIDs as specified
1212 in RFC 4122.
1313
14− These UUIDs are generated from a pseudo-random generator.
15− We use the 'getEntropy' method from the <https://hackage.haskell.org/package/entropy entropy> package,
14+ These UUIDs are generated from a pseddo-random generator.
15+ We use 'getEntropy' method from <https://hackage.haskell.org/package/entropy entropy> package,
1616 which should provide cryptographically secure random data.
1717-}
1818module Data.UUID.V4 (nextRandom) where
@@ -23,9 +23,8 @@ import Data.UUID.Types.Internal ( buildFromBytes )
2323import System.Entropy ( getEntropy )
2424import Data.ByteString ( unpack )
2525
26−-- | Generate a crytographically secure, random UUID.
27−--
28−-- @since 1.2.6
26+-- | Generate a crytographically secure, random UUID. Introduced in version
27+-- 1.2.6.
2928nextRandom :: IO UUID
3029nextRandom = do
3130 [b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf]
uuid/tests/TestUUID.hs+20−4
@@ -1,15 +1,18 @@
11{-# LANGUAGE ViewPatterns #-}
22
3+import Control.Monad (replicateM)
34import Data.Bits
45import qualified Data.ByteString.Lazy as BL
56import Data.Char (ord)
7+import Data.List (nub, (\\))
68import Data.Maybe
79import Data.Word
810import qualified Data.UUID as U
11+import qualified Data.UUID.V1 as U
912import qualified Data.UUID.V3 as U3
1013import qualified Data.UUID.V5 as U5
1114
12−import Test.QuickCheck ( Arbitrary(arbitrary) )
15+import Test.QuickCheck ( Arbitrary(arbitrary), choose )
1316import Test.Tasty ( TestTree, testGroup, defaultMain )
1417import Test.Tasty.HUnit
1518 ( assertBool, (@?=), testCase )
@@ -21,13 +24,13 @@ isValidVersion :: Int -> U.UUID -> Bool
2124isValidVersion v u = lenOK && variantOK && versionOK
2225 where bs = U.toByteString u
2326 lenOK = BL.length bs == 16
24− variantOK = BL.index bs 8 .&. 0xc0 == 0x80
25− versionOK = BL.index bs 6 .&. 0xf0 == fromIntegral (v `shiftL` 4)
27+ variantOK = (BL.index bs 8) .&. 0xc0 == 0x80
28+ versionOK = (BL.index bs 6) .&. 0xf0 == fromIntegral (v `shiftL` 4)
2629
2730
2831instance Arbitrary U.UUID where
2932 -- the UUID random instance ignores bounds
30− arbitrary = pure U.nil
33+ arbitrary = choose (U.nil, U.nil)
3134
3235
3336test_null :: Test
@@ -35,6 +38,17 @@ test_null =
3538 testCase "namespaceDNS is not null" $
3639 assertBool "" (not $ U.null U3.namespaceDNS)
3740
41+test_v1 :: [Maybe U.UUID] -> Test
42+test_v1 v1s = testGroup "version 1" [
43+ testCase "V1 unique" $ nub (v1s \\ nub v1s) @?= [],
44+ testGroup "V1 not null" $ map (testUUID (not . U.null)) v1s,
45+ testGroup "V1 valid" $ map (testUUID (isValidVersion 1)) v1s
46+ ]
47+ where testUUID :: (U.UUID -> Bool) -> Maybe U.UUID -> Test
48+ testUUID p u =
49+ testCase (show u) $
50+ assertBool "" $ maybe False p u
51+
3852test_v3 :: Test
3953test_v3 =
4054 testCase "V3 computation" $
@@ -79,11 +93,13 @@ prop_v5Valid = testProperty "V5 valid" v5Valid
7993
8094main :: IO ()
8195main = do
96+ v1s <- replicateM 100 U.nextUUID
8297 defaultMain $
8398 testGroup "tests" $
8499 concat $
85100 [ [
86101 test_null,
102+ test_v1 v1s,
87103 test_v3,
88104 test_v5
89105 ]
uuid/uuid.cabal+23−24
@@ -1,7 +1,6 @@
11cabal-version: 1.12
22name: uuid
3−version: 1.3.16
4−x-revision: 2
3+version: 1.3.13
54copyright: (c) 2008-2014 Antoine Latter
65author: Antoine Latter
76maintainer: Oleg Grenrus <oleg.grenrus@iki.fi>
@@ -10,16 +9,16 @@ license-file: LICENSE
109category: Data
1110build-type: Simple
1211tested-with:
13− GHC ==8.6.5
12+ GHC ==7.4.2
13+ || ==7.6.3
14+ || ==7.8.4
15+ || ==7.10.3
16+ || ==8.0.2
17+ || ==8.2.2
18+ || ==8.4.4
19+ || ==8.6.4
1420 || ==8.8.4
15− || ==8.10.7
16− || ==9.0.2
17− || ==9.2.8
18− || ==9.4.8
19− || ==9.6.6
20− || ==9.8.4
21− || ==9.10.1
22− || ==9.12.1
21+ || ==8.10.3
2322
2423synopsis:
2524 For creating, comparing, parsing and printing Universally Unique Identifiers
@@ -41,19 +40,22 @@ source-repository head
4140
4241library
4342 build-depends:
44− base >=4.12 && <5
45− , binary >=0.8.6.0 && <0.9
46− , bytestring >=0.10.8.2 && <0.13
43+ base >=4.3 && <5
44+ , binary >=0.4 && <0.9
45+ , bytestring >=0.9 && <0.11
4746 , cryptohash-md5 >=0.11.100 && <0.12
4847 , cryptohash-sha1 >=0.11.100 && <0.12
4948 , entropy >=0.3.7 && <0.5
49+ , network-info >=0.2 && <0.3
50+ , random >=1.1 && <1.2
51+ , text >=1.2.3 && <1.3
52+ , time >=1.1 && <1.12
53+ , uuid-types >=1.0.2 && <2
5054
51− -- strict dependency on uuid-types,
52− -- as we re-rexport datatype, thus leak instances etc.
53− build-depends: uuid-types >=1.0.6 && <1.0.7
5455 exposed-modules:
5556 Data.UUID
5657 Data.UUID.Util
58+ Data.UUID.V1
5759 Data.UUID.V3
5860 Data.UUID.V4
5961 Data.UUID.V5
@@ -66,8 +68,6 @@ library
6668 default-extensions: DeriveDataTypeable
6769 other-extensions: TypeFamilies
6870 ghc-options: -Wall
69− if impl(ghc >= 8.10)
70− ghc-options: -Wunused-packages
7171 hs-source-dirs: src
7272
7373test-suite testuuid
@@ -78,18 +78,17 @@ test-suite testuuid
7878 default-extensions: DeriveDataTypeable
7979 other-extensions: ViewPatterns
8080 ghc-options: -Wall -fno-warn-orphans
81− if impl(ghc >= 8.10)
82− ghc-options: -Wunused-packages
8381
8482 -- inherited constraints
8583 build-depends:
8684 base
8785 , bytestring
86+ , random
8887 , uuid
8988
9089 -- deps w/o inherited constraints
9190 build-depends:
92− QuickCheck >=2.14.2 && <2.16
93− , tasty >=1.4.0.1 && <1.6
91+ QuickCheck >=2.14.2 && <2.15
92+ , tasty >=1.4.0.1 && <1.5
9493 , tasty-hunit >=0.10 && <0.11
95− , tasty-quickcheck >=0.10 && <0.12
94+ , tasty-quickcheck >=0.10 && <0.11