History

[codex] Preserve desktop user-data probe failures (#3304)

Julius Marminge committed 4 months ago

Commit 515303e1 parent 20734d42 files · +57 −6Browse files

Unified · Split

2 files
  1. apps/desktop/src/app/DesktopAppIdentity.test.ts +34 −1
  2. apps/desktop/src/app/DesktopAppIdentity.ts +23 −5
apps/desktop/src/app/DesktopAppIdentity.test.ts+34−1
@@ -4,6 +4,7 @@ import * as Effect from "effect/Effect"; · 3 unmodified lines
4import * as FileSystem from "effect/FileSystem";4import * as FileSystem from "effect/FileSystem";
5import * as Layer from "effect/Layer";5import * as Layer from "effect/Layer";
6import * as Option from "effect/Option";6import * as Option from "effect/Option";
7import * as PlatformError from "effect/PlatformError";
7 8
8import type * as Electron from "electron";9import type * as Electron from "electron";
9 10
@@ -105,6 +106,7 @@ const withIdentity = <A, E, R>( · 95 unmodified lines
105 readonly calls?: ElectronAppCalls;106 readonly calls?: ElectronAppCalls;
106 readonly environment?: TestEnvironmentInput;107 readonly environment?: TestEnvironmentInput;
107 readonly legacyPathExists?: boolean;108 readonly legacyPathExists?: boolean;
109 readonly legacyPathProbeError?: PlatformError.PlatformError;
108 readonly packageJson?: string;110 readonly packageJson?: string;
109 readonly pngIconPath?: Option.Option<string>;111 readonly pngIconPath?: Option.Option<string>;
110 } = {},112 } = {},
@@ -121,7 +123,11 @@ const withIdentity = <A, E, R>( · 10 unmodified lines
121 Layer.provideMerge(123 Layer.provideMerge(
122 FileSystem.layerNoop({124 FileSystem.layerNoop({
123 exists: (path) =>125 exists: (path) =>
124 Effect.succeed(input.legacyPathExists === true && path.includes("T3 Code (Alpha)")),126 input.legacyPathProbeError
127 ? Effect.fail(input.legacyPathProbeError)
128 : Effect.succeed(
129 input.legacyPathExists === true && path.includes("T3 Code (Alpha)"),
130 ),
125 readFileString: () =>131 readFileString: () =>
126 Effect.succeed(input.packageJson ?? '{"t3codeCommitHash":"abcdef1234567890"}'),132 Effect.succeed(input.packageJson ?? '{"t3codeCommitHash":"abcdef1234567890"}'),
127 }),133 }),
@@ -147,6 +153,33 @@ describe("DesktopAppIdentity", () => { · 19 unmodified lines
147 ),153 ),
148 );154 );
149 155
156 it.effect("preserves failures while inspecting the legacy userData path", () => {
157 const legacyPath = "/Users/alice/Library/Application Support/T3 Code (Alpha)";
158 const cause = PlatformError.systemError({
159 _tag: "PermissionDenied",
160 module: "FileSystem",
161 method: "exists",
162 description: "permission denied",
163 pathOrDescriptor: legacyPath,
164 });
165
166 return withIdentity(
167 Effect.gen(function* () {
168 const identity = yield* DesktopAppIdentity.DesktopAppIdentity;
169 const error = yield* identity.resolveUserDataPath.pipe(Effect.flip);
170
171 assert.instanceOf(error, DesktopAppIdentity.DesktopUserDataPathResolutionError);
172 assert.equal(error.legacyPath, legacyPath);
173 assert.strictEqual(error.cause, cause);
174 assert.equal(
175 error.message,
176 `Failed to inspect legacy desktop user-data path at "${legacyPath}".`,
177 );
178 }),
179 { legacyPathProbeError: cause },
180 );
181 });
182
150 it.effect("configures app identity from the environment commit override", () => {183 it.effect("configures app identity from the environment commit override", () => {
151 const calls: ElectronAppCalls = {184 const calls: ElectronAppCalls = {
152 setAboutPanelOptions: [],185 setAboutPanelOptions: [],
apps/desktop/src/app/DesktopAppIdentity.ts+23−5
@@ -18,10 +18,22 @@ const AppPackageMetadata = Schema.Struct({ · 17 unmodified lines
18});18});
19const decodeAppPackageMetadata = Schema.decodeEffect(Schema.fromJsonString(AppPackageMetadata));19const decodeAppPackageMetadata = Schema.decodeEffect(Schema.fromJsonString(AppPackageMetadata));
20 20
21export class DesktopUserDataPathResolutionError extends Schema.TaggedErrorClass<DesktopUserDataPathResolutionError>()(
22 "DesktopUserDataPathResolutionError",
23 {
24 legacyPath: Schema.String,
25 cause: Schema.Defect(),
26 },
27) {
28 override get message(): string {
29 return `Failed to inspect legacy desktop user-data path at "${this.legacyPath}".`;
30 }
31}
32
21export class DesktopAppIdentity extends Context.Service<33export class DesktopAppIdentity extends Context.Service<
22 DesktopAppIdentity,34 DesktopAppIdentity,
23 {35 {
24 readonly resolveUserDataPath: Effect.Effect<string>;36 readonly resolveUserDataPath: Effect.Effect<string, DesktopUserDataPathResolutionError>;
25 readonly configure: Effect.Effect<void>;37 readonly configure: Effect.Effect<void>;
26 }38 }
27>()("@t3tools/desktop/app/DesktopAppIdentity") {}39>()("@t3tools/desktop/app/DesktopAppIdentity") {}
@@ -33,7 +45,7 @@ const normalizeCommitHash = (value: string): Option.Option<string> => { · 5 unmodified lines
33 : Option.none();45 : Option.none();
34};46};
35 47
36const make = Effect.gen(function* () {48export const make = Effect.gen(function* () {
37 const assets = yield* DesktopAssets.DesktopAssets;49 const assets = yield* DesktopAssets.DesktopAssets;
38 const electronApp = yield* ElectronApp.ElectronApp;50 const electronApp = yield* ElectronApp.ElectronApp;
39 const environment = yield* DesktopEnvironment.DesktopEnvironment;51 const environment = yield* DesktopEnvironment.DesktopEnvironment;
@@ -83,9 +95,15 @@ const make = Effect.gen(function* () { · 43 unmodified lines
83 environment.appDataDirectory,95 environment.appDataDirectory,
84 environment.legacyUserDataDirName,96 environment.legacyUserDataDirName,
85 );97 );
86 const legacyPathExists = yield* fileSystem98 const legacyPathExists = yield* fileSystem.exists(legacyPath).pipe(
87 .exists(legacyPath)99 Effect.mapError(
88 .pipe(Effect.orElseSucceed(() => false));100 (cause) =>
101 new DesktopUserDataPathResolutionError({
102 legacyPath,
103 cause,
104 }),
105 ),
106 );
89 return legacyPathExists107 return legacyPathExists
90 ? legacyPath108 ? legacyPath
91 : environment.path.join(environment.appDataDirectory, environment.userDataDirName);109 : environment.path.join(environment.appDataDirectory, environment.userDataDirName);