From f74e39c09ca0d7d3c2e3eac622c670135e4d3aee Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Tue, 27 Feb 2024 23:16:58 -0500 Subject: [PATCH] fix(bindgen): write symlink on Windows Per: https://github.com/nodejs/node/issues/18518#issuecomment-1509547477 --- .../bindgen/typescript/write-support-files.js | 211 +++++++++++++++--- 1 file changed, 176 insertions(+), 35 deletions(-) diff --git a/packages/core/typescript/itk-wasm/src/bindgen/typescript/write-support-files.js b/packages/core/typescript/itk-wasm/src/bindgen/typescript/write-support-files.js index ef1e58552..9131c94ef 100644 --- a/packages/core/typescript/itk-wasm/src/bindgen/typescript/write-support-files.js +++ b/packages/core/typescript/itk-wasm/src/bindgen/typescript/write-support-files.js @@ -1,9 +1,17 @@ -import fs from 'fs-extra' +import fs from 'fs' +import { execSync } from 'child_process' +import os from 'os' import path from 'path' import writeIfOverrideNotPresent from '../write-if-override-not-present.js' -function writeSupportFiles(outputDir, forNode, bindgenResource, packageName, packageDescription) { +function writeSupportFiles( + outputDir, + forNode, + bindgenResource, + packageName, + packageDescription +) { if (!forNode) { try { fs.mkdirSync(path.join(outputDir, 'build'), { recursive: true }) @@ -11,40 +19,113 @@ function writeSupportFiles(outputDir, forNode, bindgenResource, packageName, pac if (err.code !== 'EEXIST') throw err } try { - fs.mkdirSync(path.join(outputDir, 'test', 'browser', 'demo-app'), { recursive: true }) + fs.mkdirSync(path.join(outputDir, 'test', 'browser', 'demo-app'), { + recursive: true + }) } catch (err) { if (err.code !== 'EEXIST') throw err } - const pipelinesBaseUrlPath = path.join(outputDir, 'src', 'pipelines-base-url.ts') + const pipelinesBaseUrlPath = path.join( + outputDir, + 'src', + 'pipelines-base-url.ts' + ) if (!fs.existsSync(pipelinesBaseUrlPath)) { - fs.copyFileSync(bindgenResource('pipelines-base-url.ts'), pipelinesBaseUrlPath) - let pipelinesBaseUrlPathContent = fs.readFileSync(bindgenResource('pipelines-base-url.ts'), { encoding: 'utf8', flag: 'r' }) - pipelinesBaseUrlPathContent = pipelinesBaseUrlPathContent.replaceAll('', packageName) - writeIfOverrideNotPresent(pipelinesBaseUrlPath, pipelinesBaseUrlPathContent) + fs.copyFileSync( + bindgenResource('pipelines-base-url.ts'), + pipelinesBaseUrlPath + ) + let pipelinesBaseUrlPathContent = fs.readFileSync( + bindgenResource('pipelines-base-url.ts'), + { encoding: 'utf8', flag: 'r' } + ) + pipelinesBaseUrlPathContent = pipelinesBaseUrlPathContent.replaceAll( + '', + packageName + ) + writeIfOverrideNotPresent( + pipelinesBaseUrlPath, + pipelinesBaseUrlPathContent + ) } - const pipelineWorkerUrlPath = path.join(outputDir, 'src', 'pipeline-worker-url.ts') + const pipelineWorkerUrlPath = path.join( + outputDir, + 'src', + 'pipeline-worker-url.ts' + ) if (!fs.existsSync(pipelineWorkerUrlPath)) { - let pipelineWorkerUrlPathContent = fs.readFileSync(bindgenResource('pipeline-worker-url.ts'), { encoding: 'utf8', flag: 'r' }) - pipelineWorkerUrlPathContent = pipelineWorkerUrlPathContent.replaceAll('', packageName) - writeIfOverrideNotPresent(pipelineWorkerUrlPath, pipelineWorkerUrlPathContent) + let pipelineWorkerUrlPathContent = fs.readFileSync( + bindgenResource('pipeline-worker-url.ts'), + { encoding: 'utf8', flag: 'r' } + ) + pipelineWorkerUrlPathContent = pipelineWorkerUrlPathContent.replaceAll( + '', + packageName + ) + writeIfOverrideNotPresent( + pipelineWorkerUrlPath, + pipelineWorkerUrlPathContent + ) } - const defaultWebWorkerPath = path.join(outputDir, 'src', 'default-web-worker.ts') + const defaultWebWorkerPath = path.join( + outputDir, + 'src', + 'default-web-worker.ts' + ) if (!fs.existsSync(defaultWebWorkerPath)) { - let defaultWebWorkerContent = fs.readFileSync(bindgenResource('default-web-worker.ts'), { encoding: 'utf8', flag: 'r' }) + let defaultWebWorkerContent = fs.readFileSync( + bindgenResource('default-web-worker.ts'), + { encoding: 'utf8', flag: 'r' } + ) writeIfOverrideNotPresent(defaultWebWorkerPath, defaultWebWorkerContent) } - const indexWorkerEmbeddedPath = path.join(outputDir, 'src', 'index-worker-embedded.ts') - const indexWorkerEmbeddedContent = fs.readFileSync(bindgenResource('index-worker-embedded.ts'), { encoding: 'utf8', flag: 'r' }) - writeIfOverrideNotPresent(indexWorkerEmbeddedPath, indexWorkerEmbeddedContent) - const indexWorkerEmbeddedMinPath = path.join(outputDir, 'src', 'index-worker-embedded.min.ts') - const indexWorkerEmbeddedMinContent = fs.readFileSync(bindgenResource('index-worker-embedded.min.ts'), { encoding: 'utf8', flag: 'r' }) - writeIfOverrideNotPresent(indexWorkerEmbeddedMinPath, indexWorkerEmbeddedMinContent) + const indexWorkerEmbeddedPath = path.join( + outputDir, + 'src', + 'index-worker-embedded.ts' + ) + const indexWorkerEmbeddedContent = fs.readFileSync( + bindgenResource('index-worker-embedded.ts'), + { encoding: 'utf8', flag: 'r' } + ) + writeIfOverrideNotPresent( + indexWorkerEmbeddedPath, + indexWorkerEmbeddedContent + ) + const indexWorkerEmbeddedMinPath = path.join( + outputDir, + 'src', + 'index-worker-embedded.min.ts' + ) + const indexWorkerEmbeddedMinContent = fs.readFileSync( + bindgenResource('index-worker-embedded.min.ts'), + { encoding: 'utf8', flag: 'r' } + ) + writeIfOverrideNotPresent( + indexWorkerEmbeddedMinPath, + indexWorkerEmbeddedMinContent + ) const packageJsonSymlinkPath = path.join(outputDir, 'src', 'package.json') if (!fs.existsSync(packageJsonSymlinkPath)) { - fs.symlinkSync('../package.json', packageJsonSymlinkPath) + if (os.platform() === 'win32') { + const outputPath = path.join('..', 'package.json') + const previousCwd = process.cwd() + process.chdir(path.join(outputDir, 'src')) + if ( + typeof fs.lstatSync('package.json', { throwIfNoEntry: false }) === + 'undefined' + ) { + execSync(`mklink /J package.json ${outputPath}`, { + windowsHide: true + }) + } + process.chdir(previousCwd) + } else { + fs.symlinkSync(path.join('..', 'package.json'), packageJsonSymlinkPath) + } } const npmIgnorePath = path.join(outputDir, '.npmignore') @@ -54,29 +135,89 @@ function writeSupportFiles(outputDir, forNode, bindgenResource, packageName, pac const docsIndexPath = path.join(outputDir, 'index.html') if (!fs.existsSync(docsIndexPath)) { - let docsIndexContent = fs.readFileSync(bindgenResource('index.html'), { encoding: 'utf8', flag: 'r' }) - docsIndexContent = docsIndexContent.replaceAll('', packageName) - docsIndexContent = docsIndexContent.replaceAll('', packageDescription) + let docsIndexContent = fs.readFileSync(bindgenResource('index.html'), { + encoding: 'utf8', + flag: 'r' + }) + docsIndexContent = docsIndexContent.replaceAll( + '', + packageName + ) + docsIndexContent = docsIndexContent.replaceAll( + '', + packageDescription + ) fs.writeFileSync(docsIndexPath, docsIndexContent) - fs.copyFileSync(bindgenResource('.nojekyll'), path.join(outputDir, '.nojekll')) + fs.copyFileSync( + bindgenResource('.nojekyll'), + path.join(outputDir, '.nojekll') + ) } - const logoPath = path.join(outputDir, 'test', 'browser', 'demo-app', 'logo.svg') + const logoPath = path.join( + outputDir, + 'test', + 'browser', + 'demo-app', + 'logo.svg' + ) if (!fs.existsSync(logoPath)) { - fs.copyFileSync(bindgenResource(path.join('demo-app', 'logo.svg')), logoPath) - const jsLogoPath = path.join(outputDir, 'test', 'browser', 'demo-app', 'javascript-logo.svg') - fs.copyFileSync(bindgenResource(path.join('demo-app', 'javascript-logo.svg')), jsLogoPath) - const tsLogoPath = path.join(outputDir, 'test', 'browser', 'demo-app', 'typescript-logo.svg') - fs.copyFileSync(bindgenResource(path.join('demo-app', 'typescript-logo.svg')), tsLogoPath) + fs.copyFileSync( + bindgenResource(path.join('demo-app', 'logo.svg')), + logoPath + ) + const jsLogoPath = path.join( + outputDir, + 'test', + 'browser', + 'demo-app', + 'javascript-logo.svg' + ) + fs.copyFileSync( + bindgenResource(path.join('demo-app', 'javascript-logo.svg')), + jsLogoPath + ) + const tsLogoPath = path.join( + outputDir, + 'test', + 'browser', + 'demo-app', + 'typescript-logo.svg' + ) + fs.copyFileSync( + bindgenResource(path.join('demo-app', 'typescript-logo.svg')), + tsLogoPath + ) } - const demoStylePath = path.join(outputDir, 'test', 'browser', 'demo-app', 'style.css') + const demoStylePath = path.join( + outputDir, + 'test', + 'browser', + 'demo-app', + 'style.css' + ) if (!fs.existsSync(demoStylePath)) { - fs.copyFileSync(bindgenResource(path.join('demo-app', 'style.css')), demoStylePath) + fs.copyFileSync( + bindgenResource(path.join('demo-app', 'style.css')), + demoStylePath + ) } - const demoJsUtilities = path.join(outputDir, 'test', 'browser', 'demo-app', 'utilities.js') - writeIfOverrideNotPresent(demoJsUtilities, fs.readFileSync(bindgenResource(path.join('demo-app', 'utilities.js')), { encoding: 'utf8', flag: 'r' })) + const demoJsUtilities = path.join( + outputDir, + 'test', + 'browser', + 'demo-app', + 'utilities.js' + ) + writeIfOverrideNotPresent( + demoJsUtilities, + fs.readFileSync(bindgenResource(path.join('demo-app', 'utilities.js')), { + encoding: 'utf8', + flag: 'r' + }) + ) const viteConfigPath = path.join(outputDir, 'vite.config.js') if (!fs.existsSync(viteConfigPath)) {