Processed: Re: Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-12-02 Thread Debian Bug Tracking System
Processing control commands:

> severity 901827 wishlist
Bug #901827 [dpkg] dpkg: Support two-sided version constraint ranges, required 
to properly translate Cargo dependencies
Ignoring request to change severity of Bug 901827 to the same value.

-- 
901827: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901827
913408: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913408
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems



Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-12-02 Thread Guillem Jover
Control: severity 901827 wishlist

On Sat, 2018-11-10 at 23:16:00 +, Ximin Luo wrote:
> This translation scheme works for Depends and Build-Depends, however
> it does not work for Replaces and Breaks, please see #913408 for an
> example of the problem.
> 
> In the abstract example above, since A-5 (= 5.1.1) replaces files
> from a previously-uploaded A (= 5.1.1), it must declare
> Replaces+Breaks: A (= 5). But in reality, there may be multiple
> Debian uploads of 5.1.1 including security uploads and backports.
> So we really need to declare:
> 
> Breaks: A (>= 5.1.1~~, << 5.1.2~~)
> Replaces: A (>= 5.1.1~~, << 5.1.2~~)
> 
> but this is not possible in Debian today. Note that this:
> 
> Breaks: A (>= 5.1.1~~), A (<< 5.1.2~~)
> Replaces: A (>= 5.1.1~~), A (<< 5.1.2~~)
> 
> won't work as it is equivalent to Breaks: A, Replaces: A which is not
> what we want.

As has been mentioned elsewhere, I don't think we really need to do
this strict range coverage, because in general we do not support
downgrades, and only upgrading forward.

In any case, this is still a whishlist bug, reset accordingly.

Thanks,
Guillem



Processed: Re: Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-12-02 Thread Debian Bug Tracking System
Processing control commands:

> severity 901827 wishlist
Bug #901827 [dpkg] dpkg: Support two-sided version constraint ranges, required 
to properly translate Cargo dependencies
Severity set to 'wishlist' from 'important'

-- 
901827: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901827
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems



Processed: Re: Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-11-10 Thread Debian Bug Tracking System
Processing control commands:

> severity 901827 important
Bug #901827 [dpkg] dpkg: Support two-sided version constraint ranges, required 
to properly translate Cargo dependencies
Severity set to 'important' from 'wishlist'
> block 913408 by 901827
Bug #913408 [librust-crossbeam-epoch-0.5-dev] librust-crossbeam-epoch-0.5-dev: 
missing Breaks+Replaces: librust-crossbeam-epoch-dev (<< 0.6)
913408 was not blocked by any bugs.
913408 was not blocking any bugs.
Added blocking bug(s) of 913408: 901827

-- 
901827: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901827
913408: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913408
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems



Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-11-10 Thread Ximin Luo
Control: severity 901827 important
Control: block 913408 by 901827

Ximin Luo:
> Guillem Jover:
>> [..]
>>
>> So you could have package slab-X.Y and then depend on just that, or if
>> for some reason you need to have coinstallability down to the minor
>> version, then slab-X.Y.Z, in which case that package would provide
>> slab-X.Y (= X.Y.Z). In addition, all of these would also provide
>> slab-X (= X.Y.Z) and slab (= X.Y.Z) and probably also slab, so that
>> you can represent all the range types.
>>
>>   Cargo deps (A) dpkg deps (A-X.Y || A-X.Y.Z)
>>   A  A
>>   A (>= 6)   A (>= 6)
>>   A (>= 6.1) A (>= 6.1)
>>   A (>= 6.1.3)   A (>= 6.1.3)
>>   A (>= 6, << 7) A-6
>>   A (>= 6.1, << 6.2) A-6.1
>>   A (= 6)A-6
>>   A (= 6.1)  A-6.1
>>
> 
> Thanks for being specific here. After thinking after it for a bit, I think 
> this might work. The key is to only generate a single item within in the 
> comma-separated list of AND-clauses in the dpkg dependency, where the item 
> itself is a "|"-separated OR-clause. It would be pretty ugly in some 
> circumstances:
> 
> Cargo deps  dpkg deps
> A (>= 6.1, << 9.5) >A-6 (>= 6.1) | A-7 | A-8 | A-9 (<< 9.5)
> 
> but I think I have a decently-simple way of achieving this in debcargo.
> 

