Skip to content

Commit

Permalink
Merge pull request #11362 from archesproject/jtw/graph-in-every-langu…
Browse files Browse the repository at this point in the history
…age-check

Add check for published graph in every system language #10079
  • Loading branch information
chrabyrd authored Nov 1, 2024
2 parents 7243ae3 + 89fd1c8 commit 7289bd3
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .github/actions/build-and-test-branch/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ runs:

- name: Ensure frontend configuration files exist
run: |
python manage.py check
python manage.py check --tag=compatibility
shell: bash

- name: Install Arches applications
Expand Down Expand Up @@ -74,7 +74,7 @@ runs:

- name: Check for missing migrations
run: |
python manage.py makemigrations --check
python manage.py makemigrations --check --skip-checks
shell: bash

- name: Ensure previous Python coverage data is erased
Expand Down
49 changes: 49 additions & 0 deletions arches/app/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from arches.app.utils import import_class_from_string
from django.contrib.auth.models import Group, User
from django.contrib.gis.db import models
from django.core import checks
from django.core.exceptions import ObjectDoesNotExist
from django.db import connection
from django.db.models import JSONField
Expand Down Expand Up @@ -612,6 +613,39 @@ def save(self, *args, **kwargs):

super(GraphModel, self).save(*args, **kwargs)

@classmethod
def check(cls, **kwargs):
errors = super().check(**kwargs)
errors.extend(cls._check_publication_in_every_language())
return errors

@classmethod
def _check_publication_in_every_language(cls):
errors = []
system_languages = {lang[0] for lang in settings.LANGUAGES}

for graph in (
cls.objects.filter(publication__isnull=False)
.select_related("publication")
.prefetch_related("publication__publishedgraph_set")
):
languages_with_a_publication = {
published_graph.language_id
for published_graph in graph.publication.publishedgraph_set.all()
}
missing_languages = system_languages - languages_with_a_publication
if missing_languages:
errors.append(
checks.Error(
"This graph is not published in all enabled languages.",
hint="Run python manage.py graph publish --update",
obj=graph,
id="arches.E004", # TODO: enum in arches 8
)
)

return errors

def __str__(self):
return str(self.name)

Expand Down Expand Up @@ -2289,3 +2323,18 @@ def to_json(self):
"attributenodes": self.attributenodes,
"isactive": self.isactive,
}


# Import proxy models to ensure they are always discovered.
# For example, if the urls.py module is not imported because a management command
# skips system checks, the coincidental importing of the Graph(Proxy)Model
# by certain views will not happen, and Django will never find the proxy models.
# Long term, we want the module in INSTALLED_APPS (arches.app.models)
# to contain all the models, usually done by creating arches.app.models.__init__,
# but there's a circular import between the model and proxy model that subclasses it.
# The circular import is the same reason these imports are at the bottom of this file.
# Or can we replace the proxy models by moving functionality to plain model methods?
from .card import *
from .graph import *
from .resource import *
from .tile import *
3 changes: 0 additions & 3 deletions arches/app/utils/index_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
import uuid
import pyprind
import sys
import django

django.setup()

from datetime import datetime
from django.db import connection, connections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ runs:

- name: Ensure frontend configuration files exist
run: |
python manage.py check
python manage.py check --tag=compatibility
shell: bash

- name: Install Arches applications
Expand Down Expand Up @@ -74,7 +74,7 @@ runs:

- name: Check for missing migrations
run: |
python manage.py makemigrations --check
python manage.py makemigrations --check --skip-checks
shell: bash

- name: Ensure previous Python coverage data is erased
Expand Down
4 changes: 4 additions & 0 deletions arches/management/commands/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class Command(BaseCommand):
"""

# Silence system checks since this command is the cure for
# one of the system checks (arches.E004)
requires_system_checks = []

def add_arguments(self, parser):
parser.add_argument(
"operation",
Expand Down
3 changes: 3 additions & 0 deletions arches/management/commands/setup_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class Command(BaseCommand):
during development.
"""

# Silence system checks: this command should always succeed.
requires_system_checks = []

def add_arguments(self, parser):

parser.add_argument(
Expand Down
1 change: 1 addition & 0 deletions releases/8.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Arches 8.0.0 Release Notes

### Additional highlights
- Add session-based REST APIs for login, logout [#11261](https://github.com/archesproject/arches/issues/11261)
- Add system check advising next action when enabling additional languages without updating graphs [#10079](https://github.com/archesproject/arches/issues/10079)
- Improve handling of longer model names [#11317](https://github.com/archesproject/arches/issues/11317)
- Support more expressive plugin URLs [#11320](https://github.com/archesproject/arches/issues/11320)
- Concepts API no longer responds with empty body for error conditions [#11519](https://github.com/archesproject/arches/issues/11519)
Expand Down
7 changes: 4 additions & 3 deletions tests/utils/test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest import mock

from django.apps import apps
from django.core.checks import Tags
from django.core.management import call_command
from django.core.management.base import SystemCheckError
from django.test import SimpleTestCase, override_settings
Expand Down Expand Up @@ -31,20 +32,20 @@ def test_compatibility(self):
SystemCheckError,
"Arches requirement is invalid, missing, or given by a URL.",
):
call_command("check")
call_command("check", tag=[Tags.compatibility])

# Mock having to go to the pyproject.toml
with mock.patch("arches.apps.requires", raise_package_not_found_error):
with self.assertRaisesMessage(
SystemCheckError,
"Arches requirement is invalid, missing, or given by a URL.",
):
call_command("check")
call_command("check", tag=[Tags.compatibility])

# Mock an incompatible version requirement.
with mock.patch(
"arches.apps.requires",
lambda app_name: ["arches-for-x==0.0.1", "arches==1.0.1"],
):
with self.assertRaisesMessage(SystemCheckError, "arches==1.0.1"):
call_command("check")
call_command("check", tag=[Tags.compatibility])

0 comments on commit 7289bd3

Please sign in to comment.