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

Split settings.BASE_DIR into MODULE and DATADIR #2374

Merged
merged 6 commits into from
Feb 3, 2025
Merged
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
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ evap/localsettings.py
evap/static/css/evap.css
evap/static/css/evap.css.map
evap/static/ts/rendered
evap/static_collected
evap/media
evap/database.sqlite3
evap/upload

evap/evaluation/templates/legal_notice_text.html

Expand Down
4 changes: 1 addition & 3 deletions evap/development/management/commands/dump_testdata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os

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

Expand All @@ -12,7 +10,7 @@ class Command(BaseCommand):
requires_migrations_checks = True

def handle(self, *args, **options):
outfile_name = os.path.join(settings.BASE_DIR, "development", "fixtures", "test_data.json")
outfile_name = settings.MODULE / "development" / "fixtures" / "test_data.json"
logged_call_command(
self.stdout,
"dumpdata",
Expand Down
18 changes: 14 additions & 4 deletions evap/development/management/commands/reload_testdata.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import shutil

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

from evap.evaluation.management.commands.tools import confirm_harmful_operation, logged_call_command


class Command(BaseCommand):
args = ""
help = "Drops the database, recreates it and then loads the testdata."
help = "Drops the database, recreates it, and then loads the testdata. Also resets the upload directory."

def add_arguments(self, parser):
parser.add_argument("--noinput", action="store_true")

def handle(self, *args, **options):
self.stdout.write("")
self.stdout.write("WARNING! This will drop the database and cause IRREPARABLE DATA LOSS.")
if not confirm_harmful_operation(self.stdout):
self.stdout.write("WARNING! This will drop the database and upload directory and cause IRREPARABLE DATA LOSS.")
if not options["noinput"] and not confirm_harmful_operation(self.stdout):
return

logged_call_command(self.stdout, "reset_db", interactive=False)
Expand All @@ -27,4 +32,9 @@ def handle(self, *args, **options):

logged_call_command(self.stdout, "refresh_results_cache")

upload_dir = settings.MEDIA_ROOT
if upload_dir.exists():
shutil.rmtree(upload_dir)
richardebeling marked this conversation as resolved.
Show resolved Hide resolved
shutil.copytree(settings.MODULE / "development" / "fixtures" / "upload", upload_dir)

self.stdout.write("Done.")
24 changes: 14 additions & 10 deletions evap/development/tests/test_commands.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
from io import StringIO
from unittest.mock import call, patch

Expand All @@ -14,7 +13,7 @@ def test_dumpdata_called():
with patch("evap.evaluation.management.commands.tools.call_command") as mock:
management.call_command("dump_testdata", stdout=StringIO())

outfile_name = os.path.join(settings.BASE_DIR, "development", "fixtures", "test_data.json")
outfile_name = settings.MODULE / "development" / "fixtures" / "test_data.json"
mock.assert_called_once_with(
"dumpdata",
"auth.group",
Expand All @@ -31,20 +30,20 @@ def test_dumpdata_called():


class TestReloadTestdataCommand(TestCase):
@patch("builtins.input")
@patch("builtins.input", return_value="not yes")
@patch("evap.development.management.commands.reload_testdata.shutil")
@patch("evap.evaluation.management.commands.tools.call_command")
def test_aborts(self, mock_call_command, mock_input):
mock_input.return_value = "not yes"

def test_aborts(self, mock_call_command, mock_shutil, _mock_input):
management.call_command("reload_testdata", stdout=StringIO())

self.assertEqual(mock_call_command.call_count, 0)
self.assertFalse(mock_shutil.method_calls)

@patch("builtins.input")
@patch("builtins.input", return_value="yes")
@patch("pathlib.Path.exists", return_value=True)
@patch("evap.development.management.commands.reload_testdata.shutil")
@patch("evap.evaluation.management.commands.tools.call_command")
def test_executes_key_commands(self, mock_call_command, mock_input):
mock_input.return_value = "yes"

def test_executes_key_commands(self, mock_call_command, mock_shutil, mock_exists, _mock_input):
management.call_command("reload_testdata", stdout=StringIO())

mock_call_command.assert_any_call("reset_db", interactive=False)
Expand All @@ -56,6 +55,11 @@ def test_executes_key_commands(self, mock_call_command, mock_input):

self.assertEqual(mock_call_command.call_count, 6)

# The directory for uploads is cleared and reinitialized
mock_exists.assert_called_once()
mock_shutil.rmtree.assert_called_once()
mock_shutil.copytree.assert_called_once()


class TestRunCommand(TestCase):
def test_calls_runserver(self):
Expand Down
6 changes: 2 additions & 4 deletions evap/development/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os

from django.conf import settings
from django.core.exceptions import BadRequest
from django.http import HttpResponse
Expand All @@ -16,9 +14,9 @@ def development_components(request):


def development_rendered(request, filename):
fixtures_directory = os.path.join(settings.STATICFILES_DIRS[0], "ts", "rendered")
fixtures_directory = settings.STATICFILES_DIRS[0] / "ts" / "rendered"
try:
with open(os.path.join(fixtures_directory, filename), encoding="utf-8") as fixture:
with open(fixtures_directory / filename, encoding="utf-8") as fixture:
return HttpResponse(fixture)
except (FileNotFoundError, ValueError, OSError) as e:
raise BadRequest from e
5 changes: 2 additions & 3 deletions evap/evaluation/management/commands/scss.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import subprocess # nosec

from django.conf import settings
Expand All @@ -24,8 +23,8 @@ def handle(self, *args, **options):
command = [
"npx",
"sass",
os.path.join(static_directory, "scss", "evap.scss"),
os.path.join(static_directory, "css", "evap.css"),
static_directory / "scss" / "evap.scss",
static_directory / "css" / "evap.css",
]

if options["watch"]:
Expand Down
8 changes: 2 additions & 6 deletions evap/evaluation/management/commands/ts.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import argparse
import os
import subprocess # nosec
import unittest

Expand Down Expand Up @@ -67,17 +66,14 @@
"npx",
"tsc",
"--project",
os.path.join(static_directory, "ts", "tsconfig.compile.json"),
static_directory / "ts" / "tsconfig.compile.json",
]

if watch:
command += ["--watch"]

if fresh:
try:
os.remove(os.path.join(static_directory, "ts", ".tsbuildinfo.json"))
except FileNotFoundError:
pass
(static_directory / "ts" / ".tsbuildinfo.json").unlink(missing_ok=True)

Check warning on line 76 in evap/evaluation/management/commands/ts.py

View check run for this annotation

Codecov / codecov/patch

evap/evaluation/management/commands/ts.py#L76

Added line #L76 was not covered by tests

self.run_command(command)

Expand Down
13 changes: 6 additions & 7 deletions evap/evaluation/tests/test_commands.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import random
from collections import defaultdict
from datetime import date, datetime, timedelta
Expand Down Expand Up @@ -204,8 +203,8 @@ def test_calls_cache_results(self):

class TestScssCommand(TestCase):
def setUp(self):
self.scss_path = os.path.join(settings.STATICFILES_DIRS[0], "scss", "evap.scss")
self.css_path = os.path.join(settings.STATICFILES_DIRS[0], "css", "evap.css")
self.scss_path = settings.STATICFILES_DIRS[0] / "scss" / "evap.scss"
self.css_path = settings.STATICFILES_DIRS[0] / "css" / "evap.css"

@patch("subprocess.run")
def test_scss_called(self, mock_subprocess_run):
Expand Down Expand Up @@ -246,14 +245,14 @@ def test_scss_called_with_no_sass_installed(self, mock_subprocess_run):

class TestTsCommand(TestCase):
def setUp(self):
self.ts_path = os.path.join(settings.STATICFILES_DIRS[0], "ts")
self.ts_path = settings.STATICFILES_DIRS[0] / "ts"

@patch("subprocess.run")
def test_ts_compile(self, mock_subprocess_run):
management.call_command("ts", "compile")

mock_subprocess_run.assert_called_once_with(
["npx", "tsc", "--project", os.path.join(self.ts_path, "tsconfig.compile.json")],
["npx", "tsc", "--project", self.ts_path / "tsconfig.compile.json"],
check=True,
)

Expand All @@ -264,7 +263,7 @@ def test_ts_compile_with_watch(self, mock_subprocess_run):
management.call_command("ts", "compile", "--watch")

mock_subprocess_run.assert_called_once_with(
["npx", "tsc", "--project", os.path.join(self.ts_path, "tsconfig.compile.json"), "--watch"],
["npx", "tsc", "--project", self.ts_path / "tsconfig.compile.json", "--watch"],
check=True,
)

Expand All @@ -280,7 +279,7 @@ def test_ts_test(self, mock_render_pages, mock_call_command, mock_subprocess_run
mock_subprocess_run.assert_has_calls(
[
call(
["npx", "tsc", "--project", os.path.join(self.ts_path, "tsconfig.compile.json")],
["npx", "tsc", "--project", self.ts_path / "tsconfig.compile.json"],
check=True,
),
call(["npx", "jest"], check=True),
Expand Down
5 changes: 2 additions & 3 deletions evap/evaluation/tests/test_misc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os.path
from io import StringIO

from django.conf import settings
Expand Down Expand Up @@ -29,7 +28,7 @@ def test_sample_semester_file(self):
original_user_count = UserProfile.objects.count()

form = page.forms["semester-import-form"]
form["excel_file"] = (os.path.join(settings.BASE_DIR, "static", "sample.xlsx"),)
form["excel_file"] = (str(settings.MODULE / "static" / "sample.xlsx"),)
page = form.submit(name="operation", value="test")

form = page.forms["semester-import-form"]
Expand All @@ -45,7 +44,7 @@ def test_sample_user_file(self):
original_user_count = UserProfile.objects.count()

form = page.forms["user-import-form"]
form["excel_file"] = (os.path.join(settings.BASE_DIR, "static", "sample_user.xlsx"),)
form["excel_file"] = (str(settings.MODULE / "static" / "sample_user.xlsx"),)
page = form.submit(name="operation", value="test")

form = page.forms["user-import-form"]
Expand Down
4 changes: 2 additions & 2 deletions evap/evaluation/tests/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ def let_user_vote_for_evaluation(user, evaluation, create_answers=False):


def store_ts_test_asset(relative_path: str, content) -> None:
absolute_path = os.path.join(settings.STATICFILES_DIRS[0], "ts", "rendered", relative_path)
absolute_path = settings.STATICFILES_DIRS[0] / "ts" / "rendered" / relative_path

os.makedirs(os.path.dirname(absolute_path), exist_ok=True)
absolute_path.parent.mkdir(parents=True, exist_ok=True)

with open(absolute_path, "wb") as file:
file.write(content)
Expand Down
4 changes: 0 additions & 4 deletions evap/logs/.gitignore

This file was deleted.

17 changes: 9 additions & 8 deletions evap/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
"""

import logging
import os
import sys
from fractions import Fraction
from pathlib import Path
from typing import Any

from django.contrib.staticfiles.storage import ManifestStaticFilesStorage

from evap.tools import MonthAndDay

BASE_DIR = os.path.dirname(os.path.realpath(__file__))

MODULE = Path(__file__).parent.resolve()
CWD = Path(".").resolve()
DATADIR = CWD / "data"

### Debugging

Expand Down Expand Up @@ -184,7 +185,7 @@ class ManifestStaticFilesStorageWithJsReplacement(ManifestStaticFilesStorage):
"file": {
"level": "DEBUG",
"class": "logging.handlers.RotatingFileHandler",
"filename": BASE_DIR + "/logs/evap.log",
"filename": DATADIR / "evap.log",
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
"formatter": "default",
Expand Down Expand Up @@ -334,7 +335,7 @@ class ManifestStaticFilesStorageWithJsReplacement(ManifestStaticFilesStorage):

USE_TZ = False

LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")]
LOCALE_PATHS = [MODULE / "locale"]

FORMAT_MODULE_PATH = ["evap.locale"]

Expand All @@ -351,17 +352,17 @@ class ManifestStaticFilesStorageWithJsReplacement(ManifestStaticFilesStorage):

# Additional locations of static files
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
MODULE / "static",
]

# Absolute path to the directory static files should be collected to.
STATIC_ROOT = os.path.join(BASE_DIR, "static_collected")
STATIC_ROOT = DATADIR / "static_collected"


### User-uploaded files

# Absolute filesystem path to the directory that will hold user-uploaded files.
MEDIA_ROOT = os.path.join(BASE_DIR, "upload")
MEDIA_ROOT = DATADIR / "upload"

### Evaluation progress rewards
GLOBAL_EVALUATION_PROGRESS_REWARDS: list[tuple[Fraction, str]] = (
Expand Down
3 changes: 1 addition & 2 deletions evap/staff/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import csv
import datetime
import os
from abc import ABC, abstractmethod
from io import BytesIO
from typing import Literal
Expand Down Expand Up @@ -420,7 +419,7 @@ def test_shows_swap_users_option(self):

class TestUserBulkUpdateView(WebTestStaffMode):
url = "/staff/user/bulk_update"
filename = os.path.join(settings.BASE_DIR, "staff/fixtures/test_user_bulk_update_file.txt")
filename = str(settings.MODULE / "staff" / "fixtures" / "test_user_bulk_update_file.txt")

@classmethod
def setUpTestData(cls):
Expand Down
10 changes: 3 additions & 7 deletions evap/staff/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import os
import time
from contextlib import contextmanager

from evap.evaluation.tests.tools import WebTest, WebTestWith200Check
from evap.staff.tools import ImportType, generate_import_filename
from evap.staff.tools import ImportType, generate_import_path


def helper_enter_staff_mode(webtest):
Expand Down Expand Up @@ -46,11 +45,8 @@ def setUp(self):

def helper_delete_all_import_files(user_id):
for import_type in ImportType:
filename = generate_import_filename(user_id, import_type)
try:
os.remove(filename)
except FileNotFoundError:
pass
path = generate_import_path(user_id, import_type)
path.unlink(missing_ok=True)


# For some form fields, like a <select> which can be configured to create new options,
Expand Down
Loading
Loading