Skip to content

Commit

Permalink
Add checksum
Browse files Browse the repository at this point in the history
  • Loading branch information
mxr committed Apr 25, 2024
1 parent 56166fc commit 2f03d55
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 4 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,46 @@ You can pass the jar file path to the `--ktfmt-jar` argument:
args: [--ktfmt, --ktfmt-jar=/usr/bin/ktfmt-0.47.jar]
```

### How can I verify the checksum of the jar?

_Only supported for the `pretty-format-java` and `pretty-format-kotlin-hooks`_

Use the corresponding `[...]-checksum` argument

```yaml
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: ...
hooks:
- id: pretty-format-java
args: [
--google-java-formatter-version=1.17.0,
--formatter-jar-checksum=33068bbbdce1099982ec1171f5e202898eb35f2919cf486141e439fc6e3a4203,
]
```

```yaml
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: ...
hooks:
- id: pretty-format-kotlin
args: [
--ktlint-version=1.2.1,
--formatter-jar-checksum=2e28cf46c27d38076bf63beeba0bdef6a845688d6c5dccd26505ce876094eb92,
]
```

```yaml
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: ...
hooks:
- id: pretty-format-kotlin
args: [
--ktfmt,
--ktfmt-version=0.47,
--formatter-jar-checksum=af61161faacd74ac56374e0b43003dbe742ddc0d6a7e2c1fe43e15415e65ffbd,
]
```

### How to use ktfmt instead of ktlint?

```yaml
Expand Down
10 changes: 10 additions & 0 deletions language_formatters_pre_commit_hooks/pretty_format_java.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from language_formatters_pre_commit_hooks import _get_default_version
from language_formatters_pre_commit_hooks.pre_conditions import assert_max_jdk_version
from language_formatters_pre_commit_hooks.pre_conditions import java_required
from language_formatters_pre_commit_hooks.utils import does_checksum_match
from language_formatters_pre_commit_hooks.utils import download_url
from language_formatters_pre_commit_hooks.utils import run_command

