Skip to content

Commit f8e21cb

Browse files
committed
add support for dart as a hook language
1 parent 0f08ba7 commit f8e21cb

File tree

19 files changed

+227
-29
lines changed

19 files changed

+227
-29
lines changed

azure-pipelines.yml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ jobs:
2626
Write-Host "##vso[task.prependpath]C:\Strawberry\perl\site\bin"
2727
Write-Host "##vso[task.prependpath]C:\Strawberry\c\bin"
2828
displayName: Add strawberry perl to PATH
29-
- task: PowerShell@2
30-
inputs:
31-
filePath: "testing/get-r.ps1"
29+
- bash: testing/get-dart.sh
30+
displayName: install dart
31+
- powershell: testing/get-r.ps1
3232
displayName: install R
3333
- template: job--python-tox.yml@asottile
3434
parameters:
@@ -38,13 +38,11 @@ jobs:
3838
pre_test:
3939
- task: UseRubyVersion@0
4040
- template: step--git-install.yml
41-
- bash: |
42-
testing/get-coursier.sh
43-
echo '##vso[task.prependpath]/tmp/coursier'
41+
- bash: testing/get-coursier.sh
4442
displayName: install coursier
45-
- bash: |
46-
testing/get-swift.sh
47-
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
43+
- bash: testing/get-dart.sh
44+
displayName: install dart
45+
- bash: testing/get-swift.sh
4846
displayName: install swift
4947
- bash: testing/get-r.sh
5048
displayName: install R
@@ -54,13 +52,11 @@ jobs:
5452
os: linux
5553
pre_test:
5654
- task: UseRubyVersion@0
57-
- bash: |
58-
testing/get-coursier.sh
59-
echo '##vso[task.prependpath]/tmp/coursier'
55+
- bash: testing/get-coursier.sh
6056
displayName: install coursier
61-
- bash: |
62-
testing/get-swift.sh
63-
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
57+
- bash: testing/get-dart.sh
58+
displayName: install dart
59+
- bash: testing/get-swift.sh
6460
displayName: install swift
6561
- bash: testing/get-r.sh
6662
displayName: install R

pre_commit/languages/all.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pre_commit.hook import Hook
88
from pre_commit.languages import conda
99
from pre_commit.languages import coursier
10+
from pre_commit.languages import dart
1011
from pre_commit.languages import docker
1112
from pre_commit.languages import docker_image
1213
from pre_commit.languages import dotnet
@@ -44,6 +45,7 @@ class Language(NamedTuple):
4445
# BEGIN GENERATED (testing/gen-languages-all)
4546
'conda': Language(name='conda', ENVIRONMENT_DIR=conda.ENVIRONMENT_DIR, get_default_version=conda.get_default_version, healthy=conda.healthy, install_environment=conda.install_environment, run_hook=conda.run_hook), # noqa: E501
4647
'coursier': Language(name='coursier', ENVIRONMENT_DIR=coursier.ENVIRONMENT_DIR, get_default_version=coursier.get_default_version, healthy=coursier.healthy, install_environment=coursier.install_environment, run_hook=coursier.run_hook), # noqa: E501
48+
'dart': Language(name='dart', ENVIRONMENT_DIR=dart.ENVIRONMENT_DIR, get_default_version=dart.get_default_version, healthy=dart.healthy, install_environment=dart.install_environment, run_hook=dart.run_hook), # noqa: E501
4749
'docker': Language(name='docker', ENVIRONMENT_DIR=docker.ENVIRONMENT_DIR, get_default_version=docker.get_default_version, healthy=docker.healthy, install_environment=docker.install_environment, run_hook=docker.run_hook), # noqa: E501
4850
'docker_image': Language(name='docker_image', ENVIRONMENT_DIR=docker_image.ENVIRONMENT_DIR, get_default_version=docker_image.get_default_version, healthy=docker_image.healthy, install_environment=docker_image.install_environment, run_hook=docker_image.run_hook), # noqa: E501
4951
'dotnet': Language(name='dotnet', ENVIRONMENT_DIR=dotnet.ENVIRONMENT_DIR, get_default_version=dotnet.get_default_version, healthy=dotnet.healthy, install_environment=dotnet.install_environment, run_hook=dotnet.run_hook), # noqa: E501

