feat: warn on multiple class overrides (#34169)

This commit is contained in:
Raffael Meyer 2025-10-25 14:38:31 +02:00 committed by GitHub
parent 69b857a8f4
commit ea4cdf68f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 1 deletions

View file

@ -296,6 +296,14 @@ def install_app(name, verbose=False, set_as_patched=True, force=False):
print(f"\nInstalling {name}...")
other_class_overrides = frappe.get_hooks("override_doctype_class")
if (
other_class_overrides
and app_hooks.override_doctype_class
and any(dt in app_hooks.override_doctype_class for dt in other_class_overrides)
):
click.secho(f"App {name} overrides a doctype that is already overridden by another app.", fg="yellow")
if name != "frappe":
frappe.only_for("System Manager")

View file

@ -7,8 +7,11 @@ import json
import os
import threading
import time
from collections import defaultdict
from textwrap import dedent
import click
import frappe
import frappe.model.sync
import frappe.modules.patch_handler
@ -24,7 +27,7 @@ from frappe.modules.utils import sync_customizations
from frappe.search.website_search import build_index_for_all_routes
from frappe.utils.connections import check_connection
from frappe.utils.dashboard import sync_dashboards
from frappe.utils.data import cint
from frappe.utils.data import cint, comma_and
from frappe.utils.fixtures import sync_fixtures
from frappe.website.utils import clear_website_cache
@ -115,10 +118,21 @@ class SiteMigration:
@atomic
def pre_schema_updates(self):
"""Executes `before_migrate` hooks"""
overrides = defaultdict(list)
for app in frappe.get_installed_apps():
for fn in frappe.get_hooks("before_migrate", app_name=app):
frappe.get_attr(fn)()
for doctype in frappe.get_hooks("override_doctype_class", {}, app_name=app).keys():
overrides[doctype].append(app)
for doctype, app_names in overrides.items():
if len(app_names) > 1:
click.secho(
f"The controller for {doctype} is overridden by multiple apps: {comma_and(app_names, add_quotes=False)}.",
fg="yellow",
)
@atomic
def run_schema_updates(self):
"""Run patches as defined in patches.txt, sync schema changes as defined in the {doctype}.json files"""