This translation scheme works for Depends and Build-Depends, however it does 
not work for Replaces and Breaks, please see #913408 for an example of the 
problem.

In the abstract example above, since A-5 (= 5.1.1) replaces files from a 
previously-uploaded A (= 5.1.1), it must declare Replaces+Breaks: A (= 5). But 
in reality, there may be multiple Debian uploads of 5.1.1 including security 
uploads and backports. So we really need to declare:

Breaks: A (>= 5.1.1~~, << 5.1.2~~)
Replaces: A (>= 5.1.1~~, << 5.1.2~~)

but this is not possible in Debian today. Note that this:

Breaks: A (>= 5.1.1~~), A (<< 5.1.2~~)
Replaces: A (>= 5.1.1~~), A (<< 5.1.2~~)

won't work as it is equivalent to Breaks: A, Replaces: A which is not what we 
want.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-19 Thread Ximin Luo
Guillem Jover:
> [..]
> 
> We discussed this briefly yesterday on IRC before Ximin filed the
> report. I don't see much difference with what was mentioned and I'll
> repeat what David Kalnischkies and me proposed on the spot, as a
> potentiall working solution.
> 

To be fair, neither of you were very specific and the words you said could just 
have as easily described what we were already doing previously, which is how I 
interpreted it at the time.

> [..]
> 
> So you could have package slab-X.Y and then depend on just that, or if
> for some reason you need to have coinstallability down to the minor
> version, then slab-X.Y.Z, in which case that package would provide
> slab-X.Y (= X.Y.Z). In addition, all of these would also provide
> slab-X (= X.Y.Z) and slab (= X.Y.Z) and probably also slab, so that
> you can represent all the range types.
> 
>   Cargo deps (A)  dpkg deps (A-X.Y || A-X.Y.Z)
>   A   A
>   A (>= 6)A (>= 6)
>   A (>= 6.1)  A (>= 6.1)
>   A (>= 6.1.3)A (>= 6.1.3)
>   A (>= 6, << 7)  A-6
>   A (>= 6.1, << 6.2)  A-6.1
>   A (= 6) A-6
>   A (= 6.1)   A-6.1
> 

Thanks for being specific here. After thinking after it for a bit, I think this 
might work. The key is to only generate a single item within in the 
comma-separated list of AND-clauses in the dpkg dependency, where the item 
itself is a "|"-separated OR-clause. It would be pretty ugly in some 
circumstances:

Cargo deps  dpkg deps
A (>= 6.1, << 9.5) >A-6 (>= 6.1) | A-7 | A-8 | A-9 (<< 9.5)

but I think I have a decently-simple way of achieving this in debcargo.

> [..] 
>> In the Debian Rust team, we previously experimented with e.g. converting:
>>
>> - Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
>> - Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 | 
>> X-9 | X-10
> 
> That seems indeed wrong. At least the first should have been just X-6,
> and yeah the second should have used more granular versioned provides
> as shown above.
> 

The first was a typo, and as for the second I did not realise by "granular" you 
meant Provides both X (= 6) and X-6 (= 6) etc, I thought you meant just the 
latter which is what we were already doing.

>> [..]
>>
>> So the cleanest solution to this problem would be to support two-sided 
>> version
>> ranges. This would be beneficial across the whole archive as well - I have
>> needed to do the Depends: X (>= 4), X (<< 5) hack before when what I really
>> meant was (>= 4, << 5), and I remember this in others' packages too.
> 
> Depends on how you define cleanest. :) In this case that means you
> cannot use this anyway until a stable+1 (assuming just dpkg and apt
> implemented this right away), and it would not be usable anyway until
> most major dependency parsers/satisfiers would support it too, which
> might be stable+2, perhaps.
> 

If you guys implement it, I'd be happy to switch to it after 2 stable releases, 
that's only 4 years and I'm sure Rust will be around for a long time. The fact 
that it's so hard means there's a load of technical debt there that is worth 
trying to pay back anyways.

> Of course the counter-proposal that David and me provided assumes the
> versions have sane semantics (similar to semver), and that their
> format is uniform all over Cargo. If that's not the case then that
> might be a problem, if you are converting the dependencies
> automatically. :)
> 

Yes luckily it's uniform enough. semver actually has very specific semantics to 
do with API compatibility, but we don't even need to rely on that here, we just 
need that the version numbers are constrained enough to be able to do this 
Provides: A (= X.Y.Z) A-X (= X.Y.Z) A-Y (= X.Y.Z) thing. I think the only way 
to sustainably do it long-term is to automatically generate it.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-19 Thread Guillem Jover
Hi!

On Mon, 2018-06-18 at 19:55:31 -0700, Ximin Luo wrote:
> Package: dpkg
> Version: 1.19.0.5+b1
> Severity: wishlist

We discussed this briefly yesterday on IRC before Ximin filed the
report. I don't see much difference with what was mentioned and I'll
repeat what David Kalnischkies and me proposed on the spot, as a
potentiall working solution.

> The Rust package manager Cargo, makes it possible to declare two-sided version
> constraint ranges such as X (>= 6, << 7). In dpkg, historically this has been
> expressed by declaring two one-sided version constraint ranges for the same
> package like X (>= 6), X (<< 7), however this is not sufficient for Cargo due
> to its other feature of allowing transitive dependencies on multiple versions
> of the same package.
> 
> Currently to support this we are creating packages called X-$version, and
> declaring Provides: X (= $version). This breaks in the following situation:
> 
> mdbook 0.1.7 transitively depends on slab 0.1.3, 0.3.0, and 0.4.0, via mio 
> 0.5.1,
> mio 0.6.14, and ws-0.7.6. These dependencies are declared as:
> 
> mio-0.5.1/debian/control: librust-slab+default-dev (>= 0.1.0~~),
> mio-0.5.1/debian/control: librust-slab+default-dev (<< 0.2~~),
> ws-0.7.6/debian/control: librust-slab+default-dev (>= 0.3~~),
> ws-0.7.6/debian/control: librust-slab+default-dev (<< 0.4~~),
> mio-0.6.14/debian/control: librust-slab+default-dev (>= 0.4.0~~),
> mio-0.6.14/debian/control: librust-slab+default-dev (<< 0.5~~),

The problem is that you want to depend on independent "major" versions
of these packages, while making using the minor versions available.

I see multiple ways to go about this, but these are based on
assumptions about the versions and the relationships that I'm not sure
hold within Cargo.

The key is, when having an X.Y.Z version in Cargo, not to use that
either as part of the real or virtual package names. Because I
understand you/Cargo care only about the "major" part of that version.

So you could have package slab-X.Y and then depend on just that, or if
for some reason you need to have coinstallability down to the minor
version, then slab-X.Y.Z, in which case that package would provide
slab-X.Y (= X.Y.Z). In addition, all of these would also provide
slab-X (= X.Y.Z) and slab (= X.Y.Z) and probably also slab, so that
you can represent all the range types.

  Cargo deps (A)dpkg deps (A-X.Y || A-X.Y.Z)
  A A
  A (>= 6)  A (>= 6)
  A (>= 6.1)A (>= 6.1)
  A (>= 6.1.3)  A (>= 6.1.3)
  A (>= 6, << 7)A-6
  A (>= 6.1, << 6.2)A-6.1
  A (= 6)   A-6
  A (= 6.1) A-6.1

> RPM has resolved this by implementing "rich dependencies" which is a general
> solution to express "the same package must satisfy both A and B". However, it
> is apparently more difficult to do this in dpkg.

I've not checked how difficult it would be in dpkg. The main problem
here is that the dependency resolution logic is not concentrated just
within dpkg itself, but spread all over the place, and changing/extending
the semantics of these tend to be very painful, and long-winded
processes. So there's general reluctance to do that when there's no
apparent need.

Check for example versioned provides, some people are still afraid to
use them!

> What I am suggesting is smaller: we only need to support two-sided version
> ranges like (>= 0.3~~, << 0.4~~), which does not seem to be such a major
> addition to the existing one-sided version range syntax.

It's still a change in the current semantics, and implies modifying a
ton of projects, I'm afraid.

> In the Debian Rust team, we previously experimented with e.g. converting:
> 
> - Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
> - Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 | 
> X-9 | X-10

That seems indeed wrong. At least the first should have been just X-6,
and yeah the second should have used more granular versioned provides
as shown above.

> but this causes other problems (unwieldy dependency conversion logic) and does
> not really solve the problem described within this bug report, since it is
> perfectly legal for separate Cargo crates to declare (= 6.1) (= 6.2) (= 6.3)
> dependencies and Cargo will require all three to be installed even though they
> are (supposed to be) semantically compatible. In this case, we would have to
> create new Debian packages called X-6.i (Provides: X-6 = 6.i) for i={1,2,3}
> which puts us right back where we started. (Although granted it is unlikely,
> assuming that everyone in the Rust ecosystem is sane and avoids this forever.)
> 
> So the cleanest solution to this problem would be to support two-sided version
> ranges. This would be beneficial across the whole archive as well - I have
> needed to do the Depends: X (>= 4), X (<< 5) hack before when what I really
> meant was (>= 4, << 5), and 

Bug#901827: [Pkg-rust-maintainers] Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Josh Triplett
On Tue, Jun 19, 2018 at 04:08:00AM +, Ximin Luo wrote:
> Josh Triplett:
> > While I *would* like to see support for version intervals, this
> > particular issue is a bug introduced through changes to debcargo. The
> > original debcargo intentionally generated versioned dependencies on
> > packages like librust-slab-0.3+default-dev rather than
> > librust-slab+default-dev. That would prevent this issue. [..]
> > Re-adding that will eliminate this issue.
> 
> Josh, I'm well aware of what the previous debcargo behaviour was and
> it doesn't eliminate this issue, as I tried to explain in my previous
> comment:

I very carefully read your comment before replying.

> I wrote:
> > In the Debian Rust team, we previously experimented with e.g. converting:
> > 
> > - Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
> > - Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 
> > | X-9 | X-10

This is not equivalent to what I was referring to.

> > but this causes other problems (unwieldy dependency conversion logic) and 
> > does
> > not really solve the problem described within this bug report, since it is
> > perfectly legal for separate Cargo crates to declare (= 6.1) (= 6.2) (= 6.3)
> > dependencies and Cargo will require all three to be installed even though 
> > they
> > are (supposed to be) semantically compatible. In this case, we would have to
> > create new Debian packages called X-6.i (Provides: X-6 = 6.i) for i={1,2,3}
> > which puts us right back where we started. (Although granted it is unlikely,
> > assuming that everyone in the Rust ecosystem is sane and avoids this 
> > forever.)

I've checked for that exact problem throughout the Rust crate ecosystem,
and found very few instances of it (some of which were quite fixable).

> You haven't been following the latest developments which are
> plentiful; please take some time to get up-to-date before confusing
> the discussion with irrelevant information.

I have not seen the proposal or rationale to diverge from the previous
approach discussed on pkg-rust-maintainers at all; do you have a pointer
to where that was proposed and discussed?

I also very specifically said that I *do* want to see the proposed
improvement to dpkg regardless.  But a change to dpkg's version handling
won't be usable until after a subsequent stable release.

> I made the decision to do it the current way and diverge from the
> previous approach, where we generate dependencies based on
> versionless-package-names, based on a request from Sylvestre Ledru
> about the long-term maintenance of rust packages. I've been
> auto-building hundreds of variations of these Rust packages for the
> past few months; I'm well aware of the repercussions of both
> approaches and don't need to be reminded. After implementing
> Sylvestre's request I do think it's much cleaner; and the old way
> doesn't solve the problem it just hides it under the carpet and we
> will have to deal with it eventually anyway.

On the contrary, the previous approach works for the majority of version
dependencies, as long as you don't want multiple compatible versions
simultaneously installed. As long as you don't hit that case, which the
vast majority of Cargo crates don't hit (I scanned for such dependencies
throughout the entire ecosystem at the time and found very few), then it
handles cases such as the one you originally posted just fine. And we
could always switch to the other approach after version range support
appears in dpkg.

By contrast, this approach to Provides and Depends seems to fail in the
most *common* cases of Cargo dependencies, including simple "compatible"
dependencies.

I'm not proposing to hide a problem; I'm proposing that, given that
*both* approaches would benefit from dpkg support for version range
dependencies, we should in the meantime attempt to accommodate the most
common dependencies without that dpkg support.



Bug#901827: [Pkg-rust-maintainers] Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Ximin Luo
+pkg-rust-maintainers, -901827 bug report

