Skip to content

Commit

Permalink
Add coverage and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vemel committed Aug 23, 2024
1 parent a1cc2bb commit d9d69f9
Show file tree
Hide file tree
Showing 21 changed files with 509 additions and 63 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/on_push_coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Send coverage report

on:
push:
branches:
- main
paths:
- istub/**
- tests/**
workflow_dispatch: {}

jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "poetry"
- name: Install dependencies
run: |
poetry install -n
- name: Build coverage report
run: |
poetry run pytest --cov istub --cov-report=xml --junitxml=junit.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
67 changes: 64 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,68 @@ var/
*.egg-info/
.installed.cfg
*.egg
node_modules

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
junit.xml

nohup*

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
.venv/
venv*
.venv*
ENV/

# Spyder project settings
Expand All @@ -37,6 +95,10 @@ ENV/
# pycharm
.idea*

# Vim swap files
.*.sw?
.sw?

# macOS
.DS_Store

Expand All @@ -48,4 +110,3 @@ ENV/

# Typing
.mypy_cache
.pytest_cache
2 changes: 2 additions & 0 deletions istub.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
packages:
- name: istub
path: ../istub
- name: s3transfer
checks:
stubtest: true
Expand Down
1 change: 0 additions & 1 deletion istub/checks/mypy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,3 @@ def run(self) -> str:
return "\n".join(e.data.splitlines()[:-1])

return ""
return ""
1 change: 1 addition & 0 deletions istub/checks/ruff.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def default_command(self) -> Tuple[str, ...]:
self.python_path,
"-m",
"ruff",
"check",
)

def run(self) -> str:
Expand Down
1 change: 0 additions & 1 deletion istub/checks/stubtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,3 @@ def is_ignored_line_diff(self, line: str) -> bool:
return True

return False
return False
52 changes: 40 additions & 12 deletions istub/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,34 @@
"""

import argparse
import contextlib
import logging
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import List
from typing import List, Sequence

from istub.checks import CHECKS_MAP
from istub.config import Config
from istub.constants import PACKAGE_NAME, PROG_NAME

if sys.version_info >= (3, 8):
from importlib import metadata # type: ignore
else:
import importlib_metadata as metadata # type: ignore


def get_version() -> str:
"""
Get istub package version.
Returns:
Version as a string.
"""
with contextlib.suppress(metadata.PackageNotFoundError):
return metadata.version(PACKAGE_NAME)

return "0.0.0"


@dataclass
Expand Down Expand Up @@ -38,11 +59,11 @@ def load_config(path_str: str) -> Config:
return Config(path)


def parse_args() -> CLINamespace:
def parse_args(args: Sequence[str]) -> CLINamespace:
"""
CLI parser.
"""
parser = argparse.ArgumentParser(__file__)
parser = argparse.ArgumentParser(PROG_NAME)
parser.add_argument("-b", "--build", action="store_true", help="Generate packages")
parser.add_argument("-i", "--install", action="store_true", help="Install packages")
parser.add_argument("-u", "--update", action="store_true", help="Update snapshots")
Expand All @@ -64,19 +85,26 @@ def parse_args() -> CLINamespace:
help="Checks to run",
)
parser.add_argument("-d", "--debug", action="store_true", help="Verbose output")
parser.add_argument("-V", "--version", action="store_true", help="Show version")
parser.add_argument(
"packages",
nargs="*",
help="Packages to check",
)
args = parser.parse_args()
namespace = parser.parse_args(args)

if namespace.version:
version = get_version()
print(version)
exit()

return CLINamespace(
config=args.config or Config(Path.cwd() / "istub.yml"),
build=args.build,
install=args.install,
update=args.update,
exitfirst=args.exitfirst,
packages=args.packages,
log_level=logging.DEBUG if args.debug else logging.INFO,
checks=args.checks,
config=namespace.config or Config(Path.cwd() / "istub.yml"),
build=namespace.build,
install=namespace.install,
update=namespace.update,
exitfirst=namespace.exitfirst,
packages=namespace.packages,
log_level=logging.DEBUG if namespace.debug else logging.INFO,
checks=namespace.checks,
)
2 changes: 2 additions & 0 deletions istub/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
Project contants.
"""

PACKAGE_NAME = "istub"
PROG_NAME = "istub"
LOGGER_NAME = "istub"
20 changes: 13 additions & 7 deletions istub/logger.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
"""
Logging setup.
Logging utils.
"""

import logging

from istub.constants import LOGGER_NAME

FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
TIME_FORMAT = "%H:%M:%S"

def setup_logging(level: int = 0) -> logging.Logger:

def get_logger(level: int = logging.DEBUG) -> logging.Logger:
"""
Get Logger instance.
Get default logger.
Arguments:
level -- Logging level
level -- Python log level
Returns:
Created Logger.
New or existing logger instance.
"""
logger = logging.getLogger(LOGGER_NAME)
if logger.handlers:
return logger

stream_handler = logging.StreamHandler()
formatter = logging.Formatter("%(levelname)s %(message)s", datefmt="%H:%M:%S")
stream_handler.setFormatter(formatter)
stream_handler.setFormatter(logging.Formatter(FORMAT, datefmt=TIME_FORMAT))
stream_handler.setLevel(level)
logger.addHandler(stream_handler)
logger.setLevel(level)

return logger
32 changes: 17 additions & 15 deletions istub/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import logging
import shlex
from typing import List
import sys
from typing import List, Sequence

from istub.cli import CLINamespace, parse_args
from istub.config import Config
from istub.constants import LOGGER_NAME
from istub.exceptions import CheckFailedError, ConfigError, RunFailedError
from istub.logger import setup_logging
from istub.logger import get_logger
from istub.subprocess import check_call


Expand Down Expand Up @@ -101,7 +102,7 @@ def main() -> None:
Entry point for the main CLI.
"""
try:
main_api()
main_api(sys.argv[1:])
except ConfigError as e:
logger = logging.getLogger(LOGGER_NAME)
logger.error(f"Configuration error: {e}")
Expand All @@ -112,25 +113,26 @@ def main() -> None:
exit(1)


def main_api() -> None:
def main_api(args: Sequence[str]) -> None:
"""
Entry point for the main API.
"""
args = parse_args()
logger = setup_logging(args.log_level)
config = args.config
if args.packages:
config.filter_packages(args.packages)
if args.checks:
config.filter_checks(args.checks)
if args.install:
cli_namespace = parse_args(args)

logger = get_logger(cli_namespace.log_level)
config = cli_namespace.config
if cli_namespace.packages:
config.filter_packages(cli_namespace.packages)
if cli_namespace.checks:
config.filter_checks(cli_namespace.checks)
if cli_namespace.install:
pip_install(config)
if args.build and config.build:
if cli_namespace.build and config.build:
build(config)
if args.install:
if cli_namespace.install:
path_install(config)

check_packages(config, args)
check_packages(config, cli_namespace)

if config.is_updated():
logger.info("Saving configuration...")
Expand Down
Loading

0 comments on commit d9d69f9

Please sign in to comment.