Skip to main content

pre_commit_models/
config.rs

1//! Pre-commit configuration models, i.e. for `.pre-commit-config.yml`.
2//!
3//! See: <https://pre-commit.com/#plugins>
4
5use crate::common;
6use indexmap::IndexMap;
7
8/// A single pre-commit configuration, containing one or more repositories,
9/// each of which may reference one or more hooks.
10#[derive(Debug, serde::Deserialize)]
11#[serde(rename_all = "snake_case")]
12pub struct Config {
13    /// A list of repository mappings.
14    #[serde(deserialize_with = "common::non_empty_vec")]
15    pub repos: Vec<Repo>,
16    /// An optional list of `--hook-types`.
17    ///
18    /// If not supplied, this defaults to `[pre-commit]`.
19    ///
20    // TODO: Model that?
21    pub default_install_hook_types: Option<Vec<String>>,
22
23    /// A mapping from language to the default language version that
24    /// should be used for that language, if a hook does not supply its
25    /// own `language_version`.
26    #[serde(default)]
27    pub default_language_version: IndexMap<String, String>,
28
29    /// The `stages` property for a hook, if a hook does not supply its
30    /// own `stages`.
31    pub default_stages: Option<Vec<String>>,
32
33    /// The global file include pattern.
34    #[serde(default)]
35    pub files: String,
36
37    /// The global file exclude pattern.
38    #[serde(default)]
39    pub exclude: String,
40
41    /// Whether to have pre-commit stop running hooks after the first
42    /// failure.
43    #[serde(default)]
44    pub fail_fast: bool,
45
46    /// The minimum version of pre-commit required.
47    #[serde(default = "common::default_minimum_pre_commit_version")]
48    pub minimum_pre_commit_version: String,
49}
50
51/// A repository, i.e. where to get one or more hooks from.
52///
53/// This concept is slightly overloaded in pre-commit, as there are
54/// two special sentinel "repository" types, `local`, and `meta`, which
55/// have a different shape than a normal Git repository.
56#[derive(Debug, serde::Deserialize)]
57#[serde(
58    rename_all = "snake_case",
59    rename_all_fields = "snake_case",
60    tag = "repo"
61)]
62pub enum Repo {
63    /// A special 'local' repository, for hooks defined within the current Git repository.
64    ///
65    /// See: <https://pre-commit.com/#repository-local-hooks>
66    // TODO: Fill this in. It's seemingly identical to a normal hook,
67    // except without `rev`.
68    Local {},
69    /// A special 'meta' repository, for hooks defined by pre-commit itself.
70    ///
71    /// See: <https://pre-commit.com/#meta-hooks>
72    // TODO: Fill this in, it's a fixed set of IDs for hooks.
73    Meta {},
74    /// A special 'builtin` repository, for hooks defined by prek itself.
75    ///
76    /// This is a prek-specific extension.
77    ///
78    /// See: <https://prek.j178.dev/builtin/#2-explicit-builtin-repository>
79    Builtin {},
80    #[serde(untagged)]
81    Remote(RemoteRepo),
82}
83
84/// A remote repository reference, i.e. the home of one or more pre-commit hooks.
85///
86/// This reference is only "remote" in the sense that it's sourced via a URL.
87/// However, that URL could be `file://` or anything else.
88#[derive(Debug, serde::Deserialize)]
89#[serde(rename_all = "snake_case")]
90pub struct RemoteRepo {
91    pub repo: url::Url,
92    pub rev: String,
93    #[serde(deserialize_with = "common::non_empty_vec")]
94    pub hooks: Vec<Hook>,
95}
96
97/// A single hook.
98#[derive(Debug, serde::Deserialize)]
99#[serde(rename_all = "snake_case")]
100pub struct Hook {
101    /// The ID of the hook to use.
102    pub id: String,
103
104    /// An optional additional ID to use when referring to the hook.
105    pub alias: Option<String>,
106
107    /// Overrides the name of the hook, as shown during execution.
108    pub name: Option<String>,
109
110    /// Overrides the language version for the hook.
111    pub language_version: Option<String>,
112
113    /// Overrides the files pattern for the hook.
114    pub files: Option<String>,
115
116    /// Overrides the exclude pattern for the hook.
117    pub exclude: Option<String>,
118
119    /// Overrides the default file types to run on for the hook (AND).
120    pub types: Option<Vec<String>>,
121
122    /// Overrides the default file types to run on for the hook (OR).
123    pub types_or: Option<Vec<String>>,
124
125    /// Overrides the types to exclude for the hook.
126    pub exclude_types: Option<Vec<String>>,
127
128    /// Optional list of additional args to supply to the hook.
129    #[serde(default)]
130    pub args: Vec<String>,
131
132    /// Overrides the set of stages to run the hook for.
133    pub stages: Option<Vec<String>>,
134
135    /// Additional dependencies to install into the hook's environment.
136    #[serde(default)]
137    pub additional_dependencies: Vec<String>,
138
139    /// If true, run the hook even when there are no matching files.
140    #[serde(default)]
141    pub always_run: bool,
142
143    /// If true, force the hook's output to be printed even if it passes.
144    #[serde(default)]
145    pub verbose: bool,
146
147    /// If present, additionally append the hook's log output to this file.
148    #[serde(default)]
149    pub log_file: Option<String>,
150}