Skip to content

Commit be3e16b

Browse files
committed
feat: basic pnpm support
1 parent 74e5074 commit be3e16b

File tree

6 files changed

+112
-1
lines changed

6 files changed

+112
-1
lines changed

lib/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ $injector.requireCommand(["setup|cloud", "cloud|setup"], "./commands/setup");
112112
$injector.requirePublic("packageManager", "./package-manager");
113113
$injector.requirePublic("npm", "./node-package-manager");
114114
$injector.requirePublic("yarn", "./yarn-package-manager");
115+
$injector.requirePublic("pnpm", "./pnpm-package-manager");
115116
$injector.requireCommand("package-manager|set", "./commands/package-manager-set");
116117
$injector.requireCommand("package-manager|get", "./commands/package-manager-get");
117118

lib/common/commands/package-manager-set.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export class PackageManagerCommand implements ICommand {
1010
public execute(args: string[]): Promise<void> {
1111
if (args[0] === 'yarn') {
1212
return this.$userSettingsService.saveSetting("packageManager", "yarn");
13+
} else if (args[0] === 'pnpm') {
14+
return this.$userSettingsService.saveSetting("packageManager", "pnpm");
1315
} else if (args[0] === 'npm') {
1416
return this.$userSettingsService.saveSetting("packageManager", "npm");
1517
}

lib/declarations.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ interface IOptions extends IRelease, IDeviceIdentifier, IJustLaunch, IAvd, IAvai
552552
frameworkName: string;
553553
frameworkVersion: string;
554554
yarn: string,
555+
pnpm: string,
555556
ipa: string;
556557
tsc: boolean;
557558
ts: boolean;

lib/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export class Options {
100100
ts: { type: OptionType.Boolean, hasSensitiveValue: false },
101101
typescript: { type: OptionType.Boolean, hasSensitiveValue: false },
102102
yarn: { type: OptionType.Boolean, hasSensitiveValue: false },
103+
pnpm: { type: OptionType.Boolean, hasSensitiveValue: false },
103104
androidTypings: { type: OptionType.Boolean, hasSensitiveValue: false },
104105
bundle: { type: OptionType.String, hasSensitiveValue: false },
105106
all: { type: OptionType.Boolean, hasSensitiveValue: false },

lib/package-manager.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export class PackageManager implements IPackageManager {
99
private $npm: INodePackageManager,
1010
private $options: IOptions,
1111
private $yarn: INodePackageManager,
12+
private $pnpm: INodePackageManager,
1213
private $logger: ILogger,
1314
private $userSettingsService: IUserSettingsService
1415
) { }
@@ -98,7 +99,9 @@ export class PackageManager implements IPackageManager {
9899

99100
if (pm === 'yarn' || this.$options.yarn) {
100101
return this.$yarn;
101-
} else {
102+
} else if (pm === 'pnpm' || this.$options.pnpm) {
103+
return this.$pnpm;
104+
} else{
102105
return this.$npm;
103106
}
104107
}

lib/pnpm-package-manager.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import * as path from "path";
2+
import { BasePackageManager } from "./base-package-manager";
3+
import { exported } from './common/decorators';
4+
5+
export class PnpmPackageManager extends BasePackageManager {
6+
7+
constructor(
8+
$childProcess: IChildProcess,
9+
private $errors: IErrors,
10+
$fs: IFileSystem,
11+
$hostInfo: IHostInfo,
12+
private $httpClient: Server.IHttpClient,
13+
private $logger: ILogger,
14+
$pacoteService: IPacoteService
15+
) {
16+
super($childProcess, $fs, $hostInfo, $pacoteService, 'pnpm');
17+
}
18+
19+
@exported("pnpm")
20+
public async install(packageName: string, pathToSave: string, config: INodePackageManagerInstallOptions): Promise<INpmInstallResultInfo> {
21+
if (config.disableNpmInstall) {
22+
return;
23+
}
24+
if (config.ignoreScripts) {
25+
config['ignore-scripts'] = true;
26+
}
27+
28+
const packageJsonPath = path.join(pathToSave, 'package.json');
29+
const jsonContentBefore = this.$fs.readJson(packageJsonPath);
30+
31+
const flags = this.getFlagsString(config, true);
32+
let params = [];
33+
const isInstallingAllDependencies = packageName === pathToSave;
34+
if (!isInstallingAllDependencies) {
35+
params.push('i', packageName);
36+
}
37+
38+
params = params.concat(flags);
39+
const cwd = pathToSave;
40+
41+
try {
42+
const result = await this.processPackageManagerInstall(packageName, params, { cwd, isInstallingAllDependencies });
43+
return result;
44+
} catch (e) {
45+
this.$fs.writeJson(packageJsonPath, jsonContentBefore);
46+
throw e;
47+
}
48+
}
49+
50+
@exported("pnpm")
51+
public uninstall(packageName: string, config?: IDictionary<string | boolean>, cwd?: string): Promise<string> {
52+
const flags = this.getFlagsString(config, false);
53+
return this.$childProcess.exec(`pnpm remove ${packageName} ${flags}`, { cwd });
54+
}
55+
56+
@exported("pnpm")
57+
public async view(packageName: string, config: Object): Promise<any> {
58+
const wrappedConfig = _.extend({}, config, { json: true });
59+
60+
const flags = this.getFlagsString(wrappedConfig, false);
61+
let viewResult: any;
62+
try {
63+
viewResult = await this.$childProcess.exec(`pnpm info ${packageName} ${flags}`);
64+
} catch (e) {
65+
this.$errors.fail(e.message);
66+
}
67+
68+
const result = JSON.parse(viewResult);
69+
return result.data;
70+
}
71+
72+
@exported("pnpm")
73+
public search(filter: string[], config: IDictionary<string | boolean>): Promise<string> {
74+
this.$errors.fail("Method not implemented. pnpm does not support searching for packages in the registry.");
75+
return null;
76+
}
77+
78+
public async searchNpms(keyword: string): Promise<INpmsResult> {
79+
const httpRequestResult = await this.$httpClient.httpRequest(`https://api.npms.io/v2/search?q=keywords:${keyword}`);
80+
const result: INpmsResult = JSON.parse(httpRequestResult.body);
81+
return result;
82+
}
83+
84+
@exported("pnpm")
85+
public async getRegistryPackageData(packageName: string): Promise<any> {
86+
const registry = await this.$childProcess.exec(`pnpm config get registry`);
87+
const url = `${registry.trim()}/${packageName}`;
88+
this.$logger.trace(`Trying to get data from pnpm registry for package ${packageName}, url is: ${url}`);
89+
const responseData = (await this.$httpClient.httpRequest(url)).body;
90+
this.$logger.trace(`Successfully received data from pnpm registry for package ${packageName}. Response data is: ${responseData}`);
91+
const jsonData = JSON.parse(responseData);
92+
this.$logger.trace(`Successfully parsed data from pnpm registry for package ${packageName}.`);
93+
return jsonData;
94+
}
95+
96+
@exported("pnpm")
97+
public async getCachePath(): Promise<string> {
98+
const result = await this.$childProcess.exec(`pnpm cache dir`);
99+
return result.toString().trim();
100+
}
101+
}
102+
103+
$injector.register("pnpm", PnpmPackageManager);

0 commit comments

Comments
 (0)