pre-commit-html 0.1.4__tar.gz → 0.1.4.post1__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.
@@ -1,14 +1,15 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pre_commit_html
3
- Version: 0.1.4
3
+ Version: 0.1.4.post1
4
4
  Summary: Format results from pre-commit cmd to HTML file
5
5
  License: MIT
6
6
  Author: Robotz213
7
7
  Author-email: nicholas@robotz.dev
8
- Requires-Python: >=3.13
8
+ Requires-Python: >=3.13,<4.0
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: html2text (>=2024.2.26,<2025.0.0)
12
13
  Requires-Dist: jinja2 (>=3.1.5,<4.0.0)
13
14
  Requires-Dist: pre-commit (>=4.1.0,<5.0.0)
14
15
  Description-Content-Type: text/markdown
@@ -0,0 +1,210 @@
1
+ """Module for formatting pre-commit results into an HTML file."""
2
+
3
+ import os
4
+ import subprocess
5
+ from pathlib import Path
6
+
7
+ import html2text
8
+ import yaml # noqa: F401
9
+ from jinja2 import Environment, FileSystemLoader
10
+
11
+ from pre_commit_html.utils import generate_editor_links
12
+
13
+ env = Environment( # noqa:S701
14
+ loader=FileSystemLoader(
15
+ Path(
16
+ __file__,
17
+ )
18
+ .parent.resolve()
19
+ .joinpath("site/templates")
20
+ ),
21
+ )
22
+
23
+ render_template = env.get_template
24
+
25
+ result_html = Path("result_pre_commit.html")
26
+ result_md = Path("result_pre_commit.md")
27
+
28
+
29
+ class PreCommitToHTML:
30
+ """Class to parse and format pre-commit results.
31
+
32
+ Attributes:
33
+ code_error (list[str]): Represents the section where the linter
34
+ error is occurring with:
35
+ - File path
36
+ - Line number
37
+ - Column number
38
+ - Error message
39
+
40
+ code_part (list[str]): Represents the code part where the linter
41
+ html_content (list[str]): Represents the HTML content to be written to the file.
42
+
43
+ """
44
+
45
+ theme = "dark"
46
+ ide = "VS Code"
47
+ to_markdown = False
48
+ code_error: list[str | list[str]] = []
49
+ code_part: list[str] = []
50
+ html_content: list[list[str | list[str]]] = []
51
+
52
+ uri_html = ""
53
+
54
+ def __init__(self, ide: str = "VS Code", to_markdown: bool = False, theme: str = "dark") -> None:
55
+ """Initialize the PreCommitToHTML class."""
56
+ self.ide = ide
57
+ self.to_markdown = to_markdown
58
+ self.theme = theme
59
+ self.pre_commit_html()
60
+
61
+ def render_template(self) -> None:
62
+ """Render the template and write the result to an HTML file."""
63
+ html_content = render_template("html_content.jinja").render(content=self.html_content, theme=self.theme)
64
+ if result_html.exists():
65
+ os.remove(str(result_html))
66
+
67
+ with result_html.open("w", encoding="utf-8") as f:
68
+ f.write(html_content)
69
+
70
+ if self.to_markdown:
71
+ try:
72
+ converter = html2text.HTML2Text()
73
+ converter.body_width = 0
74
+ converter.code = True
75
+
76
+ with result_md.open("w", encoding="utf-8") as f:
77
+ result = converter.handle(html_content)
78
+ f.write(result)
79
+
80
+ except ImportError:
81
+ print( # noqa:T201
82
+ """
83
+ ====================================
84
+ Docling package is required to convert HTML to Markdown.
85
+ Please install it using the following command:
86
+ `pip install docling` or poetry add docling
87
+ ====================================
88
+ """
89
+ )
90
+
91
+ def run_pre_commit(self) -> str:
92
+ """Run the pre-commit command and capture its output.
93
+
94
+ Returns:
95
+ str: The output of the pre-commit command.
96
+
97
+ Raises:
98
+ subprocess.CalledProcessError: If the pre-commit command fails.
99
+
100
+ """
101
+ try:
102
+ results = ""
103
+ yaml_config = yaml.safe_load(Path(".pre-commit-config.yaml").read_text())
104
+ repos = yaml_config.get("repos")
105
+ for repo in repos:
106
+ hooks = repo.get("hooks")
107
+ for hook in hooks:
108
+ id_hook = hook.get("id")
109
+ if id_hook:
110
+ result = subprocess.run(
111
+ ["pre-commit", "run", id_hook, "--all-files"],
112
+ capture_output=True,
113
+ text=True,
114
+ )
115
+
116
+ if "passed" not in result.stdout.lower():
117
+ if results != "":
118
+ results += f"{result.stdout}\n"
119
+ continue
120
+
121
+ results = result.stdout
122
+ return results
123
+ except subprocess.CalledProcessError as e:
124
+ return f"Erro ao executar pre-commit: {e.stderr}"
125
+
126
+ def format_result(self, h3_file: str) -> None:
127
+ """Format the error head message."""
128
+ ruff_ref = ""
129
+ path_code_file = h3_file.split(":")[0]
130
+ line_code = h3_file.split(":")[1]
131
+ column_code = h3_file.split(":")[2]
132
+ message = h3_file.split(":")[3]
133
+ path_file_link = str(path_code_file)
134
+
135
+ try:
136
+ workdir = Path.cwd().resolve()
137
+ path_code_file = h3_file.split(":")[0]
138
+
139
+ path_file_link = generate_editor_links(
140
+ workdir.joinpath(str(path_code_file)), int(line_code), int(column_code)
141
+ )[self.ide]
142
+ except Exception as e:
143
+ print( # noqa:T201
144
+ f"""
145
+ ====================================
146
+ Error to generate link to file editor
147
+ File: {path_code_file}
148
+ Exception: {e}
149
+ ====================================
150
+ """
151
+ )
152
+ self.code_error.append(message)
153
+ self.code_error.append(f"{path_code_file}:{line_code}:{column_code}")
154
+ self.code_error.append(path_file_link)
155
+ if len(message.split(" ")) > 1:
156
+ ruff_ref = message.split(" ")[1]
157
+ self.code_error.append(f"https://docs.astral.sh/ruff/rules/#{ruff_ref}")
158
+
159
+ else:
160
+ self.code_error.append("")
161
+
162
+ def pre_commit_html(self) -> None:
163
+ """Format the pre-commit output into an HTML file.
164
+
165
+ This method runs the pre-commit command, processes its output, and writes the formatted
166
+ results into an HTML file.
167
+ """
168
+ content = self.run_pre_commit()
169
+
170
+ content_splitlines = content.splitlines()
171
+
172
+ for line in content_splitlines:
173
+ if "\\" in line and ":" in line:
174
+ # if a file is found, add it to the code_part list if it is empty
175
+ h3_file = line.replace("\\", "/")
176
+
177
+ if len(self.code_part) > 0:
178
+ self.code_error.append(self.code_part)
179
+ to_append = self.code_error
180
+ self.html_content.append(to_append)
181
+
182
+ self.code_error = []
183
+ self.code_part = []
184
+
185
+ if len(h3_file.split(":")) > 3:
186
+ self.format_result(h3_file=h3_file)
187
+
188
+ elif "|" in line:
189
+ code_content = line
190
+ if code_content.strip() == "|":
191
+ continue
192
+ self.code_part.append(code_content)
193
+
194
+ if all(
195
+ [ # noqa:W503
196
+ len(self.html_content) == 0,
197
+ len(self.code_part) > 0,
198
+ len(self.code_error) > 0,
199
+ ],
200
+ ):
201
+ self.code_error.append(self.code_part)
202
+ self.html_content.append(self.code_error)
203
+
204
+ h3_file = line.replace("\\", "/")
205
+ if len(h3_file.split(":")) == 4:
206
+ self.format_result(h3_file=h3_file)
207
+
208
+ self.render_template()
209
+ self.uri_html = result_html.resolve().as_uri()
210
+ print(f"HTML file generated: {self.uri_html}") # noqa:T201
@@ -0,0 +1,39 @@
1
+ """Main module for the pre-commit-html package."""
2
+
3
+ import argparse
4
+ import sys
5
+ import webbrowser
6
+ from typing import Sequence
7
+
8
+ from pre_commit_html import PreCommitToHTML
9
+
10
+
11
+ def main(argv: Sequence[str] | None = None) -> None:
12
+ """Run the pre-commit formatter."""
13
+ argv = argv if argv is not None else sys.argv[1:]
14
+ parser = argparse.ArgumentParser(prog="pre-commit-html")
15
+
16
+ parser.add_argument(
17
+ "-i",
18
+ "--IDE",
19
+ type=str,
20
+ help="""IDE for config link files. Supported IDEs: VS Code, Sublime Text, Atom, PyCharm, IntelliJ IDEA, and
21
+ WebStorm""",
22
+ default="VS Code",
23
+ )
24
+ parser.add_argument("-m", "--to-markdown", "--md", help="Convert the HTML file to Markdown.", action="store_true")
25
+ parser.add_argument(
26
+ "-t",
27
+ "--theme",
28
+ type=str,
29
+ help="Theme for the HTML file. Supported themes: dark, light",
30
+ default="dark",
31
+ )
32
+ args = parser.parse_args(argv)
33
+ instance_ = PreCommitToHTML(
34
+ ide=args.IDE,
35
+ to_markdown=args.to_markdown,
36
+ theme=args.theme,
37
+ )
38
+
39
+ webbrowser.open(str(instance_.uri_html))
@@ -0,0 +1,78 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-bs-theme="{{ theme }}">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Pre-Commit Result</title>
8
+
9
+
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
11
+ integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g=="
12
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.8/umd/popper.min.js"
14
+ integrity="sha512-TPh2Oxlg1zp+kz3nFA0C5vVC6leG/6mm1z9+mA81MI5eaUVqasPLO8Cuk4gMF4gUfP5etR73rgU/8PNMsSesoQ=="
15
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"
17
+ integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ=="
18
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
19
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css"
20
+ integrity="sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg=="
21
+ crossorigin="anonymous" referrerpolicy="no-referrer" />
22
+ <link rel="stylesheet"
23
+ href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css"
24
+ integrity="sha512-Jk4AqjWsdSzSWCSuQTfYRIF84Rq/eV0G2+tu07byYwHcbTGfdmLrHjUSwvzp5HvbiqK4ibmNwdcG49Y5RGYPTg=="
25
+ crossorigin="anonymous" referrerpolicy="no-referrer" />
26
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"
27
+ integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ=="
28
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
29
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"
30
+ integrity="sha512-wW8K3TEH5ZViD4aMPzwPdhXKs/Kb5MAm7qLRd3QliYlHy0u9utSKZsZzqlZAgJ9xxXp81acwnrZVZ8oTfoLG1g=="
31
+ crossorigin="anonymous" referrerpolicy="no-referrer"></script>
32
+ </head>
33
+
34
+ <body class="bg-{{ theme }}">
35
+
36
+ <div class="container">
37
+ <div class="card mt-4">
38
+ <div class="card-header" style="background-color: rgb(36, 51, 1);">
39
+ <h1>Pre-Commit Result</h1>
40
+ <!-- <p>Pre-Commit Result:
41
+ <span id="result">
42
+
43
+ </span>
44
+ </p> -->
45
+ </div>
46
+ <div class="card-body">
47
+ <div class="list-group">
48
+ {% for item in content %}
49
+ <a href="{{ item[2] }}" class="list-group-item list-group-item-action d-flex gap-3 py-3"
50
+ aria-current="true">
51
+ <div class="d-block w-100 gap-2 justify-content-between">
52
+ <div>
53
+ <h6 class="mb-0">{{ item[1] }}</h6>
54
+ <p class="mb-0 opacity-75">{{ item[0] }}</p>
55
+ {% set code = item[4] %}
56
+ <pre
57
+ class="theme-atom-one-dark shadow-3xl text-sm relative overflow-hidden max-w-full tab-size h-full ">
58
+ <code class="language-python">
59
+ {% for linecode in code %}
60
+ {{ linecode }}
61
+ {% endfor %}
62
+ </code>
63
+
64
+ </pre>
65
+ </div>
66
+ </div>
67
+ </a>
68
+ {% endfor %}
69
+ </div>
70
+ </ul>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ <script>hljs.highlightAll();</script>
75
+
76
+ </body>
77
+
78
+ </html>
@@ -1,12 +1,16 @@
1
1
  [project]
