Created
February 20, 2025 01:45
-
-
Save iohub/00a9406b317d3865d4ea51222c13b356 to your computer and use it in GitHub Desktop.
Revisions
-
iohub created this gist
Feb 20, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,85 @@ import * as fs from 'fs'; import * as path from 'path'; import * as crypto from 'crypto'; export interface CacheEntry { key: string; timestamp: number; files: string[]; } export class BuildCache { private cacheDir: string; private cacheFile: string; private entries: Map<string, CacheEntry>; constructor(cacheDir: string) { this.cacheDir = cacheDir; this.cacheFile = path.join(cacheDir, 'cache.json'); this.entries = new Map(); this.load(); } private load() { try { if (fs.existsSync(this.cacheFile)) { const data = JSON.parse(fs.readFileSync(this.cacheFile, 'utf8')); this.entries = new Map(Object.entries(data)); } } catch (err) { console.warn('Failed to load build cache:', err); } } private save() { try { const data = Object.fromEntries(this.entries); fs.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2)); } catch (err) { console.warn('Failed to save build cache:', err); } } public get(key: string): string[] | undefined { const entry = this.entries.get(key); if (!entry) return undefined; // Validate files still exist and haven't changed for (const file of entry.files) { try { const stat = fs.statSync(file); if (stat.mtimeMs > entry.timestamp) { this.entries.delete(key); return undefined; } } catch { this.entries.delete(key); return undefined; } } return entry.files; } public set(key: string, files: string[]) { this.entries.set(key, { key, timestamp: Date.now(), files }); this.save(); } public clear() { this.entries.clear(); this.save(); } } export function createHash(...inputs: string[]): string { const hash = crypto.createHash('sha256'); for (const input of inputs) { hash.update(input); } return hash.digest('hex'); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,2 @@ 2024-12-11T00:28:56.838Z cache-version=1.0.0 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ export interface CompilationCacheEntry { hash: string; outputFiles: { [path: string]: string }; timestamp: number; } export declare class CompilationCache { constructor(cacheDir: string); getEntry(key: string, sourceHash: string): CompilationCacheEntry | undefined; setEntry(key: string, sourceHash: string, outputFiles: { [path: string]: string }): void; clear(): void; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; export interface CompilationCacheEntry { hash: string; outputFiles: { [path: string]: string }; // path -> content hash timestamp: number; } export class CompilationCache { private cacheDir: string; private cache: { [key: string]: CompilationCacheEntry } = {}; constructor(cacheDir: string) { this.cacheDir = cacheDir; this.loadCache(); } private loadCache() { try { const cacheFile = path.join(this.cacheDir, 'compilation-cache.json'); if (fs.existsSync(cacheFile)) { this.cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8')); } } catch (err) { // Start with empty cache if loading fails this.cache = {}; } } private saveCache() { try { if (!fs.existsSync(this.cacheDir)) { fs.mkdirSync(this.cacheDir, { recursive: true }); } fs.writeFileSync( path.join(this.cacheDir, 'compilation-cache.json'), JSON.stringify(this.cache, null, 2) ); } catch (err) { console.error('Failed to save compilation cache:', err); } } public getEntry(key: string, sourceHash: string): CompilationCacheEntry | undefined { const entry = this.cache[key]; if (entry && entry.hash === sourceHash) { return entry; } return undefined; } public setEntry(key: string, sourceHash: string, outputFiles: { [path: string]: string }) { this.cache[key] = { hash: sourceHash, outputFiles, timestamp: Date.now() }; this.saveCache(); } public clear() { this.cache = {}; this.saveCache(); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,77 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; const { dirs } = require('../../npm/dirs'); const ROOT = path.join(__dirname, '../../../'); const shasum = crypto.createHash('sha256'); // Add build configuration files shasum.update(fs.readFileSync(path.join(ROOT, 'build/.cachesalt'))); shasum.update(fs.readFileSync(path.join(ROOT, '.npmrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'build', '.npmrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'remote', '.npmrc'))); // Add build scripts that could affect the build const buildScripts = [ 'gulpfile.js', 'build/gulpfile.js', 'build/gulpfile.vscode.js', 'build/lib/util.js' ]; for (const script of buildScripts) { try { const scriptPath = path.join(ROOT, script); if (fs.existsSync(scriptPath)) { shasum.update(fs.readFileSync(scriptPath)); } } catch (err) { console.warn(`Warning: Could not read build script ${script}`); } } // Add package.json and package-lock.json files for (const dir of dirs) { const packageJsonPath = path.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { dependencies: packageJson.dependencies, devDependencies: packageJson.devDependencies, optionalDependencies: packageJson.optionalDependencies, resolutions: packageJson.resolutions, distro: packageJson.distro, scripts: packageJson.scripts // Include build scripts }; shasum.update(JSON.stringify(relevantPackageJsonSections)); const packageLockPath = path.join(ROOT, dir, 'package-lock.json'); shasum.update(fs.readFileSync(packageLockPath)); } // Add environment variables that could affect the build const relevantEnvVars = [ 'VSCODE_QUALITY', 'VSCODE_BUILD_STAGE', 'VSCODE_BUILD_ARCH', 'ENABLE_EXTENSIONS' ]; for (const envVar of relevantEnvVars) { if (process.env[envVar]) { shasum.update(envVar + '=' + process.env[envVar]); } } // Add any other command line arguments for (let i = 2; i < process.argv.length; i++) { shasum.update(process.argv[i]); } process.stdout.write(shasum.digest('hex'));