Skip to content

Commit

Permalink
#13 Clean up code
Browse files Browse the repository at this point in the history
  • Loading branch information
mcsken committed Nov 15, 2024
1 parent fbf9d59 commit 4c73ce1
Show file tree
Hide file tree
Showing 28 changed files with 894 additions and 936 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
check-style:
runs-on: ubuntu-latest
# Disable pre-commit check on main and production to prevent
# pull request merges to fail with don't commit to branch".
# pull request merges to fail with don't commit to branch.
if: github.ref != 'refs/heads/main'
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions .license-in-code
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Copyright (C) 2024 by Siisurit e.U., Austria.
All rights reserved. Distributed under the MIT License.
15 changes: 12 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,18 @@ repos:
- id: end-of-file-fixer
- id: mixed-line-ending

# TODO#13 Add check for copyright. Use:
# Copyright (c) 2024, Siisurit e.U.
# All rights reserved. Distributed under the MIT License.
- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.5.5
hooks:
- id: insert-license
files: \.(po|py)$
args:
- --license-filepath=.license-in-code
- --comment-style=#
- --detect-license-in-X-top-lines=2
- --no-extra-eol
- --allow-past-years # Using these arguments allows for a date range
- --use-current-year # (original_date - current_date) to be generated.

# NOTE: This should be the last check to ensure everything else is checked
# even for the rare case a commit should go into one of the protected
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# check_done

Check_done is a command line tool to check that finished issues and pull requests in a GitHub project board are really done.
check_done is a command line tool to check that finished issues and pull requests in a GitHub project board are really done.

## Configuration

Expand Down
2 changes: 2 additions & 0 deletions check_done/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright (C) 2024 by Siisurit e.U., Austria.
# All rights reserved. Distributed under the MIT License.
from importlib.metadata import version

__version__ = version(__name__)
93 changes: 0 additions & 93 deletions check_done/checks.py

This file was deleted.

6 changes: 4 additions & 2 deletions check_done/command.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Copyright (C) 2024 by Siisurit e.U., Austria.
# All rights reserved. Distributed under the MIT License.
import argparse
import logging
import sys

import check_done
from check_done.checks import check_done_project_items_for_warnings
from check_done.done_project_items_info import done_project_items_info
from check_done.warning_checks import warnings_for_done_project_items

logger = logging.getLogger(__name__)

Expand All @@ -29,7 +31,7 @@ def apply_arguments(self, arguments=None):
@staticmethod
def execute():
done_project_items = done_project_items_info()
warnings = check_done_project_items_for_warnings(done_project_items)
warnings = warnings_for_done_project_items(done_project_items)
if len(warnings) == 0:
logger.info("check_done found no problems with the items in the specified project state/column.")
else:
Expand Down
97 changes: 10 additions & 87 deletions check_done/common.py → check_done/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright (C) 2024 by Siisurit e.U., Austria.
# All rights reserved. Distributed under the MIT License.
import os
import re
import string
Expand All @@ -7,10 +9,8 @@

import yaml
from dotenv import load_dotenv
from pydantic import BaseModel, Field, field_validator, model_validator
from requests.auth import AuthBase

# TODO#13: Move parts to separate module "config".
from pydantic import Field, field_validator, model_validator
from pydantic.dataclasses import dataclass

load_dotenv()

Expand All @@ -23,13 +23,14 @@
)


class ConfigurationInfo2(BaseModel):
@dataclass
class ConfigurationInfo:
project_url: str

# Required for user project
# Required for user owned project
personal_access_token: str | None = None

# Required for organization project
# Required for organization owned project
check_done_github_app_id: str | None = None
check_done_github_app_private_key: str | None = None

Expand Down Expand Up @@ -59,61 +60,11 @@ def value_from_env(cls, value: Any | None):
return result

@model_validator(mode="after")
def validate_at_least_one_authentication_method_in_configuration(self):
def validate_project_details_from_url_and_at_least_one_authentication_method_in_configuration(self):
self.project_owner_type, self.project_owner_name, self.project_number = (
github_project_owner_type_and_project_owner_name_and_project_number_from_url_if_matches(self.project_url)
)
has_user_authentication = (
self.personal_access_token is not None and self.project_owner_type == ProjectOwnerType.User.value
)
has_organizational_authentication = (
self.check_done_github_app_id is not None
and self.check_done_github_app_private_key is not None
and self.project_owner_type == ProjectOwnerType.Organization.value
)
if not (has_user_authentication or has_organizational_authentication):
raise ValueError("At least one authentication method must be configured.")
return self


class YamlInfo(BaseModel):
check_done_github_app_id: str | None = None
check_done_github_app_private_key: str | None = None
personal_access_token: str | None = None
project_status_name_to_check: str | None = None
project_url: str

# TODO#13: Add more descriptive error messages than the default pydantic for miss-configurations.

@field_validator(
"project_url",
"project_status_name_to_check",
"personal_access_token",
"check_done_github_app_id",
"check_done_github_app_private_key",
mode="before",
)
def value_from_env(cls, value: Any | None):
stripped_value = value.strip()
result = (
resolved_environment_variables(value, fail_on_missing_envvar=False)
if stripped_value.startswith("${") and stripped_value.endswith("}")
else stripped_value
)
return result


class ConfigurationInfo(BaseModel):
check_done_github_app_id: str | None = None
check_done_github_app_private_key: str | None = None
personal_access_token: str | None = None
project_number: int
project_owner_name: str
project_owner_type: str
project_status_name_to_check: str | None = None

@model_validator(mode="after")
def validate_at_least_one_authentication_method_in_configuration(self):
has_user_authentication = (
self.personal_access_token is not None and self.project_owner_type == ProjectOwnerType.User.value
)
Expand All @@ -129,20 +80,7 @@ def validate_at_least_one_authentication_method_in_configuration(self):

def configuration_info() -> ConfigurationInfo:
yaml_map = configuration_map_from_yaml_file(_CONFIGURATION_PATH)
yaml_info = YamlInfo(**yaml_map)
project_url = yaml_info.project_url
project_owner_type, project_owner_name, project_number = (
github_project_owner_type_and_project_owner_name_and_project_number_from_url_if_matches(project_url)
)
return ConfigurationInfo(
check_done_github_app_id=yaml_info.check_done_github_app_id,
check_done_github_app_private_key=yaml_info.check_done_github_app_private_key,
personal_access_token=yaml_info.personal_access_token,
project_number=project_number,
project_owner_name=project_owner_name,
project_owner_type=project_owner_type,
project_status_name_to_check=yaml_info.project_status_name_to_check,
)
return ConfigurationInfo(**yaml_map)


class ProjectOwnerType(StrEnum):
Expand Down Expand Up @@ -189,18 +127,3 @@ def configuration_map_from_yaml_file(configuration_path: Path) -> dict:
except FileNotFoundError as error:
raise FileNotFoundError(f"Cannot find check_done configuration: {configuration_path}") from error
return result


class AuthenticationError(Exception):
"""Error raised due to failed JWT authentication process."""


class HttpBearerAuth(AuthBase):
# Source:
# <https://stackoverflow.com/questions/29931671/making-an-api-call-in-python-with-an-api-that-requires-a-bearer-token>
def __init__(self, token):
self.token = token

def __call__(self, request):
request.headers["Authorization"] = "Bearer " + self.token
return request
Loading

0 comments on commit 4c73ce1

Please sign in to comment.