Repository navigation
Open
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listc: tech-debtTechnical debt, code quality, testing, etc.Technical debt, code quality, testing, etc.p: toolingAffects the flutter_plugin_tools packageAffects the flutter_plugin_tools packagepackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem teamTriaged by Ecosystem team
Description
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
-
Implementing/mocking a concrete class from an external package (
GitDirfrompackage: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
implementsthat interface and overrides that method. - Mockito's
@GenerateMocks(<Type>[GitDir])generates explicit@overridestubs for all ~25 methods onGitDirinto the checked-inscript/tool/test/common/package_command_test.mocks.dart. - Even a handwritten
FakeGitDir implements GitDirthat only overridespathandrunCommandwould still be vulnerable ifpackage:gitever added an optional parameter toGitDir.runCommandor markedGitDirasbase/final. - Notably,
script/tooldoes not usepackage:git's higher-level APIs (Commit,BranchReference,Tag, etc.) at all—it only callsgitDir.runCommand(<String>[...])andgitDir.path, and in testscreateForwardingMockGitDirexists solely to forwardMockGitDir.runCommandcalls back intoscript/tool's ownProcessRunner(RecordingProcessRunner).
- 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
-
Unlocked dependencies in
script/toolrunning on every PR:- Unlike the published packages under
packages/,script/tool(flutter_plugin_tools) is an internal repository CLI tool that runs inLinux repo_checkson every PR influtter/packages. - Because
pubspec.lockis globally ignored in.gitignore, everyLinux repo_checksrun executesdart pub getinscript/toolagainst livepub.dev, immediately pulling any newly published transitive or direct dependency into presubmit for the entire repo rather than gating updates through a roll PR.
- Unlike the published packages under
Potential Solutions
-
Replace
package:git(GitDir) inscript/toolwithProcessRunner(or an internalGitDirwrapper aroundProcessRunner):script/toolalready usesProcessRunner(processRunner.run('git', ...), e.g. informat_command.dart) for subprocess execution andRecordingProcessRunnerin tests.- Replacing
package:git'sGitDirwithProcessRunner(or a thin internal wrapper owned byscript/tool) removes the need to mock orimplementan externalGitDirclass altogether, and allows removingpackage:git,package_command_test.mocks.dart,mockito, andbuild_runnerfromscript/tool.
-
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.lockin.gitignore) and configuring Dependabot to roll it ensures that external pub releases are tested in isolated roll PRs rather than spontaneously breakingLinux repo_checksacross all open PRs.
- Per Dart's guidance for application/tooling packages, committing
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listc: tech-debtTechnical debt, code quality, testing, etc.Technical debt, code quality, testing, etc.p: toolingAffects the flutter_plugin_tools packageAffects the flutter_plugin_tools packagepackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem teamTriaged by Ecosystem team
Activity
[tool] Regenerate `MockGitDir` for `package:git` 2.5.0 (#13544)