On Fri, Feb 22, 2008 at 06:23:28PM -0800, Daniel Burrows wrote:
>   Would it be possible to only re-order elements that were introduced by
> a variable substitution?  That would make the list deterministic without
> changing what the maintainer wrote.

At best you could:

        (a) sort substvar dependencies
        (b) drop repeated deps from substvars

without messing up the maintainer's ordering. If you've got, say:

        Depends: foo, bar, ${baz:Depends}

with ${baz:Depends} expanding to "foo (>= 1.2)", then you have the choice
of:

        Depends: foo, bar, foo (>= 1.2)    # duplicates foo dep "uselessly"

        Depends: bar, foo (>= 1.2)         # drops explicitly added dep,
                                           # and reorders, changing apt's
                                           # behaviour

        Depends: foo (>= 1.2), bar         # adds version info from shlibdep
                                           # to explicit dep

I'm not sure the latter actually has the exact same behaviour as the
first; if foo2 Provides: foo and has a higher Priority: the first Depends:
might install foo2,bar,foo instead of just foo and bar; likewise if bar
Depends: foo2|foo.

For comparison, if you had:

        Depends: foo (>= 1.3), bar, ${baz:Depends}

ending up with

        Depends: bar, foo (>= 1.3)

instead of just ignoring the redundant baz:Depends entirely seems a
bit silly. 

The *safest* way of doing eliminations is thus probably:

        new_deps = []
        for dep in expands_substvars(cur_deps):
                add = 1
                for odep in new_deps:
                        if odep.implies(dep): add = 0
                if add:
                        new_deps.append(dep)

And if you're willing to have `foo, bar, foo (>= 1.2)' -> `foo (>= 1.2),
bar' (as per above), then something like:

        new_deps = []
        for dep in expands_substvars(cur_deps):
                add = 1
                for odep_pos in range(len(new_deps)):
                        odep = new_deps[odep_pos]

                        if odep is None:
                                continue
                        elif odep.implies(dep):
                                add = 0
                                break
                        elif dep.implies(odep):
                                if add:
                                        new_deps[odep_pos] = dep
                                else:
                                        new_deps[odep_pos] = None
                                add = 0
                if add:
                        new_deps.append(dep)
        new_deps = [ x for x in new_deps if x is not None]

would work.

The "new_deps[odep_pos] = None" portion lets you turn:

        foo, foo (>= 1.0), foo (<= 2.0), foo (= 1.5)

into:

    new_dep                     still to look at
                                foo, foo (>= 1.0), foo (<= 2.0), foo (= 1.5)
    foo                         foo (>= 1.0), foo (<= 2.0), foo (= 1.5)
    foo (>= 1.0),               foo (<= 2.0), foo (= 1.5)
    foo (>= 1.0), foo (<= 2.0)  foo (= 1.5)
    foo (= 1.5)

Cheers,
aj

Attachment: signature.asc
Description: Digital signature

Reply via email to