Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ci modifications #351

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
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
14 changes: 0 additions & 14 deletions .codeclimate.yml

This file was deleted.

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
38 changes: 0 additions & 38 deletions .travis.yml

This file was deleted.

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