Browse Source

Merge pull request #19245 from Ultimaker/CURA-10899_warn_experimental_settings_used

CURA-10899 Warn if experimental settings are used
HellAholic 2 weeks ago
parent
commit
3f0fc3e399

+ 1 - 0
.printer-linter

@@ -2,6 +2,7 @@ checks:
     diagnostic-mesh-file-extension: true
     diagnostic-mesh-file-size: true
     diagnostic-definition-redundant-override: true
+    diagnostic-definition-experimental-setting: true
     diagnostic-resources-macos-app-directory-name: true
     diagnostic-incorrect-formula: true
     diagnostic-resource-file-deleted: true

+ 2 - 2
printer-linter/src/printerlinter/factory.py

@@ -14,10 +14,10 @@ def getLinter(file: Path, settings: dict) -> Optional[List[Linter]]:
     if not file.exists():
         return [Directory(file, settings)]
 
-    if ".inst" in file.suffixes and ".cfg" in file.suffixes:
+    if ".inst" in file.suffixes and file.suffixes[-1] == ".cfg":
         return [Directory(file, settings), Profile(file, settings), Formulas(file, settings)]
 
-    if ".def" in file.suffixes and ".json" in file.suffixes:
+    if ".def" in file.suffixes and file.suffixes[-1] == ".json":
         if file.stem in ("fdmprinter.def", "fdmextruder.def"):
             return  [Formulas(file, settings)]
         return [Directory(file, settings), Definition(file, settings), Formulas(file, settings)]

+ 36 - 6
printer-linter/src/printerlinter/linters/defintion.py

@@ -13,8 +13,11 @@ class Definition(Linter):
     def __init__(self, file: Path, settings: dict) -> None:
         super().__init__(file, settings)
         self._definitions = {}
+        self._definition_name = None
+        self._experimental_settings = []
         self._loadDefinitionFiles(file)
         self._content = self._file.read_text()
+        self._loadExperimentalSettings()
         self._loadBasePrinterSettings()
 
     @property
@@ -32,6 +35,10 @@ class Definition(Linter):
             for check in self.checkMaterialTemperature():
                 yield check
 
+        if self._settings["checks"].get("diagnostic-definition-experimental-setting", False):
+            for check in self.checkExperimentalSetting():
+                yield check
+
         # Add other which will yield Diagnostic's
         # TODO: A check to determine if the user set value is with the min and max value defined in the parent and doesn't trigger a warning
         # TODO: A check if the key exist in the first place
@@ -41,9 +48,8 @@ class Definition(Linter):
 
     def checkRedefineOverride(self) -> Iterator[Diagnostic]:
         """ Checks if definition file overrides its parents settings with the same value. """
-        definition_name = list(self._definitions.keys())[0]
-        definition = self._definitions[definition_name]
-        if "overrides" in definition and definition_name not in ("fdmprinter", "fdmextruder"):
+        definition = self._definitions[self._definition_name]
+        if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"):
             for key, value_dict in definition["overrides"].items():
                 is_redefined, child_key, child_value, parent, inherited_by= self._isDefinedInParent(key, value_dict, definition['inherits'])
                 if is_redefined:
@@ -71,9 +77,8 @@ class Definition(Linter):
 
     def checkMaterialTemperature(self) -> Iterator[Diagnostic]:
         """Checks if definition file has material tremperature defined within them"""
-        definition_name = list(self._definitions.keys())[0]
-        definition = self._definitions[definition_name]
-        if "overrides" in definition and definition_name not in ("fdmprinter", "fdmextruder"):
+        definition = self._definitions[self._definition_name]
+        if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"):
             for key, value_dict in definition["overrides"].items():
                 if "temperature" in key and "material" in key:
 
@@ -97,6 +102,22 @@ class Definition(Linter):
                         replacements=replacements
                     )
 
+    def checkExperimentalSetting(self) -> Iterator[Diagnostic]:
+        """Checks if definition uses experimental settings"""
+        definition = self._definitions[self._definition_name]
+        if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"):
+            for setting in definition["overrides"]:
+                if setting in self._experimental_settings:
+                    redefined = re.compile(setting)
+                    found = redefined.search(self._content)
+                    yield Diagnostic(
+                        file=self._file,
+                        diagnostic_name="diagnostic-definition-experimental-setting",
+                        message=f"Setting {setting} is still experimental and should not be used in default profiles",
+                        level="Warning",
+                        offset=found.span(0)[0]
+                    )
+
     def _loadDefinitionFiles(self, definition_file) -> None:
         """ Loads definition file contents into self._definitions. Also load parent definition if it exists. """
         definition_name = Path(definition_file.stem).stem
@@ -104,6 +125,9 @@ class Definition(Linter):
         if not definition_file.exists() or definition_name in self._definitions:
             return
 
+        if self._definition_name is None:
+            self._definition_name = definition_name
+
         # Load definition file into dictionary
         self._definitions[definition_name] = json.loads(definition_file.read_text())
 
@@ -152,6 +176,12 @@ class Definition(Linter):
                     return self._isDefinedInParent(key, value_dict, parent["inherits"])
         return False, None, None, None, None
 
+    def _loadExperimentalSettings(self):
+        try:
+            self._experimental_settings = self._definitions[self.base_def]["settings"]["experimental"]["children"].keys()
+        except:
+            pass
+
     def _loadBasePrinterSettings(self):
         settings = {}
         for k, v in self._definitions[self.base_def]["settings"].items():

+ 7 - 6
printer-linter/src/printerlinter/linters/formulas.py

@@ -146,12 +146,13 @@ class Formulas(Linter):
 
         available_sections = ["values"]
         for section in available_sections:
-            options = config.options(section)
-            for option in options:
-                values ={}
-                values["value"] = config.get(section, option)
-                overrides[option] = values
-            file_data["overrides"]= overrides# Process the value here
+            if config.has_section(section):
+                options = config.options(section)
+                for option in options:
+                    values ={}
+                    values["value"] = config.get(section, option)
+                    overrides[option] = values
+                file_data["overrides"]= overrides# Process the value here
 
         return file_data
 

+ 1 - 1
printer-linter/src/printerlinter/linters/profile.py

@@ -37,6 +37,6 @@ class Profile(Linter):
         config = ConfigParser()
         config.read([self._file])
         name_of_profile = config.get("general", "name")
-        redefined = re.compile(name_of_profile)
+        redefined = re.compile(re.escape(name_of_profile))
         found = redefined.search(self._content)
         return name_of_profile, found