Skip to content

Commit

Permalink
Merge pull request #177 from goestav/feature/support-multiple-package…
Browse files Browse the repository at this point in the history
…-managers

Feature: support multiple package managers
  • Loading branch information
andrewbranch authored Jul 2, 2024
2 parents 3729bc2 + b8d7fa0 commit e051c7f
Show file tree
Hide file tree
Showing 5 changed files with 2,726 additions and 2,159 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-points-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@arethetypeswrong/cli": minor
---

Add support for multiple package managers like [pnpm](https://pnpm.io/) and [yarn](https://yarnpkg.com/) ([#173](https://github.com/arethetypeswrong/arethetypeswrong.github.io/issues/173))
4 changes: 3 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@types/marked-terminal": "^3.1.3",
"@types/node": "^20.2.5",
"@types/semver": "^7.5.3",
"@types/which-pm-runs": "^1.0.2",
"ts-expose-internals-conditionally": "1.0.0-empty.0",
"typescript": "5.3.3"
},
Expand All @@ -59,7 +60,8 @@
"commander": "^10.0.1",
"marked": "^9.1.2",
"marked-terminal": "^6.0.0",
"semver": "^7.5.4"
"semver": "^7.5.4",
"which-pm-runs": "^1.1.0"
},
"engines": {
"node": ">=18"
Expand Down
25 changes: 14 additions & 11 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { readConfig } from "./readConfig.js";
import * as render from "./render/index.js";
import { major, minor } from "semver";
import { getExitCode } from "./getExitCode.js";
import { determinePackCommand, determineTarballFilename } from "./utils.js";
import detectPackageManager from "which-pm-runs";

const packageJson = createRequire(import.meta.url)("../package.json");
const version = packageJson.version;
Expand Down Expand Up @@ -74,8 +76,8 @@ particularly ESM-related module resolution issues.`,
.option("--exclude-entrypoints <entrypoints...>", "Specify entrypoints to exclude from checking.")
.option(
"--entrypoints-legacy",
'In packages without the `exports` field, every file is an entry point. Specifying this option ' +
'only takes effect when no entrypoints are automatically detected, or explicitly provided with other options.'
"In packages without the `exports` field, every file is an entry point. Specifying this option " +
"only takes effect when no entrypoints are automatically detected, or explicitly provided with other options.",
)
.addOption(
new Option("--ignore-rules <rules...>", "Specify rules to ignore").choices(Object.values(problemFlags)).default([]),
Expand Down Expand Up @@ -159,29 +161,30 @@ particularly ESM-related module resolution issues.`,
);
}

const packageManager = (await detectPackageManager()?.name) ?? "npm";
const packCommand = determinePackCommand(packageManager);

if (!opts.pack) {
if (!process.stdout.isTTY) {
program.error(
"Specifying a directory requires the --pack option to confirm that running `npm pack` is ok.",
`Specifying a directory requires the --pack option to confirm that running \`${packCommand}\` is ok.`,
);
}
const rl = readline.createInterface(process.stdin, process.stdout);
const answer = await new Promise<string>((resolve) => {
rl.question(`Run \`npm pack\`? (Pass -P/--pack to skip) (Y/n) `, resolve);
rl.question(`Run \`${packCommand}\`? (Pass -P/--pack to skip) (Y/n) `, resolve);
});
rl.close();
if (answer.trim() && !answer.trim().toLowerCase().startsWith("y")) {
process.exit(1);
}
}

const manifest = JSON.parse(await readFile(path.join(fileOrDirectory, "package.json"), { encoding: "utf8" }));
fileName = deleteTgz = path.join(
fileOrDirectory,
// https://github.com/npm/cli/blob/f875caa86900122819311dd77cde01c700fd1817/lib/utils/tar.js#L123-L125
`${manifest.name.replace("@", "").replace("/", "-")}-${manifest.version}.tgz`,
);
execSync("npm pack", { cwd: fileOrDirectory, encoding: "utf8", stdio: "ignore" });
fileName = deleteTgz = await determineTarballFilename(fileOrDirectory);

const packCommandWithFilename = determinePackCommand(packageManager, fileName);

execSync(packCommandWithFilename, { cwd: fileOrDirectory, encoding: "utf8", stdio: "ignore" });
}
const file = await readFile(fileName);
const data = new Uint8Array(file);
Expand Down
26 changes: 26 additions & 0 deletions packages/cli/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { readFile } from "fs/promises";
import path from "path";

/** Determine which CLI command to use to create a tarball from a package. */
export const determinePackCommand = (packageManager: string, filename?: string) => {
switch (packageManager) {
case "pnpm":
// PNPM does not support custom destination filenames (see: https://github.com/pnpm/pnpm/issues/7834)
return "pnpm pack";
case "yarn":
return filename ? `yarn pack --out ${filename}` : "yarn pack";
default:
return filename ? `npm pack ${filename}` : "npm pack";
}
};

/** Determine which tarball filename to use. */
export const determineTarballFilename = async (fileOrDirectory: string) => {
const manifest = JSON.parse(await readFile(path.join(fileOrDirectory, "package.json"), { encoding: "utf8" }));

return path.join(
fileOrDirectory,
// https://github.com/npm/cli/blob/f875caa86900122819311dd77cde01c700fd1817/lib/utils/tar.js#L123-L125
`${manifest.name.replace("@", "").replace("/", "-")}-${manifest.version}.tgz`,
);
};
Loading

0 comments on commit e051c7f

Please sign in to comment.