pre_commit/languages/dart.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import contextlib
2+
import os.path
3+
import shutil
4+
import tempfile
5+
from typing import Generator
6+
from typing import Sequence
7+
from typing import Tuple
8+
9+
import pre_commit.constants as C
10+
from pre_commit.envcontext import envcontext
11+
from pre_commit.envcontext import PatchesT
12+
from pre_commit.envcontext import Var
13+
from pre_commit.hook import Hook
14+
from pre_commit.languages import helpers
15+
from pre_commit.prefix import Prefix
16+
from pre_commit.util import clean_path_on_failure
17+
from pre_commit.util import win_exe
18+
from pre_commit.util import yaml_load
19+
20+
ENVIRONMENT_DIR = 'dartenv'
21+
22+
get_default_version = helpers.basic_get_default_version
23+
healthy = helpers.basic_healthy
24+
25+
26+
def get_env_patch(venv: str) -> PatchesT:
27+
return (
28+
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
29+
)
30+
31+
32+
@contextlib.contextmanager
33+
def in_env(prefix: Prefix) -> Generator[None, None, None]:
34+
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
35+
envdir = prefix.path(directory)
36+
with envcontext(get_env_patch(envdir)):
37+
yield
38+
39+
40+
def install_environment(
41+
prefix: Prefix,
42+
version: str,
43+
additional_dependencies: Sequence[str],
44+
) -> None:
45+
helpers.assert_version_default('dart', version)
46+
47+
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
48+
bin_dir = os.path.join(envdir, 'bin')
49+
50+
def _install_dir(prefix_p: Prefix, pub_cache: str) -> None:
51+
dart_env = {**os.environ, 'PUB_CACHE': pub_cache}
52+
53+
with open(prefix_p.path('pubspec.yaml')) as f:
54+
pubspec_contents = yaml_load(f)
55+
56+
helpers.run_setup_cmd(prefix_p, ('dart', 'pub', 'get'), env=dart_env)
57+
58+
for executable in pubspec_contents['executables']:
59+
helpers.run_setup_cmd(
60+
prefix_p,
61+
(
62+
'dart', 'compile', 'exe',
63+
'--output', os.path.join(bin_dir, win_exe(executable)),
64+
prefix_p.path('bin', f'{executable}.dart'),
65+
),
66+
env=dart_env,
67+
)
68+
69+
with clean_path_on_failure(envdir):
70+
os.makedirs(bin_dir)
71+
72+
with tempfile.TemporaryDirectory() as tmp:
73+
_install_dir(prefix, tmp)
74+
75+
for dep_s in additional_dependencies:
76+
with tempfile.TemporaryDirectory() as dep_tmp:
77+
dep, _, version = dep_s.partition(':')
78+
if version:
79+
dep_cmd: Tuple[str, ...] = (dep, '--version', version)
80+
else:
81+
dep_cmd = (dep,)
82+
83+
helpers.run_setup_cmd(
84+
prefix,
85+
('dart', 'pub', 'cache', 'add', *dep_cmd),
86+
env={**os.environ, 'PUB_CACHE': dep_tmp},
87+
)
88+
89+
# try and find the 'pubspec.yaml' that just got added
90+
for root, _, filenames in os.walk(dep_tmp):
91+
if 'pubspec.yaml' in filenames:
92+
with tempfile.TemporaryDirectory() as copied:
93+
pkg = os.path.join(copied, 'pkg')
94+
shutil.copytree(root, pkg)
95+
_install_dir(Prefix(pkg), dep_tmp)
96+
break
97+
else:
98+
raise AssertionError(
99+
f'could not find pubspec.yaml for {dep_s}',
100+
)
101+
102+
103+
def run_hook(
104+
hook: Hook,
105+
file_args: Sequence[str],
106+
color: bool,
107+
) -> Tuple[int, bytes]:
108+
with in_env(hook.prefix):
109+
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)

