pre-commit-localupdate 0.4.1__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/PKG-INFO +38 -22
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/README.md +36 -20
- pre_commit_localupdate-0.5.1/pre_commit_localupdate/__init__.py +1 -0
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/__main__.py +9 -3
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/cli.py +31 -3
- pre_commit_localupdate-0.5.1/pre_commit_localupdate/io.py +121 -0
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/golang.py +16 -32
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/julia.py +44 -37
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/node.py +24 -38
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/package.py +18 -8
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/python.py +18 -32
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/rust.py +17 -28
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/pre_commit_config.py +43 -59
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pyproject.toml +2 -2
- pre_commit_localupdate-0.4.1/pre_commit_localupdate/__init__.py +0 -1
- pre_commit_localupdate-0.4.1/pre_commit_localupdate/io.py +0 -53
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/LICENSE +0 -0
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/error.py +0 -0
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/logs.py +0 -0
- {pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/packages/__init__.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pre-commit-localupdate
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A CLI tool to automatically update additional dependencies within local
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: A CLI tool to automatically update additional dependencies within local hooks in pre-commit config files.
|
|
5
5
|
Author: M. Farzalipour Tabriz
|
|
6
6
|
Classifier: Development Status :: 3 - Alpha
|
|
7
7
|
Classifier: Environment :: Console
|
|
@@ -16,7 +16,7 @@ Description-Content-Type: text/markdown
|
|
|
16
16
|
|
|
17
17
|
# pre-commit-localupdate
|
|
18
18
|
|
|
19
|
-
A CLI tool to automatically update dependencies in `pre-commit-config.yml` files. It specifically targets `additional_dependencies` within local
|
|
19
|
+
A CLI tool to automatically update dependencies in `pre-commit-config.yml` files. It specifically targets `additional_dependencies` within local hooks to ensure your tooling stays up-to-date. It also adds version to unversioned packages and pins exact version of loosely defined ones. You can also pin a specific package to an older version by adding a `# freeze` comment.
|
|
20
20
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
@@ -34,20 +34,25 @@ pre-commit-localupdate
|
|
|
34
34
|
|
|
35
35
|
All options:
|
|
36
36
|
|
|
37
|
-
```
|
|
38
|
-
usage: pre-commit-localupdate [-h] [--debug] [--dry-run] [-c CONFIG] [--timeout TIMEOUT]
|
|
37
|
+
```text
|
|
38
|
+
usage: pre-commit-localupdate [-h] [--debug] [--dry-run] [-c PRE-COMMIT-CONFIG] [--timeout TIMEOUT]
|
|
39
|
+
[--indent-mapping INDENT_MAPPING] [--indent-sequence INDENT_SEQUENCE]
|
|
40
|
+
[--indent-offset INDENT_OFFSET] [--line-width LINE_WIDTH] [--version]
|
|
39
41
|
|
|
40
|
-
Automatically update additional dependencies within local
|
|
41
|
-
file.
|
|
42
|
+
Automatically update additional dependencies within local hooks in a pre-commit config file.
|
|
42
43
|
|
|
43
44
|
options:
|
|
44
|
-
-h, --help
|
|
45
|
-
--debug
|
|
46
|
-
--dry-run
|
|
47
|
-
|
|
48
|
-
-c, --config CONFIG
|
|
49
|
-
--timeout TIMEOUT
|
|
50
|
-
--
|
|
45
|
+
-h, --help show this help message and exit
|
|
46
|
+
--debug enable debug logging (default: False)
|
|
47
|
+
--dry-run dry run mode. Do not update the file and exit with a non-zero code if the
|
|
48
|
+
configuration file require an update. (default: False)
|
|
49
|
+
-c, --config PRE-COMMIT-CONFIG pre-commit config file path (default: .pre-commit-config.yaml)
|
|
50
|
+
--timeout TIMEOUT connection timeout in seconds (default: 10)
|
|
51
|
+
--indent-mapping INDENT_MAPPING YAML indentation for mappings (default: 2)
|
|
52
|
+
--indent-sequence INDENT_SEQUENCE YAML indentation for sequences (default: 4)
|
|
53
|
+
--indent-offset INDENT_OFFSET YAML indentation offset (default: 2)
|
|
54
|
+
--line-width LINE_WIDTH maximum line width (default: 80)
|
|
55
|
+
--version show program's version number and exit
|
|
51
56
|
```
|
|
52
57
|
|
|
53
58
|
## Example
|
|
@@ -70,7 +75,7 @@ repos:
|
|
|
70
75
|
# All comment are preserved
|
|
71
76
|
- id: black
|
|
72
77
|
name: black
|
|
73
|
-
description: "
|
|
78
|
+
description: "Length of strings is automatically adjusted based on the value of --line-width"
|
|
74
79
|
entry: black
|
|
75
80
|
language: python
|
|
76
81
|
minimum_pre_commit_version: 2.9.2
|
|
@@ -84,7 +89,7 @@ repos:
|
|
|
84
89
|
|
|
85
90
|
- id: julia-format
|
|
86
91
|
name: format julia code
|
|
87
|
-
description:
|
|
92
|
+
description: Unicodeテキストは保持されます。
|
|
88
93
|
language: julia
|
|
89
94
|
types: [julia]
|
|
90
95
|
entry: tools/formatter.jl
|
|
@@ -120,8 +125,8 @@ repos:
|
|
|
120
125
|
# All comment are preserved
|
|
121
126
|
- id: black
|
|
122
127
|
name: black
|
|
123
|
-
description: "
|
|
124
|
-
|
|
128
|
+
description: "Length of strings is automatically adjusted based on the value
|
|
129
|
+
of --line-width"
|
|
125
130
|
entry: black
|
|
126
131
|
language: python
|
|
127
132
|
minimum_pre_commit_version: 2.9.2
|
|
@@ -135,7 +140,7 @@ repos:
|
|
|
135
140
|
|
|
136
141
|
- id: julia-format
|
|
137
142
|
name: format julia code
|
|
138
|
-
description:
|
|
143
|
+
description: Unicodeテキストは保持されます。
|
|
139
144
|
language: julia
|
|
140
145
|
types: [julia]
|
|
141
146
|
entry: tools/formatter.jl
|
|
@@ -153,14 +158,25 @@ repos:
|
|
|
153
158
|
additional_dependencies: ["cli:mdbook-lint:0.14.2"]
|
|
154
159
|
```
|
|
155
160
|
|
|
161
|
+
## Supported Languages
|
|
162
|
+
|
|
163
|
+
Following local hook languages are currently supported:
|
|
164
|
+
|
|
165
|
+
- Go (golang)
|
|
166
|
+
- Julia
|
|
167
|
+
- Node.js (node)
|
|
168
|
+
- Python
|
|
169
|
+
- Rust
|
|
170
|
+
|
|
156
171
|
## Formatting
|
|
157
172
|
|
|
158
|
-
|
|
173
|
+
Significant effort has been made to ensure `pre-commit-localupdate` maintains the original style and preserves comments in pre-commit configuration files. However, since the current version of the underlying library does not perfectly preserve the original YAML file format after processing, `pre-commit-localupdate` automatically folds long string values (like descriptions) and enforces block indentation by default when updating files to enhance readability. Both behaviors can be adjusted using command-line parameters.
|
|
159
174
|
|
|
160
175
|
## Requirements
|
|
161
176
|
|
|
162
|
-
-
|
|
163
|
-
- requests
|
|
177
|
+
- `packaging`
|
|
178
|
+
- `requests`
|
|
179
|
+
- `ruamel.yaml`
|
|
164
180
|
|
|
165
181
|
## License
|
|
166
182
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pre-commit-localupdate
|
|
2
2
|
|
|
3
|
-
A CLI tool to automatically update dependencies in `pre-commit-config.yml` files. It specifically targets `additional_dependencies` within local
|
|
3
|
+
A CLI tool to automatically update dependencies in `pre-commit-config.yml` files. It specifically targets `additional_dependencies` within local hooks to ensure your tooling stays up-to-date. It also adds version to unversioned packages and pins exact version of loosely defined ones. You can also pin a specific package to an older version by adding a `# freeze` comment.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,20 +18,25 @@ pre-commit-localupdate
|
|
|
18
18
|
|
|
19
19
|
All options:
|
|
20
20
|
|
|
21
|
-
```
|
|
22
|
-
usage: pre-commit-localupdate [-h] [--debug] [--dry-run] [-c CONFIG] [--timeout TIMEOUT]
|
|
21
|
+
```text
|
|
22
|
+
usage: pre-commit-localupdate [-h] [--debug] [--dry-run] [-c PRE-COMMIT-CONFIG] [--timeout TIMEOUT]
|
|
23
|
+
[--indent-mapping INDENT_MAPPING] [--indent-sequence INDENT_SEQUENCE]
|
|
24
|
+
[--indent-offset INDENT_OFFSET] [--line-width LINE_WIDTH] [--version]
|
|
23
25
|
|
|
24
|
-
Automatically update additional dependencies within local
|
|
25
|
-
file.
|
|
26
|
+
Automatically update additional dependencies within local hooks in a pre-commit config file.
|
|
26
27
|
|
|
27
28
|
options:
|
|
28
|
-
-h, --help
|
|
29
|
-
--debug
|
|
30
|
-
--dry-run
|
|
31
|
-
|
|
32
|
-
-c, --config CONFIG
|
|
33
|
-
--timeout TIMEOUT
|
|
34
|
-
--
|
|
29
|
+
-h, --help show this help message and exit
|
|
30
|
+
--debug enable debug logging (default: False)
|
|
31
|
+
--dry-run dry run mode. Do not update the file and exit with a non-zero code if the
|
|
32
|
+
configuration file require an update. (default: False)
|
|
33
|
+
-c, --config PRE-COMMIT-CONFIG pre-commit config file path (default: .pre-commit-config.yaml)
|
|
34
|
+
--timeout TIMEOUT connection timeout in seconds (default: 10)
|
|
35
|
+
--indent-mapping INDENT_MAPPING YAML indentation for mappings (default: 2)
|
|
36
|
+
--indent-sequence INDENT_SEQUENCE YAML indentation for sequences (default: 4)
|
|
37
|
+
--indent-offset INDENT_OFFSET YAML indentation offset (default: 2)
|
|
38
|
+
--line-width LINE_WIDTH maximum line width (default: 80)
|
|
39
|
+
--version show program's version number and exit
|
|
35
40
|
```
|
|
36
41
|
|
|
37
42
|
## Example
|
|
@@ -54,7 +59,7 @@ repos:
|
|
|
54
59
|
# All comment are preserved
|
|
55
60
|
- id: black
|
|
56
61
|
name: black
|
|
57
|
-
description: "
|
|
62
|
+
description: "Length of strings is automatically adjusted based on the value of --line-width"
|
|
58
63
|
entry: black
|
|
59
64
|
language: python
|
|
60
65
|
minimum_pre_commit_version: 2.9.2
|
|
@@ -68,7 +73,7 @@ repos:
|
|
|
68
73
|
|
|
69
74
|
- id: julia-format
|
|
70
75
|
name: format julia code
|
|
71
|
-
description:
|
|
76
|
+
description: Unicodeテキストは保持されます。
|
|
72
77
|
language: julia
|
|
73
78
|
types: [julia]
|
|
74
79
|
entry: tools/formatter.jl
|
|
@@ -104,8 +109,8 @@ repos:
|
|
|
104
109
|
# All comment are preserved
|
|
105
110
|
- id: black
|
|
106
111
|
name: black
|
|
107
|
-
description: "
|
|
108
|
-
|
|
112
|
+
description: "Length of strings is automatically adjusted based on the value
|
|
113
|
+
of --line-width"
|
|
109
114
|
entry: black
|
|
110
115
|
language: python
|
|
111
116
|
minimum_pre_commit_version: 2.9.2
|
|
@@ -119,7 +124,7 @@ repos:
|
|
|
119
124
|
|
|
120
125
|
- id: julia-format
|
|
121
126
|
name: format julia code
|
|
122
|
-
description:
|
|
127
|
+
description: Unicodeテキストは保持されます。
|
|
123
128
|
language: julia
|
|
124
129
|
types: [julia]
|
|
125
130
|
entry: tools/formatter.jl
|
|
@@ -137,14 +142,25 @@ repos:
|
|
|
137
142
|
additional_dependencies: ["cli:mdbook-lint:0.14.2"]
|
|
138
143
|
```
|
|
139
144
|
|
|
145
|
+
## Supported Languages
|
|
146
|
+
|
|
147
|
+
Following local hook languages are currently supported:
|
|
148
|
+
|
|
149
|
+
- Go (golang)
|
|
150
|
+
- Julia
|
|
151
|
+
- Node.js (node)
|
|
152
|
+
- Python
|
|
153
|
+
- Rust
|
|
154
|
+
|
|
140
155
|
## Formatting
|
|
141
156
|
|
|
142
|
-
|
|
157
|
+
Significant effort has been made to ensure `pre-commit-localupdate` maintains the original style and preserves comments in pre-commit configuration files. However, since the current version of the underlying library does not perfectly preserve the original YAML file format after processing, `pre-commit-localupdate` automatically folds long string values (like descriptions) and enforces block indentation by default when updating files to enhance readability. Both behaviors can be adjusted using command-line parameters.
|
|
143
158
|
|
|
144
159
|
## Requirements
|
|
145
160
|
|
|
146
|
-
-
|
|
147
|
-
- requests
|
|
161
|
+
- `packaging`
|
|
162
|
+
- `requests`
|
|
163
|
+
- `ruamel.yaml`
|
|
148
164
|
|
|
149
165
|
## License
|
|
150
166
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.5.1'
|
{pre_commit_localupdate-0.4.1 → pre_commit_localupdate-0.5.1}/pre_commit_localupdate/__main__.py
RENAMED
|
@@ -11,10 +11,10 @@ to their latest versions.
|
|
|
11
11
|
|
|
12
12
|
import logging
|
|
13
13
|
import sys
|
|
14
|
-
from pathlib import Path
|
|
15
14
|
|
|
16
15
|
from pre_commit_localupdate.cli import parse_args
|
|
17
16
|
from pre_commit_localupdate.error import PreCommitLocalUpdateError
|
|
17
|
+
from pre_commit_localupdate.io import YAMLFormat
|
|
18
18
|
from pre_commit_localupdate.logs import setup_logging
|
|
19
19
|
from pre_commit_localupdate.pre_commit_config import update_additional_dependencies
|
|
20
20
|
|
|
@@ -23,12 +23,18 @@ def main() -> None:
|
|
|
23
23
|
"""Main entry point for the script."""
|
|
24
24
|
args = parse_args()
|
|
25
25
|
setup_logging(debug=args.debug)
|
|
26
|
-
|
|
26
|
+
yaml_format = YAMLFormat(
|
|
27
|
+
indent_mapping=args.indent_mapping,
|
|
28
|
+
indent_sequence=args.indent_sequence,
|
|
29
|
+
indent_offset=args.indent_offset,
|
|
30
|
+
line_width=args.line_width,
|
|
31
|
+
)
|
|
27
32
|
try:
|
|
28
33
|
if update_additional_dependencies(
|
|
29
|
-
|
|
34
|
+
args.config, args.timeout, yaml_format, dry_run=args.dry_run
|
|
30
35
|
):
|
|
31
36
|
if args.dry_run:
|
|
37
|
+
logging.info("Additional dependencies require updating!")
|
|
32
38
|
sys.exit(1)
|
|
33
39
|
logging.info("Done.")
|
|
34
40
|
else:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
from pre_commit_localupdate import __version__
|
|
7
8
|
|
|
@@ -13,8 +14,10 @@ def parse_args() -> argparse.Namespace:
|
|
|
13
14
|
argparse.Namespace: Parsed arguments.
|
|
14
15
|
"""
|
|
15
16
|
parser = argparse.ArgumentParser(
|
|
16
|
-
description="Automatically update additional dependencies within local
|
|
17
|
-
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
|
17
|
+
description="Automatically update additional dependencies within local hooks in a pre-commit config file.",
|
|
18
|
+
formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(
|
|
19
|
+
prog, max_help_position=40, width=120
|
|
20
|
+
),
|
|
18
21
|
)
|
|
19
22
|
parser.add_argument(
|
|
20
23
|
"--debug",
|
|
@@ -29,9 +32,10 @@ def parse_args() -> argparse.Namespace:
|
|
|
29
32
|
parser.add_argument(
|
|
30
33
|
"-c",
|
|
31
34
|
"--config",
|
|
32
|
-
type=
|
|
35
|
+
type=Path,
|
|
33
36
|
help="pre-commit config file path",
|
|
34
37
|
default=".pre-commit-config.yaml",
|
|
38
|
+
metavar="PRE-COMMIT-CONFIG",
|
|
35
39
|
)
|
|
36
40
|
parser.add_argument(
|
|
37
41
|
"--timeout",
|
|
@@ -39,6 +43,30 @@ def parse_args() -> argparse.Namespace:
|
|
|
39
43
|
help="connection timeout in seconds",
|
|
40
44
|
default=10,
|
|
41
45
|
)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"--indent-mapping",
|
|
48
|
+
type=int,
|
|
49
|
+
help="YAML indentation for mappings",
|
|
50
|
+
default=2,
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"--indent-sequence",
|
|
54
|
+
type=int,
|
|
55
|
+
help="YAML indentation for sequences",
|
|
56
|
+
default=4,
|
|
57
|
+
)
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"--indent-offset",
|
|
60
|
+
type=int,
|
|
61
|
+
help="YAML indentation offset",
|
|
62
|
+
default=2,
|
|
63
|
+
)
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
"--line-width",
|
|
66
|
+
type=int,
|
|
67
|
+
help="maximum line width",
|
|
68
|
+
default=80,
|
|
69
|
+
)
|
|
42
70
|
parser.add_argument(
|
|
43
71
|
"--version",
|
|
44
72
|
action="version",
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 M. Farzalipour Tabriz, Max Planck Institute for Physics
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import io
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import tempfile
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from ruamel.yaml import YAML
|
|
12
|
+
from ruamel.yaml.comments import CommentedMap
|
|
13
|
+
|
|
14
|
+
from pre_commit_localupdate.error import PreCommitLocalUpdateError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class YAMLFormat:
|
|
19
|
+
"""Configuration for YAML file formatting parameters.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
indent_mapping (int): YAML indentation for mappings
|
|
23
|
+
indent_sequence (int): YAML indentation for sequences
|
|
24
|
+
indent_offset (int): YAML indentation offset
|
|
25
|
+
line_width (int): maximum line width
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
indent_mapping: int
|
|
30
|
+
indent_sequence: int
|
|
31
|
+
indent_offset: int
|
|
32
|
+
line_width: int
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def load_config_file(file_path: Path) -> tuple[list[str], str]:
|
|
36
|
+
"""Reads pre-commit configuration file and returns its header lines and content.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
file_path (Path): Path to config file
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
tuple[list[str], str]: Header lines, config file content
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
PreCommitLocalUpdateError: Error in reading config file
|
|
46
|
+
"""
|
|
47
|
+
logging.debug("Reading configuration file: %s", file_path)
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
file_content = file_path.read_text(encoding="utf-8")
|
|
51
|
+
except FileNotFoundError as exc:
|
|
52
|
+
raise PreCommitLocalUpdateError(f"File not found: {file_path}") from exc
|
|
53
|
+
except OSError as exc:
|
|
54
|
+
raise PreCommitLocalUpdateError(
|
|
55
|
+
f"IOError while reading file {file_path}"
|
|
56
|
+
) from exc
|
|
57
|
+
|
|
58
|
+
raw_lines = file_content.splitlines(keepends=True)
|
|
59
|
+
|
|
60
|
+
content_start_index = 0
|
|
61
|
+
for i, line in enumerate(raw_lines):
|
|
62
|
+
stripped = line.strip()
|
|
63
|
+
if stripped == "---":
|
|
64
|
+
logging.debug("YAML marker found.")
|
|
65
|
+
content_start_index = i + 1
|
|
66
|
+
break
|
|
67
|
+
if stripped and not stripped.startswith("#"):
|
|
68
|
+
content_start_index = i
|
|
69
|
+
break
|
|
70
|
+
|
|
71
|
+
header_lines = raw_lines[:content_start_index]
|
|
72
|
+
content = "".join(raw_lines[content_start_index:])
|
|
73
|
+
|
|
74
|
+
return header_lines, content
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def save_config_file(
|
|
78
|
+
file_path: Path,
|
|
79
|
+
config: CommentedMap,
|
|
80
|
+
header_lines: list[str],
|
|
81
|
+
yaml_dumper: YAML,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Writes pre-commit configuration file.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
file_path (Path): Path to config file
|
|
87
|
+
config (CommentedMap): Config file content
|
|
88
|
+
header_lines (list[str]): File header lines
|
|
89
|
+
yaml_dumper (YAML): YAML dumper
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
PreCommitLocalUpdateError: Error in writing config file
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
logging.debug("Writing modifications to disk...")
|
|
96
|
+
stream = io.StringIO()
|
|
97
|
+
yaml_dumper.dump(config, stream)
|
|
98
|
+
modified_body = stream.getvalue()
|
|
99
|
+
final_content = "".join(header_lines) + modified_body
|
|
100
|
+
|
|
101
|
+
temp_file_path = None
|
|
102
|
+
try:
|
|
103
|
+
with tempfile.NamedTemporaryFile(
|
|
104
|
+
mode="w",
|
|
105
|
+
encoding="utf-8",
|
|
106
|
+
dir=file_path.parent,
|
|
107
|
+
delete=False,
|
|
108
|
+
) as temp_file:
|
|
109
|
+
temp_file_path = temp_file.name
|
|
110
|
+
temp_file.write(final_content)
|
|
111
|
+
os.fsync(temp_file.fileno())
|
|
112
|
+
|
|
113
|
+
os.replace(temp_file_path, file_path)
|
|
114
|
+
logging.info("Successfully updated %s", file_path)
|
|
115
|
+
|
|
116
|
+
except OSError as exc:
|
|
117
|
+
if temp_file_path and os.path.exists(temp_file_path):
|
|
118
|
+
os.unlink(temp_file_path)
|
|
119
|
+
raise PreCommitLocalUpdateError(
|
|
120
|
+
f"IOError while writing to file {file_path}"
|
|
121
|
+
) from exc
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2026 M. Farzalipour Tabriz, Max Planck Institute for Physics
|
|
2
2
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
3
|
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
4
6
|
import logging
|
|
5
7
|
import re
|
|
6
|
-
from dataclasses import dataclass
|
|
7
8
|
|
|
8
9
|
import requests
|
|
9
10
|
|
|
@@ -13,51 +14,39 @@ from .package import PackageBase
|
|
|
13
14
|
GO_PKG_LATEST_VERSION_API_URL = "https://proxy.golang.org/{package_path}/@latest"
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
@dataclass
|
|
17
17
|
class GoPackage(PackageBase):
|
|
18
18
|
"""Represents a Go module."""
|
|
19
19
|
|
|
20
20
|
@classmethod
|
|
21
|
-
def from_specification(
|
|
22
|
-
cls, spec: str, connection_timeout: int
|
|
23
|
-
) -> "GoPackage" | None:
|
|
21
|
+
def from_specification(cls, spec: str) -> "GoPackage" | None:
|
|
24
22
|
"""Parse a Go module specification string into a Package object.
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
24
|
+
Supported formats:
|
|
25
|
+
- `mvdan.cc/sh` (Module path only)
|
|
26
|
+
- `mvdan.cc/sh@v1.3.0` (Module path with specific version)
|
|
27
|
+
- `mvdan.cc/sh/v3` (Module path with major version suffix)
|
|
28
|
+
- `mvdan.cc/sh/v3@v3.10.0` (Major suffix with version)
|
|
29
|
+
- `mvdan.cc/sh/v3/cmd/shfmt` (Submodule)
|
|
30
|
+
- `mvdan.cc/sh/v3/cmd/shfmt@v3.10.0` (Submodule with version)
|
|
33
31
|
|
|
34
32
|
Args:
|
|
35
|
-
spec (str): The package specification string.
|
|
36
|
-
connection_timeout (int): Connection timeout in seconds.
|
|
33
|
+
spec (str): The package specification string (without quotations).
|
|
37
34
|
|
|
38
35
|
Returns:
|
|
39
36
|
"GoPackage" | None: A Package instance if parsing succeeds, otherwise None.
|
|
40
37
|
"""
|
|
41
|
-
clean_spec = spec.strip().strip('"').strip("'")
|
|
42
38
|
|
|
43
|
-
match = re.match(r"^([a-zA-Z0-9._/-]+)(@.+)?$",
|
|
39
|
+
match = re.match(r"^([a-zA-Z0-9._/-]+)(@.+)?$", spec)
|
|
44
40
|
|
|
45
41
|
if not match:
|
|
46
|
-
logging.warning(
|
|
47
|
-
"Could not parse the Go package specification: %s", clean_spec
|
|
48
|
-
)
|
|
49
42
|
return None
|
|
50
43
|
|
|
51
44
|
name = match.group(1)
|
|
52
45
|
raw_spec = match.group(2)
|
|
53
46
|
|
|
54
|
-
module_path = cls._resolve_module_path(name)
|
|
55
|
-
latest_version = cls._get_latest_version(module_path, connection_timeout)
|
|
56
|
-
|
|
57
47
|
return cls(
|
|
58
48
|
name=name,
|
|
59
49
|
raw_spec=raw_spec,
|
|
60
|
-
latest_version=latest_version,
|
|
61
50
|
)
|
|
62
51
|
|
|
63
52
|
@staticmethod
|
|
@@ -82,17 +71,13 @@ class GoPackage(PackageBase):
|
|
|
82
71
|
|
|
83
72
|
return package_path
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
def _get_latest_version(package_path: str, connection_timeout: int) -> str | None:
|
|
74
|
+
def fetch_latest_version(self, connection_timeout: int) -> None:
|
|
87
75
|
"""Fetch the latest version of a Go module from proxy.golang.org.
|
|
88
76
|
|
|
89
77
|
Args:
|
|
90
|
-
package_path (str): The module path (e.g., mvdan.cc/sh/v3).
|
|
91
78
|
connection_timeout (int): Connection timeout in seconds.
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
str | None: The latest version string (e.g., v3.10.0) if found, otherwise None.
|
|
95
79
|
"""
|
|
80
|
+
package_path = self._resolve_module_path(self.name)
|
|
96
81
|
logging.debug("Fetching latest version for %s", package_path)
|
|
97
82
|
try:
|
|
98
83
|
url = GO_PKG_LATEST_VERSION_API_URL.format(package_path=package_path)
|
|
@@ -103,16 +88,15 @@ class GoPackage(PackageBase):
|
|
|
103
88
|
data = response.json()
|
|
104
89
|
latest_version = data.get("Version")
|
|
105
90
|
|
|
106
|
-
|
|
91
|
+
if isinstance(latest_version, str):
|
|
92
|
+
self.latest_version = latest_version
|
|
107
93
|
|
|
108
94
|
except requests.exceptions.RequestException as exc:
|
|
109
95
|
logging.warning(
|
|
110
96
|
"Could not fetch latest version for %s: %s", package_path, exc
|
|
111
97
|
)
|
|
112
|
-
return None
|
|
113
98
|
except (KeyError, ValueError) as exc:
|
|
114
99
|
logging.warning("Could not parse response for %s: %s", package_path, exc)
|
|
115
|
-
return None
|
|
116
100
|
|
|
117
101
|
def latest_version_specification(self) -> str | None:
|
|
118
102
|
"""Version specification of package pinned to the latest version.
|