Skip to content

Commit 37e2ba8

Browse files
committed
wip
1 parent 65175f3 commit 37e2ba8

File tree

13 files changed

+134
-0
lines changed

13 files changed

+134
-0
lines changed

TODO.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### tool resolutions
2+
3+
- deterministic `node lts`
4+
- updateable
5+
6+
```sql
7+
CREATE TABLE IF NOT EXISTS tool_resolutions (
8+
tool TEXT NOT NULL,
9+
version TEXT NOT NULL,
10+
resolved TEXT NOT NULL,
11+
PRIMARY KEY (tool, version)
12+
);
13+
```
14+
15+
```console
16+
$ pre-commit tools autoupdate [--only ...] # update config override versions
17+
$ pre-commit tools resolve [--only ...] # update resolved versions
18+
```
19+
20+
```yaml
21+
# in .pre-commit-config.yaml
22+
tool_resolution:
23+
node: {lts: '24.2.0'}
24+
```

pre_commit/all_tools.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from __future__ import annotations
2+
3+
from pre_commit.tool_base import Tool
4+
from pre_commit.tools import go
5+
from pre_commit.tools import node
6+
from pre_commit.tools import python
7+
from pre_commit.tools import rbenv
8+
from pre_commit.tools import ruby
9+
from pre_commit.tools import rust
10+
from pre_commit.tools import rustup
11+
from pre_commit.tools import uv
12+
13+
14+
tools: dict[str, Tool] = {
15+
'go': go,
16+
'node': node,
17+
'python': python,
18+
'rbenv': rbenv,
19+
'ruby': ruby,
20+
'rust': rust,
21+
'rustup': rustup,
22+
'uv': uv,
23+
}

pre_commit/request.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from __future__ import annotations
2+
3+
import sys
4+
import urllib.request
5+
from typing import IO
6+
7+
from pre_commit.constants import VERSION
8+
9+
10+
def fetch(url: str) -> IO[bytes]:
11+
pyver = '.'.join(str(v) for v in sys.version_info[:3])
12+
req = urllib.request.Request(
13+
url,
14+
headers={'User-Agent': f'pre-commit/{VERSION} python/{pyver}'},
15+
)
16+
return urllib.request.urlopen(req)

pre_commit/tool_base.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from __future__ import annotations
2+
3+
from typing import Protocol
4+
5+
from pre_commit.prefix import Prefix
6+
7+
8+
class Tool(Protocol):
9+
# "special" versions which can be resolved
10+
@property
11+
def RESOLVABLE(self) -> tuple[str, ...]: ...
12+
# TODO: what if not resolvable? (no current examples?)
13+
def resolve(self, version: str) -> str: ...
14+
def install(self, prefix: Prefix, version: str) -> None: ...
15+
def health_check(self, prefix: Prefix, version: str) -> str | None: ...
16+
# TODO: how to env patch?

pre_commit/tools/__init__.py

Whitespace-only changes.

pre_commit/tools/go.py

Whitespace-only changes.

pre_commit/tools/node.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from __future__ import annotations
2+
3+
import functools
4+
import json
5+
6+
from pre_commit.prefix import Prefix
7+
from pre_commit.request import fetch
8+
9+
RESOLVABLE = ('latest', 'lts')
10+
11+
12+
@functools.cache
13+
def _node_versions() -> dict[str, str]:
14+
resp = fetch('https://nodejs.org/download/release/index.json')
15+
contents = json.load(resp)
16+
17+
ret = {'latest': contents[0]['version']}
18+
for dct in contents:
19+
if dct['lts']:
20+
ret['lts'] = dct['version']
21+
break
22+
else:
23+
raise AssertionError('unreachable')
24+
25+
return ret
26+
27+
28+
def resolve(version: str) -> str:
29+
return _node_versions()[version]
30+
31+
32+
@functools.cache
33+
def _target_platform() -> str:
34+
# to support:
35+
# linux-arm64, linux-ppc64le, linux-s390x, linux-x64
36+
# osx-arm64-tar, osx-x86-tar
37+
# win-arm64-zip, win-x64-zip
38+
# or fallback to `src` ?
39+
raise NotImplementedError
40+
41+
42+
def install(prefix: Prefix, version: str) -> None:
43+
# TODO: download and extract to prefix
44+
raise NotImplementedError
45+
46+
47+
def health_check(prefix: Prefix, version: str) -> str | None:
48+
# TODO: previously checked `node --version`
49+
# TODO: but maybe just check that the installed os/arch is correct?
50+
return None

pre_commit/tools/python.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from __future__ import annotations
2+
3+
# TODO: how to get "latest" supported uv python?
4+
# TODO: should this support `3.##` as resolvable?
5+
# TODO: how would dynamic resolvables work...

pre_commit/tools/rbenv.py

Whitespace-only changes.

pre_commit/tools/ruby.py

Whitespace-only changes.

0 commit comments

Comments
 (0)