FEDX-7265: Dependencies used inside hook/ must be regular dependencies, not dev_dependencies - #194
FEDX-7265: Dependencies used inside hook/ must be regular dependencies, not dev_dependencies#194engops-wk wants to merge 8 commits into
Conversation
Co-authored-by: Dustin Pauze <dustin.pauze@workiva.com>
engops-wk
left a comment
There was a problem hiding this comment.
Review round 1 — CHANGES REQUESTED (posted as a comment; GitHub blocks REQUEST_CHANGES on one's own PR)
Do not merge: CI is red. The checks job (Workiva/gha-dart-oss/.github/workflows/checks.yaml@v0.1.14, which runs dart format --output=none --set-exit-if-changed . and dart analyze) fails on an unformatted line introduced at test/executable_test.dart:52. build and unit-tests must also be confirmed green. Please push fixes and re-request review once all three jobs pass.
Assessment of the change itself
The direction is correct and the implementation is appropriately minimal. Adding $root/hook/ to publicDirs in lib/src/dependency_validator.dart flows automatically through publicDartFiles/publicScssFiles/publicLessFiles, through publicDirGlobs (so hook files are properly excluded from the non-public set rather than double-counted), and therefore through all five checks: missing, missing-dev, over-promoted, under-promoted, and unused. No special-casing was needed, which is the right call.
Test coverage is well-chosen: dev_dependency in hook/ fails; regular dependency in hook/ passes (which also implicitly proves a hook-only dep is no longer flagged over-promoted — a real regression risk given the over-promoted logic keys off packagesUsedInPublicFiles); undeclared fails; and ignore still suppresses. That is the right matrix.
Blocking issues (inline comments posted)
- Formatting —
test/executable_test.dart:52exceeds the line limit and is notdart formatclean, failingchecks. - Inconsistent user-facing messages —
lib/src/dependency_validator.dartnow emitslib/, bin/, or hook/for missing and under-promoted, but still emitsoutside lib/for missing-dev and over-promoted. The tool's own output contradicts itself. - CHANGELOG severity and accuracy — This will newly fail previously-passing consumer builds. The analogous
bin/expansion was documented as a Breaking Change in 4.0.0 with a stated resolution; match that precedent. Also, hooks run at build/link time (dart build,flutter build), not atpub get/install time, so the stated rationale is technically wrong. - README over-promoted bullet — Still says "only used outside
lib/", which is now inaccurate.
Non-blocking notes
- Fixture is
hook/post_install.dart; Dart only recognizeshook/build.dartandhook/link.dart. Renaming (or adding ahook/build.dartcase) would make the tests self-documenting. - Because the scan is directory-wide rather than entrypoint-based, repos using
hook/for unrelated scripts will now needexclude: ["hook/**"]. Acceptable tradeoff; item 3 is what makes it discoverable. - The new groups use
test('', ...), consistent with the existing file, so not a change request — but naming them would improve failure output.
- Reformat long contains() assertion in executable_test.dart - Align missing-dev and over-promoted warning messages with lib/, bin/, hook/ - Mark CHANGELOG entry as Breaking Change with resolution path - Fix hook timing (build/link time) and update README over-promoted bullet Co-authored-by: Dustin Pauze <dustin.pauze@workiva.com>
engops-wk
left a comment
There was a problem hiding this comment.
Review round 2 — CHANGES REQUESTED (posted as a comment; GitHub blocks REQUEST_CHANGES on my own PR)
Not approved. CI is red on this commit.
The core change is right and small: adding '$root/hook/' to publicDirs in lib/src/dependency_validator.dart correctly reclassifies hook imports as public usage, and because publicDirs also drives publicDirGlobs, the non-public file walk and the over-promoted/unused sets stay internally consistent. Round-1 feedback on the README over-promoted bullet, the missing-dev-dependency / over-promoted message wording, and the CHANGELOG breaking-change framing was all addressed. Thank you.
Blocking: CI failed on this commit (147706b)
checks / format—dart format --output=none --set-exit-if-changed .(SDK 3.7.2, from.github/workflows/ci.yaml→Workiva/gha-dart-oss/.github/workflows/checks.yaml@v0.1.14). Same failure flagged in round 1; the formatter still wants the longcontains(...)string arguments intest/executable_test.dartreflowed.unit-tests / unit—dart test.test/executable_test.dartstill asserts pre-change message text (notably "contain executables, and are only used outside of lib/"), andlib/src/dependency_validator.dartstill emits at least one non-updated message, so expectations and output are out of sync.
The checks / dependency-validator job is not a signal here: it runs dart pub global activate dependency_validator ^4.1.0 — the published 4.x tool, not this PR's code — so it never exercises the new hook/ behavior. Don't treat green there as validation.
Push a commit that runs dart format . and gets dart test green on Dart 3.7.2, then re-request review.
Blocking correctness / consistency
- One message was missed. The executables warning ("The following packages contain executables, and are only used outside of lib/. These should be downgraded to dev_dependencies") still says
lib/only — now inaccurate, and its test assertion fails. - The public-dir description is duplicated ~12 times across source and tests. Round 1 caught exactly this drift class; hoist a single derived constant so the next directory addition is a one-line change.
Blocking coverage gap
- No test asserts the most user-visible consequence: a dependency used only in
hook/must no longer be reported as over-promoted. That's the regression that would silently reverse this behavior. - The new
hook/group omits the(deprecated pubspec method)variant its sibling groups have, and three newgroup(...)wrappers contain a single unnamedtest(''), producing empty leaf test names.
Blocking release hygiene
pubspec.yamlis stillversion: 5.0.6and the CHANGELOG entry has no target version. The precedent for this exact change category (bin/in 4.0.0) was a major bump; shipping behavior-breaking validation as a patch fails consumers on a routinepub upgrade. Confirm and record the intended major version.- README documents the changed bullets but never explains what
hook/is or why it's public-facing. Add one line with the rationale and theignore/excludeescape hatch.
Not blocking
- Consider whether
hook/should be config-gated for one minor release before default-on. I'm fine with default-on given the correctness risk it prevents — just make the migration path explicit in release notes. - CHANGELOG's "build/link time (dart build, flutter build)" is the right fix; consider linking the Dart hooks docs.
- Derive publicDirsDescription from publicDirNames constant - Update all warning messages including executables check - Add hook/ over-promotion exemption test and deprecated ignore variant - Collapse single-test hook groups into named tests - Bump version to 6.0.0 and document hook/ in README Co-authored-by: Dustin Pauze <dustin.pauze@workiva.com>
engops-wk
left a comment
There was a problem hiding this comment.
Round 3 — CHANGES REQUESTED (posted as a comment; GitHub blocks REQUEST_CHANGES on an authored PR). Do not merge.
Round 2 feedback was addressed well: the publicDirNames/publicDirsDescription() single source of truth is in place, all five warning messages now derive from it, the README/CHANGELOG document the breaking behavior with a resolution path, the version is bumped to 6.0.0, and the new coverage includes the deprecated-pubspec ignore variant plus the "hook-only dep is not over-promoted" case. The core logic change (publicDirs derived from publicDirNames) is correct and minimal.
Blocking
- CI is failing on
9414a46. Per.github/workflows/ci.yaml, thechecksjob (dart format/dart analyze) and theunit-testsjob are red. I will not approve on a red build — the longcontains(...)interpolations added inlib/src/dependency_validator.dartandtest/executable_test.dartexceed the formatter's line width, the same class of failure flagged in round 2. Rundart format .,dart analyze, anddart testagainst SDK 3.7.2 (per.tool-versions) and push a green commit. Note thatchecks / dependency-validatorruns the published 5.x validator, so it will not exercisehook/— it is not evidence the feature works. - Test assertions are now tautological. Every message assertion in
test/executable_test.dartinterpolatespublicDirsDescription(), so a regression in that helper would silently change both the tool output and the expectation. Pin the literal user-facing text once intest/utils_test.dart. - Hook fixtures use a filename that isn't part of the hook contract.
hook/post_install.dartshould behook/build.dart(Dart's hook entrypoints arebuild.dart/link.dart); as written the tests only prove directory-name matching, not the real scenario, and the name perpetuates the "install time" framing we corrected in the CHANGELOG.
Non-blocking nits
passes when hook scripts use regular dependenciesandpasses when hook-only dependency is not flagged as over-promotedbuild the identical project and both assert exit code 0; consider collapsing them into one test with both assertions.CHANGELOG.mddropped the# Unreleased/<!-- Add unreleased changes here -->placeholder. Consider keeping it above# 6.0.0.publicDirsDescription()is prose formatting living inconstants.dart;lib/src/utils.dartwould be a more natural home alongsidebulletItems.
…ures Co-authored-by: Dustin Pauze <dustin.pauze@workiva.com>
| @@ -1,5 +1,5 @@ | |||
| name: dependency_validator | |||
| version: 5.0.6 | |||
| version: 6.0.0 | |||
|
@cursor resolve merge conflicts |
|
Merge conflicts on Conflicts resolved
Also merged in from
|
Combine hook/ public-dir support with master's nested-package exclusion. Keep hook/ breaking change under Unreleased per version guidance. Co-authored-by: Dustin Pauze <dustin.pauze@workiva.com>
|
Let's get other non-major things merged and released before shipping this as a major |
… cursor/hook-dev-dependencies-0eac


Opened by Dustin Pauze with the ai-sdlc workflow for FEDX-7265
Pull Request
Description
This PR extends
dependency_validatorto treathook/as a public-facing directory alongsidelib/andbin/. Dependencies used in hook scripts must now be declared as regular dependencies, not just dev-only dependencies, to ensure they're available at build/link time for consuming packages in production mode.Motivation
Dependencies imported inside a package's
hook/directory run at build/link time (dart build,flutter build) via the package manager. If such a dependency is only declared as adev_dependency, it won't be resolved when a consuming package installs in production mode, causing hook execution to fail at build time.dependency_validatorpreviously only treatedlib/andbin/as public-facing directories, so it did not flag dependencies used exclusively inhook/as needing promotion to a regular dependency.Changes
hook/as a public-facing directory alongsidelib/andbin/for the purposes of dependency validation (lib/src/constants.dart,lib/src/dependency_validator.dart)publicDirNamesconstant and apublicDirsDescription()helper to build human-readable messages (e.g.lib/, bin/, or hook/) used in warning output for missing, under-promoted, over-promoted, and unused-executable-dependency checksdependency_validator.dartto reference the dynamic public directories list instead of hardcodedlib/text6.0.0and records this as a breaking change inCHANGELOG.md, since existing codebases with dev-only dependencies used inhook/will now fail validationREADME.mdto document thathook/is now considered public-facing and that hook-only dependencies must be regular dependencies (or explicitlyignored/excluded)test/executable_test.dartandtest/utils_test.dartcovering: hook scripts using dev_dependencies (fails, unless ignored via config or embedded pubspec config), hook scripts using regular dependencies (passes), hook-only dependencies not being flagged as over-promoted, hook scripts using undeclared dependencies (fails), and the newpublicDirsDescription()helper's output for both default andandconjunctionsTesting
dart test(orpub run test) and confirm all tests passhook/build.dartusing a dev_dependency and verify validation fails appropriatelyChecklist
Intent
This change extends dependency validation to treat the
hook/directory as a public-facing directory alongsidelib/andbin/, ensuring that dependencies used in build hooks are properly declared as regular dependencies rather than dev-only. It addresses a critical issue where hook dependencies declared only in dev_dependencies would fail at build time when consumed by other packages in production mode.How To QA