1 |
On Tue, 1 Nov 2016 01:31:55 +0100 |
2 |
Michał Górny <mgorny@g.o> wrote: |
3 |
|
4 |
Haskell package ecosystem (hackage) encourages |
5 |
upper version bounds and strict version bounds on |
6 |
dependencies: http://pvp.haskell.org/ |
7 |
|
8 |
Most of dependencies look like: |
9 |
>=foo-1.3 <foo-1.5 |
10 |
>=bar-2.1 <bar-2.8 |
11 |
|| ( ( >=baz-2.1 <baz-2.8 ) ( >=baz-2.9 <baz-3.1 ) ) |
12 |
Or even: |
13 |
~bar-1.4.2.0 |
14 |
|
15 |
If we want to preserve upstream's versioning (and |
16 |
we most of the time do). That requires support for |
17 |
things that portage does not provide in it's current |
18 |
form. |
19 |
|
20 |
> Therefore, I would like to ask the following questions: |
21 |
> |
22 |
> 1. How often do you find '~' useful? Do you think there should be |
23 |
> additional operators that ignore revision part? |
24 |
|
25 |
Haskell packages occasionally bind to very specific library version. |
26 |
The set of packages is usually released together because |
27 |
package author tests against that single set of versions. |
28 |
|
29 |
::gentoo examples: |
30 |
|
31 |
dev-haskell/haddock/haddock-2.16.1.ebuild: ~dev-haskell/haddock-api-2.16.1 |
32 |
dev-haskell/hspec/hspec-2.2.1.ebuild:RDEPEND="~dev-haskell/hspec-core-2.2.1:=[profile?] |
33 |
dev-haskell/hspec/hspec-2.2.1.ebuild: ~dev-haskell/hspec-discover-2.2.1:=[profile?] |
34 |
|
35 |
::haskell examples: |
36 |
|
37 |
dev-haskell/edisoncore/edisoncore-1.2.2.1.ebuild:RDEPEND="~dev-haskell/edisonapi-1.2.2.1:=[profile?] |
38 |
dev-haskell/ghc-api/ghc-api-7.10.3.ebuild: ~dev-haskell/binary-0.7.6.1:= |
39 |
dev-haskell/ghc-api/ghc-api-7.10.3.ebuild: ~dev-haskell/transformers-0.4.3.0:= |
40 |
dev-haskell/hledger-web/hledger-web-0.27.ebuild: ~dev-haskell/hledger-0.27:=[profile?] |
41 |
dev-haskell/hledger-web/hledger-web-0.27.ebuild: ~dev-haskell/hledger-lib-0.27:=[profile?] |
42 |
dev-haskell/hledger/hledger-0.27.ebuild: ~dev-haskell/hledger-lib-0.27:=[profile?] |
43 |
dev-haskell/hprotoc/hprotoc-2.4.0.ebuild: ~dev-haskell/protocol-buffers-2.4.0:=[profile?] |
44 |
dev-haskell/hprotoc/hprotoc-2.4.0.ebuild: ~dev-haskell/protocol-buffers-descriptor-2.4.0:=[profile?] |
45 |
dev-haskell/llvm-general/llvm-general-3.5.1.2.ebuild:RDEPEND="~dev-haskell/llvm-general-pure-3.5.1.0:=[profile?] |
46 |
dev-haskell/protocol-buffers-descriptor/protocol-buffers-descriptor-2.4.0.ebuild:RDEPEND="~dev-haskell/protocol-buffers-2.4.0:=[profile?] |
47 |
dev-haskell/yarr/yarr-1.4.0.2.ebuild: ~dev-haskell/missing-foreign-0.1.1:=[profile?] |
48 |
dev-lang/elm-make/elm-make-0.17.1-r1.ebuild: ~dev-lang/elm-compiler-0.17.1:= |
49 |
dev-lang/elm-meta/elm-meta-0.17.1.ebuild: ~dev-lang/elm-compiler-${PV} |
50 |
dev-lang/elm-meta/elm-meta-0.17.1.ebuild: ~dev-lang/elm-make-${PV} |
51 |
dev-lang/elm-meta/elm-meta-0.17.1.ebuild: ~dev-lang/elm-package-${PV} |
52 |
dev-lang/elm-meta/elm-meta-0.17.1.ebuild: ~dev-lang/elm-reactor-${PV} |
53 |
dev-lang/elm-meta/elm-meta-0.17.1.ebuild: ~dev-lang/elm-repl-${PV} |
54 |
dev-lang/elm-package/elm-package-0.17.1-r2.ebuild: ~dev-lang/elm-compiler-0.17.1:=[profile?] |
55 |
dev-lang/elm-reactor/elm-reactor-0.17.1.ebuild: ~dev-lang/elm-compiler-0.17.1:= |
56 |
dev-lang/elm-reactor/elm-reactor-0.17.1.ebuild: ~dev-lang/elm-make-${PV} |
57 |
dev-lang/elm-repl/elm-repl-0.17.1.ebuild: ~dev-lang/elm-compiler-0.17.1:= |
58 |
sci-mathematics/agda/agda-9999.ebuild: ~dev-haskell/edisonapi-1.3:=[profile?] |
59 |
|
60 |
> 2. How often do you find '=...*' wildcard syntax useful? To what |
61 |
> purpose do you use it? Do you find its behavior confusing [1]? |
62 |
|
63 |
haskell used to optimise ranged dependencies of style |
64 |
>=foo-2 && <foo-3 |
65 |
into |
66 |
=foo-2* |
67 |
but now we always generate |
68 |
>=foo-2 && <foo-3 |
69 |
to ease ebuild patching when package is ported to foo-3 |
70 |
dependency. |
71 |
|
72 |
Special care must be taken when 'foo' is slotted but we |
73 |
try not to slot things. |
74 |
|
75 |
> 4. What are the common tasks that you find unnecessarily complex / |
76 |
> lengthy with the current version specifications? |
77 |
|
78 |
Problem 1: |
79 |
|
80 |
Sometimes upstream decides that one of their dependencies |
81 |
is broken on a version range (package compiles but does |
82 |
horrible things due to accidental semantic change in a dependency) |
83 |
|
84 |
Common example is aeson. Upstream dependency looks like: |
85 |
|| ( ( >=aeson-0.5 <aeson-0.10 ) |
86 |
( >=aeson-0.11 <aeson-1.2 ) ) |
87 |
|
88 |
While it works there is no matching syntax |
89 |
for the same behaviour but with added rebuild on upgrade. |
90 |
|
91 |
This is not accepted nowadays: |
92 |
|| ( ( >=aeson-0.5:= <aeson-0.10:= ) |
93 |
( >=aeson-0.11:= <aeson-1.2:= ) ) |
94 |
|
95 |
Currently we avoid it by simplifying the depend down to |
96 |
latest available or throw away broken versions from tree |
97 |
completely if the breakage is common enough: |
98 |
|
99 |
( >=aeson-0.11:= <aeson-1.2:= ) |
100 |
or |
101 |
( >=aeson-0.5:= <aeson-1.2:= ) |
102 |
|
103 |
Problem 2: |
104 |
|
105 |
Haskell ABI it a SUM of: |
106 |
- ABIs of its dependency libraries |
107 |
- own exports |
108 |
Library version is a part of that library ABI. |
109 |
Thus library ABI is guaranteed to change every library release. |
110 |
|
111 |
It means that once end user merges a library version bump |
112 |
user needs to rebuild all library's transitive reverse dependencies. |
113 |
Sometimes library is deep in the dependency chain (5-10 levels deep). |
114 |
|
115 |
There is no way to express that style of dependency in portage: |
116 |
https://bugs.gentoo.org/show_bug.cgi?id=449094 |
117 |
and app-admin/haskell-updater is still a needed thing to restore |
118 |
world sanity after a library upgrade. |
119 |
|
120 |
-- |
121 |
|
122 |
Sergei |