Skip to content

Commit 52293f4

Browse files
authored
feat: pnpm and uv support (#672)
* feat: adds uv and pnpm support * chore: patching test * chore: patching test * chore: patching tests * fix: enhances project bootstrapping logic Refactors project bootstrapping to improve package manager selection and installation. - Streamlines PNPM installation by leveraging its automatic CI environment detection. - Improves UV installation on Unix systems using `proc.run` with `sh -c` for safer pipe handling. - Enhances package manager selection by clarifying fallback behavior for interactive prompts and saving user preferences. - Adds unit tests to validate package manager precedence hierarchy logic. * refactor: global poetry version output scrubber; git output scrubber * ci: retrigger workflow
1 parent 44c84ab commit 52293f4

File tree

94 files changed

+1258
-94
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+1258
-94
lines changed

docs/cli/index.md

Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@
3535
- [-f, --force](#-f---force)
3636
- [Arguments](#arguments-4)
3737
- [ENGINE](#engine)
38-
- [version-prompt](#version-prompt)
38+
- [js-package-manager](#js-package-manager)
3939
- [Arguments](#arguments-5)
40+
- [PACKAGE_MANAGER](#package_manager)
41+
- [py-package-manager](#py-package-manager)
42+
- [Arguments](#arguments-6)
43+
- [PACKAGE_MANAGER](#package_manager-1)
44+
- [version-prompt](#version-prompt)
45+
- [Arguments](#arguments-7)
4046
- [ENABLE](#enable)
4147
- [dispenser](#dispenser)
4248
- [fund](#fund)
@@ -60,22 +66,22 @@
6066
- [Options](#options-9)
6167
- [-c, --copy-to-clipboard](#-c---copy-to-clipboard)
6268
- [explore](#explore)
63-
- [Arguments](#arguments-6)
69+
- [Arguments](#arguments-8)
6470
- [NETWORK](#network)
6571
- [generate](#generate)
6672
- [client](#client)
6773
- [Options](#options-10)
6874
- [-o, --output ](#-o---output--1)
6975
- [-l, --language ](#-l---language-)
7076
- [-v, --version ](#-v---version--1)
71-
- [Arguments](#arguments-7)
77+
- [Arguments](#arguments-9)
7278
- [APP_SPEC_PATH_OR_DIR](#app_spec_path_or_dir)
7379
- [ARGS](#args)
7480
- [goal](#goal)
7581
- [Options](#options-11)
7682
- [--console](#--console)
7783
- [--interactive](#--interactive)
78-
- [Arguments](#arguments-8)
84+
- [Arguments](#arguments-10)
7985
- [GOAL_ARGS](#goal_args)
8086
- [init](#init)
8187
- [Options](#options-12)
@@ -93,7 +99,7 @@
9399
- [example](#example)
94100
- [Options](#options-13)
95101
- [-l, --list](#-l---list)
96-
- [Arguments](#arguments-9)
102+
- [Arguments](#arguments-11)
97103
- [EXAMPLE_ID](#example_id)
98104
- [localnet](#localnet)
99105
- [codespace](#codespace)
@@ -109,7 +115,7 @@
109115
- [config](#config-1)
110116
- [Options](#options-15)
111117
- [-f, --force](#-f---force-2)
112-
- [Arguments](#arguments-10)
118+
- [Arguments](#arguments-12)
113119
- [ENGINE](#engine-1)
114120
- [console](#console)
115121
- [explore](#explore-1)
@@ -141,44 +147,46 @@
141147
- [--interactive, --non-interactive, --ci](#--interactive---non-interactive---ci)
142148
- [Options](#options-22)
143149
- [--ci, --no-ci](#--ci---no-ci)
144-
- [deploy](#deploy)
145150
- [Options](#options-23)
151+
- [--ci, --no-ci](#--ci---no-ci-1)
152+
- [deploy](#deploy)
153+
- [Options](#options-24)
146154
- [-C, -c, --command ](#-c--c---command-)
147155
- [--interactive, --non-interactive, --ci](#--interactive---non-interactive---ci-1)
148156
- [-P, --path ](#-p---path-)
149157
- [--deployer ](#--deployer-)
150158
- [--dispenser ](#--dispenser-)
151159
- [-p, --project-name ](#-p---project-name--1)
152-
- [Arguments](#arguments-11)
160+
- [Arguments](#arguments-13)
153161
- [ENVIRONMENT_NAME](#environment_name)
154162
- [EXTRA_ARGS](#extra_args)
155163
- [link](#link)
156-
- [Options](#options-24)
164+
- [Options](#options-25)
157165
- [-p, --project-name ](#-p---project-name--2)
158166
- [-l, --language ](#-l---language--1)
159167
- [-a, --all](#-a---all)
160168
- [-f, --fail-fast](#-f---fail-fast)
161169
- [-v, --version ](#-v---version--2)
162170
- [list](#list)
163-
- [Arguments](#arguments-12)
171+
- [Arguments](#arguments-14)
164172
- [WORKSPACE_PATH](#workspace_path)
165173
- [run](#run)
166174
- [task](#task)
167175
- [analyze](#analyze)
168-
- [Options](#options-25)
176+
- [Options](#options-26)
169177
- [-r, --recursive](#-r---recursive)
170178
- [--force](#--force-2)
171179
- [--diff](#--diff)
172180
- [-o, --output ](#-o---output--2)
173181
- [-e, --exclude ](#-e---exclude-)
174-
- [Arguments](#arguments-13)
182+
- [Arguments](#arguments-15)
175183
- [INPUT_PATHS](#input_paths)
176184
- [ipfs](#ipfs)
177-
- [Options](#options-26)
185+
- [Options](#options-27)
178186
- [-f, --file ](#-f---file--1)
179187
- [-n, --name ](#-n---name--2)
180188
- [mint](#mint)
181-
- [Options](#options-27)
189+
- [Options](#options-28)
182190
- [--creator ](#--creator-)
183191
- [--name ](#--name-)
184192
- [-u, --unit ](#-u---unit-)
@@ -190,66 +198,66 @@
190198
- [--mutable, --immutable](#--mutable---immutable)
191199
- [-n, --network ](#-n---network-)
192200
- [nfd-lookup](#nfd-lookup)
193-
- [Options](#options-28)
201+
- [Options](#options-29)
194202
- [-o, --output ](#-o---output--3)
195-
- [Arguments](#arguments-14)
203+
- [Arguments](#arguments-16)
196204
- [VALUE](#value)
197205
- [opt-in](#opt-in)
198-
- [Options](#options-29)
206+
- [Options](#options-30)
199207
- [-a, --account ](#-a---account-)
200208
- [-n, --network ](#-n---network--1)
201-
- [Arguments](#arguments-15)
209+
- [Arguments](#arguments-17)
202210
- [ASSET_IDS](#asset_ids)
203211
- [opt-out](#opt-out)
204-
- [Options](#options-30)
212+
- [Options](#options-31)
205213
- [-a, --account ](#-a---account--1)
206214
- [--all](#--all)
207215
- [-n, --network ](#-n---network--2)
208-
- [Arguments](#arguments-16)
216+
- [Arguments](#arguments-18)
209217
- [ASSET_IDS](#asset_ids-1)
210218
- [send](#send)
211-
- [Options](#options-31)
219+
- [Options](#options-32)
212220
- [-f, --file ](#-f---file--2)
213221
- [-t, --transaction ](#-t---transaction-)
214222
- [-n, --network ](#-n---network--3)
215223
- [sign](#sign)
216-
- [Options](#options-32)
224+
- [Options](#options-33)
217225
- [-a, --account ](#-a---account--2)
218226
- [-f, --file ](#-f---file--3)
219227
- [-t, --transaction ](#-t---transaction--1)
220228
- [-o, --output ](#-o---output--4)
221229
- [--force](#--force-3)
222230
- [transfer](#transfer)
223-
- [Options](#options-33)
231+
- [Options](#options-34)
224232
- [-s, --sender ](#-s---sender-)
225233
- [-r, --receiver ](#-r---receiver--1)
226234
- [--asset, --id ](#--asset---id-)
227235
- [-a, --amount ](#-a---amount--1)
228236
- [--whole-units](#--whole-units-2)
229237
- [-n, --network ](#-n---network--4)
230238
- [vanity-address](#vanity-address)
231-
- [Options](#options-34)
239+
- [Options](#options-35)
232240
- [-m, --match ](#-m---match-)
233241
- [-o, --output ](#-o---output--5)
234242
- [-a, --alias ](#-a---alias-)
235243
- [--file-path ](#--file-path-)
236244
- [-f, --force](#-f---force-3)
237-
- [Arguments](#arguments-17)
245+
- [Arguments](#arguments-19)
238246
- [KEYWORD](#keyword)
239247
- [wallet](#wallet)
240-
- [Options](#options-35)
248+
- [Options](#options-36)
241249
- [-a, --address ](#-a---address-)
242250
- [-m, --mnemonic](#-m---mnemonic)
243251
- [-f, --force](#-f---force-4)
244-
- [Arguments](#arguments-18)
252+
- [Arguments](#arguments-20)
245253
- [ALIAS_NAME](#alias_name)
246-
- [Arguments](#arguments-19)
254+
- [Arguments](#arguments-21)
247255
- [ALIAS](#alias)
248-
- [Options](#options-36)
256+
- [Options](#options-37)
249257
- [-f, --force](#-f---force-5)
250-
- [Arguments](#arguments-20)
258+
- [Arguments](#arguments-22)
251259
- [ALIAS](#alias-1)
252-
- [Options](#options-37)
260+
- [Options](#options-38)
253261
- [-f, --force](#-f---force-6)
254262

255263
# algokit
@@ -430,6 +438,34 @@ Skip confirmation prompts. Defaults to 'yes' to all prompts.
430438
### ENGINE
431439
Optional argument
432440

441+
### js-package-manager
442+
443+
Set the default JavaScript package manager for use by AlgoKit CLI.
444+
445+
```shell
446+
algokit config js-package-manager [OPTIONS] [[npm|pnpm]]
447+
```
448+
449+
### Arguments
450+
451+
452+
### PACKAGE_MANAGER
453+
Optional argument
454+
455+
### py-package-manager
456+
457+
Set the default Python package manager for use by AlgoKit CLI.
458+
459+
```shell
460+
algokit config py-package-manager [OPTIONS] [[poetry|uv]]
461+
```
462+
463+
### Arguments
464+
465+
466+
### PACKAGE_MANAGER
467+
Optional argument
468+
433469
### version-prompt
434470

435471
Controls whether AlgoKit checks and prompts for new versions.
@@ -1005,6 +1041,20 @@ algokit project bootstrap npm [OPTIONS]
10051041
### --ci, --no-ci
10061042
Run 'npm ci' instead of 'npm install' in CI mode (clean install).
10071043

1044+
#### pnpm
1045+
1046+
Runs pnpm install in the current working directory to install Node.js dependencies.
1047+
1048+
```shell
1049+
algokit project bootstrap pnpm [OPTIONS]
1050+
```
1051+
1052+
### Options
1053+
1054+
1055+
### --ci, --no-ci
1056+
Run 'pnpm install --frozen-lockfile' instead of 'pnpm install' in CI mode (clean install with frozen lockfile).
1057+
10081058
#### poetry
10091059

10101060
Installs Python Poetry (if not present) and runs poetry install in the current working directory to install Python dependencies.
@@ -1013,6 +1063,14 @@ Installs Python Poetry (if not present) and runs poetry install in the current w
10131063
algokit project bootstrap poetry [OPTIONS]
10141064
```
10151065

1066+
#### uv
1067+
1068+
Installs UV (if not present) and runs uv sync in the current working directory to install Python dependencies.
1069+
1070+
```shell
1071+
algokit project bootstrap uv [OPTIONS]
1072+
```
1073+
10161074
### deploy
10171075

10181076
Deploy smart contracts from AlgoKit compliant repository.

docs/features/config.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Subcommands
99

1010
- `version-prompt`: Configure the version prompt settings.
1111
- `container-engine`: Configure the container engine settings.
12+
- `js-package-manager`: Configure the default JavaScript package manager.
13+
- `py-package-manager`: Configure the default Python package manager.
1214

1315
### Version Prompt Configuration
1416

@@ -24,13 +26,37 @@ This command configures the version prompt settings for AlgoKit.
2426
### Container Engine Configuration
2527

2628
```zsh
27-
$ algokit config container-engine [OPTIONS]
29+
$ algokit config container-engine [OPTIONS] [ENGINE]
2830
```
2931

3032
This command configures the container engine settings for AlgoKit.
3133

32-
- `--engine`, -e: Specify the container engine to use (e.g., Docker, Podman). This option is required.
33-
- `--path`, -p: Specify the path to the container engine executable. Optional.
34+
- `--force`, `-f`: Skip confirmation prompts. Defaults to 'yes' to all prompts.
35+
- `ENGINE`: Optional argument to specify the container engine (docker or podman).
36+
37+
### JavaScript Package Manager Configuration
38+
39+
```zsh
40+
$ algokit config js-package-manager [OPTIONS] [PACKAGE_MANAGER]
41+
```
42+
43+
This command configures the default JavaScript package manager used by AlgoKit's bootstrap command.
44+
45+
- `PACKAGE_MANAGER`: Optional argument to specify the package manager (npm or pnpm).
46+
47+
If no package manager is specified, AlgoKit will prompt you to select one interactively.
48+
49+
### Python Package Manager Configuration
50+
51+
```zsh
52+
$ algokit config py-package-manager [OPTIONS] [PACKAGE_MANAGER]
53+
```
54+
55+
This command configures the default Python package manager used by AlgoKit's bootstrap command.
56+
57+
- `PACKAGE_MANAGER`: Optional argument to specify the package manager (poetry or uv).
58+
59+
If no package manager is specified, AlgoKit will prompt you to select one interactively.
3460

3561
## Further Reading
3662

docs/features/project/bootstrap.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,41 @@ This is useful to allow for expedited initial setup for each developer e.g. when
66

77
It can bootstrap one or all of the following (with other options potentially being added in the future):
88

9-
- Python Poetry projects - Installs Poetry via pipx if its not present and then runs `poetry install`
10-
- Node.js project - Checks if npm is installed and runs `npm install`
9+
- Python projects - Supports Poetry and uv package managers. Installs the configured package manager if not present and runs the appropriate install command.
10+
- JavaScript/Node.js projects - Supports npm and pnpm package managers. Runs the appropriate install command for the configured package manager.
1111
- dotenv (.env) file - Checks for `.env.template` files, copies them to `.env` (which should be in `.gitignore` so developers can safely make local specific changes) and prompts for any blank values (so the developer has an easy chance to fill in their initial values where there isn't a clear default).
1212

1313
> **Note**: Invoking bootstrap from `algokit bootstrap` is not recommended. Please prefer using `algokit project bootstrap` instead.
1414
15+
You can configure which package managers are used by default via:
16+
- `algokit config py-package-manager` - Configure Python package manager (poetry or uv)
17+
- `algokit config js-package-manager` - Configure JavaScript package manager (npm or pnpm)
18+
19+
For more details, see the [configuration documentation](../config.md).
20+
21+
## Package Manager Override
22+
23+
You can override the default package manager settings on a per-project basis by adding configuration to your project's `.algokit.toml` file:
24+
25+
```toml
26+
[package_manager]
27+
python = "uv" # Override Python package manager (poetry or uv)
28+
javascript = "pnpm" # Override JavaScript package manager (npm or pnpm)
29+
```
30+
31+
This project-specific configuration takes precedence over your global settings, allowing different projects to use different package managers as needed.
32+
33+
### Configuration Precedence
34+
35+
The bootstrap command follows this precedence order when determining which package manager to use:
36+
37+
1. **Project override** - Configuration in `.algokit.toml` (highest priority)
38+
2. **User preference** - Global configuration set via `algokit config` (respects your explicit choice)
39+
3. **Smart defaults** - Based on project structure (e.g., `poetry.toml` → Poetry, `pnpm-lock.yaml` → PNPM)
40+
4. **Interactive prompt** - Asked on first use if no preference is set
41+
42+
This means if you set a global preference (e.g., `algokit config py-package-manager uv`), it will be used across all projects unless explicitly overridden at the project level. Smart defaults only apply when you haven't set a preference yet.
43+
1544
## Usage
1645

1746
Available commands and possible usage as follows:

src/algokit/cli/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import click
22

33
from algokit.core.config_commands.container_engine import container_engine_configuration_command
4+
from algokit.core.config_commands.js_package_manager import js_package_manager_configuration_command
5+
from algokit.core.config_commands.py_package_manager import py_package_manager_configuration_command
46
from algokit.core.config_commands.version_prompt import version_prompt_configuration_command
57

68

@@ -11,3 +13,5 @@ def config_group() -> None:
1113

1214
config_group.add_command(version_prompt_configuration_command)
1315
config_group.add_command(container_engine_configuration_command)
16+
config_group.add_command(js_package_manager_configuration_command)
17+
config_group.add_command(py_package_manager_configuration_command)

0 commit comments

Comments
 (0)