From 76a435d86fcd1d48b18feffdc6a337bd7abe2ffa Mon Sep 17 00:00:00 2001 From: nachoaldamav Date: Sat, 15 Oct 2022 12:24:03 +0200 Subject: [PATCH 1/4] =?UTF-8?q?perf=20=F0=9F=9A=80:=20(cli)=20Improve=20CL?= =?UTF-8?q?I=20start=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +300ms before -> 50ms now --- packages/cli/src/bin/cli.ts | 8 +-- packages/cli/src/commands/ci.ts | 5 +- packages/cli/src/commands/create.ts | 2 +- packages/cli/src/commands/index.ts | 81 ++++++++++++++++++---------- packages/cli/src/commands/init.ts | 2 +- packages/cli/src/commands/install.ts | 4 +- packages/cli/src/commands/list.ts | 2 +- packages/cli/src/commands/remove.ts | 2 +- packages/cli/src/commands/run.ts | 2 +- packages/cli/src/commands/test.ts | 2 +- packages/cli/src/commands/upgrade.ts | 2 +- 11 files changed, 69 insertions(+), 43 deletions(-) diff --git a/packages/cli/src/bin/cli.ts b/packages/cli/src/bin/cli.ts index eebc829..034870e 100644 --- a/packages/cli/src/bin/cli.ts +++ b/packages/cli/src/bin/cli.ts @@ -1,13 +1,11 @@ #!/usr/bin/env node -import { commands } from "../commands/index.js"; -import { args } from "../utils/arguments.js"; import chalk from "chalk"; import path from "node:path"; import readPackage from "../utils/readPackage.js"; import { __dirname } from "../utils/__dirname.js"; import "../utils/globals.js"; -function main() { +async function main() { const { version } = readPackage( path.join(__dirname, "..", "..", "package.json") ); @@ -18,8 +16,12 @@ function main() { ) ); + const { args } = await import("../utils/arguments.js"); + const argv = args(); + const { commands } = await import("../commands/index.js"); + commands(argv); } diff --git a/packages/cli/src/commands/ci.ts b/packages/cli/src/commands/ci.ts index b77f08e..2150cf8 100644 --- a/packages/cli/src/commands/ci.ts +++ b/packages/cli/src/commands/ci.ts @@ -12,7 +12,7 @@ import parseTime from "../utils/parseTime.js"; import { ultraExtract } from "../utils/extract.js"; import readPackage from "../utils/readPackage.js"; -export default async function continuousInstall() { +export async function continuousInstall() { try { const lockFile: string | null = readFileSync( join(process.cwd(), "ultra.lock"), @@ -90,6 +90,7 @@ async function ciDownloader(spec: string, pathname: string, spinner: Ora) { }); const tarball = manifest.dist.tarball; + const integrity = manifest.dist.integrity; if (!existsSync(pathname)) { mkdirSync(pathname, { recursive: true }); @@ -97,7 +98,7 @@ async function ciDownloader(spec: string, pathname: string, spinner: Ora) { spinner.text = chalk.green(`${spec}`); spinner.prefixText = "📦"; - await ultraExtract(pathname, tarball); + await ultraExtract(pathname, tarball, integrity); spinner.prefixText = "🔗"; const pkg = readPackage(join(pathname, "package.json")); diff --git a/packages/cli/src/commands/create.ts b/packages/cli/src/commands/create.ts index 3380494..c92c3cb 100644 --- a/packages/cli/src/commands/create.ts +++ b/packages/cli/src/commands/create.ts @@ -10,7 +10,7 @@ import { getDeps } from "../utils/getDeps.js"; import readPackage from "../utils/readPackage.js"; import manifestFetcher from "../utils/manifestFetcher.js"; -export default async function create(args: string[]) { +export async function create(args: string[]) { if (args.length === 0) { console.log( chalk.red( diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 588131e..f397e29 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { clear } from "./clear.js"; +/* import { clear } from "./clear.js"; import install from "./install.js"; import { benchmark } from "./benchmark.js"; import upgrade from "./upgrade.js"; @@ -10,91 +10,79 @@ import create from "./create.js"; import remove from "./remove.js"; import test from "./test.js"; import init from "./init.js"; -import continuousInstall from "./ci.js"; +import continuousInstall from "./ci.js"; */ import readPackage from "../utils/readPackage.js"; const comms = [ { name: "install", description: "Install a package", - command: install, abr: "i", params: true, }, { name: "benchmark", description: "Benchmark a package", - command: benchmark, abr: "b", params: false, }, { name: "upgrade", description: "Upgrade FNPM", - command: upgrade, abr: "u", params: false, }, { name: "set", description: "Set a config value", - command: update, abr: "s", params: true, }, { name: "list", description: "List package versions", - command: list, abr: "ls", params: true, }, { name: "run", description: "Run a script", - command: run, abr: "r", params: true, }, { name: "create", description: "Create a new package from a template", - command: create, abr: "c", params: true, }, { name: "remove", description: "Remove a package", - command: remove, abr: "rm", params: true, }, { name: "clear", description: "Clear the cache", - command: clear, abr: "c", params: false, }, { name: "test", description: "Run a tests", - command: test, abr: "t", params: true, }, { name: "init", description: "Initialize a package.json file", - command: init, abr: "init", params: true, }, { name: "ci", description: "Run a continuous install", - command: continuousInstall, abr: "ci", params: false, }, @@ -107,22 +95,57 @@ export async function commands(args: string[]) { process.exit(0); } - const comm = comms.find((c) => c.name === command || c.abr === command); - - if (comm) { - // @ts-ignore-next-line - return comm.command(rest); - } + if (command === "help" || command === "-h") { + process.exit(0); + } else if (command === "upgrade" || command === "u") { + const { upgrade } = await import("./upgrade.js"); + return upgrade(); + } else if (command === "install" || command === "i") { + const { install } = await import("./install.js"); + return install(rest); + } else if (command === "benchmark" || command === "b") { + const { benchmark } = await import("./benchmark.js"); + return benchmark(rest); + } else if (command === "set" || command === "s") { + const { update } = await import("../utils/readConfig.js"); + return update(rest); + } else if (command === "list" || command === "ls") { + const { list } = await import("./list.js"); + return list(rest); + } else if (command === "run" || command === "r") { + const { run } = await import("./run.js"); + return run(rest); + } else if (command === "create" || command === "c") { + const { create } = await import("./create.js"); + return create(rest); + } else if (command === "remove" || command === "rm") { + const { remove } = await import("./remove.js"); + return remove(rest); + } else if (command === "clear" || command === "c") { + const { clear } = await import("./clear.js"); + return clear(); + } else if (command === "test" || command === "t") { + const { test } = await import("./test.js"); + return test(rest); + } else if (command === "init" || command === "init") { + const { init } = await import("./init.js"); + return init(rest); + } else if (command === "ci" || command === "ci") { + const { continuousInstall } = await import("./ci.js"); + return continuousInstall(); + } else { + const pkg = readPackage(path.join(process.cwd(), "package.json")); - const pkg = readPackage(path.join(process.cwd(), "package.json")); + if (pkg && pkg.scripts && pkg.scripts[command]) { + const { run } = await import("./run.js"); + return run([command, ...rest]); + } - if (pkg && pkg.scripts && pkg.scripts[command]) { - return run([command, ...rest]); + console.log("Unknown command"); + console.log("Available commands:"); + comms.forEach((c) => { + console.log(`- ${c.name}: ${c.description}`); + }); + process.exit(1); } - - console.log("Unknown command"); - console.log("Available commands:"); - comms.forEach((c) => { - console.log(`- ${c.name}: ${c.description}`); - }); } diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 6ba2293..af6c83e 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -5,7 +5,7 @@ import chalk from "chalk"; import { __dirname } from "../utils/__dirname.js"; import samplePkg from "../utils/sample/package.js"; -export default async function init(args: string[]) { +export async function init(args: string[]) { let sampleJson = samplePkg; if (existsSync("package.json")) { console.log( diff --git a/packages/cli/src/commands/install.ts b/packages/cli/src/commands/install.ts index 7337e22..61cee57 100644 --- a/packages/cli/src/commands/install.ts +++ b/packages/cli/src/commands/install.ts @@ -19,7 +19,7 @@ import { __dirname } from "../utils/__dirname.js"; import { hardLinkSync } from "../utils/hardLinkSync.js"; import checkLock from "../utils/checkLock.js"; -export default async function installBeta(opts: string[]) { +export async function install(opts: string[]) { const start = performance.now(); const newDeps = opts.filter((opt) => !opt.startsWith("-")).length > 0; @@ -104,7 +104,7 @@ export default async function installBeta(opts: string[]) { chalk.yellow("Lockfile is outdated, installing from cache...") ).warn(); await unlink(path.join(process.cwd(), "ultra.lock")); - await installBeta(opts); + await install(opts); return; } } diff --git a/packages/cli/src/commands/list.ts b/packages/cli/src/commands/list.ts index f2d7ffd..f6729e1 100644 --- a/packages/cli/src/commands/list.ts +++ b/packages/cli/src/commands/list.ts @@ -5,7 +5,7 @@ import ora from "ora"; import os from "os"; import path from "path"; -export default async function list(pkgs: string[]) { +export async function list(pkgs: string[]) { if (!pkgs) { ora(chalk.red("Missing package name")).fail(); const packages = await readdir(path.join(os.homedir(), ".ultra-cache")); diff --git a/packages/cli/src/commands/remove.ts b/packages/cli/src/commands/remove.ts index f701d66..0ced44c 100644 --- a/packages/cli/src/commands/remove.ts +++ b/packages/cli/src/commands/remove.ts @@ -2,7 +2,7 @@ import chalk from "chalk"; import { writeFile } from "node:fs/promises"; import readPackage from "../utils/readPackage.js"; -export default async function remove(args: string[]) { +export async function remove(args: string[]) { if (args.length === 0) { console.log( chalk.red("Please provide packages to remove, e.g. fnpm remove react") diff --git a/packages/cli/src/commands/run.ts b/packages/cli/src/commands/run.ts index 3f4cfaf..9d90885 100644 --- a/packages/cli/src/commands/run.ts +++ b/packages/cli/src/commands/run.ts @@ -7,7 +7,7 @@ import { execa } from "execa"; import checkNodeVersion from "../utils/checkNodeVersion.js"; import readPackage from "../utils/readPackage.js"; -export default async function run(args: Array) { +export async function run(args: Array) { const pkg = readPackage(path.join(process.cwd(), "package.json")); await checkNodeVersion(pkg.engines); diff --git a/packages/cli/src/commands/test.ts b/packages/cli/src/commands/test.ts index 374aa18..fa9e4a2 100644 --- a/packages/cli/src/commands/test.ts +++ b/packages/cli/src/commands/test.ts @@ -4,7 +4,7 @@ import { performance } from "perf_hooks"; import ora from "ora"; import parseTime from "../utils/parseTime.js"; -export default async function test(args: string[]) { +export async function test(args: string[]) { const typeArg = args.find((arg) => arg.startsWith("--type=")) || "--type=clean"; const runsArg = args.find((arg) => arg.startsWith("--runs=")) || "--runs=1"; diff --git a/packages/cli/src/commands/upgrade.ts b/packages/cli/src/commands/upgrade.ts index b8a8390..2de560f 100644 --- a/packages/cli/src/commands/upgrade.ts +++ b/packages/cli/src/commands/upgrade.ts @@ -3,7 +3,7 @@ import pacote from "pacote"; import ora from "ora"; import chalk from "chalk"; -export default async function upgrade() { +export async function upgrade() { const spinner = ora("Upgrading to latest version...").start(); await execa("npm", ["install", "-g", "ultrapkg@latest"]); From 9016699eef060fcc103f23689c23c6ffe6b63121 Mon Sep 17 00:00:00 2001 From: nachoaldamav Date: Sat, 15 Oct 2022 17:32:38 +0200 Subject: [PATCH 2/4] =?UTF-8?q?fix=20=F0=9F=90=9B:=20(cli)=20Fix=20manifes?= =?UTF-8?q?ts=20cache=20filenames?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/src/utils/manifestFetcher.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/utils/manifestFetcher.ts b/packages/cli/src/utils/manifestFetcher.ts index 263a06f..1a29692 100644 --- a/packages/cli/src/utils/manifestFetcher.ts +++ b/packages/cli/src/utils/manifestFetcher.ts @@ -12,12 +12,16 @@ const token = readConfig().token; const specialChars = ["^", "~", ">", "<", "=", "|", "&", "*"]; export default async function manifestFetcher(spec: string, props: any) { - const cacheFile = path.join(cacheFolder, `${spec}.json`); + // Remove spaces from spec + const sanitizedSpec = spec.replace(/\s/g, ""); + const cacheFile = path.join(cacheFolder, `${sanitizedSpec}.json`); const now = Date.now(); try { await mkdir(cacheFolder, { recursive: true }).catch((e) => {}); - const isExact = !specialChars.some((char) => spec.includes(char) || spec === "latest"); + const isExact = !specialChars.some( + (char) => sanitizedSpec.includes(char) || sanitizedSpec === "latest" + ); // Check if cache file exists const cacheExists = readFileSync(cacheFile, "utf-8"); From 6460ebde5a7900a29f4cc4da027723f9805818e1 Mon Sep 17 00:00:00 2001 From: nachoaldamav Date: Sat, 15 Oct 2022 18:43:38 +0200 Subject: [PATCH 3/4] =?UTF-8?q?perf=20=F0=9F=9A=80:=20(cli)=20Some=20impro?= =?UTF-8?q?vements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/src/commands/index.ts | 12 --- packages/cli/src/commands/install.ts | 5 +- packages/cli/src/utils/extract.ts | 104 ++++++++++++---------- packages/cli/src/utils/installPkg.ts | 12 ++- packages/cli/src/utils/manifestFetcher.ts | 9 +- 5 files changed, 78 insertions(+), 64 deletions(-) diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index f397e29..fe1ea0e 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -1,16 +1,4 @@ import path from "node:path"; -/* import { clear } from "./clear.js"; -import install from "./install.js"; -import { benchmark } from "./benchmark.js"; -import upgrade from "./upgrade.js"; -import list from "./list.js"; -import run from "./run.js"; -import { update } from "../utils/readConfig.js"; -import create from "./create.js"; -import remove from "./remove.js"; -import test from "./test.js"; -import init from "./init.js"; -import continuousInstall from "./ci.js"; */ import readPackage from "../utils/readPackage.js"; const comms = [ diff --git a/packages/cli/src/commands/install.ts b/packages/cli/src/commands/install.ts index 61cee57..64d965e 100644 --- a/packages/cli/src/commands/install.ts +++ b/packages/cli/src/commands/install.ts @@ -11,7 +11,6 @@ import { installLocalDep } from "../utils/installLocalDep.js"; import getParamsDeps from "../utils/parseDepsParams.js"; import parseTime from "../utils/parseTime.js"; import { spinnerGradient } from "../utils/spinnerGradient.js"; -import { installPkg } from "../utils/installPkg.js"; import manifestFetcher from "../utils/manifestFetcher.js"; import readPackage from "../utils/readPackage.js"; import basePostInstall from "../utils/basePostInstall.js"; @@ -192,9 +191,11 @@ export async function install(opts: string[]) { const __install = spinnerGradient(chalk.green("Installing packages...")); const __install_start = performance.now(); + const { installPkg } = await import("../utils/installPkg.js"); + await Promise.all( pkgs.map(async (pkg) => { - return await installPkg(pkg, pkg.parent, __install); + return installPkg(pkg, pkg.parent, __install); }) ); diff --git a/packages/cli/src/utils/extract.ts b/packages/cli/src/utils/extract.ts index 27c4e23..8276288 100644 --- a/packages/cli/src/utils/extract.ts +++ b/packages/cli/src/utils/extract.ts @@ -5,6 +5,7 @@ import { existsSync, readFileSync, writeFileSync, + unlinkSync, } from "node:fs"; import axios from "axios"; import { createHash } from "node:crypto"; @@ -22,7 +23,7 @@ export async function ultraExtract( target: string, tarball: string, sha: string -) { +): Promise { if (!tarball) { throw new Error("No tarball provided"); } @@ -49,58 +50,67 @@ export async function ultraExtract( mkdirSync(cacheBasePath); } - if (!existsSync(file)) { - const writer = createWriteStream(file); - const response = await axios({ - url: tarball, - method: "GET", - responseType: "stream", - }); + try { + if (!existsSync(file)) { + const writer = createWriteStream(file); + const response = await axios({ + url: tarball, + method: "GET", + responseType: "stream", + }); - response.data.pipe(writer); + response.data.pipe(writer); - await new Promise((resolve, reject) => { - writer.on("finish", resolve); - writer.on("error", reject); - }); + await new Promise((resolve, reject) => { + writer.on("finish", resolve); + writer.on("error", reject); + }); - const fileBuffer = readFileSync(file); - const hashSum = createHash("sha512"); + const fileBuffer = readFileSync(file); + const hashSum = createHash("sha512"); - hashSum.update(fileBuffer); - const hash = "sha512-" + hashSum.digest("base64"); + hashSum.update(fileBuffer); + const hash = "sha512-" + hashSum.digest("base64"); - if (hash !== sha) { - ora().fail(chalk.red(`SHA512 mismatch for ${tarball}`)); - ora().fail(chalk.red(`Expected ${sha} but got ${hash}`)); + if (hash !== sha) { + ora().fail(chalk.red(`SHA512 mismatch for ${tarball}`)); + ora().fail(chalk.red(`Expected ${sha} but got ${hash}`)); + } + + __VERIFIED.push(tarball); } - __VERIFIED.push(tarball); - } + // Extract "package" directory from tarball to "target" directory + mkdirSync(target, { recursive: true }); + + await tar + .extract({ + file, + cwd: target, + strip: 1, + }) + .catch((err) => { + ora( + chalk.red( + `Error extracting ${file} to ${target}: ${err.message || err}` + ) + ).fail(); + }); + + // Create .ultra file + writeFileSync(ultraFile, "{}"); + + __DOWNLOADING.splice(__DOWNLOADING.indexOf(tarball), 1); - // Extract "package" directory from tarball to "target" directory - mkdirSync(target, { recursive: true }); - - await tar - .extract({ - file, - cwd: target, - strip: 1, - }) - .catch((err) => { - ora( - chalk.red( - `Error extracting ${file} to ${target}: ${err.message || err}` - ) - ).fail(); - }); - - // Create .ultra file - writeFileSync(ultraFile, "{}"); - - __DOWNLOADING.splice(__DOWNLOADING.indexOf(tarball), 1); - - return { - res: "extracted", - }; + return { + res: "extracted", + }; + } catch (err) { + // Try again but remove the file + if (existsSync(file)) { + unlinkSync(file); + } + + return ultraExtract(target, tarball, sha); + } } diff --git a/packages/cli/src/utils/installPkg.ts b/packages/cli/src/utils/installPkg.ts index 660d118..37d3674 100644 --- a/packages/cli/src/utils/installPkg.ts +++ b/packages/cli/src/utils/installPkg.ts @@ -167,6 +167,10 @@ export async function installPkg( readFileSync(`${cacheFolder}/${downloadFile}`, "utf-8") ); + const deps = getDeps(pkgJson, { + dev: true, + }); + // Symlink bin files await binLinks({ path: pkgProjectDir, @@ -190,6 +194,12 @@ export async function installPkg( ); } + for (const dep of deps) { + if (!cachedDeps[dep.name]) { + await installPkg(dep, pkgProjectDir, spinner); + } + } + __INSTALLED.push({ name: manifest.name, version: manifest.version, @@ -265,7 +275,7 @@ export async function installPkg( pkg.dist.integrity ); - if (status.res === "skipped") { + if (status && status.res === "skipped") { return null; } diff --git a/packages/cli/src/utils/manifestFetcher.ts b/packages/cli/src/utils/manifestFetcher.ts index 1a29692..ee1f543 100644 --- a/packages/cli/src/utils/manifestFetcher.ts +++ b/packages/cli/src/utils/manifestFetcher.ts @@ -12,8 +12,13 @@ const token = readConfig().token; const specialChars = ["^", "~", ">", "<", "=", "|", "&", "*"]; export default async function manifestFetcher(spec: string, props: any) { - // Remove spaces from spec - const sanitizedSpec = spec.replace(/\s/g, ""); + // Remove spaces "|", ">" and "<" from the spec + const sanitizedSpec = spec + .replace(/ /g, "") + .replace(/\|/g, "") + .replace(/>/g, "") + .replace(/ Date: Sat, 15 Oct 2022 19:21:35 +0200 Subject: [PATCH 4/4] Fix manifests in Windows --- packages/cli/src/commands/benchmark.ts | 33 ++++++++++++----------- packages/cli/src/utils/manifestFetcher.ts | 11 ++++---- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/packages/cli/src/commands/benchmark.ts b/packages/cli/src/commands/benchmark.ts index 5f047b8..902ebc7 100644 --- a/packages/cli/src/commands/benchmark.ts +++ b/packages/cli/src/commands/benchmark.ts @@ -11,6 +11,8 @@ import { execa } from "execa"; import { fileURLToPath } from "url"; import readPackage from "../utils/readPackage.js"; +const delCommand = os.platform() === "win32" ? "del /s /q" : "rm -rf"; + const homeDir = os.homedir(); const __filename = fileURLToPath(import.meta.url); @@ -21,7 +23,7 @@ const tests = [ { name: "NPM install (no cache / no lockfile)", command: "npm install --force", - pre: "npm cache clean -f && rm -rf node_modules package-lock.json", + pre: `npm cache clean -f && ${delCommand} node_modules package-lock.json`, spinner: ora( chalk.green(`Running "NPM install (no cache / no lockfile)"...`) ).stop(), @@ -30,7 +32,7 @@ const tests = [ { name: "NPM install (with cache / no lockfile)", command: "npm install --force", - pre: "rm -rf node_modules package-lock.json", + pre: `${delCommand} node_modules package-lock.json`, spinner: ora( chalk.green(`Running "NPM install (with cache / no lockfile)"...`) ).stop(), @@ -39,7 +41,7 @@ const tests = [ { name: "NPM install (with cache / with lockfile)", command: "npm install --force", - pre: "rm -rf node_modules/", + pre: `${delCommand} node_modules`, spinner: ora( chalk.green(`Running "NPM install (with cache / with lockfile)"...`) ).stop(), @@ -48,7 +50,7 @@ const tests = [ { name: "YARN install (no cache / no lockfile)", command: "yarn install --force", - pre: "yarn cache clean && rm -rf node_modules yarn.lock", + pre: `yarn cache clean && ${delCommand} node_modules yarn.lock`, spinner: ora( chalk.green(`Running "YARN install (no cache / no lockfile)"...`) ).stop(), @@ -57,7 +59,7 @@ const tests = [ { name: "YARN install (with cache / no lockfile)", command: "yarn install --force", - pre: "rm -rf node_modules yarn.lock", + pre: `${delCommand} node_modules yarn.lock`, spinner: ora( chalk.green(`Running "YARN install (with cache / no lockfile)"...`) ).stop(), @@ -66,7 +68,7 @@ const tests = [ { name: "YARN install (with cache / with lockfile)", command: "yarn install --force", - pre: "rm -rf node_modules", + pre: `${delCommand} node_modules`, spinner: ora( chalk.green(`Running "YARN install (with cache / with lockfile)"...`) ).stop(), @@ -76,7 +78,7 @@ const tests = [ { name: "⚡ ULTRA install (no cache / no lockfile)", command: "ultra install", - pre: "npm cache clean -f && ultra clear", + pre: "ultra clear", spinner: ora( chalk.green(`Running "ULTRA install (no cache / no lockfile)"...`) ).stop(), @@ -85,7 +87,8 @@ const tests = [ { name: "⚡ ULTRA install (with cache / no lockfile)", command: "ultra install", - pre: "rm -rf node_modules ultra.lock", + /* pre: "rm -rf node_modules ultra.lock", */ + pre: `${delCommand} node_modules ultra.lock`, spinner: ora( chalk.green(`Running "ULTRA install (with cache / no lockfile)"...`) ).stop(), @@ -94,7 +97,7 @@ const tests = [ { name: "⚡ ULTRA install (with cache / with lockfile)", command: "ultra install", - pre: "rm -rf node_modules", + pre: `${delCommand} node_modules`, spinner: ora( chalk.green(`Running "ULTRA install (with cache / with lockfile)"...`) ).stop(), @@ -131,7 +134,7 @@ const tests = [ name: "PNPM install (no cache / no lockfile)", command: "pnpm install --force --cache-dir=cache/cache --store-dir=cache/store --no-strict-peer-dependencies", - pre: `npm cache clean -f && pnpm store prune && rm -rf node_modules pnpm-lock.yaml ${homeDir}.local/share/pnpm/store/v3 cache/`, + pre: `npm cache clean -f && pnpm store prune && ${delCommand} node_modules pnpm-lock.yaml ${homeDir}.local/share/pnpm/store/v3 cache/`, spinner: ora(chalk.green(`Running "PNPM install (no cache)"...`)).stop(), group: 1, }, @@ -139,7 +142,7 @@ const tests = [ name: "PNPM install (with cache / no lockfile)", command: "pnpm install --force --cache-dir=cache/cache --store-dir=cache/store --no-strict-peer-dependencies", - pre: `rm -rf node_modules pnpm-lock.yaml`, + pre: `${delCommand} node_modules pnpm-lock.yaml`, spinner: ora( chalk.green(`Running "PNPM install (with cache / no lockfile)"...`) ).stop(), @@ -149,7 +152,7 @@ const tests = [ name: "PNPM install (with cache / with lockfile)", command: "pnpm install --force --cache-dir=cache/cache --store-dir=cache/store --no-strict-peer-dependencies", - pre: "rm -rf node_modules", + pre: `${delCommand} node_modules`, spinner: ora(chalk.green(`Running "PNPM install (with cache)"...`)).stop(), group: 3, }, @@ -157,7 +160,7 @@ const tests = [ { name: "Bun install (no cache / no lockfile)", command: "bun install", - pre: `npm cache clean -f && rm -rf ${homeDir}.bun bun.lockb node_modules package-lock.json yarn.lock`, + pre: `npm cache clean -f && ${delCommand} ${homeDir}.bun bun.lockb node_modules package-lock.json yarn.lock`, spinner: ora( chalk.green(`Running "Bun install (no cache / no lockfile)"...`) ).stop(), @@ -166,7 +169,7 @@ const tests = [ { name: "Bun install (with cache / no lockfile)", command: "bun install", - pre: "rm -rf node_modules bun.lockb package-lock.json yarn.lock", + pre: `${delCommand} node_modules bun.lockb package-lock.json yarn.lock`, spinner: ora( chalk.green(`Running "Bun install (with cache / no lockfile)"...`) ).stop(), @@ -175,7 +178,7 @@ const tests = [ { name: "Bun install (with cache / with lockfile)", command: "bun install", - pre: "rm -rf node_modules", + pre: `${delCommand} node_modules`, spinner: ora( chalk.green(`Running "Bun install (with cache / with lockfile)"...`) ).stop(), diff --git a/packages/cli/src/utils/manifestFetcher.ts b/packages/cli/src/utils/manifestFetcher.ts index ee1f543..c5e7ce4 100644 --- a/packages/cli/src/utils/manifestFetcher.ts +++ b/packages/cli/src/utils/manifestFetcher.ts @@ -4,6 +4,8 @@ import pacote from "pacote"; import { mkdir } from "node:fs/promises"; import { readFileSync, writeFileSync, mkdirSync } from "node:fs"; import readConfig from "./readConfig.js"; +import ora from "ora"; +import chalk from "chalk"; const cacheFolder = path.join(os.homedir(), ".ultra", "__manifests__"); @@ -14,10 +16,9 @@ const specialChars = ["^", "~", ">", "<", "=", "|", "&", "*"]; export default async function manifestFetcher(spec: string, props: any) { // Remove spaces "|", ">" and "<" from the spec const sanitizedSpec = spec - .replace(/ /g, "") - .replace(/\|/g, "") - .replace(/>/g, "") - .replace(//g, "3E") + .replace(/ {}); const isExact = !specialChars.some( - (char) => sanitizedSpec.includes(char) || sanitizedSpec === "latest" + (char) => sanitizedSpec.includes(char) || sanitizedSpec.includes("latest") ); // Check if cache file exists