Skip to content

Commit a182ace

Browse files
committed
feat: Added pnpm
1 parent c05c297 commit a182ace

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { GitLfsResource } from './resources/git/lfs/git-lfs.js';
1414
import { HomebrewResource } from './resources/homebrew/homebrew.js';
1515
import { JenvResource } from './resources/java/jenv/jenv.js';
1616
import { NvmResource } from './resources/node/nvm/nvm.js';
17+
import { Pnpm } from './resources/node/pnpm/pnpm.js';
1718
import { PgcliResource } from './resources/pgcli/pgcli.js';
1819
import { PyenvResource } from './resources/python/pyenv/pyenv.js';
1920
import { Virtualenv } from './resources/python/virtualenv/virtualenv.js';
@@ -59,6 +60,7 @@ runPlugin(Plugin.create(
5960
new ActionResource(),
6061
new FileResource(),
6162
new Virtualenv(),
62-
new VirtualenvProject()
63+
new VirtualenvProject(),
64+
new Pnpm()
6365
])
6466
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema",
3+
"$id": "https://www.codifycli.com/pnpm.json",
4+
"title": "Nvm resource",
5+
"description": "Install and manage Node versions using nvm.",
6+
"type": "object",
7+
"properties": {
8+
"version": {
9+
"type": "string",
10+
"description": "A specific version of pnpm to install. (defaults to the latest)"
11+
}
12+
},
13+
"additionalProperties": false
14+
}

src/resources/node/pnpm/pnpm.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { CreatePlan, DestroyPlan, RefreshContext, Resource, ResourceSettings, getPty } from 'codify-plugin-lib';
2+
import { ResourceConfig } from 'codify-schemas';
3+
import fs from 'node:fs/promises';
4+
import os from 'node:os';
5+
import path from 'node:path';
6+
7+
import { codifySpawn } from '../../../utils/codify-spawn.js';
8+
import { FileUtils } from '../../../utils/file-utils.js';
9+
import schema from './pnpm-schema.json';
10+
11+
export interface PnpmConfig extends ResourceConfig {
12+
version?: string;
13+
}
14+
15+
export class Pnpm extends Resource<PnpmConfig> {
16+
getSettings(): ResourceSettings<PnpmConfig> {
17+
return {
18+
id: 'pnpm',
19+
schema,
20+
parameterSettings: {
21+
version: { type: 'version' }
22+
}
23+
}
24+
}
25+
26+
async refresh(parameters: Partial<PnpmConfig>, context: RefreshContext<PnpmConfig>): Promise<Partial<PnpmConfig> | Partial<PnpmConfig>[] | null> {
27+
const pty = getPty();
28+
29+
const { status } = await pty.spawnSafe('which pnpm');
30+
if (status === 'error') {
31+
return null;
32+
}
33+
34+
// Return a specific version if it's required from the user.
35+
if (parameters.version) {
36+
const { data } = await pty.spawn('pnpm --version');
37+
return { version: data }
38+
}
39+
40+
return parameters;
41+
42+
}
43+
44+
async create(plan: CreatePlan<PnpmConfig>): Promise<void> {
45+
const specificVersion = plan.desiredConfig.version;
46+
47+
specificVersion
48+
? await codifySpawn(`curl -fsSL https://get.pnpm.io/install.sh | env PNPM_VERSION=${specificVersion} sh -`)
49+
: await codifySpawn('curl -fsSL https://get.pnpm.io/install.sh | sh -')
50+
}
51+
52+
async destroy(plan: DestroyPlan<PnpmConfig>): Promise<void> {
53+
const { data: pnpmLocation } = await codifySpawn('which pnpm');
54+
if (pnpmLocation.trim().toLowerCase() !== path.join(os.homedir(), 'Library', 'pnpm', 'pnpm').trim().toLowerCase()) {
55+
throw new Error('pnpm was installed outside of Codify. Please uninstall manually and re-run Codify');
56+
}
57+
58+
const { data: pnpmHome } = await codifySpawn('echo $PNPM_HOME', { throws: false });
59+
if (!pnpmHome) {
60+
throw new Error('$PNPM_HOME variable is not set. Unable to determine how to uninstall pnpm. Please uninstall manually and re-run Codify.')
61+
}
62+
63+
await fs.rm(pnpmHome, { recursive: true, force: true });
64+
console.log('Successfully uninstalled pnpm');
65+
66+
await FileUtils.removeLineFromZshrc('# pnpm')
67+
await FileUtils.removeLineFromZshrc(`export PNPM_HOME="${os.homedir()}/Library/pnpm"`)
68+
await FileUtils.removeFromFile(path.join(os.homedir(), '.zshrc'),
69+
`case ":$PATH:" in
70+
*":$PNPM_HOME:"*) ;;
71+
*) export PATH="$PNPM_HOME:$PATH" ;;
72+
esac`)
73+
await FileUtils.removeLineFromZshrc('# pnpm end')
74+
}
75+
}

test/node/pnpm/pnpm.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { PluginTester } from 'codify-plugin-test';
3+
import path from 'node:path';
4+
import fs from 'node:fs';
5+
import os from 'node:os';
6+
7+
describe('Pnpm tests', () => {
8+
const pluginPath = path.resolve('./src/index.ts');
9+
10+
it('Can install and uninstall pnpm', { timeout: 300000 }, async () => {
11+
await PluginTester.fullTest(pluginPath, [
12+
{ type: 'pnpm' },
13+
], {
14+
validateDestroy: async () => {
15+
const zshFile = fs.readFileSync(path.join(os.homedir(), '.zshrc'), 'utf8')
16+
expect(zshFile.trim()).to.eq('');
17+
}
18+
})
19+
})
20+
})

0 commit comments

Comments
 (0)