From 6e163600bd1ae290e4acde2515098240df5477e1 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Thu, 8 May 2025 16:59:45 +0200 Subject: [PATCH 1/8] Download platform specific package if `optionalDependencies` are skipped --- crates/node/package.json | 10 +- crates/node/scripts/install.js | 134 +++++++++++++++++++++++++ integrations/oxide/postinstall.test.ts | 73 ++++++++++++++ integrations/utils.ts | 5 +- pnpm-lock.yaml | 80 +++++++++++---- 5 files changed, 279 insertions(+), 23 deletions(-) create mode 100644 crates/node/scripts/install.js create mode 100644 integrations/oxide/postinstall.test.ts diff --git a/crates/node/package.json b/crates/node/package.json index 71f126010f81..a3f71a0b9d4e 100644 --- a/crates/node/package.json +++ b/crates/node/package.json @@ -32,6 +32,10 @@ } }, "license": "MIT", + "dependencies": { + "tar": "^7.4.3", + "detect-libc": "^2.0.4" + }, "devDependencies": { "@napi-rs/cli": "^3.0.0-alpha.78", "@napi-rs/wasm-runtime": "^0.2.9", @@ -42,7 +46,8 @@ }, "files": [ "index.js", - "index.d.ts" + "index.d.ts", + "scripts/install.js" ], "publishConfig": { "provenance": true, @@ -57,7 +62,8 @@ "postbuild:wasm": "node ./scripts/move-artifacts.mjs", "dev": "cargo watch --quiet --shell 'npm run build'", "build:debug": "napi build --platform --no-const-enum", - "version": "napi version" + "version": "napi version", + "postinstall": "node ./scripts/install.js" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "workspace:*", diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js new file mode 100644 index 000000000000..064b9cddd53f --- /dev/null +++ b/crates/node/scripts/install.js @@ -0,0 +1,134 @@ +#!/usr/bin/env node + +/** + * @tailwindcss/oxide postinstall script + * + * This script ensures that the correct binary for the current platform and + * architecture is downloaded and available. + */ + +const fs = require('fs') +const path = require('path') +const https = require('https') +const { extract } = require('tar') +const packageJson = require('../package.json') +const detectLibc = require('detect-libc') + +const version = packageJson.version + +function getPlatformPackageName() { + const platform = process.platform + const arch = process.arch + + let libc = '' + if (platform === 'linux') { + libc = detectLibc.isNonGlibcLinuxSync() ? 'musl' : 'gnu' + } + + // Map to our package naming conventions + switch (platform) { + case 'darwin': + return arch === 'arm64' ? '@tailwindcss/oxide-darwin-arm64' : '@tailwindcss/oxide-darwin-x64' + case 'win32': + if (arch === 'arm64') return '@tailwindcss/oxide-win32-arm64-msvc' + if (arch === 'ia32') return '@tailwindcss/oxide-win32-ia32-msvc' + return '@tailwindcss/oxide-win32-x64-msvc' + case 'linux': + if (arch === 'x64') { + return libc === 'musl' + ? '@tailwindcss/oxide-linux-x64-musl' + : '@tailwindcss/oxide-linux-x64-gnu' + } else if (arch === 'arm64') { + return libc === 'musl' + ? '@tailwindcss/oxide-linux-arm64-musl' + : '@tailwindcss/oxide-linux-arm64-gnu' + } else if (arch === 'arm') { + return '@tailwindcss/oxide-linux-arm-gnueabihf' + } + break + case 'freebsd': + return '@tailwindcss/oxide-freebsd-x64' + + case 'android': + return '@tailwindcss/oxide-android-arm64' + default: + return '@tailwindcss/oxide-wasm32-wasi' + } +} + +function isPackageAvailable(packageName) { + try { + require.resolve(packageName) + return true + } catch (e) { + return false + } +} + +// Extract all files from a tarball to a destination directory +async function extractTarball(tarballStream, destDir) { + if (!fs.existsSync(destDir)) { + fs.mkdirSync(destDir, { recursive: true }) + } + + return new Promise((resolve, reject) => { + tarballStream + .pipe(extract({ cwd: destDir, strip: 1 })) + .on('error', (err) => reject(err)) + .on('end', () => resolve()) + }) +} + +async function downloadAndExtractBinary(packageName) { + let tarballUrl = `https://registry.npmjs.org/${packageName}/-/${packageName.replace('@tailwindcss/', '')}-${version}.tgz` + console.log(`Downloading ${tarballUrl}...`) + + return new Promise((resolve) => { + https + .get(tarballUrl, (response) => { + if (response.statusCode === 302 || response.statusCode === 301) { + // Handle redirects + https.get(response.headers.location, handleResponse).on('error', (err) => { + console.error('Download error:', err) + resolve() + }) + return + } + + handleResponse(response) + + async function handleResponse(response) { + try { + if (response.statusCode !== 200) { + throw new Error(`Download failed with status code: ${response.statusCode}`) + } + + await extractTarball( + response, + path.join(__dirname, '..', 'node_modules', ...packageName.split('/')), + ) + console.log(`Successfully downloaded and installed ${packageName}`) + } catch (error) { + console.error('Error during extraction:', error) + resolve() + } finally { + resolve() + } + } + }) + .on('error', (err) => { + console.error('Download error:', err) + resolve() + }) + }) +} + +async function main() { + const packageName = getPlatformPackageName() + if (!packageName) return + if (isPackageAvailable(packageName)) return + + await downloadAndExtractBinary(packageName) +} + +main() diff --git a/integrations/oxide/postinstall.test.ts b/integrations/oxide/postinstall.test.ts new file mode 100644 index 000000000000..3a711ffc6174 --- /dev/null +++ b/integrations/oxide/postinstall.test.ts @@ -0,0 +1,73 @@ +import fs from 'node:fs/promises' +import path from 'node:path' +import { js, json, test } from '../utils' + +test( + '@tailwindcss/oxide will fail when architecture-specific packages are missing', + { + fs: { + 'package.json': json` + { + "dependencies": { + "@tailwindcss/oxide": "workspace:^" + } + } + `, + 'test.js': js` + try { + let Scanner = require('@tailwindcss/oxide') + console.log('SUCCESS: @tailwindcss/oxide loaded successfully', Scanner) + } catch (error) { + console.log('FAILURE: Failed to load @tailwindcss/oxide:', error.message) + } + `, + }, + }, + async ({ exec, root, expect, fs }) => { + await removePlatformSpecificExtensions(path.join(root, 'node_modules')) + + // Get last published version + let version = (await exec('npm show @tailwindcss/oxide version')).trim() + // Ensure that we don't depend on a specific version number in the download + // script in case we bump the version number in the repository and CI is run + // before a release + let packageJson = JSON.parse(await fs.read('node_modules/@tailwindcss/oxide/package.json')) + packageJson.version = version + await fs.write( + 'node_modules/@tailwindcss/oxide/package.json', + JSON.stringify(packageJson, null, 2), + ) + + let opts = { + // Ensure that we don't include any node paths from the test runner + env: { NODE_PATH: '' }, + } + + expect(await exec('node test.js', opts)).toMatch(/FAILURE/) + + // Now run the post-install script + await exec('node node_modules/@tailwindcss/oxide/scripts/install.js', opts) + + expect(await exec('node test.js', opts)).toMatch(/SUCCESS/) + }, +) + +async function removePlatformSpecificExtensions(directory: string) { + const entries = await fs.readdir(directory, { withFileTypes: true }) + + for (const entry of entries) { + const fullPath = path.join(directory, entry.name) + + if (entry.name.startsWith('oxide-')) { + if (entry.isSymbolicLink()) { + await fs.unlink(fullPath) + } else if (entry.isFile()) { + await fs.unlink(fullPath) + } else if (entry.isDirectory()) { + await fs.rm(fullPath, { recursive: true, force: true }) + } + } else if (entry.isDirectory()) { + await removePlatformSpecificExtensions(fullPath) + } + } +} diff --git a/integrations/utils.ts b/integrations/utils.ts index 8affff3b4a83..cc1702918625 100644 --- a/integrations/utils.ts +++ b/integrations/utils.ts @@ -122,7 +122,10 @@ export function test( { cwd, ...childProcessOptions, - env: childProcessOptions.env, + env: { + ...process.env, + ...childProcessOptions.env, + }, }, (error, stdout, stderr) => { if (error) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b68a70eb09e..4251cc330121 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,6 +87,13 @@ importers: version: 2.0.5(@types/node@20.14.13)(lightningcss@1.29.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6) crates/node: + dependencies: + detect-libc: + specifier: ^2.0.4 + version: 2.0.4 + tar: + specifier: ^7.4.3 + version: 7.4.3 optionalDependencies: '@tailwindcss/oxide-android-arm64': specifier: workspace:* @@ -1525,6 +1532,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -2068,7 +2079,6 @@ packages: '@parcel/watcher-darwin-arm64@2.5.1': resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} engines: {node: '>= 10.0.0'} - cpu: [arm64] os: [darwin] '@parcel/watcher-darwin-x64@2.5.0': @@ -2080,7 +2090,6 @@ packages: '@parcel/watcher-darwin-x64@2.5.1': resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} engines: {node: '>= 10.0.0'} - cpu: [x64] os: [darwin] '@parcel/watcher-freebsd-x64@2.5.0': @@ -2128,7 +2137,6 @@ packages: '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} - cpu: [arm64] os: [linux] '@parcel/watcher-linux-arm64-musl@2.5.0': @@ -2140,7 +2148,6 @@ packages: '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} - cpu: [arm64] os: [linux] '@parcel/watcher-linux-x64-glibc@2.5.0': @@ -2152,7 +2159,6 @@ packages: '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} - cpu: [x64] os: [linux] '@parcel/watcher-linux-x64-musl@2.5.0': @@ -2164,7 +2170,6 @@ packages: '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} - cpu: [x64] os: [linux] '@parcel/watcher-wasm@2.5.0': @@ -2206,7 +2211,6 @@ packages: '@parcel/watcher-win32-x64@2.5.1': resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} engines: {node: '>= 10.0.0'} - cpu: [x64] os: [win32] '@parcel/watcher@2.5.0': @@ -2621,7 +2625,6 @@ packages: bun@1.2.11: resolution: {integrity: sha512-9brVfsp6/TYVsE3lCl1MUxoyKhvljqyL1MNPErgwsOaS9g4Gzi2nY+W5WtRAXGzLrgz5jzsoGHHwyH/rTeRCIg==} - cpu: [arm64, x64, aarch64] os: [darwin, linux, win32] hasBin: true @@ -2677,6 +2680,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -2833,8 +2840,8 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} didyoumean@1.2.2: @@ -3480,13 +3487,11 @@ packages: lightningcss-darwin-arm64@1.29.2: resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} engines: {node: '>= 12.0.0'} - cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.29.2: resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} engines: {node: '>= 12.0.0'} - cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.29.2: @@ -3504,25 +3509,21 @@ packages: lightningcss-linux-arm64-gnu@1.29.2: resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} engines: {node: '>= 12.0.0'} - cpu: [arm64] os: [linux] lightningcss-linux-arm64-musl@1.29.2: resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} engines: {node: '>= 12.0.0'} - cpu: [arm64] os: [linux] lightningcss-linux-x64-gnu@1.29.2: resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} engines: {node: '>= 12.0.0'} - cpu: [x64] os: [linux] lightningcss-linux-x64-musl@1.29.2: resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} engines: {node: '>= 12.0.0'} - cpu: [x64] os: [linux] lightningcss-win32-arm64-msvc@1.29.2: @@ -3534,7 +3535,6 @@ packages: lightningcss-win32-x64-msvc@1.29.2: resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} engines: {node: '>= 12.0.0'} - cpu: [x64] os: [win32] lightningcss@1.29.2: @@ -3635,6 +3635,15 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mlly@1.7.3: resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} @@ -4231,6 +4240,10 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + terser@5.31.6: resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==} engines: {node: '>=10'} @@ -4614,6 +4627,10 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@2.6.0: resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} engines: {node: '>= 14'} @@ -5307,6 +5324,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -6402,6 +6423,8 @@ snapshots: dependencies: readdirp: 4.1.1 + chownr@3.0.0: {} + citty@0.1.6: dependencies: consola: 3.2.3 @@ -6531,7 +6554,7 @@ snapshots: detect-libc@1.0.3: {} - detect-libc@2.0.3: {} + detect-libc@2.0.4: {} didyoumean@1.2.2: {} @@ -7490,7 +7513,7 @@ snapshots: lightningcss@1.29.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm): dependencies: - detect-libc: 2.0.3 + detect-libc: 2.0.4 optionalDependencies: lightningcss-darwin-arm64: 1.29.2 lightningcss-darwin-x64: 1.29.2 @@ -7596,6 +7619,12 @@ snapshots: minipass@7.1.2: {} + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + mlly@1.7.3: dependencies: acorn: 8.14.0 @@ -8038,7 +8067,7 @@ snapshots: sharp@0.34.1: dependencies: color: 4.2.3 - detect-libc: 2.0.3 + detect-libc: 2.0.4 semver: 7.7.1 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.1 @@ -8233,6 +8262,15 @@ snapshots: tapable@2.2.1: {} + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + terser@5.31.6: dependencies: '@jridgewell/source-map': 0.3.6 @@ -8623,6 +8661,8 @@ snapshots: yallist@3.1.1: {} + yallist@5.0.0: {} + yaml@2.6.0: {} yocto-queue@0.1.0: {} From 5d2970b65ca89e8a46d01f6a373f45bd5354f446 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Thu, 8 May 2025 17:48:20 +0200 Subject: [PATCH 2/8] What's up with that? --- packages/@tailwindcss-upgrade/src/utils/git.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/@tailwindcss-upgrade/src/utils/git.ts b/packages/@tailwindcss-upgrade/src/utils/git.ts index d716fbb8a4c5..e8b292df0ae3 100644 --- a/packages/@tailwindcss-upgrade/src/utils/git.ts +++ b/packages/@tailwindcss-upgrade/src/utils/git.ts @@ -3,8 +3,10 @@ import { execSync } from 'node:child_process' export function isRepoDirty() { try { let stdout = execSync('git status --porcelain', { encoding: 'utf-8' }) + console.log({ stdout }) return stdout.trim() !== '' } catch (error) { + console.log({ error }) // If it's not a git repository we don't know if it's dirty or not. But we // also don't want to block the migration. Maybe we can still fail and // require a `--force` flag? From 216426567e74b0957b77c8c3a08052328d3780fa Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Thu, 8 May 2025 18:03:51 +0200 Subject: [PATCH 3/8] Fix --- crates/node/scripts/install.js | 5 +++++ packages/@tailwindcss-upgrade/src/utils/git.ts | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js index 064b9cddd53f..6bae9737061a 100644 --- a/crates/node/scripts/install.js +++ b/crates/node/scripts/install.js @@ -124,6 +124,11 @@ async function downloadAndExtractBinary(packageName) { } async function main() { + // Don't run this script in the package source + if (fs.existsSync(path.join(__dirname, '..', 'build.rs'))) { + return + } + const packageName = getPlatformPackageName() if (!packageName) return if (isPackageAvailable(packageName)) return diff --git a/packages/@tailwindcss-upgrade/src/utils/git.ts b/packages/@tailwindcss-upgrade/src/utils/git.ts index e8b292df0ae3..d716fbb8a4c5 100644 --- a/packages/@tailwindcss-upgrade/src/utils/git.ts +++ b/packages/@tailwindcss-upgrade/src/utils/git.ts @@ -3,10 +3,8 @@ import { execSync } from 'node:child_process' export function isRepoDirty() { try { let stdout = execSync('git status --porcelain', { encoding: 'utf-8' }) - console.log({ stdout }) return stdout.trim() !== '' } catch (error) { - console.log({ error }) // If it's not a git repository we don't know if it's dirty or not. But we // also don't want to block the migration. Maybe we can still fail and // require a `--force` flag? From 713663b39aa0b970e1179adab979b9fc39aedc6d Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Thu, 8 May 2025 18:23:09 +0200 Subject: [PATCH 4/8] Try again I guess From 32263b60e6dbec2b86cee43f9f414ba0e2d3e12c Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 9 May 2025 13:33:41 +0200 Subject: [PATCH 5/8] Thanks Claude Co-authored-by: Robin Malfait --- crates/node/scripts/install.js | 6 +++--- integrations/oxide/postinstall.test.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js index 6bae9737061a..f72938d9552b 100644 --- a/crates/node/scripts/install.js +++ b/crates/node/scripts/install.js @@ -17,8 +17,8 @@ const detectLibc = require('detect-libc') const version = packageJson.version function getPlatformPackageName() { - const platform = process.platform - const arch = process.arch + let platform = process.platform + let arch = process.arch let libc = '' if (platform === 'linux') { @@ -129,7 +129,7 @@ async function main() { return } - const packageName = getPlatformPackageName() + let packageName = getPlatformPackageName() if (!packageName) return if (isPackageAvailable(packageName)) return diff --git a/integrations/oxide/postinstall.test.ts b/integrations/oxide/postinstall.test.ts index 3a711ffc6174..70683c82e525 100644 --- a/integrations/oxide/postinstall.test.ts +++ b/integrations/oxide/postinstall.test.ts @@ -53,10 +53,10 @@ test( ) async function removePlatformSpecificExtensions(directory: string) { - const entries = await fs.readdir(directory, { withFileTypes: true }) + let entries = await fs.readdir(directory, { withFileTypes: true }) - for (const entry of entries) { - const fullPath = path.join(directory, entry.name) + for (let entry of entries) { + let fullPath = path.join(directory, entry.name) if (entry.name.startsWith('oxide-')) { if (entry.isSymbolicLink()) { From a5897252fd63144b329d57d79ed1371da4cf41fd Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 9 May 2025 13:34:01 +0200 Subject: [PATCH 6/8] Update crates/node/scripts/install.js --- crates/node/scripts/install.js | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js index f72938d9552b..9eaf567b2d14 100644 --- a/crates/node/scripts/install.js +++ b/crates/node/scripts/install.js @@ -48,7 +48,6 @@ function getPlatformPackageName() { break case 'freebsd': return '@tailwindcss/oxide-freebsd-x64' - case 'android': return '@tailwindcss/oxide-android-arm64' default: From 7eeba142cf77e3ca162f5f87809956466919c679 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 9 May 2025 13:34:30 +0200 Subject: [PATCH 7/8] Update crates/node/scripts/install.js Co-authored-by: Robin Malfait --- crates/node/scripts/install.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js index 9eaf567b2d14..2f08996d54b2 100644 --- a/crates/node/scripts/install.js +++ b/crates/node/scripts/install.js @@ -124,7 +124,11 @@ async function downloadAndExtractBinary(packageName) { async function main() { // Don't run this script in the package source - if (fs.existsSync(path.join(__dirname, '..', 'build.rs'))) { + try { + if (fs.existsSync(path.join(__dirname, '..', 'build.rs'))) { + return + } + } catch { return } From f889eb992ab7430f61b902933a1a2e8ce72266eb Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Fri, 9 May 2025 13:37:06 +0200 Subject: [PATCH 8/8] Wrap everything in a trycatch --- crates/node/scripts/install.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/node/scripts/install.js b/crates/node/scripts/install.js index 2f08996d54b2..f9cefe01c7c9 100644 --- a/crates/node/scripts/install.js +++ b/crates/node/scripts/install.js @@ -128,15 +128,16 @@ async function main() { if (fs.existsSync(path.join(__dirname, '..', 'build.rs'))) { return } - } catch { - return - } - let packageName = getPlatformPackageName() - if (!packageName) return - if (isPackageAvailable(packageName)) return + let packageName = getPlatformPackageName() + if (!packageName) return + if (isPackageAvailable(packageName)) return - await downloadAndExtractBinary(packageName) + await downloadAndExtractBinary(packageName) + } catch (error) { + console.error(error) + return + } } main()