Skip to content

Commit 5fa5c87

Browse files
committed
feat: Add pip-sync resource + added schema for pip
1 parent 2182dc7 commit 5fa5c87

File tree

6 files changed

+167
-6
lines changed

6 files changed

+167
-6
lines changed

src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import { JenvResource } from './resources/java/jenv/jenv.js';
1717
import { NvmResource } from './resources/node/nvm/nvm.js';
1818
import { Pnpm } from './resources/node/pnpm/pnpm.js';
1919
import { PgcliResource } from './resources/pgcli/pgcli.js';
20-
import { PipResource } from './resources/python/pip/pip.js';
20+
import { Pip } from './resources/python/pip/pip.js';
21+
import { PipSync } from './resources/python/pip-sync/pip-sync.js';
2122
import { PyenvResource } from './resources/python/pyenv/pyenv.js';
2223
import { VenvProject } from './resources/python/venv/venv-project.js';
2324
import { Virtualenv } from './resources/python/virtualenv/virtualenv.js';
@@ -67,6 +68,7 @@ runPlugin(Plugin.create(
6768
new Pnpm(),
6869
new WaitGithubSshKey(),
6970
new VenvProject(),
70-
new PipResource(),
71+
new Pip(),
72+
new PipSync()
7173
])
7274
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema",
3+
"$id": "https://www.codifycli.com/pip-sync.json",
4+
"title": "Pip-sync resource",
5+
"type": "object",
6+
"description": "Install and manage though pip-tools by installing + uninstalling packages using pip-sync",
7+
"properties": {
8+
"virtualEnv": {
9+
"type": "string",
10+
"description": "A virtual env to activate before issuing commands."
11+
},
12+
"requirementFiles": {
13+
"type": "array",
14+
"items": { "type": "string" },
15+
"description": "A list of requirement files to supply pip-sync."
16+
},
17+
"cwd": {
18+
"type": "string",
19+
"description": "The working directory to run commands from. If cwd is supplied, the other parameters can be specified as relative to cwd."
20+
}
21+
},
22+
"additionalProperties": false,
23+
"required": ["requirementFiles"]
24+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { CreatePlan, DestroyPlan, RefreshContext, Resource, ResourceSettings, getPty } from 'codify-plugin-lib';
2+
import { ResourceConfig } from 'codify-schemas';
3+
4+
import { codifySpawn } from '../../../utils/codify-spawn.js';
5+
import schema from './pip-sync-schema.json'
6+
import { RequirementFilesParameter } from './requirement-files-parameter.js';
7+
8+
export interface PipSyncConfig extends ResourceConfig {
9+
requirementFiles: string[];
10+
virtualEnv?: string;
11+
cwd?: string;
12+
}
13+
14+
export class PipSync extends Resource<PipSyncConfig> {
15+
getSettings(): ResourceSettings<PipSyncConfig> {
16+
return {
17+
id: 'pip-sync',
18+
schema,
19+
parameterSettings: {
20+
requirementFiles: { type: 'stateful', definition: new RequirementFilesParameter() },
21+
virtualEnv: { type: 'directory', setting: true },
22+
cwd: { type: 'directory', setting: true }
23+
},
24+
dependencies: ['pyenv', 'pip', 'venv-project', 'virtualenv-project', 'virtualenv'],
25+
allowMultiple: {
26+
identifyingParameters: ['virtualEnv'],
27+
}
28+
};
29+
}
30+
31+
async refresh(parameters: Partial<PipSyncConfig>, context: RefreshContext<PipSyncConfig>): Promise<Partial<PipSyncConfig> | Partial<PipSyncConfig>[] | null> {
32+
const pty = getPty()
33+
34+
const { status: pipStatus } = await pty.spawnSafe(PipSync.withVirtualEnv('which pip', parameters.virtualEnv), { cwd: parameters.cwd ?? undefined });
35+
if (pipStatus === 'error') {
36+
return null;
37+
}
38+
39+
const { status: pipSyncStatus } = await pty.spawnSafe(PipSync.withVirtualEnv('which pip-sync', parameters.virtualEnv), { cwd: parameters.cwd ?? undefined })
40+
return pipSyncStatus === 'error' ? null : parameters;
41+
}
42+
43+
async create(plan: CreatePlan<PipSyncConfig>): Promise<void> {
44+
await codifySpawn(PipSync.withVirtualEnv('pip install pip-tools'), { cwd: plan.desiredConfig.cwd ?? undefined })
45+
}
46+
47+
async destroy(plan: DestroyPlan<PipSyncConfig>): Promise<void> {
48+
await codifySpawn(PipSync.withVirtualEnv('pip uninstall -y pip-tools'), { cwd: plan.currentConfig.cwd ?? undefined })
49+
}
50+
51+
static withVirtualEnv(command: string, virtualEnv?: string, ): string {
52+
if (!virtualEnv) {
53+
return command;
54+
}
55+
56+
return `source ${virtualEnv}/bin/activate; ${command}; deactivate`;
57+
}
58+
59+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ArrayParameterSetting, Plan, StatefulParameter, getPty } from 'codify-plugin-lib';
2+
3+
import { codifySpawn } from '../../../utils/codify-spawn.js';
4+
import { PipSync, PipSyncConfig } from './pip-sync.js';
5+
6+
export class RequirementFilesParameter extends StatefulParameter<PipSyncConfig, string[]> {
7+
getSettings(): ArrayParameterSetting {
8+
return {
9+
type: 'array',
10+
itemType: 'directory',
11+
canModify: true,
12+
}
13+
}
14+
15+
async refresh(desired: null | string[], config: Partial<PipSyncConfig>): Promise<null | string[]> {
16+
if (!desired || desired?.length === 0) {
17+
return null;
18+
}
19+
20+
const pty = getPty();
21+
const { status } = await pty.spawnSafe(PipSync.withVirtualEnv(`pip-sync -n ${desired?.join(' ')}`), { cwd: config.cwd ?? undefined })
22+
return status === 'error' ? null : desired;
23+
}
24+
25+
async add(valueToAdd: string[], plan: Plan<PipSyncConfig>): Promise<void> {
26+
await codifySpawn(PipSync.withVirtualEnv(`pip-sync ${valueToAdd.join(' ')}`), { cwd: plan.desiredConfig?.cwd ?? undefined })
27+
}
28+
29+
async modify(newValue: string[], _: string[], plan: Plan<PipSyncConfig>): Promise<void> {
30+
await codifySpawn(PipSync.withVirtualEnv(`pip-sync ${newValue.join(' ')}`), { cwd: plan.desiredConfig?.cwd ?? undefined })
31+
}
32+
33+
async remove(valueToRemove: string[], plan: Plan<PipSyncConfig>): Promise<void> {
34+
await codifySpawn(PipSync.withVirtualEnv(`pip-sync ${valueToRemove.join(' ')}`), { cwd: plan.currentConfig?.cwd ?? undefined })
35+
}
36+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema",
3+
"$id": "https://www.codifycli.com/pip.json",
4+
"title": "Pip resource",
5+
"type": "object",
6+
"description": "Install and manage packages using pip",
7+
"properties": {
8+
"virtualEnv": {
9+
"type": "string",
10+
"description": "A virtual env to activate before issuing pip commands."
11+
},
12+
"install": {
13+
"type": "array",
14+
"description": "Packages to install.",
15+
"items": {
16+
"oneOf": [
17+
{
18+
"type": "string"
19+
},
20+
{
21+
"type": "object",
22+
"properties": {
23+
"name": {
24+
"type": "string"
25+
},
26+
"version": {
27+
"type": "string"
28+
}
29+
},
30+
"required": ["name"]
31+
}
32+
]
33+
}
34+
}
35+
},
36+
"additionalProperties": false,
37+
"required": ["install"]
38+
}

