start addressing pr feedback

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
aramissennyeydd
2025-05-08 11:18:02 -04:00
parent 7e7ea1477a
commit 82a46e979d
4 changed files with 71 additions and 23 deletions
+2 -1
View File
@@ -82,7 +82,8 @@
"portfinder": "^1.0.32",
"tar": "^6.1.12",
"ts-morph": "^24.0.0",
"yaml-diff-patch": "^2.0.0"
"yaml-diff-patch": "^2.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
@@ -0,0 +1,37 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Lockfile } from '@backstage/cli-node';
import { PackageDocsCache } from './Cache';
import { join as joinPath } from 'path';
import {
createMockDirectory,
MockDirectory,
} from '@backstage/backend-test-utils';
describe('PackageDocsCache', () => {
let testDir: MockDirectory;
beforeEach(async () => {
testDir = createMockDirectory();
});
it('should be able to parse cache files', async () => {
const cache = await PackageDocsCache.loadAsync(
joinPath(__dirname, 'test-cache'),
new Lockfile(),
);
cache.add('test', 'test');
});
});
@@ -15,11 +15,12 @@
*/
import { readFile, writeFile, cp } from 'fs/promises';
import globby from 'globby';
import workerPath, { dirname } from 'path';
import { dirname, join as joinPath, relative } from 'path';
import crypto from 'crypto';
import { Lockfile } from '@backstage/cli-node';
import { paths as cliPaths } from '../../lib/paths';
import { mkdirp } from 'fs-extra';
import { z } from 'zod';
const version = '1';
const CACHE_FILE = 'cache.json';
@@ -31,10 +32,19 @@ interface CacheEntry {
version: string;
}
const cacheEntrySchema = z.object({
hash: z.string(),
packageName: z.string(),
restoreTo: z.string(),
version: z.string(),
});
export class PackageDocsCache {
// A map of package directory to package hash.
private keyCache: Map<string, string>;
constructor(
private readonly lockfile: Lockfile,
// A map of package directory to cache entry.
private readonly cache: Map<string, CacheEntry>,
private readonly cacheDir: string,
) {
@@ -47,16 +57,21 @@ export class PackageDocsCache {
const map = new Map<string, CacheEntry>();
for (const file of cacheFiles) {
const pkg = dirname(file);
const cache = await readFile(workerPath.join(cacheDir, file), 'utf-8');
const cacheJson = JSON.parse(cache);
map.set(pkg, cacheJson);
const cache = await readFile(joinPath(cacheDir, file), 'utf-8');
try {
const cacheJson = JSON.parse(cache);
const parsed = cacheEntrySchema.parse(cacheJson);
map.set(pkg, parsed);
} catch (e) {
console.error(`Skipping unparseable cache file ${file}: ${e}`);
}
}
return new PackageDocsCache(lockfile, map, cacheDir);
}
async directoryToName(directory: string) {
const packageJson = await readFile(
workerPath.join(directory, 'package.json'),
joinPath(directory, 'package.json'),
'utf-8',
);
return JSON.parse(packageJson).name;
@@ -79,7 +94,7 @@ export class PackageDocsCache {
for (const path of result.sort()) {
const absPath = cliPaths.resolveTargetRoot(pkg, path);
const pathInPackage = workerPath.join(absPath, path);
const pathInPackage = joinPath(absPath, path);
hash.update(pathInPackage);
hash.update('\0');
hash.update(await readFile(absPath));
@@ -107,8 +122,8 @@ export class PackageDocsCache {
}
const cacheEntry = this.cache.get(pkg);
const restoreTo = cacheEntry!.restoreTo;
const cacheDir = workerPath.join(this.cacheDir, pkg);
const contentsDir = workerPath.join(cacheDir, 'contents');
const cacheDir = joinPath(this.cacheDir, pkg);
const contentsDir = joinPath(cacheDir, 'contents');
const targetDir = cliPaths.resolveTargetRoot(restoreTo);
await mkdirp(targetDir);
@@ -116,23 +131,17 @@ export class PackageDocsCache {
}
async write(pkg: string, contentDirectory: string) {
const cacheDir = workerPath.join(this.cacheDir, pkg);
const contentsDir = workerPath.join(cacheDir, 'contents');
await mkdirp(cacheDir);
const cacheDir = joinPath(this.cacheDir, pkg);
const contentsDir = joinPath(cacheDir, 'contents');
await mkdirp(contentsDir);
const hashString = await this.toKey(pkg);
await cp(contentDirectory, contentsDir, { recursive: true });
const cacheEntry: CacheEntry = {
hash: hashString,
packageName: await this.directoryToName(pkg),
restoreTo: workerPath.relative(
cliPaths.resolveTargetRoot(),
contentDirectory,
),
restoreTo: relative(cliPaths.resolveTargetRoot(), contentDirectory),
version,
};
await writeFile(
workerPath.join(cacheDir, CACHE_FILE),
JSON.stringify(cacheEntry),
);
await writeFile(joinPath(cacheDir, CACHE_FILE), JSON.stringify(cacheEntry));
}
}
+4 -3
View File
@@ -8429,6 +8429,7 @@ __metadata:
ts-morph: "npm:^24.0.0"
typedoc: "npm:^0.27.6"
yaml-diff-patch: "npm:^2.0.0"
zod: "npm:^3.22.4"
peerDependencies:
"@microsoft/api-extractor-model": "*"
"@microsoft/tsdoc": "*"
@@ -48020,9 +48021,9 @@ __metadata:
linkType: hard
"zod@npm:^3.22.4":
version: 3.23.8
resolution: "zod@npm:3.23.8"
checksum: 10/846fd73e1af0def79c19d510ea9e4a795544a67d5b34b7e1c4d0425bf6bfd1c719446d94cdfa1721c1987d891321d61f779e8236fde517dc0e524aa851a6eff1
version: 3.24.4
resolution: "zod@npm:3.24.4"
checksum: 10/3d545792fa54bb27ee5dbc34a5709e81f603185fcc94c8204b5d95c20dc4c81d870ff9c51f3884a30ef05cdc601449f4c4df254ac4783f0827b1faed7c1cdb48
languageName: node
linkType: hard