From 5e08104d5d48be8275ac32af26c95d3d3e318bef Mon Sep 17 00:00:00 2001 From: markthree <1801982702@qq.com> Date: Sun, 12 Mar 2023 15:29:16 +0800 Subject: [PATCH] fix: check depsNotInstalled --- mod.ts | 22 ++++++++++++++++------ src/deps.ts | 16 +++++++--------- src/fs.ts | 26 ++++++++++++++++++++++++++ src/path.ts | 3 +++ 4 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 src/path.ts diff --git a/mod.ts b/mod.ts index 01afad1..e968f8d 100644 --- a/mod.ts +++ b/mod.ts @@ -5,10 +5,11 @@ import { yellow, } from "https://deno.land/std@0.178.0/fmt/colors.ts"; -import { exist } from "./src/fs.ts"; +import { exist, findUpNodeModules, findUpPackageJson } from "./src/fs.ts"; import { listLog } from "./src/log.ts"; import type { PackageManager } from "./src/pm.ts"; import { execa, normalFusing } from "./src/process.ts"; +import { join } from "https://deno.land/std@0.179.0/path/mod.ts"; import { isPackageManager, usePackageManager } from "./src/pm.ts"; import { extractDeps, extractDepsFromPackageJson } from "./src/deps.ts"; @@ -131,7 +132,18 @@ async function autoInstall( ) { if (auto) { const base = Deno.cwd(); - const depsInPackageJson = await extractDepsFromPackageJson(base); + const packageJsonPath = await findUpPackageJson(base) || ""; + const depsInPackageJson = await extractDepsFromPackageJson(packageJsonPath); + + const nodeModulesPath = await findUpNodeModules(base) || ""; + + const depsNotInstalled = + (await Promise.all(depsInPackageJson.map(async (dep) => { + return { + name: dep, + exist: await exist(join(nodeModulesPath, dep)), + }; + }))).filter((dep) => !dep.exist).map((dep) => dep.name); const deps = await extractDeps(base); @@ -162,7 +174,7 @@ async function autoInstall( } } - if (depsInPackageJson.length) { + if (depsNotInstalled.length) { console.log( `🌳 The deps is detected from ${green("package.json")}`, ); @@ -180,9 +192,7 @@ async function autoInstall( await execa([ packageManager.value ?? "npm", packageManager.value === "yarn" ? "add" : "install", - ...depsInPackageJson.filter((dep) => - !depsNotInPackageJson.includes(dep) - ), + ...depsNotInstalled, ]); } } diff --git a/src/deps.ts b/src/deps.ts index 0794983..ecf8d20 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -1,7 +1,6 @@ import { exist } from "./fs.ts"; import { builtinModules as _builtinModules } from "node:module"; import { walk } from "https://deno.land/std@0.179.0/fs/walk.ts"; -import { join } from "https://deno.land/std@0.179.0/path/mod.ts"; export const builtinModules = [ "module", @@ -41,7 +40,7 @@ export function filterDeps(specifiers: string[]) { }); } -export async function readCodes(path: string) { +export async function readCodes(base: string) { const options = { includeFiles: true, includeDirs: false, @@ -51,7 +50,7 @@ export async function readCodes(path: string) { }; const codes: string[] = []; - for await (const entry of walk(path, options)) { + for await (const entry of walk(base, options)) { const code = await Deno.readTextFile(entry.path); codes.push(code); } @@ -59,8 +58,8 @@ export async function readCodes(path: string) { return codes; } -export async function extractDeps(path: string) { - const codes = await readCodes(path); +export async function extractDeps(base: string) { + const codes = await readCodes(base); const deps = codes.map((code) => filterDeps(extractSpecifier(eliminateComments(code))) @@ -69,12 +68,11 @@ export async function extractDeps(path: string) { return uniqueDeps(...deps); } -export async function extractDepsFromPackageJson(path: string) { - const packageJson = join(path, "package.json"); - if (!await exist(packageJson)) { +export async function extractDepsFromPackageJson(packageJsonPath: string) { + if (!await exist(packageJsonPath)) { return []; } - const packageJsonText = await Deno.readTextFile(packageJson); + const packageJsonText = await Deno.readTextFile(packageJsonPath); const packageJsonObject = JSON.parse(packageJsonText); diff --git a/src/fs.ts b/src/fs.ts index 5be57d0..c6cc1b0 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -1,3 +1,6 @@ +import { slash } from "./path.ts"; +import { dirname, join } from "https://deno.land/std@0.179.0/path/mod.ts"; + export async function exist(path: string) { try { await Deno.stat(path); @@ -9,3 +12,26 @@ export async function exist(path: string) { throw error; } } + +export function createFindUp(target: string) { + return async function findUp(base: string) { + base = slash(base); + const paths = [join(base, target)]; + let total = base.split("/").length - 1; + while (total) { + base = dirname(base); + paths.push(join(base, target)); + total--; + } + + for (const path of paths) { + if (await exist(path)) { + return path; + } + } + return null; + }; +} + +export const findUpNodeModules = createFindUp("node_modules"); +export const findUpPackageJson = createFindUp("package.json"); diff --git a/src/path.ts b/src/path.ts new file mode 100644 index 0000000..f78ad4a --- /dev/null +++ b/src/path.ts @@ -0,0 +1,3 @@ +export function slash(path: string) { + return path.replace(/\\/g, "/"); +}