Josh Triplett:
>> I wrote:
>>> In the Debian Rust team, we previously experimented with e.g. converting:
>>>
>>> - Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
>>> - Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 
>>> | X-9 | X-10
> 
> This is not equivalent to what I was referring to.
> 

How not?

> [..]
> 
>> You haven't been following the latest developments which are
>> plentiful; please take some time to get up-to-date before confusing
>> the discussion with irrelevant information.
> 
> I have not seen the proposal or rationale to diverge from the previous
> approach discussed on pkg-rust-maintainers at all; do you have a pointer
> to where that was proposed and discussed?
> 

It was on IRC and that's where much of the discussion happens, you're missing a 
lot by not being on it. Also on 
https://salsa.debian.org/rust-team/debcargo/issues/6 where you can see I was 
initially against the proposal until I implemented it.

> I also very specifically said that I *do* want to see the proposed
> improvement to dpkg regardless.  But a change to dpkg's version handling
> won't be usable until after a subsequent stable release.
> 
>> I made the decision to do it the current way and diverge from the
>> previous approach, [..]
> 
> On the contrary, the previous approach works for the majority of version
> dependencies, as long as you don't want multiple compatible versions
> simultaneously installed. As long as you don't hit that case, which the
> vast majority of Cargo crates don't hit (I scanned for such dependencies
> throughout the entire ecosystem at the time and found very few), then it
> handles cases such as the one you originally posted just fine. And we
> could always switch to the other approach after version range support
> appears in dpkg.
> 
> By contrast, this approach to Provides and Depends seems to fail in the
> most *common* cases of Cargo dependencies, including simple "compatible"
> dependencies.
> 

The old code was complex and took me many hours to get right, e.g. see all the 
commits from June 09 that I did. The previous version was buggy and would not 
work for some packages; that includes both your old code and Vasudev's work on 
top of it. The bug-free version has pretty complex logic that I don't think is 
easy for a newbie to grasp either.

By contrast the new code took me about 2 hours to write, and only fails for 
this mdbook case out of all of the transitive dependencies of {mdbook, exa, 
ripgrep, debcargo}, and only because dpkg cannot properly express what is 
needed for Cargo crates.

> I'm not proposing to hide a problem; I'm proposing that, given that
> *both* approaches would benefit from dpkg support for version range
> dependencies, we should in the meantime attempt to accommodate the most
> common dependencies without that dpkg support.
> 

It is possible to revert to the previous behaviour but Sylvestre's concerns in 
issue #6 remain and I am starting to agree with him. I actually would just 
prefer to add an override to mdbook for the time being in order to forcibly add 
an extra dependency on slab 0.3.0, and link to this issue in the comments 
explaining that override.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



Bug#901827: [Pkg-rust-maintainers] Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Ximin Luo
Josh Triplett:
> [..]
> 
> While I *would* like to see support for version intervals, this
> particular issue is a bug introduced through changes to debcargo. The
> original debcargo intentionally generated versioned dependencies on
> packages like librust-slab-0.3+default-dev rather than
> librust-slab+default-dev. That would prevent this issue. [..]
> Re-adding that will eliminate this issue.
> 

Josh, I'm well aware of what the previous debcargo behaviour was and it doesn't 
eliminate this issue, as I tried to explain in my previous comment:

I wrote:
> In the Debian Rust team, we previously experimented with e.g. converting:
> 
> - Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
> - Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 | 
> X-9 | X-10
> 
> but this causes other problems (unwieldy dependency conversion logic) and does
> not really solve the problem described within this bug report, since it is
> perfectly legal for separate Cargo crates to declare (= 6.1) (= 6.2) (= 6.3)
> dependencies and Cargo will require all three to be installed even though they
> are (supposed to be) semantically compatible. In this case, we would have to
> create new Debian packages called X-6.i (Provides: X-6 = 6.i) for i={1,2,3}
> which puts us right back where we started. (Although granted it is unlikely,
> assuming that everyone in the Rust ecosystem is sane and avoids this forever.)
You haven't been following the latest developments which are plentiful; please 
take some time to get up-to-date before confusing the discussion with 
irrelevant information.

