Skip to content

A way to restrict the allowed hosts for dependencies. #4328

@matanlurey

Description

@matanlurey

Context: flutter/engine prohibits dependencies from pub, requiring all packages to come from gclient sync (i.e. our Chromium version of git submodules), so we go out of our way to make sure that, given a repo xyz, package xyx/packages/foo doesn't start depending on say, package:archive without adding it to xyz/DEPS.

In flutter/engine#53539 (comment), @zanderso asked:

For my understanding, is it possible for a pubspec that uses the workspace to add a dependency on a package that isn't in the workspace? Like can a workspace-using pubspec add a new dependency and pull a package from pub that isn't declared in the workspace?

It looks like the answer was surprisingly yes:

# Declare all packages that are part of the workspace.
workspace:
  - tools/engine_tool

dependencies:
  args: any

dependency_overrides:
  args:
    path: ./third_party/dart/third_party/pkg/args

And then later, in tools/engine_tool/pubspec.yaml:

name: engine_tool

# This package is managed as part of the engine workspace.
resolution: workspace

dependencies:
  archive: any
  args: any

I expected this to fail, or warn, or do something. Here is the result of dart pub get:

Resolving dependencies in `/Users/matanl/Developer/engine/src/flutter`... 
Downloading packages... 
! args 2.5.1-wip from path ../../third_party/dart/third_party/pkg/args (overridden)
! async 2.12.0-wip from path ../../third_party/dart/third_party/pkg/async (overridden)
! async_helper 0.0.0 from path ../../third_party/dart/pkg/async_helper (overridden)
! collection 1.19.0 from path ../../third_party/dart/third_party/pkg/collection (overridden)
! engine_build_configs 0.0.0 from path ../pkg/engine_build_configs (overridden)
! engine_repo_tools 0.0.0 from path ../pkg/engine_repo_tools (overridden)
! expect 0.0.0 from path ../../third_party/dart/pkg/expect (overridden)
! file 7.0.1-dev from path ../../third_party/dart/third_party/pkg/file/packages/file (overridden)
! litetest 0.0.0 from path ../../testing/litetest (overridden)
! logging 1.3.0-wip from path ../../third_party/dart/third_party/pkg/logging (overridden)
! meta 1.16.0-dev from path ../../third_party/dart/pkg/meta (overridden)
! path 1.9.1-wip from path ../../third_party/dart/third_party/pkg/path (overridden)
! platform 3.1.0 from path ../../third_party/pkg/platform (overridden)
! process 4.2.1 from path ../../third_party/pkg/process (overridden)
! process_fakes 0.0.0 from path ../pkg/process_fakes (overridden)
! process_runner 4.1.3 from path ../../third_party/pkg/process_runner (overridden)
! smith 0.0.0 from path ../../third_party/dart/pkg/smith (overridden)
! source_span 1.10.1-wip from path ../../third_party/dart/third_party/pkg/source_span (overridden)
! string_scanner 1.3.0 from path ../../third_party/dart/third_party/pkg/string_scanner (overridden)
! term_glyph 1.2.2-wip from path ../../third_party/dart/third_party/pkg/term_glyph (overridden)
! yaml 3.1.3-wip from path ../../third_party/dart/third_party/pkg/yaml (overridden)
Got dependencies in `/Users/matanl/Developer/engine/src/flutter`!

Note that archive is omitted, and not mentioned. However, if I look at the root .dart_tool/package_config.json:

{
  "configVersion": 2,
  "packages": [
    {
      "name": "archive",
      "rootUri": "file:///Users/matanl/.pub-cache/hosted/pub.dev/archive-3.6.1",
      "packageUri": "lib/",
      "languageVersion": "3.0"
    },
    {
      "name": "args",
      "rootUri": "../third_party/dart/third_party/pkg/args",
      "packageUri": "lib/",
      "languageVersion": "3.3"
    }
}

... and I can indeed import and use package:archive in engine_tool. This is not a blocker for us as we have that custom script that checks that packages aren't resolved to pub, but it was surprising and silent behavior - I'd love to see some mechanism to get "protection" or at least notice that this is happening.


Possible suggestions for improvement:

  • Clarify how the tool is intended to work to make sure the above is expected
  • Ensure package:archive comes up in dart pub get and similar, perhaps with a (not from workspace) moniker?
  • Allow the root pubspec to have something like workspace_options: { "dependency_sources": "workspace_only" }
  • Add a lint, pub_workspace_single_source_of_dependencies that can be opted-in to

/cc @kevmoo @jtmcdole

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions