Skip to content

Commit

Permalink
add check quality and check coverage commands
Browse files Browse the repository at this point in the history
  • Loading branch information
edd19 committed Nov 5, 2021
1 parent 90d672d commit f5de26d
Show file tree
Hide file tree
Showing 9 changed files with 554 additions and 1 deletion.
17 changes: 17 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[run]
branch = True
source = .
concurrency = multiprocessing
parallel = True
omit =
*/migrations/*
venv/*
*/tests/*

[report]
fail_under = 90
precision = 2
sort = Cover
show_missing = False
skip_covered = True
skip_empty = True
71 changes: 71 additions & 0 deletions install_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2021 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
#
##############################################################################
import glob
import subprocess
import sys
from typing import List
import argparse


DEFAULT_CORE_REQUIREMENTS_FILE = './dev-requirements.txt'

parser = argparse.ArgumentParser(description="A utility to install OSIS project requirements.")
parser.add_argument(
"-c",
"--core",
help="core requirements file (default: dev-requirements.txt)",
default=DEFAULT_CORE_REQUIREMENTS_FILE,
type=str,
metavar="FILE"
)

args = parser.parse_args()


def install(core_file: str) -> None:
install_requirement(core_file)
install_app_requirements()


def install_app_requirements():
app_requirements = find_app_requirements()
for requirement in app_requirements:
install_requirement(requirement)


def find_app_requirements() -> List[str]:
return [file for file in glob.glob("./*/requirements.txt")]


def install_requirement(path: str) -> None:
subprocess.run(
["pip", "install", "-r", path],
stdout=sys.stdout,
stderr=sys.stderr,
universal_newlines=True,
)


install(args.core)
67 changes: 67 additions & 0 deletions management/commands/check_all_app_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# ############################################################################
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2020 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
# ############################################################################
import pathlib
import subprocess
from typing import Tuple

from django.conf import settings
from django.core.management import BaseCommand

OUTPUT_MESSAGE = str
RETURN_CODE = int
SUCCESS_RETURN_CODE = 0


class Command(BaseCommand):
def handle(self, *args, **options):
apps = settings.INSTALLED_APPS
apps_with_locale_directory = [app for app in apps if has_locale_directory(app)]

errors = []
for app in apps_with_locale_directory:
output_message, return_code = check_messages_for_app(app)
if return_code != SUCCESS_RETURN_CODE:
error_message = "{app}\n{output}".format(app=app, output=output_message)
errors.append(error_message)

if errors:
self.stderr.write("\n".join(errors))
raise SystemExit(1)
else:
self.stdout.write("All good")


def check_messages_for_app(app_name: str) -> Tuple[OUTPUT_MESSAGE, RETURN_CODE]:
completed_process = subprocess.run(
["./manage.py", "check_app_messages", app_name],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
return completed_process.stderr, completed_process.returncode


def has_locale_directory(app_name: str) -> bool:
path = pathlib.Path(app_name) / "locale"
return path.exists()
71 changes: 71 additions & 0 deletions management/commands/check_app_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# ############################################################################
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2020 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
# ############################################################################
import os
import subprocess

from osis_common.management.commands import makemessages


class MessagesNotTranslatedException(Exception):
pass


class Command(makemessages.Command):
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument('directory')

def handle(self, *args, **options):
options['keep_pot'] = True
options['verbosity'] = 0

# Change dir for makemessage execution
previous_dir = os.getcwd()
os.chdir(options['directory'])
super().handle(*args, **options)

self.check_all_messages_are_translated()
os.chdir(previous_dir)

def check_all_messages_are_translated(self):
fr_po_file_location = "locale/fr_BE/LC_MESSAGES/django.po"
pot_file_location = "locale/django.pot"

try:
subprocess.run(
["msgcmp", fr_po_file_location, pot_file_location],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
check=True
)
except subprocess.CalledProcessError as e:
self.stderr.write(e.stderr)
raise SystemExit(1)
finally:
self.remove_potfiles()

def write_po_file(self, potfile, locale):
# don't need to overwrite existing po file
pass
108 changes: 108 additions & 0 deletions management/commands/check_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# ############################################################################
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2020 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
# ############################################################################

from django.core.management import BaseCommand

from osis_common.management import utils
from osis_common.management.utils import RunCommandMixin


ALL_APPS = 'ALL'
DEFAULT_TARGET_BRANCH = "origin/dev"


class Command(BaseCommand, RunCommandMixin):
help = "Launch tests and show diff coverage."

def add_arguments(self, parser):
super().add_arguments(parser)

parser.add_argument(
"-t",
"--target_branch",
help="target branch to compare with",
default=DEFAULT_TARGET_BRANCH,
type=str,
metavar="BRANCH"
)

parser.add_argument(
"-a",
"--app",
help="limit to app",
default=ALL_APPS,
type=str,
metavar="APP"
)

def handle(self, *args, **options):
target_branch = options['target_branch']
target_app = options['app']

success = self.run_tests(target_app)
self.show_diff_coverage(target_branch, target_app)

if not success:
self.stdout.write(
self.style.ERROR("TESTS FAILED")
)
raise SystemExit(1)

self.stdout.write(
self.style.SUCCESS("TESTS PASSED")
)

def run_tests(self, target_app: str) -> utils.SUCCESS_RESULT:
return self.run_command(
[
"coverage",
"run",
"--rcfile=osis_common/.coveragerc",
"--source={}/".format(target_app) if target_app != ALL_APPS else "",
"manage.py",
"test",
target_app if target_app != ALL_APPS else "",
"--parallel",
"--no-logs",
"--noinput"
]
)

def show_diff_coverage(self, target_branch: str, target_app):
self.run_command(
["coverage", "combine"],
)

self.run_command(
["coverage", "xml"],
)

self.run_command(
[
"diff-cover",
"../coverage.xml" if target_app != ALL_APPS else "coverage.xml",
"--compare-branch={}".format(target_branch)
],
cwd=self.compute_app_path(target_app) if target_app != ALL_APPS else None
)
Loading

0 comments on commit f5de26d

Please sign in to comment.