Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/check-licenses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Check Licenses
on:
pull_request

jobs:
check-licenses:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: technote-space/[email protected]
id: git_diff
with:
PATTERNS: |
**/**.go
**/**.proto
- run: |
make check-licenses
if: env.GIT_DIFF
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,11 @@ create-contracts-json:
mv $(TMP_JSON) $(COMPILED_DIR)/$${c}.json ;\
done
@rm -rf tmp

###############################################################################
### Licenses ###
###############################################################################

check-licenses:
@echo "Checking licenses..."
@python3 scripts/check_licenses.py .
130 changes: 130 additions & 0 deletions scripts/check_licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import os
import re
import sys
from typing import Dict, List

FILTER: re.Pattern = re.compile(r"^((?!(_test|\.pb|\.pb\.gw)\.go$).)*\.(go|proto)$")
EXEMPT_FILES: List[str] = [
r"x/revenue/v1/", # All files in this folder
r"x/claims/genesis\.go$",
r"x/erc20/keeper/proposals\.go$",
r"x/erc20/types/utils\.go$",
]

LGPL3_LICENSE = [
"// Copyright Tharsis Labs Ltd.(Evmos)\n",
"// SPDX-License-Identifier:LGPL-3.0-only\n"
]

ENCL_LICENSE = [
"// Copyright Tharsis Labs Ltd.(Evmos)\n",
"// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)\n"
]


def check_licenses_in_path(
path: str, name_filter: re.Pattern = re.compile(".*"), add: bool = False
) -> Dict[str, int]:
"""
Iterate over all files in the current directory and its subdirectories
and check if the appropriate licenses are contained in the files.
"""

files_with_wrong_license = []
n_files = 0
n_files_with = 0
n_files_generated = 0
n_files_lic_removed = 0
n_files_geth = 0
n_files_lgpl3 = 0
n_files_encl = 0

for root, _, files in os.walk(path):
for file in files:
full_path = os.path.join(root, file)
if not name_filter.search(full_path):
continue

n_files += 1

lgpl3 = check_if_in_exempt_files(full_path)
checked_license = LGPL3_LICENSE if lgpl3 else ENCL_LICENSE

found = check_license_in_file(os.path.join(root, file), checked_license)
if found is True:
n_files_with += 1
if lgpl3:
n_files_lgpl3 += 1
else:
n_files_encl += 1
elif found == "generated":
n_files_with += 1
n_files_generated += 1
continue
elif found == "geth":
n_files_with += 1
n_files_geth += 1
continue
else:
files_with_wrong_license.append(full_path)

print(f"\n{n_files_with}/{n_files} contain a license comment")
print(f" -> {n_files_generated} are generated files")
print(f" -> {n_files_geth} have a geth license")
print(f" -> {n_files_lgpl3} have the LGPL3 license")
print(f" -> {n_files_encl} have the ENCL license")
if len(files_with_wrong_license) > 0:
print("---------------------------")
print(
f""" -> {len(files_with_wrong_license)} files have the wrong license or are missing a license altogether!
Please check the output above."""
)

return {
"total": n_files,
"with_license": n_files_with,
"generated": n_files_generated,
"geth": n_files_geth,
"license_removed": n_files_lic_removed,
"lgpl3": n_files_lgpl3,
"encl": n_files_encl,
"wrong_license": len(files_with_wrong_license),
}


def check_if_in_exempt_files(file: str) -> bool:
"""
Check if the file is in the exempt files list.
"""

for exempt_file in EXEMPT_FILES:
if re.search(exempt_file, file):
return True
return False


def check_license_in_file(file: str, checked_license: List[str]) -> bool | str:
"""
Check if the file has the license.
"""

with open(file, "r") as f:
lines = f.readlines()

if "generated" in lines[0].lower() or "do not edit" in lines[0].lower():
return "generated"
elif "ethereum" in lines[0].lower():
return "geth"

for expected_line, line in zip(checked_license, lines[: len(checked_license)]):
if line != expected_line:
print(" - ", file)
return False

return True


if __name__ == "__main__":
result = check_licenses_in_path(sys.argv[1], FILTER)
if result["wrong_license"] > 0:
sys.exit(1)
59 changes: 59 additions & 0 deletions scripts/test_check_licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import os

import check_licenses as cl
import pytest

_FILE_WITH_LICENSE = "./app/app.go"
_FILE_WITH_GETH_LICENSE = "./x/evm/statedb/journal.go"


@pytest.fixture
def cleanup():
yield
file = "test.txt"
if os.path.exists(file):
os.remove(file)


def test_check_license_in_file_no_license():
file = "test.txt"
with open(file, "w") as f:
f.write("test")
assert cl.check_license_in_file(file, cl.ENCL_LICENSE) is False


def test_check_license_in_file_geth_license():
assert cl.check_license_in_file(_FILE_WITH_GETH_LICENSE, cl.ENCL_LICENSE) == "geth"


def test_check_license_in_file_license():
assert cl.check_license_in_file(_FILE_WITH_LICENSE, cl.ENCL_LICENSE) is True


def test_check_license_in_file_generated(cleanup):
file = "test.txt"
with open(file, "w") as f:
f.write("// Code generated by go generate; DO NOT EDIT.")
assert cl.check_license_in_file(file, cl.ENCL_LICENSE) == "generated"


def test_check_if_in_exempt_files_not_included():
file = "/Users/malte/dev/go/evmos/evmos/app/app.go"
assert cl.check_if_in_exempt_files(file) is False


def test_check_if_in_exempt_files_included():
file = "/Users/malte/dev/go/evmos/evmos/x/revenue/v1/genesis.go"
assert cl.check_if_in_exempt_files(file) is True

file = "/Users/malte/dev/go/evmos/evmos/x/claims/genesis.go"
assert cl.check_if_in_exempt_files(file) is True

file = "/Users/malte/dev/go/evmos/evmos/x/erc20/keeper/proposals.go"
assert cl.check_if_in_exempt_files(file) is True

file = "/Users/malte/dev/go/evmos/evmos/x/erc20/types/utils.go"
assert cl.check_if_in_exempt_files(file) is True

file = "/Users/malte/dev/go/evmos/evmos/x/evm/genesis.go"
assert cl.check_if_in_exempt_files(file) is False