I made the decision to do it the current way and diverge from the previous 
approach, where we generate dependencies based on versionless-package-names, 
based on a request from Sylvestre Ledru about the long-term maintenance of rust 
packages. I've been auto-building hundreds of variations of these Rust packages 
for the past few months; I'm well aware of the repercussions of both approaches 
and don't need to be reminded. After implementing Sylvestre's request I do 
think it's much cleaner; and the old way doesn't solve the problem it just 
hides it under the carpet and we will have to deal with it eventually anyway.

Let's please get back on topic.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



Bug#901827: [Pkg-rust-maintainers] Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Josh Triplett
On Mon, Jun 18, 2018 at 07:55:31PM -0700, Ximin Luo wrote:
> Package: dpkg
> Version: 1.19.0.5+b1
> Severity: wishlist
> 
> Dear Maintainer,
> 
> The Rust package manager Cargo, makes it possible to declare two-sided version
> constraint ranges such as X (>= 6, << 7). In dpkg, historically this has been
> expressed by declaring two one-sided version constraint ranges for the same
> package like X (>= 6), X (<< 7), however this is not sufficient for Cargo due
> to its other feature of allowing transitive dependencies on multiple versions
> of the same package.
> 
> Currently to support this we are creating packages called X-$version, and
> declaring Provides: X (= $version). This breaks in the following situation:
> 
> mdbook 0.1.7 transitively depends on slab 0.1.3, 0.3.0, and 0.4.0, via mio 
> 0.5.1,
> mio 0.6.14, and ws-0.7.6. These dependencies are declared as:
> 
> mio-0.5.1/debian/control: librust-slab+default-dev (>= 0.1.0~~),
> mio-0.5.1/debian/control: librust-slab+default-dev (<< 0.2~~),
> ws-0.7.6/debian/control: librust-slab+default-dev (>= 0.3~~),
> ws-0.7.6/debian/control: librust-slab+default-dev (<< 0.4~~),
> mio-0.6.14/debian/control: librust-slab+default-dev (>= 0.4.0~~),
> mio-0.6.14/debian/control: librust-slab+default-dev (<< 0.5~~),

While I *would* like to see support for version intervals, this
particular issue is a bug introduced through changes to debcargo. The
original debcargo intentionally generated versioned dependencies on
packages like librust-slab-0.3+default-dev rather than
librust-slab+default-dev. That would prevent this issue.

Quoting the relevant commit message:

> Always include ABI version in package name; drop --multi
>
> Using versioned Provides to allow packages to include or omit the
> package name doesn't work in all cases; in particular, in some cases, it
> could allow satisfying the Debian package dependencies without
> satisfying the cargo dependencies, by installing multiple different
> providers of the package name simultaneously, none of which meet all the
> constraints.
>
> Switch to always including versions in the package names, and change
> dependencies to include the version of the target package.  Add
> error-handling to dependency processing, to bail out on unrepresentable
> dependencies.

That change evidently got dropped as part of further changes to debcargo
(and the Rust packaging policy). Re-adding that will eliminate this
issue.

