Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added pnpm support #8

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ typings/
# Compile Output
lib/
coverage/
docs/
docs/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Full documentation of available functions and configuration can be found on:

### 1. Disparity in supported flags

At the current moment `yarn` has no equivalent flags for `--save-bundle` or `--no-save`. These will be ignored when `yarn` has been detected as package manager.
At the current moment `yarn` and `pnpm` have no equivalent flags for `--save-bundle` or `--no-save`. These will be ignored when `yarn` or `pnpm` has been detected as package manager.

The flags that were ignored in the run are returned as the `ignoredFlags` property.

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"keywords": [
"npm",
"yarn",
"pnpm",
"install",
"cli",
"script"
Expand All @@ -37,7 +38,7 @@
"typedoc": "^0.14.2",
"typedoc-plugin-external-module-name": "^2.0.0",
"typedoc-plugin-internal-external": "^2.0.1",
"typescript": "^3.3.3"
"typescript": "^5.4.3"
},
"bugs": {
"url": "https://github.com/dkundel/pkg-install/issues",
Expand Down
25 changes: 21 additions & 4 deletions src/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { getExecaConfig, getPackageList } from './helpers';
import { constructNpmArguments, npmProjectInstallArgs } from './npm';
import { getPackageManager, getPackageManagerSync } from './package-manager';
import { constructPnpmArguments, pnpmProjectInstallArgs } from "./pnpm";
import { PackageList, Packages } from './types';
import { constructYarnArguments, yarnProjectInstallArgs } from './yarn';

Expand Down Expand Up @@ -36,7 +37,11 @@ export async function install(

const packageList = getPackageList(packages);
const getArguments =
pkgManager === 'npm' ? constructNpmArguments : constructYarnArguments;
pkgManager === "npm"
? constructNpmArguments
: pkgManager === "yarn"
? constructYarnArguments
: constructPnpmArguments;
const { args, ignoredFlags } = getArguments(packageList, config);

const result = await execa(pkgManager, args, getExecaConfig(config));
Expand Down Expand Up @@ -68,7 +73,11 @@ export function installSync(

const packageList = getPackageList(packages);
const getArguments =
pkgManager === 'npm' ? constructNpmArguments : constructYarnArguments;
pkgManager === "npm"
? constructNpmArguments
: pkgManager === "yarn"
? constructYarnArguments
: constructPnpmArguments;
const { args, ignoredFlags } = getArguments(packageList, config);

const result = execa.sync(pkgManager, args, getExecaConfig(config));
Expand Down Expand Up @@ -97,7 +106,11 @@ export async function projectInstall(
const pkgManager = await getPackageManager(config);

const args =
pkgManager === 'npm' ? npmProjectInstallArgs : yarnProjectInstallArgs;
pkgManager === "npm"
? npmProjectInstallArgs
: pkgManager === "yarn"
? yarnProjectInstallArgs
: pnpmProjectInstallArgs;

return execa(pkgManager, args, getExecaConfig(config));
}
Expand All @@ -121,7 +134,11 @@ export function projectInstallSync(
const pkgManager = getPackageManagerSync(config);

const args =
pkgManager === 'npm' ? npmProjectInstallArgs : yarnProjectInstallArgs;
pkgManager === "npm"
? npmProjectInstallArgs
: pkgManager === "yarn"
? yarnProjectInstallArgs
: pnpmProjectInstallArgs;

return execa.sync(pkgManager, args, getExecaConfig(config));
}
2 changes: 1 addition & 1 deletion src/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {

/**
* Determine what package manager to use based on what preference is set,
* and whether it's currently running in a yarn/npm script
* and whether it's currently running in a yarn/npm/pnpm script
*
* @export
* @param {InstallConfig} config
Expand Down
48 changes: 48 additions & 0 deletions src/pnpm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { InstallConfig, PackageManagerFlag } from "./config";
import { getFlagsToSet } from "./flags";
import { UnreachableCaseError } from "./helpers";
import { ConstructArgumentsResult, PackageList } from "./types";

export function constructPnpmArguments(
packageList: PackageList,
config: InstallConfig
): ConstructArgumentsResult {
const flagsToSet = getFlagsToSet(config);
const globalCommand = config.global ? ["--global"] : [];
const cwdCommand = config.forceCwd ? ["--pnpm-prefix", config.cwd] : [];
const args: string[] = [
"install",
...globalCommand,
...cwdCommand,
"add",
...packageList,
];

const ignoredFlags: PackageManagerFlag[] = [];
flagsToSet.forEach((flag) => {
switch (flag) {
case "dev":
if (!config.global) {
args.push("--save-dev");
} else {
ignoredFlags.push(flag);
}
break;
case "exact":
args.push("--save-exact");
break;
case "verbose":
case "bundle":
case "noSave":
ignoredFlags.push(flag);
break;
/* istanbul ignore next */
default:
throw new UnreachableCaseError(flag);
}
});

return { args, ignoredFlags };
}

export const pnpmProjectInstallArgs = ["install"];
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type PackageMap = {

export type PackageList = string[];
export type Packages = PackageMap | PackageList;
export type SupportedPackageManagers = 'yarn' | 'npm';
export type SupportedPackageManagers = 'yarn' | 'npm' | 'pnpm';

/**
* What to do with I/O. This is passed to `execa`
Expand Down
20 changes: 18 additions & 2 deletions src/utils/package-manager-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export function getCurrentPackageManager(): SupportedPackageManagers | null {
return 'yarn';
}

if (userAgent.startsWith('pnpm')) {
return 'pnpm';
}

return null;
}

Expand All @@ -77,6 +81,7 @@ export async function getPackageManagerFromLockfile(
): Promise<SupportedPackageManagers | null> {
const pkgLockPath = path.join(config.cwd, 'package-lock.json');
const yarnLockPath = path.join(config.cwd, 'yarn.lock');
const pnpmLockPath = path.join(config.cwd, 'pnpm-lock.yaml');
try {
await access(pkgLockPath);
return 'npm';
Expand All @@ -85,7 +90,12 @@ export async function getPackageManagerFromLockfile(
await access(yarnLockPath);
return 'yarn';
} catch (err) {
return null;
try {
await access(pnpmLockPath);
return 'pnpm';
} catch (err) {
return null;
}
}
}
}
Expand All @@ -102,6 +112,7 @@ export function getPackageManagerFromLockfileSync(
): SupportedPackageManagers | null {
const pkgLockPath = path.join(config.cwd, 'package-lock.json');
const yarnLockPath = path.join(config.cwd, 'yarn.lock');
const pnpmLockPath = path.join(config.cwd, 'pnpm-lock.yaml');
try {
accessSync(pkgLockPath);
return 'npm';
Expand All @@ -110,7 +121,12 @@ export function getPackageManagerFromLockfileSync(
accessSync(yarnLockPath);
return 'yarn';
} catch (err) {
return null;
try {
accessSync(pnpmLockPath);
return 'pnpm';
} catch (err) {
return null;
}
}
}
}
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */

/* Source Map Options */
Expand All @@ -56,5 +56,7 @@
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */

"useUnknownInCatchVariables": false
}
}
2 changes: 1 addition & 1 deletion typedoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"mode": "modules",
"out": "docs",
"theme": "default",
"exclude": ["**/__tests__/*.ts", "**/helpers.ts", "**/npm.ts", "**/yarn.ts"],
"exclude": ["**/__tests__/*.ts", "**/helpers.ts", "**/npm.ts", "**/yarn.ts", "**/pnpm.ts"],
"gaID": "UA-40008341-3"
}