pre_commit/languages/helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ def exe_exists(exe: str) -> bool:
4848
)
4949

5050

51-
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...]) -> None:
52-
cmd_output_b(*cmd, cwd=prefix.prefix_dir)
51+
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...], **kwargs: Any) -> None:
52+
cmd_output_b(*cmd, cwd=prefix.prefix_dir, **kwargs)
5353

5454

5555
@overload

pre_commit/languages/python.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from pre_commit.util import clean_path_on_failure
2222
from pre_commit.util import cmd_output
2323
from pre_commit.util import cmd_output_b
24+
from pre_commit.util import win_exe
2425

2526
ENVIRONMENT_DIR = 'py_env'
2627

@@ -172,7 +173,7 @@ def healthy(prefix: Prefix, language_version: str) -> bool:
172173
if not os.path.exists(pyvenv_cfg):
173174
return False
174175

175-
exe_name = 'python.exe' if sys.platform == 'win32' else 'python'
176+
exe_name = win_exe('python')
176177
py_exe = prefix.path(bin_dir(envdir), exe_name)
177178
cfg = _read_pyvenv_cfg(pyvenv_cfg)
178179

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: pre_commit_empty_pubspec
2+
environment:
3+
sdk: '>=2.10.0'
4+
executables: {}

pre_commit/store.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def _git_cmd(*args: str) -> None:
189189
LOCAL_RESOURCES = (
190190
'Cargo.toml', 'main.go', 'go.mod', 'main.rs', '.npmignore',
191191
'package.json', 'pre_commit_placeholder_package.gemspec', 'setup.py',
192-
'environment.yml', 'Makefile.PL',
192+
'environment.yml', 'Makefile.PL', 'pubspec.yaml',
193193
'renv.lock', 'renv/activate.R', 'renv/LICENSE.renv',
194194
)
195195

pre_commit/util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,7 @@ def handle_remove_readonly(
268268
def parse_version(s: str) -> Tuple[int, ...]:
269269
"""poor man's version comparison"""
270270
return tuple(int(p) for p in s.split('.'))
271+
272+
273+
def win_exe(s: str) -> str:
274+
return s if sys.platform != 'win32' else f'{s}.exe'

testing/gen-languages-all

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import sys
33

44
LANGUAGES = [
5-
'conda', 'coursier', 'docker', 'docker_image', 'dotnet', 'fail', 'golang',
6-
'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust', 'script',
7-
'swift', 'system',
5+
'conda', 'coursier', 'dart', 'docker', 'docker_image', 'dotnet', 'fail',
6+
'golang', 'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust',
7+
'script', 'swift', 'system',
88
]
99
FIELDS = [
1010
'ENVIRONMENT_DIR', 'get_default_version', 'healthy', 'install_environment',

testing/get-coursier.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22
# This is a script used in CI to install coursier
3-
set -euxo pipefail
3+
set -euo pipefail
44

55
COURSIER_URL="https://github.com/coursier/coursier/releases/download/v2.0.0/cs-x86_64-pc-linux"
66
COURSIER_HASH="e2e838b75bc71b16bcb77ce951ad65660c89bda7957c79a0628ec7146d35122f"
@@ -11,3 +11,5 @@ rm -f "$ARTIFACT"
1111
curl --location --silent --output "$ARTIFACT" "$COURSIER_URL"
1212
echo "$COURSIER_HASH $ARTIFACT" | sha256sum --check
1313
chmod ugo+x /tmp/coursier/cs
14+
15+
echo '##vso[task.prependpath]/tmp/coursier'

0 commit comments

Comments
 (0)