Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
43 changes: 43 additions & 0 deletions .github/workflows/python_analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Python analysis

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- develop
- main
- release/**
- feature/**
- hotfix/**
push:
branches:
- develop
- main
- release/**
- feature/**
- hotfix/**

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
call-workflow-static-analysis:
name: Static analysis
uses: MiraGeoscience/CI-tools/.github/workflows/reusable-python-static_analysis.yml@main
with:
package-manager: 'poetry'
app-name: 'mirageoscience'
python-version: '3.10'
call-workflow-pytest:
name: Pytest
uses: MiraGeoscience/CI-tools/.github/workflows/reusable-python-pytest.yml@main
with:
package-manager: 'poetry'
python-versions: '["3.10", "3.11", "3.12"]'
os: '["ubuntu-latest", "windows-latest"]'
cache-number: 1
codecov-reference-python-version: '3.10'
codecov-reference-os: '["windows-latest"]'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ venv.bak/
# mkdocs documentation
/site

#pycharm
/.idea/*
!/.idea/scopes/
!/.idea/copyright/

# mypy
.mypy_cache/
.dmypy.json
Expand Down
8 changes: 8 additions & 0 deletions .idea/copyright/MiraGeoscience.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions .idea/copyright/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .idea/scopes/sources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 17 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
default_language_version:
python: python3
exclude: ^docs/(conf.py|_ext/)
default_stages: [commit,push]
default_stages: [pre-commit,pre-push]
fail_fast: false

ci:
Expand All @@ -16,12 +16,12 @@ repos:
- id: poetry-check
args: [--lock]
- repo: https://github.com/hadialqattan/pycln
rev: v2.4.0
rev: v2.5.0
hooks:
- id: pycln
args: [ --config=pyproject.toml ]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.1
rev: v0.9.1
hooks:
- id: ruff
args:
Expand All @@ -30,33 +30,43 @@ repos:
# - --unsafe-fixes
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.1
rev: v1.14.1
hooks:
- id: mypy
additional_dependencies: [
tomli, # to read config from pyproject.toml
]
- repo: https://github.com/codingjoe/relint
rev: 3.1.1
rev: 3.3.1
hooks:
- id: relint
args: [-W] # to fail on warnings
- repo: https://github.com/MiraGeoscience/pre-commit-hooks
rev: v1.0.0
rev: v1.0.2
hooks:
- id: check-copyright
files: (^LICENSE|^README(|-dev).rst|\.py|\.pyi)$
exclude: (^\.|^docs/)
- id: prepare-commit-msg
- id: check-commit-msg
- repo: local
hooks:
- id: pylint
name: pylint
entry: poetry run pylint
language: system
require_serial: true # pylint does its own parallelism
types: [text]
types_or: [python, pyi]
exclude: ^(devtools|docs)/
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
exclude: (\.lock|\.ipynb|^THIRD_PARTY_SOFTWARE\.rst)$
entry: codespell -I .codespellignore
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: \.mdj$
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Mira Geoscience
Copyright (c) 2024-2025 Mira Geoscience

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
5 changes: 3 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ Usage
Example of ``.pre-commit-config.yamnl``:

.. code:: yaml
repos:

repos:
- repo: http://github.com/MiraGeoscience/pre-commit-hooks
rev: <release>
hooks:
Expand Down Expand Up @@ -63,4 +64,4 @@ SOFTWARE.

Copyright
^^^^^^^^^
Copyright (c) 2024 Mira Geoscience Ltd.
Copyright (c) 2024-2025 Mira Geoscience Ltd.
8 changes: 8 additions & 0 deletions mirageoscience/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Copyright (c) 2024-2025 Mira Geoscience Ltd. '
# '
# This file is part of mirageoscience.pre-commit-hooks package. '
# '
# mirageoscience.pre-commit-hooks is distributed under the terms and conditions '
# of the MIT License (see LICENSE file at the root of this source code package). '
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
17 changes: 9 additions & 8 deletions mirageoscience/hooks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Copyright (c) 2024 Mira Geoscience Ltd. '
# '
# This file is part of mirageoscience.pre-commit-hooks package. '
# '
# All rights reserved. '
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Copyright (c) 2024-2025 Mira Geoscience Ltd. '
# '
# This file is part of mirageoscience.pre-commit-hooks package. '
# '
# mirageoscience.pre-commit-hooks is distributed under the terms and conditions '
# of the MIT License (see LICENSE file at the root of this source code package). '
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

__version__ = "1.0.2"
__version__ = "1.1.0"
90 changes: 66 additions & 24 deletions mirageoscience/hooks/check_copyright.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,62 @@
#!/usr/bin/env python3

# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Copyright (c) 2024 Mira Geoscience Ltd. '
# '
# This file is part of mirageoscience.pre-commit-hooks package. '
# '
# mirageoscience_pre_commit_hooks is distributed under the terms and conditions of '
# the MIT License (see LICENSE file at the root of this source code package). '
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Copyright (c) 2024-2025 Mira Geoscience Ltd. '
# '
# This file is part of mirageoscience.pre-commit-hooks package. '
# '
# mirageoscience.pre-commit-hooks is distributed under the terms and conditions '
# of the MIT License (see LICENSE file at the root of this source code package). '
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

from __future__ import annotations

import argparse
import re
import sys
from datetime import date
from pathlib import Path


def main(args=None):
MAX_TOP_LINES = 10
_FULL_SCAN_FILE_NAMES = ["README.rst", "README-dev.rst", "package.rst"]


def check_files(
files: list[str] | None = None, full_scan_files: list[str] | None = None
) -> bool:
"""Checks for valid copyright statements in given files.

This function scans the specified files for copyright notices and reports
any files that either lack a copyright statement or have an invalid year.

Args:
args (list, optional): A list of filenames to be checked. Defaults to
files (list, optional): A list of filenames to be checked. Defaults to
`sys.argv[1:]` if not provided.
full_scan_files (list, optional): A list of filenames to be scanned
entirely, instead of checking only the top lines.

Raises:
SystemExit: Exits the program with an exit code of 1 if any
files have missing or invalid copyright statements.
Returns:
bool: True if all files have valid copyright statements,
False otherwise.
"""
current_year = date.today().year
copyright_re = re.compile(
rf"\bcopyright \(c\) (:?\d{{4}}-|)\b{current_year}\b", re.IGNORECASE
)
files = sys.argv[1:]
max_lines = 10
if full_scan_files is None:
full_scan_files = []
if files is None:
files = sys.argv[1:]
file_paths = [Path(f) for f in files]
report_files = []
for f in files:
for f in file_paths:
with open(f, encoding="utf-8") as file:
count = 0
has_dated_copyright = False
for line in file:
count += 1
if count >= max_lines and not (
f.endswith("README.rst") or f.endswith("README-dev.rst") or f.endswith("package.rst")
):
if count >= MAX_TOP_LINES and f.name not in full_scan_files:
break
if re.search(copyright_re, line):
has_dated_copyright = True
Expand All @@ -54,15 +65,46 @@ def main(args=None):
if not has_dated_copyright:
report_files.append(f)

if len(report_files) > 0:
for f in report_files:
sys.stderr.write(f"{f}: No copyright or invalid year\n")
exit(1)
if len(report_files) == 0:
return True

for f in report_files:
sys.stderr.write(f"{f}: No copyright or invalid year\n")
return False

# readonly CURRENT_YEAR=$(date +"%Y")

def main():
"""Parses command line arguments and calls the `check_files` function.

Raises:
SystemExit: If check_files returns False.
"""

parser = argparse.ArgumentParser()
parser.add_argument("files", nargs="+", help="list of files to scan")
parser.add_argument(
"--full-scan-files",
type=lambda s: s.split(","),
help=(
"Comma-separated list of names for files to scan entirely, "
f"instead of checking only the top {MAX_TOP_LINES} lines"
),
metavar="FILE1,FILE2,...",
default=[],
required=False,
)

args = parser.parse_args()
if not check_files(args.files, _FULL_SCAN_FILE_NAMES + args.full_scan_files):
sys.exit(1)


# Note: a simpler bash script for this task would be:
# ----------------------------
# readonly CURRENT_YEAR=$(date +"%Y")
#
# if ! grep -e "Copyright (c) .*$CURRENT_YEAR" $(head -10 $f) 2>&1 1>/dev/null; then
# echo "File '$f' has no copyright or an invalid year"
# exit 1
# fi
# ----------------------------
Loading