-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuv.ts
More file actions
152 lines (129 loc) · 4.29 KB
/
Copy pathuv.ts
File metadata and controls
152 lines (129 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import {
ExampleConfig,
FileUtils,
getPty,
Resource,
ResourceSettings,
SpawnStatus,
Utils,
PackageManager,
z
} from '@codifycli/plugin-core';
import { OS } from '@codifycli/schemas';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { UvGlobalParameter } from './global-parameter.js';
import { UvPythonVersionsParameter } from './python-versions-parameter.js';
import { UvToolsParameter } from './tools-parameter.js';
const UV_LOCAL_BIN = path.join(os.homedir(), '.local', 'bin');
const UV_LOCAL_BIN_PATH_EXPORT = `export PATH="$HOME/.local/bin:$PATH"`;
const schema = z.object({
pythonVersions: z
.array(z.string())
.describe('Python versions to install via uv (e.g. ["3.12", "3.11"])')
.optional(),
global: z
.string()
.describe('Python version to set as the global default (exposes `python` and `python3` on PATH via --default flag)')
.optional(),
tools: z
.array(z.string())
.describe('Global CLI tools to install via uv tool install (e.g. ["ruff", "black"])')
.optional(),
})
.describe('uv resource — fast Python package and project manager from Astral');
export type UvConfig = z.infer<typeof schema>;
const defaultConfig: Partial<UvConfig> = {
pythonVersions: [],
tools: [],
}
const examplePython: ExampleConfig = {
title: 'Install uv with Python versions',
description: 'Install uv, pin one or more Python versions, and set one as the global default accessible as `python` on PATH.',
configs: [{
type: 'uv',
pythonVersions: ['3.12', '3.11'],
global: '3.12',
}]
}
const exampleWithTools: ExampleConfig = {
title: 'Install uv with Python and global tools',
description: 'Install uv, set a global default Python, and install commonly used global CLI tools like ruff and black.',
configs: [{
type: 'uv',
pythonVersions: ['3.12'],
global: '3.12',
tools: ['ruff', 'black', 'httpie'],
}]
}
export class UvResource extends Resource<UvConfig> {
getSettings(): ResourceSettings<UvConfig> {
return {
id: 'uv',
defaultConfig,
exampleConfigs: {
example1: examplePython,
example2: exampleWithTools,
},
operatingSystems: [OS.Darwin, OS.Linux],
schema,
removeStatefulParametersBeforeDestroy: true,
parameterSettings: {
pythonVersions: { type: 'stateful', definition: new UvPythonVersionsParameter(), order: 1 },
global: { type: 'stateful', definition: new UvGlobalParameter(), order: 2 },
tools: { type: 'stateful', definition: new UvToolsParameter(), order: 3 },
},
dependencies: [...(Utils.isMacOS() ? ['homebrew'] : [])],
};
}
async refresh(): Promise<Partial<UvConfig> | null> {
const $ = getPty();
const { status } = await $.spawnSafe('uv --version');
return status === SpawnStatus.SUCCESS ? {} : null;
}
async create(): Promise<void> {
if (Utils.isMacOS()) {
await installOnMacOS();
} else {
await installOnLinux();
}
}
async destroy(): Promise<void> {
if (Utils.isMacOS()) {
await uninstallOnMacOS();
} else {
await uninstallOnLinux();
}
}
}
async function installOnMacOS(): Promise<void> {
const $ = getPty();
await Utils.installViaPkgMgr('uv', undefined, PackageManager.BREW);
}
async function uninstallOnMacOS(): Promise<void> {
const $ = getPty();
await Utils.uninstallViaPkgMgr('uv', undefined, PackageManager.BREW);
}
async function installOnLinux(): Promise<void> {
const $ = getPty();
const { status: curlStatus } = await $.spawnSafe('which curl');
if (curlStatus === SpawnStatus.ERROR) {
await Utils.installViaPkgMgr('curl');
}
await fs.mkdir(UV_LOCAL_BIN, { recursive: true });
await $.spawn('curl -LsSf https://astral.sh/uv/install.sh | sh', {
interactive: true,
env: { UV_NO_MODIFY_PATH: '1' },
});
await FileUtils.addToShellRc(UV_LOCAL_BIN_PATH_EXPORT);
}
async function uninstallOnLinux(): Promise<void> {
const uvBin = path.join(UV_LOCAL_BIN, 'uv');
const uvxBin = path.join(UV_LOCAL_BIN, 'uvx');
await fs.rm(uvBin, { force: true });
await fs.rm(uvxBin, { force: true });
const uvDataDir = path.join(os.homedir(), '.local', 'share', 'uv');
await fs.rm(uvDataDir, { recursive: true, force: true });
await FileUtils.removeLineFromShellRc(UV_LOCAL_BIN_PATH_EXPORT);
}