mono_repo.dart icon indicating copy to clipboard operation
mono_repo.dart copied to clipboard

Support one version rule for mono-repos

Open jonasfj opened this issue 3 years ago • 4 comments

It would be useful for mono-repos if mono_repo.yaml could contain an option like force_one_version: true, to support mono-repos following the one version rule.

Features:

  1. Check that dependency constraints on a given package name, is the same in all pubspec.yaml files in the mono-repo.
  2. Resolve all pubspec.yaml to the same versions when running mono_repo pub get.

(2) is probably a bit hard to do, might involve generating a single pubspec.yaml containing all dependency constraints, resolving it, and writing the pubspec.lock to all packages in the mono-repo before running pub get for each package in the mono-repo.

(it's rather easy to generate such a pubspec.yaml, save it in a temporary folder that is deleted after it's used for resolution).

@yjbanov, pointed out that many Flutter mono-repos would benefit from something like this, as they are currently using pinning and various scripts to ensure that they only have one version of each package.

jonasfj avatar Mar 11 '21 19:03 jonasfj

All top Flutter repos have multiple pubspec.yaml files, and could use this feature:

  • flutter/flutter - currently implements its own, but I wonder if it's better for us to standardize on a common solution /cc @Hixie
  • flutter/plugins /cc @ditman @stuartmorgan to confirm if this works for plugins
  • flutter/packages /cc @kf6gpe
  • flutter/engine /cc @chinmaygarde @cbracken

yjbanov avatar Mar 12 '21 00:03 yjbanov

flutter/flutter (and flutter/engine? I haven't looked at the Dart side of that in detail), is a very different kind of mono-repo than flutter/plugins and flutter/packages. The latter are not repos that are used in their entirety by anyone, but collections of unrelated packages. For flutter/p*, I don't think the one-version rule even makes sense:

  • Maintenance: There are no copies of code, no forks, and no merging, so this doesn't apply.
  • Security: I expect it's going to be quite rare for a security fix to be a major version change, so our dependency versions should not, in general, affect clients' ability to get security fixes for dependencies.
  • Diamond Dependencies: This is a real problem, but it can also show up in transitive dependencies that (1) wouldn't prevent anyway.

2. Resolve all pubspec.yaml to the same versions when running mono_repo pub get.

This isn't even a particularly useful command in flutter/p*; it's not that kind of repo.

For flutter/plugins we solve the diamond dependency problem by building a mega-app in CI that includes every package in the repo, so we catch even transitive conflicts. I suppose an implementation of (2) could address that need more efficiently in CI, but since it would be a different path than what clients of the packages would actually do I would worry that there could be edge cases that would pass that check, but be caught by the current approach (e.g., build time conflicts with native code dependencies).

For flutter/packages we currently seem to be ignoring the potential problem, but could do the same thing we do for flutter/plugins if it becomes an issue.

stuartmorgan avatar Mar 12 '21 02:03 stuartmorgan

For flutter/plugins we solve the diamond dependency problem by building a mega-app in CI that includes every package in the repo, so we catch even transitive conflicts.

This is probably more powerful, because such mega app won't be encumbered by the dev_dependencies of the packages, the same way developers using the packages won't get dev_dependencies.

I think (1) and (2) is mostly useful if you have a mono-repo where you enforce a one-version-policy, which is typically something you would do to ease development (and keep consistency with CI).

jonasfj avatar Mar 12 '21 09:03 jonasfj

As far as I'm aware we have no problem with our current bespoke solution for flutter/flutter and it solves some problems that I suspect aren't yet solved by other solutions (e.g. we have a hash in every pubspec.yaml that we use to verify that nobody accidentally updates a pubspec.yaml without running the script). So I'm not in a rush to find a solution.

I agree with stuart that the other repos aren't really mono repos in the traditional sense.

Hixie avatar Mar 12 '21 21:03 Hixie