Skip to content

Commit 065504d

Browse files
authored
Merge pull request pre-commit#751 from chriskuehl/rust
Add Rust support
2 parents c3d1f84 + 5ac2ba0 commit 065504d

12 files changed

Lines changed: 191 additions & 0 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ before_install:
2424
fi
2525
- git --version
2626
- './get-swift.sh && export PATH="/tmp/swift/usr/bin:$PATH"'
27+
- 'curl -sSf https://sh.rustup.rs | bash -s -- -y'
28+
- export PATH="$HOME/.cargo/bin:$PATH"
2729
after_success: coveralls
2830
cache:
2931
directories:

appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ install:
1111
- pip install tox virtualenv --upgrade
1212
- "mkdir -p C:\\Temp"
1313
- "SET TMPDIR=C:\\Temp"
14+
- "curl -sSf https://sh.rustup.rs | bash -s -- -y"
15+
- "SET PATH=%USERPROFILE%\\.cargo\\bin;%PATH%"
1416

1517
# Not a C# project
1618
build: false

pre_commit/languages/all.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pre_commit.languages import python
1010
from pre_commit.languages import python_venv
1111
from pre_commit.languages import ruby
12+
from pre_commit.languages import rust
1213
from pre_commit.languages import script
1314
from pre_commit.languages import swift
1415
from pre_commit.languages import system
@@ -60,6 +61,7 @@
6061
'python': python,
6162
'python_venv': python_venv,
6263
'ruby': ruby,
64+
'rust': rust,
6365
'script': script,
6466
'swift': swift,
6567
'system': system,

pre_commit/languages/rust.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from __future__ import unicode_literals
2+
3+
import contextlib
4+
import os.path
5+
6+
import toml
7+
8+
from pre_commit.envcontext import envcontext
9+
from pre_commit.envcontext import Var
10+
from pre_commit.languages import helpers
11+
from pre_commit.util import clean_path_on_failure
12+
from pre_commit.util import cmd_output
13+
from pre_commit.xargs import xargs
14+
15+
16+
ENVIRONMENT_DIR = 'rustenv'
17+
get_default_version = helpers.basic_get_default_version
18+
healthy = helpers.basic_healthy
19+
20+
21+
def get_env_patch(target_dir):
22+
return (
23+
(
24+
'PATH',
25+
(os.path.join(target_dir, 'bin'), os.pathsep, Var('PATH')),
26+
),
27+
)
28+
29+
30+
@contextlib.contextmanager
31+
def in_env(prefix):
32+
target_dir = prefix.path(
33+
helpers.environment_dir(ENVIRONMENT_DIR, 'default'),
34+
)
35+
with envcontext(get_env_patch(target_dir)):
36+
yield
37+
38+
39+
def _add_dependencies(cargo_toml_path, additional_dependencies):
40+
with open(cargo_toml_path, 'r+') as f:
41+
cargo_toml = toml.load(f)
42+
cargo_toml.setdefault('dependencies', {})
43+
for dep in additional_dependencies:
44+
name, _, spec = dep.partition(':')
45+
cargo_toml['dependencies'][name] = spec or '*'
46+
f.seek(0)
47+
toml.dump(cargo_toml, f)
48+
f.truncate()
49+
50+
51+
def install_environment(prefix, version, additional_dependencies):
52+
helpers.assert_version_default('rust', version)
53+
directory = prefix.path(
54+
helpers.environment_dir(ENVIRONMENT_DIR, 'default'),
55+
)
56+
57+
# There are two cases where we might want to specify more dependencies:
58+
# as dependencies for the library being built, and as binary packages
59+
# to be `cargo install`'d.
60+
#
61+
# Unlike e.g. Python, if we just `cargo install` a library, it won't be
62+
# used for compilation. And if we add a crate providing a binary to the
63+
# `Cargo.toml`, the binary won't be built.
64+
#
65+
# Because of this, we allow specifying "cli" dependencies by prefixing
66+
# with 'cli:'.
67+
cli_deps = {
68+
dep for dep in additional_dependencies if dep.startswith('cli:')
69+
}
70+
lib_deps = set(additional_dependencies) - cli_deps
71+
72+
if len(lib_deps) > 0:
73+
_add_dependencies(prefix.path('Cargo.toml'), lib_deps)
74+
75+
with clean_path_on_failure(directory):
76+
packages_to_install = {()}
77+
for cli_dep in cli_deps:
78+
cli_dep = cli_dep[len('cli:'):]
79+
package, _, version = cli_dep.partition(':')
80+
if version != '':
81+
packages_to_install.add((package, '--version', version))
82+
else:
83+
packages_to_install.add((package,))
84+
85+
for package in packages_to_install:
86+
cmd_output(
87+
'cargo', 'install', '--bins', '--root', directory, *package,
88+
cwd=prefix.prefix_dir
89+
)
90+
91+
92+
def run_hook(prefix, hook, file_args):
93+
with in_env(prefix):
94+
return xargs(helpers.to_cmd(hook), file_args)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "__fake_crate"
3+
version = "0.0.0"
4+
5+
[[bin]]
6+
name = "__fake_cmd"
7+
path = "main.rs"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
'nodeenv>=0.11.1',
4343
'pyyaml',
4444
'six',
45+
'toml',
4546
'virtualenv',
4647
],
4748
entry_points={
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- id: rust-hook
2+
name: rust example hook
3+
entry: rust-hello-world
4+
language: rust
5+
files: ''

testing/resources/rust_hooks_repo/Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[package]
2+
name = "rust-hello-world"
3+
version = "0.1.0"

0 commit comments

Comments
 (0)