Skip to content

introduce the concept of opt-in package conflicts #14314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Tracked by #14265
andrewrk opened this issue Jan 14, 2023 · 2 comments
Open
Tracked by #14265

introduce the concept of opt-in package conflicts #14314

andrewrk opened this issue Jan 14, 2023 · 2 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. zig build system std.Build, the build runner, `zig build` subcommand, package management
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Jan 14, 2023

Extracted from #14265. Depends on #14288.

Motivation: to discover when a dependency tree contains cruft, in the form of fundamentally redundant code.

The idea here is that packages could declare a set of labels which are features that the package provides:

.{
    // ...
    .provides = .{ .compression, .tls },
    // ...
}

Importantly, if two different packages in the dependency tree provide the same functionality, tooling would emit a warning:

$ zig pkg audit
warning: functionality 'tls' is provided by multiple packages:
  tls-gaMwFLV5lzxK8L2S (4 uses)
    networking_utils
    foo.bar
    baz
    quux.asdf.garbo
    lalala.boog
  taylors_cool_crypto-nP9xXden9vAO5Ijq (1 uses)
    ez_request

In this case, despite how cool taylors_cool_crypto is, perhaps it might be better from a bloat perspective to fork ez_request and make it use networking_utils instead, and then send a polite merge request upstream. If the ez_request maintainers don't want to merge it, then the ecosystem forks, ever in search of reducing bloat.

For another example, consider that infamous package, left-pad. We could imagine the underscore library having something like this:

.{
    // ...
    .provides = .{
        .left_pad,
        .right_pad,
        .is_number,
        .is_float,
        // ...
    },
    // ...
}

Here, underscore would have not listed every function it provided, but would list the functionality that it provided that competed with existing, tiny packages. With this proposal implemented, it may have lead to many JavaScript developers asking themselves why they were carrying redundant dependencies in their trees, and worked a little bit to come up with coherent sets of dependencies that reduced bloat. Perhaps more people would have migrated towards utilities such as underscore, or some people might have migrated towards truly independent sets of small packages. Either way, there would have been less redundant code in the dependency tree.

Speaking of underscore, there is another interesting package to bring up: lodash. This package is intentionally competing with underscore. With the provides feature that I propose here, this could actually be codified, by directly putting the other package's ID into the provides field:

.{
    .id = "lodash-X0QPNj321y5Doywn",
    .provides = .{ .left_pad, .@"underscore-8uxWP0tQAeUhBlwM" },
    // ...
}

This would be an aggressive move, explicitly documenting that a package is competing with another package. When an application developer finds such a situation in their tree, it is clear that there could be bloat reduced by picking a lane:

$ zig pkg audit
  warning: dependency tree contains competing packages:
    underscore-SK1WsSlgpGzZWue8 (1 uses)
      foo.bar
    lodash-iV0uo8FxqzJ+7N2h (1 uses)
      baz

Open-source communities need more drama! 🔥 🍿

@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. zig build system std.Build, the build runner, `zig build` subcommand, package management labels Jan 14, 2023
@andrewrk andrewrk added this to the 0.12.0 milestone Jan 14, 2023
@andrewrk andrewrk mentioned this issue Jan 14, 2023
32 tasks
@rohlem
Copy link
Contributor

rohlem commented Jan 14, 2023

Interesting idea! Maybe it's obvious, however I'd like to mention that sometimes this redundancy can be used as a feature.
Say I want my application to be able to utilize one of 3 different "backend" libraries, e.g. for audio output, or GUI Window management.
Each of these 3 projects has had a couple of years already for implementing platform support for their cross-platform abstractions, fixing bugs along the way.

Supporting all of them (=> declaring them as dependencies) allows users to switch the backend they use via build flags, say if they're suffering from a bug in one of them.
However, the [feature flag - platform - backend] support matrix for such a project sounds like it would be complex enough that it would be better-fitted to the domain of user-provided code rather than a declarative format.

But still, for transitive dependencies (shared by backends) it may make sense to deduplicate again.
I guess since it's opt-in, users could just ignore these hints. But maybe just being able to flag specific features in dependencies as "intentionally duplicated" would already be enough to improve this use case.

@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0 Jan 16, 2023
@matu3ba
Copy link
Contributor

matu3ba commented Jan 18, 2023

Motivation: to discover when a dependency tree contains cruft, in the form of fundamentally redundant code.

I think this is a local optimum, as to handle all cases of code duplication one needs to look at AST level for each symbol.
I dont see, why the package manager could not have a dedicated mode to "temporary fetch dependencies for analysis"
instead of trying to rely on packagers providing the correct information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. zig build system std.Build, the build runner, `zig build` subcommand, package management
Projects
Status: Proposals
Development

No branches or pull requests

3 participants