src/resources/python/pip/pip.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import {
22
CreatePlan,
33
DestroyPlan,
4-
getPty,
54
ModifyPlan,
65
ParameterChange,
76
Resource,
8-
ResourceSettings
7+
ResourceSettings,
8+
getPty
99
} from 'codify-plugin-lib';
1010
import { ResourceConfig } from 'codify-schemas';
1111

1212
import { codifySpawn } from '../../../utils/codify-spawn.js';
13+
import schema from './pip-schema.json';
1314

1415
interface PipListResult {
1516
name: string;
@@ -21,11 +22,12 @@ export interface PipResourceConfig extends ResourceConfig {
2122
virtualEnv?: string,
2223
}
2324

24-
export class PipResource extends Resource<PipResourceConfig> {
25+
export class Pip extends Resource<PipResourceConfig> {
2526

2627
getSettings(): ResourceSettings<PipResourceConfig> {
2728
return {
2829
id: 'pip',
30+
schema,
2931
parameterSettings: {
3032
install: {
3133
type: 'array',
@@ -35,7 +37,7 @@ export class PipResource extends Resource<PipResourceConfig> {
3537
filterInStatelessMode: (desired, current) =>
3638
current.filter((c) => desired.find((d) => this.isSame(c, d)))
3739
},
38-
virtualEnv: { type: 'directory' }
40+
virtualEnv: { type: 'directory', setting: true }
3941
},
4042
allowMultiple: {
4143
identifyingParameters: ['virtualEnv']

0 commit comments

Comments
 (0)