2
2
  name = "pre_commit_html"
3
- version = "v0.1.4"
3
+ version = "v0.1.4.post1"
4
4
  description = "Format results from pre-commit cmd to HTML file"
5
5
  authors = [{ name = "Robotz213", email = "nicholas@robotz.dev" }]
6
6
  readme = "README.md"
7
7
  license = "MIT"
8
- requires-python = ">=3.13"
9
- dependencies = ["pre-commit (>=4.1.0,<5.0.0)", "jinja2 (>=3.1.5,<4.0.0)"]
8
+ requires-python = ">=3.13,<4.0"
9
+ dependencies = [
10
+ "pre-commit (>=4.1.0,<5.0.0)",
11
+ "jinja2 (>=3.1.5,<4.0.0)",
12
+ "html2text (>=2024.2.26,<2025.0.0)",
13
+ ]
10
14
 
11
15
  [tool.poetry.scripts]
12
16
  pre-commit-html = "pre_commit_html.__main__:main"
@@ -1,154 +0,0 @@
1
- """Module for formatting pre-commit results into an HTML file."""
2
-
3
- import os
4
- import subprocess
5
- from pathlib import Path
6
-
7
- from jinja2 import Environment, FileSystemLoader, Template # noqa: F401
8
-
9
- from pre_commit_html.utils import generate_editor_links
10
-
11
- env = Environment( # noqa:S701
12
- loader=FileSystemLoader(
13
- Path(
14
- __file__,
15
- )
16
- .parent.resolve()
17
- .joinpath("site/templates")
18
- ),
19
- )
20
-
21
- render_template = env.get_template
22
-
23
- path_result_content = Path("result_pre_commit.html")
24
-
25
-
26
- class PreCommitToHTML:
27
- """Class to parse and format pre-commit results."""
28
-
29
- def __init__(self, ide: str = "VS Code") -> None:
30
- """Initialize the PreCommitToHTML class."""
31
- self.ide = ide
32
- self.pre_commit_html()
33
-
34
- def run_pre_commit(self) -> str:
35
- """Run the pre-commit command and capture its output.
36
-
37
- Returns:
38
- str: The output of the pre-commit command.
39
-
40
- Raises:
41
- subprocess.CalledProcessError: If the pre-commit command fails.
42
-
43
- """
44
- try:
45
- result = subprocess.run(
46
- ["pre-commit", "run", "--all-files"],
47
- capture_output=True,
48
- text=True,
49
- )
50
- return result.stdout
51
- except subprocess.CalledProcessError as e:
52
- return f"Erro ao executar pre-commit: {e.stderr}"
53
-
54
- def pre_commit_html(self) -> None:
55
- """Format the pre-commit output into an HTML file.
56
-
57
- This method runs the pre-commit command, processes its output, and writes the formatted
58
- results into an HTML file.
59
- """
60
- content = self.run_pre_commit()
61
-
62
- content_splitlines = content.splitlines()
63
-
64
- html_content: list[str] = []
65
-
66
- code_part: list[str] = []
67
-
68
- code_error: list[str] = []
69
-
70
- for line in content_splitlines:
71
- if "\\" in line and ":" in line and len(code_part) == 0:
72
- h3_file = line.replace("\\", "/")
73
-
74
- if len(h3_file.split(":")) == 4:
75
- path_code_file = h3_file.split(":")[0]
76
- path_file_link = path_code_file
77
-
78
- line_code = h3_file.split(":")[1]
79
- column_code = h3_file.split(":")[2]
80
- message = h3_file.split(":")[3]
81
-
82
- try:
83
- workdir = Path.cwd().resolve()
84
- path_code_file = h3_file.split(":")[0]
85
-
86
- path_file_link = generate_editor_links(
87
- workdir.joinpath(str(path_code_file)), int(line_code), int(column_code)
88
- )[self.ide]
89
- except Exception as e:
90
- print( # noqa:T201
91
- f"""
92
- ====================================
93
- Error to generate link to file editor
94
- File: {path_code_file}
95
- Exception: {e}
96
- ====================================
97
- """
98
- )
99
-
100
- ruff_ref = message.split(" ")[1]
101
-
102
- code_error.append(
103
- "".join((
104
- f'<h3>File: <a href="{path_file_link}',
105
- f'{column_code}">{path_code_file}:{line_code}:{column_code}</a></h3>',
106
- ))
107
- )
108
- code_error.append(
109
- f'<p>Error: <a href="https://docs.astral.sh/ruff/rules/#{ruff_ref}">{ruff_ref}</a>{message}</p>'
110
- )
111
-
112
- elif "\\" in line and ":" in line and len(code_part) > 0:
113
- h3_file = line.replace("\\", "/")
114
-
115
- code_part_html = render_template("code_part.jinja").render(code_part=code_part)
116
-
117
- code_error.append(code_part_html)
118
- to_html = render_template("code_error.jinja").render(code_error=code_error)
119
-
120
- html_content.append(to_html)
121
-
122
- code_part.clear()
123
- code_error.clear()
124
-
125
- path_code_file = h3_file.split(":")[0]
126
- line_code = h3_file.split(":")[1]
127
- column_code = h3_file.split(":")[2]
128
- message = h3_file.split(":")[3]
129
-
130
- ruff_ref = message.split(" ")[1]
131
-
132
- code_error.append(
133
- "".join((
134
- f'<h3>File: <a href="./{path_code_file}:{line_code}:',
135
- f'{column_code}">{path_code_file}:{line_code}:{column_code}</a></h3>',
136
- ))
137
- )
138
- code_error.append(
139
- f'<p>Error: <a href="https://docs.astral.sh/ruff/rules/#{ruff_ref}">{ruff_ref}</a>{message}</p>'
140
- )
141
- continue
142
-
143
- if "|" in line:
144
- code_part.append(line)
145
-
146
- if path_result_content.exists():
147
- os.remove(str(path_result_content))
148
-
149
- path_result_content.touch()
150
-
151
- html_content = render_template("html_content.jinja").render(content=html_content)
152
-
153
- with open(path_result_content, "w", encoding="utf-8") as f:
154
- f.write(html_content)
@@ -1,18 +0,0 @@
1
- """Main module for the pre-commit-html package."""
2
-
3
- import argparse
4
- import sys
5
- from typing import Sequence
6
-
7
- from pre_commit_html import PreCommitToHTML
8
-
9
-
10
- def main(argv: Sequence[str] | None = None) -> None:
11
- """Run the pre-commit formatter."""
12
- argv = argv if argv is not None else sys.argv[1:]
13
- parser = argparse.ArgumentParser(prog="pre-commit-html")
14
-
15
- parser.add_argument("-i", "--IDE", type=str, help="The IDE to open the file in.", default="VS Code")
16
-
17
- args = parser.parse_args(argv)
18
- PreCommitToHTML(ide=args.IDE)
@@ -1,3 +0,0 @@
1
- {% for item in code_error %}
2
- {{ item }}
3
- {% endfor %}
@@ -1,7 +0,0 @@
1
- <pre>
2
- <code class="python">
3
- {% for item in code_part %}
4
- {{ item }}
5
- {% endfor %}
6
- </code>
7
- </pre>
@@ -1,38 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Pre-Commit Result</title>
8
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/a11y-dark.min.css"
9
- integrity="sha512-Vj6gPCk8EZlqnoveEyuGyYaWZ1+jyjMPg8g4shwyyNlRQl6d3L9At02ZHQr5K6s5duZl/+YKMnM3/8pDhoUphg=="
10
- crossorigin="anonymous" referrerpolicy="no-referrer" />
11
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"
12
- integrity="sha512-EBLzUL8XLl+va/zAsmXwS7Z2B1F9HUHkZwyS/VKwh3S7T/U0nF4BaU29EP/ZSf6zgiIxYAnKLu6bJ8dqpmX5uw=="
13
- crossorigin="anonymous" referrerpolicy="no-referrer"></script>
14
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/python.min.js"
15
- integrity="sha512-/uCTceIDOniHf+VUKbCnP/x6GQSRrm4GwUtQYMgKa9yIZPGzlR04flSsD+2or7bPn44VY9inIHI4cwNCcZmJDw=="
16
- crossorigin="anonymous" referrerpolicy="no-referrer"></script>
17
- </head>
18
-
19
- <body>
20
- <h1>Pre-Commit Result</h1>
21
- <p>Pre-Commit Result: <span id="result"></span></p>
22
-
23
- <ul>
24
- {% for item in content %}
25
- {{ item }}
26
- {% endfor %}
27
- </ul>
28
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
29
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
30
-
31
- <!-- and it's easy to individually load additional languages -->
32
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script>
33
-
34
- <script>hljs.highlightAll();</script>
35
-
36
- </body>
37
-
38
- </html>