Skip to content

Commit

Permalink
Merge a7c215d into c1d1761
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja authored May 30, 2022
2 parents c1d1761 + a7c215d commit 0a026e5
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.7.0
current_version = 1.8.0

[bumpversion:file:setup.cfg]

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/docs/_build/
/dev.md
__dev__.py
.vscode

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
13 changes: 9 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
repos:
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.0
rev: v1.20.1
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/mondeja/pre-commit-hooks
rev: v1.5.2
rev: file-check-lines
hooks:
- id: root-editorconfig-required
- id: dev-extras-required
- id: file-check-lines
files: ^MANIFEST.in$
args:
- include README.md
- include LICENSE
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.0
rev: v2.32.1
hooks:
- id: pyupgrade
args:
- --py36-plus
- repo: https://github.com/psf/black
rev: 21.12b0
rev: 22.3.0
hooks:
- id: black
files: \.py$
Expand Down
7 changes: 7 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
description: Check if your development dependencies contains all other extras requirements
files: '(setup\.cfg)|(pyproject\.toml)|(setup\.py)'
language: python
additional_dependencies:
- toml
- id: file-check-lines
name: file-check-lines
entry: file-check-lines-hook
description: Check that a set of lines exists in a file
language: python
- id: nameservers-endswith
name: nameservers-endswith
entry: nameservers-endswith-hook
Expand Down
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

```yaml
- repo: https://github.com/mondeja/pre-commit-hooks
rev: v1.7.0
rev: v1.8.0
hooks:
- id: dev-extras-required
- id: root-editorconfig-required
Expand All @@ -22,6 +22,11 @@
args:
- -domain=my-web.xyz
- -username=my_gh_username
- id: file-check-lines
files: ^MANIFEST.in$
args:
- include README.md
- include LICENSE
```
## Hooks
Expand All @@ -30,7 +35,7 @@

Add a pre-commit hook to your configuration file if is not already defined.

#### Parameters
#### Arguments

- `-repo=URL` (*str*) Repository of the new hook.
- `-rev=VERSION` (*str*) Version of the new hook.
Expand All @@ -53,7 +58,7 @@ This is useful if you want to execute `python -m pip install -e .[dev]` to
install all the optional requirements of the package, so if you add a new
requirement to another groups, it will be added to development requirements.

#### Parameters
#### Arguments

- `-extra=NAME` (*str*): Name for your development requirements extra group
(as default `dev`).
Expand All @@ -64,13 +69,23 @@ requirement to another groups, it will be added to development requirements.
mandatory if the extras requirements are defined in a `pyproject.toml` file
and this is located in another directory than the current one.

### **`file-check-lines`**

Check that a set of lines are included in a file. The file path must
be passed in the `files` argument and only one can match against the
regex.

The positional arguments must be the lines to check for inclusion in
the file, without newlines characters. Empty lines and lines composed
by newlines characters will be ignored.

### **`nameservers-endswith`**

Check that the nameservers of a domain ends with a string or raise an error.
You can use it to check if a site like Clouflare is managing a domain using
`-nameserver=cloudflare.com`.

#### Parameters
#### Arguments

- `-domain=DOMAIN` (*str*): Domain name whose nameservers will be checked.
- `-nameserver=NAMESERVER` (*str*): String to end the domain name servers in.
Expand All @@ -80,7 +95,7 @@ You can use it to check if a site like Clouflare is managing a domain using
Check that [Cloudflare][cloudflare-link] is handling the nameservers of a
domain.

#### Parameters
#### Arguments

- `-domain=DOMAIN` (*str*): Domain name whose nameservers will be checked.

Expand All @@ -102,7 +117,7 @@ The required DNS records to make it pass are:
| A | {domain} | 185.199.111.153 |
| CNAME | www | {username}.github.io |

#### Parameters
#### Arguments

- `-domain=DOMAIN`: Domain managed by Cloudflare whose DNS records will be
checked.
Expand All @@ -126,7 +141,7 @@ durations...

You need to install

#### Parameters
#### Arguments