Expand Down Expand Up @@ -65,6 +66,12 @@ def pretty_format_java(argv: typing.Optional[typing.List[str]] = None) -> int:
default=None,
help="Path to Google Java Formatter jar file. Will be downloaded if not defined. Note that --google-java-formatter-version will be ignored if this parameter is defined (default: %(default)).",
)
parser.add_argument(
"--formatter-jar-checksum",
dest="checksum",
default=None,
help="The SHA256 checksum of the jar",
)
parser.add_argument(
"--autofix",
action="store_true",
Expand Down Expand Up @@ -94,6 +101,9 @@ def pretty_format_java(argv: typing.Optional[typing.List[str]] = None) -> int:
else:
google_java_formatter_jar = args.google_java_formatter_jar

if args.checksum and not does_checksum_match(google_java_formatter_jar, args.checksum):
return 1

cmd_args = [
"java",
# export JDK internal classes for Java 16+
Expand Down
23 changes: 19 additions & 4 deletions language_formatters_pre_commit_hooks/pretty_format_kotlin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from language_formatters_pre_commit_hooks import _get_default_version
from language_formatters_pre_commit_hooks.pre_conditions import java_required
from language_formatters_pre_commit_hooks.utils import does_checksum_match
from language_formatters_pre_commit_hooks.utils import download_url
from language_formatters_pre_commit_hooks.utils import run_command

Expand Down Expand Up @@ -88,6 +89,12 @@ def pretty_format_kotlin(argv: typing.Optional[typing.List[str]] = None) -> int:
dest="ktfmt",
help="Use ktfmt",
)
parser.add_argument(
"--formatter-jar-checksum",
dest="formatter_jar_checksum",
default=None,
help="The SHA256 checksum of the jar",
)
parser.add_argument(
"--ktfmt-style",
choices=["dropbox", "google", "kotlinlang"],
Expand All @@ -98,13 +105,18 @@ def pretty_format_kotlin(argv: typing.Optional[typing.List[str]] = None) -> int:
args = parser.parse_args(argv)
if args.ktfmt:
jar = args.ktfmt_jar or _download_ktfmt_formatter_jar(args.kftmt_version)
return run_ktfmt(jar, args.filenames, args.ktfmt_style, args.autofix)
return run_ktfmt(jar, args.formatter_jar_checksum, args.filenames, args.ktfmt_style, args.autofix)
else:
jar = args.ktlint_jar or _download_ktlint_formatter_jar(args.ktlint_version)
return run_ktlint(jar, args.filenames, args.autofix)
return run_ktlint(jar, args.formatter_jar_checksum, args.filenames, args.autofix)


def run_ktfmt(jar: str, filenames: typing.Iterable[str], ktfmt_style: typing.Optional[str], autofix: bool) -> int:
def run_ktfmt(
jar: str, checksum: typing.Optional[str], filenames: typing.Iterable[str], ktfmt_style: typing.Optional[str], autofix: bool
) -> int:
if checksum and not does_checksum_match(jar, checksum):
return 1

ktfmt_args = ["--set-exit-if-changed"]
if ktfmt_style is not None:
ktfmt_args.append(f"--{ktfmt_style}-style")
Expand All @@ -121,7 +133,10 @@ def run_ktfmt(jar: str, filenames: typing.Iterable[str], ktfmt_style: typing.Opt
return return_code


def run_ktlint(jar: str, filenames: typing.Iterable[str], autofix: bool):
def run_ktlint(jar: str, checksum: typing.Optional[str], filenames: typing.Iterable[str], autofix: bool):
if checksum and not does_checksum_match(jar, checksum):
return 1

jvm_args = ["--add-opens", "java.base/java.lang=ALL-UNNAMED"]

# ktlint does not return exit-code!=0 if we're formatting them.
Expand Down
12 changes: 12 additions & 0 deletions language_formatters_pre_commit_hooks/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import hashlib
import os
import shutil
import subprocess # nosec B404 B603
Expand Down Expand Up @@ -84,3 +85,14 @@ def remove_trailing_whitespaces_and_set_new_line_ending(string: str) -> str:
return "{content}\n".format(
content="\n".join(line.rstrip() for line in string.splitlines()).rstrip(),
)


def does_checksum_match(path: str, expected: str) -> bool:
with open(path, "rb") as f:
actual = hashlib.sha256(f.read()).hexdigest()

if actual != expected:
print(f"Expected {path!r} to have checksum {expected!r} but got {actual!r}", file=sys.stderr)
return False

return True
18 changes: 18 additions & 0 deletions tests/pretty_format_java_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ def test__download_google_java_formatter_jar(ensure_download_possible, version):
(
(["invalid.java"], 1),
(["pretty-formatted.java"], 0),
pytest.param(
[
"pretty-formatted.java",
"--google-java-formatter-version=1.21.0",
"--formatter-jar-checksum=1e69f8b63c39a5124a8efb7bad213eb9ac03944339eb9580ae210b0c60565d9b",
],
0,
id="valid checksum",
),
pytest.param(
[
"pretty-formatted.java",
"--google-java-formatter-version=1.21.0",
"--formatter-jar-checksum=2d32af8ef04ffbf0ae77fc7953e86871b85143b29d51f9794466842f68f5fb48",
],
1,
id="invalid checksum",
),
(["not-pretty-formatted.java"], 1),
(["not-pretty-formatted_fixed.java"], 0),
),
Expand Down
25 changes: 25 additions & 0 deletions tests/pretty_format_kotlin_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ def test_pretty_format_kotlin_ktlint(undecorate_method, filename, expected_retva
assert undecorate_method([filename]) == expected_retval


@pytest.mark.parametrize(
("checksum", "expected_retval"),
(
("2e28cf46c27d38076bf63beeba0bdef6a845688d6c5dccd26505ce876094eb92", 0),
("2d32af8ef04ffbf0ae77fc7953e86871b85143b29d51f9794466842f68f5fb48", 1),
),
)
def test_pretty_format_kotlin_checksum(undecorate_method, checksum, expected_retval):
assert undecorate_method(["--ktlint-version=1.2.1", f"--formatter-jar-checksum={checksum}", "PrettyPormatted.kt"]) == expected_retval


@pytest.mark.parametrize(
("filename", "expected_retval"),
(
Expand All @@ -91,6 +102,20 @@ def test_pretty_format_kotlin_ktfmt(undecorate_method, filename, expected_retval
assert undecorate_method(["--ktfmt", filename]) == expected_retval


@pytest.mark.parametrize(
("checksum", "expected_retval"),
(
("af61161faacd74ac56374e0b43003dbe742ddc0d6a7e2c1fe43e15415e65ffbd", 0),
("2d32af8ef04ffbf0ae77fc7953e86871b85143b29d51f9794466842f68f5fb48", 1),
),
)
def test_pretty_format_kotlin_ktfmt_checksum(undecorate_method, checksum, expected_retval):
actual = undecorate_method(
["--ktfmt", "--ktfmt-version=0.47", f"--formatter-jar-checksum={checksum}", "NotPrettyFormattedFixedKtfmtGoogle.kt"]
)
assert actual == expected_retval


@pytest.mark.parametrize(
("filename", "expected_retval"),
(
Expand Down
14 changes: 14 additions & 0 deletions tests/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import pytest

from language_formatters_pre_commit_hooks.utils import does_checksum_match
from language_formatters_pre_commit_hooks.utils import download_url
from language_formatters_pre_commit_hooks.utils import run_command

Expand Down Expand Up @@ -44,3 +45,16 @@ def test_download_url(mock_requests, mock_shutil, tmpdir, url, does_file_already
assert not mock_requests.get.called
else:
mock_requests.get.assert_called_once_with(url, stream=True)


@pytest.mark.parametrize(
("checksum", "expected"),
(
("486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7", True),
("2d32af8ef04ffbf0ae77fc7953e86871b85143b29d51f9794466842f68f5fb48", False),
),
)
def test_does_checksum_match(tmpdir, checksum, expected):
hello = tmpdir.join("hello.txt")
hello.write("world")
assert does_checksum_match(str(hello), checksum) is expected

0 comments on commit 2f03d55

Please sign in to comment.