Skip to content

Extract shared utilities for duplicated error, file, version, and stack logic - #20

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1786151268-shared-utilities
Open

Extract shared utilities for duplicated error, file, version, and stack logic#20
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1786151268-shared-utilities

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Duplicated logic found with jscpd (plus manual review) is now extracted into shared modules. Clone count across src/, apps/, packages/, scripts/ drops from 11 to 2 (0.78% → 0.17% duplicated lines), with 443 lines deleted against 199 added. No behavior is intended to change except one guard noted below.

New shared modules:

  • src/platform/errors.jserrorCode, hasErrorCode, isMissingFile, isMissingPathSegment, isAlreadyExists, ignoreMissingFile. Replaces ~12 hand-rolled copies of

    error instanceof Error && 'code' in error && /** @type {{code?: string}} */ (error).code === 'ENOENT'

    in server/server.js, cli/stack-selection.js, platform/ownership.js, supervision/{command,launchd,manager,purge,systemd}.js, scripts/verify-release.js.

  • src/platform/files.jsatomicWrite, readOptionalFile, fileExists (moved out of src/supervision/files.js, which keeps only the executable promote/restore helpers) plus workspacePathExists, which replaces the two copies in administration/service.js and stacks/administration-service.js. The desktop update adapter's private writeCachedState is now atomicWrite(path, json) instead of its own mkdir/tmp/rename dance.

  • src/domain/semantic-version.js — one compareSemanticVersions, replacing the copy in src/supervision/version.js (deleted; its test moved to test/domain/semantic-version.test.js) and the copy in apps/desktop/main/update.js. Validation is now the shared SEMANTIC_VERSION_PATTERN rather than SemanticVersionSchema + a looser regex; both patterns were already identical, so accepted input is unchanged.

  • delay(ms) in src/domain/time.js, replacing four inline new Promise((resolve) => setTimeout(resolve, ms)).

Within-module dedupe:

  • src/docker/evidence.js gains publishedContainerPorts(component) (3 inline copies in stacks/coordination-service.js), and that service gains #resolveDockerBinding and verifyDockerBinding so the confirm path and the reconcile path share the "resolve stack/component/endpoint definition, build expected labels, verify container" sequence while keeping their different failure shapes (throw RegistryError vs. return an unknown provider status).
  • storage/registry.js: #releaseActivationRuns(activationId, timestamp, failureReason) replaces the 29-line run/endpoint release block duplicated by markStackActivationLost and endStackActivation; #leaseIsConfirmable(activationId, leaseId, bindingKind?) replaces the two near-identical leased-endpoint lookups in confirmLease and confirmDockerLease.
  • protocol/schemas.js exports CLAIM_RECORD_FIELDS, so domain/schemas.js's ClaimRecordSchema is z.object(CLAIM_RECORD_FIELDS).refine(...) instead of restating all ten fields.
  • supervision/manager.js gains assertSupervisable(status, manualServerMessage) for the identical install/manual-server guards in start() and restart() (each keeps its own manual-server message); supervision/purge.js's inspectTree now delegates to inspectTreeChildren; platform/ephemeral-ports.js parses start end once in parsePortRange.

One deliberate behavior change: the shared workspacePathExists treats only ENOENT as absence and reports true for any other error. administration/service.js already behaved that way; stacks/administration-service.js used to rethrow, so an unreadable stack root now skips pruning instead of failing the prune operation.

Not deduped: apps/desktop/renderer/state.js keeps its own compareVersions, and apps/desktop/preload/index.cjs its own channel list — the renderer is served through the app:// protocol rooted at apps/desktop/renderer, and the preload script is sandboxed CJS, so neither can import shared ESM from src/.

Verification

bun run check (toolchain, typecheck, eslint, prettier, tests): the same 13 tests fail before and after this branch on this machine, all lsof-dependent integration tests plus release metadata > renders one checksum-pinned Homebrew formula for all targets.

Link to Devin session: https://app.devin.ai/sessions/41eb2e735ff343c08b1406a042b909ca
Requested by: @TrentBrown

@TrentBrown TrentBrown self-assigned this Aug 8, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant