diff --git a/packages/cli/package.json b/packages/cli/package.json index 9c74c97..646b523 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -44,6 +44,7 @@ "@swc/core": "1.3.6", "@types/glob": "7.2.0", "@types/mv": "2.1.2", + "@types/node": "^18.11.13", "@types/pacote": "11.1.5", "@types/prompts": "2.0.14", "@types/semver": "7.3.12", diff --git a/packages/cli/src/utils/checkDist.ts b/packages/cli/src/utils/checkDist.ts index e095e38..a5eb3a9 100644 --- a/packages/cli/src/utils/checkDist.ts +++ b/packages/cli/src/utils/checkDist.ts @@ -1,8 +1,5 @@ import os from "node:os"; -import { GLIBC, MUSL } from "detect-libc"; import manifestFetcher from "./manifestFetcher.js"; -import ora from "ora"; -import chalk from "chalk"; const system = { platform: os.platform(), diff --git a/packages/cli/src/utils/genLockfile.ts b/packages/cli/src/utils/genLockfile.ts index bdec578..a137313 100644 --- a/packages/cli/src/utils/genLockfile.ts +++ b/packages/cli/src/utils/genLockfile.ts @@ -4,6 +4,15 @@ import { join } from "path"; import { readFileSync, writeFileSync } from "fs"; import os from "os"; +type DEP = { + name: string; + version: string; + integrity: string; + tarball: string; + path: string; + cache: string; +}; + export function genLock() { // Get all ".ultra" files inside node_modules const files = glob.sync("**/.ultra", { @@ -11,24 +20,35 @@ export function genLock() { absolute: false, }); - const deps = files.map((file) => { - const data = readFileSync(join("node_modules", file), "utf-8"); - const parsed = JSON.parse(data); - const { name, version, integrity, path, tarball } = parsed["ultra:self"]; - - return { - name: name, - version: version, - integrity: integrity, - tarball: tarball, - path: join("/node_modules", file.replace("/.ultra", "")), - cache: path.replace(join(os.homedir(), ".ultra-cache"), ""), - }; - }); + // @ts-ignore-next-line + const deps: DEP[] = files + .map((file) => { + const data = readFileSync(join("node_modules", file), "utf-8"); + const parsed = JSON.parse(data); + try { + const { name, version, integrity, path, tarball } = + parsed["ultra:self"]; + + return { + name: name, + version: version, + integrity: integrity, + tarball: tarball, + path: join("/node_modules", file.replace("/.ultra", "")), + cache: path.replace(join(os.homedir(), ".ultra-cache"), ""), + }; + } catch (e) { + return null; + } + }) + .filter((dep) => { + return dep !== null; + }); const lock: ultra_lock = {}; - deps.forEach((dep) => { + // Filter null values + deps.forEach((dep: DEP) => { if (!lock[dep.name]) { lock[dep.name] = {}; } diff --git a/packages/cli/src/utils/gitInstaller.ts b/packages/cli/src/utils/gitInstaller.ts index 8a48a7f..5563c5b 100644 --- a/packages/cli/src/utils/gitInstaller.ts +++ b/packages/cli/src/utils/gitInstaller.ts @@ -3,11 +3,11 @@ import { Ora } from "ora"; import { execa } from "execa"; import { join, dirname } from "path"; import { existsSync, mkdirSync, symlinkSync, writeFileSync } from "fs"; -import { hardLinkSync } from "./hardLinkSync.js"; import readPackage from "./readPackage.js"; import { getDeps } from "./getDeps.js"; import { installPkg } from "./installPkg.js"; import binLinks from "bin-links"; +import { linker } from "./linker.js"; export async function gitInstall( manifest: any, @@ -65,7 +65,7 @@ export async function gitInstall( if (!justDownload) { const nmPath = join(process.cwd(), "node_modules", manifest.name); - hardLinkSync(targetPath, nmPath); + await linker(targetPath, nmPath); __DOWNLOADED.push({ name: manifest.name, diff --git a/packages/cli/src/utils/hardLinkSync.ts b/packages/cli/src/utils/hardLinkSync.ts index 97c663a..27f2ea8 100644 --- a/packages/cli/src/utils/hardLinkSync.ts +++ b/packages/cli/src/utils/hardLinkSync.ts @@ -6,13 +6,10 @@ import { copyFileSync, constants, } from "node:fs"; -import path from "path"; -import os from "os"; +import path from "node:path"; import ora from "ora"; import chalk from "chalk"; -const isMac = os.platform() === "darwin"; - export function hardLinkSync(dir: string, targetDir: string) { try { const files = readdirSync(dir); @@ -26,26 +23,21 @@ export function hardLinkSync(dir: string, targetDir: string) { } else { // Create previous folders if they don't exist mkdirSync(path.dirname(targetPath), { recursive: true }); - if (!isMac) { - try { - linkSync(filePath, targetPath); - } catch (e: any) { - if (e.code === "EEXIST") return; - if (e.code === "EXDEV") - return copyFileSync( - filePath, - targetPath, - constants.COPYFILE_FICLONE - ); - ora( - chalk.red( - `Error: ${e.message} (file: ${filePath}, target: ${targetPath})` - ) - ).fail(); - } - } else { - // Use clonefile on mac - copyFileSync(filePath, targetPath, constants.COPYFILE_FICLONE); + try { + linkSync(filePath, targetPath); + } catch (e: any) { + if (e.code === "EEXIST") return; + if (e.code === "EXDEV") + return copyFileSync( + filePath, + targetPath, + constants.COPYFILE_FICLONE + ); + ora( + chalk.red( + `Error: ${e.message} (file: ${filePath}, target: ${targetPath})` + ) + ).fail(); } } }); diff --git a/packages/cli/src/utils/installLock.ts b/packages/cli/src/utils/installLock.ts index a84c5b4..480c6e9 100644 --- a/packages/cli/src/utils/installLock.ts +++ b/packages/cli/src/utils/installLock.ts @@ -10,13 +10,13 @@ import parseTime from "../utils/parseTime.js"; import readPackage from "../utils/readPackage.js"; import basePostInstall from "../utils/basePostInstall.js"; import { __dirname } from "../utils/__dirname.js"; -import { hardLinkSync } from "../utils/hardLinkSync.js"; import checkLock from "../utils/checkLock.js"; import { executePost } from "../utils/postInstall.js"; import { ultraExtract } from "./extract.js"; import { updateIndex } from "./updateIndex.js"; import { checkDist } from "./checkDist.js"; import { gitInstall } from "./gitInstaller.js"; +import { linker } from "./linker.js"; export async function installLock(lock: any) { const start = performance.now(); @@ -76,7 +76,7 @@ export async function installLock(lock: any) { } if (existsSync(cache)) { - hardLinkSync(cache, pathname); + await linker(cache, pathname); __install.text = chalk.green(`${pkg}`); __install.prefixText = "🔗"; } else { @@ -92,7 +92,7 @@ export async function installLock(lock: any) { } updateIndex(pkg, version); __install.prefixText = "🔗"; - hardLinkSync(cache, pathname); + await linker(cache, pathname); } manifest = readPackage(path.join(cache, "package.json")); diff --git a/packages/cli/src/utils/installPkg.ts b/packages/cli/src/utils/installPkg.ts index c999347..8908c1a 100644 --- a/packages/cli/src/utils/installPkg.ts +++ b/packages/cli/src/utils/installPkg.ts @@ -13,7 +13,6 @@ import semver from "semver"; import binLinks from "bin-links"; import { getDeps } from "./getDeps.js"; import manifestFetcher from "./manifestFetcher.js"; -import { hardLinkSync } from "./hardLinkSync.js"; import { ultraExtract } from "./extract.js"; import { gitInstall } from "./gitInstaller.js"; import { getDir } from "./getInstallableDir.js"; @@ -21,6 +20,7 @@ import { sleep } from "./sleep.js"; import getVersions from "./getVersions.js"; import { checkDist } from "./checkDist.js"; import { updateIndex } from "./updateIndex.js"; +import { linker } from "./linker.js"; type Return = { name: string; @@ -143,7 +143,7 @@ export async function installPkg( // Create directory for package without the last folder mkdirSync(path.dirname(pkgProjectDir), { recursive: true }); - hardLinkSync(cacheFolder, pkgProjectDir); + await linker(cacheFolder, pkgProjectDir); try { const pkgJson = readPackage(path.join(cacheFolder, "package.json")); @@ -345,7 +345,7 @@ export async function installPkg( mkdirSync(path.dirname(pkgProjectDir), { recursive: true }); - hardLinkSync(cacheFolder, pkgProjectDir); + await linker(cacheFolder, pkgProjectDir); if (manifest.fromMonorepo !== undefined) { try { diff --git a/packages/cli/src/utils/linker.ts b/packages/cli/src/utils/linker.ts new file mode 100644 index 0000000..3c414b0 --- /dev/null +++ b/packages/cli/src/utils/linker.ts @@ -0,0 +1,11 @@ +import { platform } from "node:os"; +import { hardLink } from "./hardLink.js"; +import { hardLinkSync } from "./hardLinkSync.js"; + +export async function linker(src: string, dest: string) { + if (platform() === "darwin" || platform() === "win32") { + return hardLink(src, dest); + } else { + return hardLinkSync(src, dest); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b483c4..acff72b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,7 @@ importers: '@swc/core': 1.3.6 '@types/glob': 7.2.0 '@types/mv': 2.1.2 + '@types/node': ^18.11.13 '@types/pacote': 11.1.5 '@types/prompts': 2.0.14 '@types/semver': 7.3.12 @@ -130,6 +131,7 @@ importers: '@swc/core': 1.3.6 '@types/glob': 7.2.0 '@types/mv': 2.1.2 + '@types/node': 18.11.13 '@types/pacote': 11.1.5 '@types/prompts': 2.0.14 '@types/semver': 7.3.12 @@ -2774,7 +2776,7 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.7.16 + '@types/node': 18.11.13 dev: true /@types/hast/2.3.4: @@ -2837,7 +2839,7 @@ packages: /@types/node-fetch/2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 form-data: 3.0.1 dev: true @@ -2845,6 +2847,10 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false + /@types/node/18.11.13: + resolution: {integrity: sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w==} + dev: true + /@types/node/18.7.16: resolution: {integrity: sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==} @@ -2859,7 +2865,7 @@ packages: /@types/npm-registry-fetch/8.0.4: resolution: {integrity: sha512-R9yEj6+NDmXLpKNS19cIaMyaHfV0aHjy/1qbo8K9jiHyjyaYg0CEmuOV/L0Q91DZDi3SuxlYY+2XYwh9TbB+eQ==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 '@types/node-fetch': 2.6.2 '@types/npm-package-arg': 6.1.1 '@types/npmlog': 4.1.4 @@ -2873,7 +2879,7 @@ packages: /@types/pacote/11.1.5: resolution: {integrity: sha512-kMsfmhP2G45ngnpvH0LKd1celWnjgdiws1FHu3vMmYuoElGdqnd0ydf1ucZzeXamYnLe0NvSzGP2gYiETOEiQA==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 '@types/npm-registry-fetch': 8.0.4 '@types/npmlog': 4.1.4 '@types/ssri': 7.1.1 @@ -2886,7 +2892,7 @@ packages: /@types/prompts/2.0.14: resolution: {integrity: sha512-HZBd99fKxRWpYCErtm2/yxUZv6/PBI9J7N4TNFffl5JbrYMHBwF25DjQGTW3b3jmXq+9P6/8fCIb2ee57BFfYA==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 dev: true /@types/prop-types/15.7.5: @@ -2954,7 +2960,7 @@ packages: /@types/ssri/7.1.1: resolution: {integrity: sha512-DPP/jkDaqGiyU75MyMURxLWyYLwKSjnAuGe9ZCsLp9QZOpXmDfuevk769F0BS86TmRuD5krnp06qw9nSoNO+0g==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 dev: true /@types/stack-trace/0.0.29: @@ -2972,7 +2978,7 @@ packages: /@types/tar/6.1.3: resolution: {integrity: sha512-YzDOr5kdAeqS8dcO6NTTHTMJ44MUCBDoLEIyPtwEn7PssKqUYL49R1iCVJPeiPzPlKi6DbH33eZkpeJ27e4vHg==} dependencies: - '@types/node': 18.7.16 + '@types/node': 18.11.13 minipass: 3.3.5 dev: true