MCPcopy
hub / github.com/Fission-AI/OpenSpec / ensureWritePermissions

Method ensureWritePermissions

src/utils/file-system.ts:278–315  ·  view source on GitHub ↗
(dirPath: string)

Source from the content-addressed store, hash-verified

276 }
277
278 static async ensureWritePermissions(dirPath: string): Promise<boolean> {
279 try {
280 // If directory doesn't exist, check parent directory permissions
281 if (!await this.directoryExists(dirPath)) {
282 const parentDir = path.dirname(dirPath);
283 if (!await this.directoryExists(parentDir)) {
284 await this.createDirectory(parentDir);
285 }
286 return await this.ensureWritePermissions(parentDir);
287 }
288
289 const testFile = path.join(dirPath, '.openspec-test-' + Date.now() + '-' + Math.random().toString(36).slice(2));
290 await fs.writeFile(testFile, '');
291
292 // On Windows, file may be temporarily locked by antivirus or indexing services.
293 // Retry unlink with a small delay if it fails.
294 const maxRetries = 3;
295 for (let attempt = 0; attempt < maxRetries; attempt++) {
296 try {
297 await fs.unlink(testFile);
298 break;
299 } catch (unlinkError: any) {
300 if (attempt === maxRetries - 1) {
301 // Last attempt failed, but we successfully wrote the file, so permissions are OK
302 // Just log and continue - the temp file will be cleaned up eventually
303 console.debug(`Could not clean up test file ${testFile}: ${unlinkError.message}`);
304 } else {
305 // Wait briefly before retrying (Windows file lock release)
306 await new Promise((resolve) => setTimeout(resolve, 50));
307 }
308 }
309 }
310 return true;
311 } catch (error: any) {
312 console.debug(`Insufficient permissions to write to ${dirPath}: ${error.message}`);
313 return false;
314 }
315 }
316}
317
318/**

Callers 2

validateMethod · 0.80

Calls 3

directoryExistsMethod · 0.95
createDirectoryMethod · 0.95
writeFileMethod · 0.80

Tested by

no test coverage detected