- `-nchannels=N` (*int*): Number of channels that your sounds must have.
- `-sample-width=N` (*int*): Number of bytes that your sounds must have.
Expand Down
48 changes: 48 additions & 0 deletions hooks/file_check_lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""Check that a set of lines are included inside the content of a file."""

import argparse
import sys


def smart_quoted(value):
return (
f"'{value}'"
if "'" not in value
else (f'"{value}"' if '"' not in value else f"'{value}'")
)


def file_check_lines(filename, expected_lines, quiet=False):
with open(filename, encoding="utf-8") as f:
lines = f.read().splitlines()

expected_lines = [line.strip("\r\n") for line in expected_lines if line]
if not expected_lines:
sys.stderr.write("Any valid non empty expected line passed as argument\n")
return 1

retcode = 0
for expected_line in expected_lines:
if expected_line in lines:
continue

retcode = 1
if not quiet:
sys.stderr.write(
f"Line {smart_quoted(expected_line)} not found in file {filename}\n"
)

return retcode


def main():
parser = argparse.ArgumentParser()
parser.add_argument("-q", "--quiet", action="store_true", help="Supress output")
parser.add_argument("lines_files", nargs='+', help="Lines and a filename to check for content")
args = parser.parse_args()

return file_check_lines(args.lines_files[-1], args.lines_files[:-1], quiet=args.quiet)


if __name__ == "__main__":
sys.exit(main())
7 changes: 4 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = mondeja_pre_commit_hooks
version = 1.7.0
version = 1.8.0
description = My own useful pre-commit hooks
long_description = file: README.md
long_description_content_type = text/markdown
Expand All @@ -22,8 +22,6 @@ classifiers =

[options]
packages = find:
install_requires =
toml
python_requires = >=3.6.1

[options.packages.find]
Expand All @@ -35,6 +33,7 @@ console_scripts =
add-pre-commit-hook = hooks.add_pre_commit_hook:main
cloudflare-gh-pages-dns-hook = hooks.cf_gh_pages_dns_records:main
dev-extras-required-hook = hooks.dev_extras_required:main
file-check-lines-hook = hooks.file_check_lines:main
nameservers-endswith-hook = hooks.nameservers_endswith:main
root-editorconfig-required-hook = hooks.root_editorconfig_required:main
wavelint-hook = hooks.wavelint:main
Expand All @@ -47,13 +46,15 @@ dev =
pytest==6.2.4
pytest-cov==2.12.1
pyyaml==5.4.1
toml==0.10.2
waves==0.2.5
test =
cloudflare==2.8.15
dnspython==2.1.0
pytest==6.2.4
pytest-cov==2.12.1
pyyaml==5.4.1
toml==0.10.2
waves==0.2.5

[bdist_wheel]
Expand Down
49 changes: 49 additions & 0 deletions tests/test_file_check_lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import contextlib
import io
import tempfile

import pytest

from hooks.file_check_lines import file_check_lines, smart_quoted


@pytest.mark.parametrize(
"quiet",
(True, False),
ids=("quiet=True", "quiet=False"),
)
@pytest.mark.parametrize(
("content", "lines", "expected_exitcode", "expected_missing_lines"),
(
pytest.param("foo\nbar\nbaz\n", ["foo", "bar"], 0, [], id="ok"),
pytest.param("foo\n\n\n", ["bar", "baz"], 1, ["bar", "baz"], id="fail"),
pytest.param(
"foo\n\n\r\n\r\n\n", ["\r\n", "\n", "baz"], 1, ["baz"], id="ignore-newlines"
),
pytest.param(
"foo\n\n\n", ["\r\n", "\n", "baz"], 1, ["baz"], id="ignore-empty-lines"
),
),
)
def test_file_check_lines(
quiet, content, lines, expected_exitcode, expected_missing_lines
):
stderr = io.StringIO()
with tempfile.NamedTemporaryFile() as f:
f.write(content.encode("utf-8"))
f.seek(0)

with contextlib.redirect_stderr(stderr):
exitcode = file_check_lines(f.name, lines, quiet=quiet)

assert exitcode == expected_exitcode

if quiet:
assert not stderr.getvalue()
else:
stderr_lines = stderr.getvalue().splitlines()
for expected_missing_line in expected_missing_lines:
assert (
f"Line {smart_quoted(expected_missing_line)} not"
f" found in file {f.name}"
) in stderr_lines

0 comments on commit 0a026e5

Please sign in to comment.