(Two-sided version constraints will make it possible, in the future, to
avoid the "unrepresentable dependencies" mentioned above; however, those
don't occur often.)

- Josh Triplett



Bug#901827: [Pkg-rust-maintainers] Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Ximin Luo
Ximin Luo:
> [..]
> 
> librust-slab-0.1-dev_0.1.3-1_amd64.deb Provides: librust-slab+default-dev (= 
> 0.1.3-1), librust-slab-0.1+default-dev (= 0.1.3-1), librust-slab-dev (= 
> 0.1.3-1)
> librust-slab-0.3-dev_0.3.0-1_amd64.deb Provides: librust-slab+default-dev (= 
> 0.3.0-1), librust-slab-0.3+default-dev (= 0.3.0-1), librust-slab-dev (= 
> 0.3.0-1)
> librust-slab-dev_0.4.0-1_amd64.deb
> 

To be clear, the last package here does Provides: librust-slab+default-dev (= 
0.4.0-1), I am not missing anything in this recard.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



Bug#901827: dpkg: Support two-sided version constraint ranges, required to properly translate Cargo dependencies

2018-06-18 Thread Ximin Luo
Package: dpkg
Version: 1.19.0.5+b1
Severity: wishlist

Dear Maintainer,

The Rust package manager Cargo, makes it possible to declare two-sided version
constraint ranges such as X (>= 6, << 7). In dpkg, historically this has been
expressed by declaring two one-sided version constraint ranges for the same
package like X (>= 6), X (<< 7), however this is not sufficient for Cargo due
to its other feature of allowing transitive dependencies on multiple versions
of the same package.

Currently to support this we are creating packages called X-$version, and
declaring Provides: X (= $version). This breaks in the following situation:

mdbook 0.1.7 transitively depends on slab 0.1.3, 0.3.0, and 0.4.0, via mio 
0.5.1,
mio 0.6.14, and ws-0.7.6. These dependencies are declared as:

mio-0.5.1/debian/control: librust-slab+default-dev (>= 0.1.0~~),
mio-0.5.1/debian/control: librust-slab+default-dev (<< 0.2~~),
ws-0.7.6/debian/control: librust-slab+default-dev (>= 0.3~~),
ws-0.7.6/debian/control: librust-slab+default-dev (<< 0.4~~),
mio-0.6.14/debian/control: librust-slab+default-dev (>= 0.4.0~~),
mio-0.6.14/debian/control: librust-slab+default-dev (<< 0.5~~),

I have:

librust-slab-0.1-dev_0.1.3-1_amd64.deb Provides: librust-slab+default-dev (= 
0.1.3-1), librust-slab-0.1+default-dev (= 0.1.3-1), librust-slab-dev (= 0.1.3-1)
librust-slab-0.3-dev_0.3.0-1_amd64.deb Provides: librust-slab+default-dev (= 
0.3.0-1), librust-slab-0.3+default-dev (= 0.3.0-1), librust-slab-dev (= 0.3.0-1)
librust-slab-dev_0.4.0-1_amd64.deb

Unfortunately, APT chooses to resolve the full set by only installing slab
0.1.3 and 0.4.0, because these two are enough to satisfy the full set,
including the two separate (>= 0.3~~) (<< 0.4~~) constraints. From dpkg's
viewpoint these are allowed to be satisfied by two separate packages.

RPM has resolved this by implementing "rich dependencies" which is a general
solution to express "the same package must satisfy both A and B". However, it
is apparently more difficult to do this in dpkg.

What I am suggesting is smaller: we only need to support two-sided version
ranges like (>= 0.3~~, << 0.4~~), which does not seem to be such a major
addition to the existing one-sided version range syntax.

In the Debian Rust team, we previously experimented with e.g. converting:

- Cargo dependencies X (>= 6, << 7) into dpkg dependencies X-6 | X-7
- Cargo dependencies X (>= 6)   into dpkg dependencies X-6 | X-7 | X-8 | 
X-9 | X-10

but this causes other problems (unwieldy dependency conversion logic) and does
not really solve the problem described within this bug report, since it is
perfectly legal for separate Cargo crates to declare (= 6.1) (= 6.2) (= 6.3)
dependencies and Cargo will require all three to be installed even though they
are (supposed to be) semantically compatible. In this case, we would have to
create new Debian packages called X-6.i (Provides: X-6 = 6.i) for i={1,2,3}
which puts us right back where we started. (Although granted it is unlikely,
assuming that everyone in the Rust ecosystem is sane and avoids this forever.)

So the cleanest solution to this problem would be to support two-sided version
ranges. This would be beneficial across the whole archive as well - I have
needed to do the Depends: X (>= 4), X (<< 5) hack before when what I really
meant was (>= 4, << 5), and I remember this in others' packages too.

X

-- System Information:
Debian Release: buster/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable-debug'), (500, 
'testing-debug'), (500, 'buildd-unstable'), (500, 'stable'), (300, 'unstable'), 
(100, 'experimental'), (1, 'experimental-debug')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.16.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8), LANGUAGE=en_GB:en 
(charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages dpkg depends on:
ii  libbz2-1.0   1.0.6-8.1
ii  libc62.27-3
ii  liblzma5 5.2.2-1.3
ii  libselinux1  2.8-1
ii  tar  1.30+dfsg-2
ii  zlib1g   1:1.2.11.dfsg-1

dpkg recommends no packages.

Versions of packages dpkg suggests:
ii  apt1.6.1
pn  debsig-verify  

-- no debconf information