Skip to content

[tool] Prevent out-of-band pub releases from breaking script/tool unit tests in Linux repo_checks #195938

Open

Description

@Piinks

Background

When package:git published 2.4.0 / 2.5.0 (a minor semver release under git: ^2.0.0), it added an optional named parameter ({bool includeUntracked = true}) to GitDir.isWorkingTreeClean.

Even though script/tool never calls GitDir.isWorkingTreeClean, this out-of-band pub release immediately broke Linux repo_checks (tool unit tests) across every PR in flutter/packages:

test/common/package_command_test.mocks.dart:204:20: Error: The method 'MockGitDir.isWorkingTreeClean' has fewer named arguments than those of overridden method 'GitDir.isWorkingTreeClean'.
  _i6.Future<bool> isWorkingTreeClean() =>
                   ^

Root Causes

  1. Implementing/mocking a concrete class from an external package (GitDir from package:git):

    • In Dart, every class defines an implicit interface. While adding an optional parameter to a method is non-breaking for callers (and thus published as a minor semver bump), it is a breaking change for any class that implements that interface and overrides that method.
    • Mockito's @GenerateMocks(<Type>[GitDir]) generates explicit @override stubs for all ~25 methods on GitDir into the checked-in script/tool/test/common/package_command_test.mocks.dart.
    • Even a handwritten FakeGitDir implements GitDir that only overrides path and runCommand would still be vulnerable if package:git ever added an optional parameter to GitDir.runCommand or marked GitDir as base/final.
    • Notably, script/tool does not use package:git's higher-level APIs (Commit, BranchReference, Tag, etc.) at all—it only calls gitDir.runCommand(<String>[...]) and gitDir.path, and in tests createForwardingMockGitDir exists solely to forward MockGitDir.runCommand calls back into script/tool's own ProcessRunner (RecordingProcessRunner).
  2. Unlocked dependencies in script/tool running on every PR:

    • Unlike the published packages under packages/, script/tool (flutter_plugin_tools) is an internal repository CLI tool that runs in Linux repo_checks on every PR in flutter/packages.
    • Because pubspec.lock is globally ignored in .gitignore, every Linux repo_checks run executes dart pub get in script/tool against live pub.dev, immediately pulling any newly published transitive or direct dependency into presubmit for the entire repo rather than gating updates through a roll PR.

Potential Solutions

  1. Replace package:git (GitDir) in script/tool with ProcessRunner (or an internal GitDir wrapper around ProcessRunner):

    • script/tool already uses ProcessRunner (processRunner.run('git', ...), e.g. in format_command.dart) for subprocess execution and RecordingProcessRunner in tests.
    • Replacing package:git's GitDir with ProcessRunner (or a thin internal wrapper owned by script/tool) removes the need to mock or implement an external GitDir class altogether, and allows removing package:git, package_command_test.mocks.dart, mockito, and build_runner from script/tool.
  2. Commit script/tool/pubspec.lock (and roll via Dependabot):

    • Per Dart's guidance for application/tooling packages, committing script/tool/pubspec.lock (via !/script/tool/pubspec.lock in .gitignore) and configuring Dependabot to roll it ensures that external pub releases are tested in isolated roll PRs rather than spontaneously breaking Linux repo_checks across all open PRs.

Activity

  1. added
    p: toolingAffects the flutter_plugin_tools package
    packageflutter/packages repository. See also p: labels.
    on Nov 3, 2026
  2. added
    c: tech-debtTechnical debt, code quality, testing, etc.
    P2Important issues not at the top of the work list
    on Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: tech-debtTechnical debt, code quality, testing, etc.p: toolingAffects the flutter_plugin_tools packagepackageflutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions