Repository: inventree/InvenTree

Issue:
[BUG] Plugins don't work on pre-2.2.0 versions of git
**Describe the bug**
All plugins in Settings->Plugin Settings->Plugins are in Error state with message `Invalid isoformat string: '%aI'`.

This message is caused by "%aI - author date, strict ISO 8601 format" git log option introduced in git ver 2.2.0-rc0.
https://github.com/inventree/InvenTree/blob/733062385c455d02371e34890a90b3be9e2dee04/InvenTree/plugin/helpers.py#L98
On some distros (Centos 7, EOL June 30, 2024) latest git is only 1.8.3.
This issue can be fixed by updating git to the latest (post 2.2.0 version).

**Deployment Method**
- Bare Metal

**Version Information**
InvenTree-Version: 0.6.0
Django Version: 3.2.12
Commit Hash: ad702e794
Commit Date: 2022-02-24
Database: mysql
Debug-Mode: True
Deployed using Docker: False


Discussion:
Ok that is my fault. Sorry about that. I will add a catch for that on the weekend.
Thank you for reporting and finding a fix @sintech ! How do you like the release except for that? 
> How do you like the release except for that?

I just updated and still can't get used to the new design ;). Working on a "classic" theme to mimic BS4 colors and forms.


Resolving patch:
diff --git a/InvenTree/plugin/apps.py b/InvenTree/plugin/apps.py
--- a/InvenTree/plugin/apps.py
+++ b/InvenTree/plugin/apps.py
@@ -5,11 +5,13 @@
 
 from django.apps import AppConfig
 from django.conf import settings
+from django.utils.translation import ugettext_lazy as _
 
 from maintenance_mode.core import set_maintenance_mode
 
 from InvenTree.ready import isImportingData
 from plugin import registry
+from plugin.helpers import check_git_version, log_error
 
 
 logger = logging.getLogger('inventree')
@@ -34,3 +36,8 @@ def ready(self):
                     # drop out of maintenance
                     # makes sure we did not have an error in reloading and maintenance is still active
                     set_maintenance_mode(False)
+
+            # check git version
+            registry.git_is_modern = check_git_version()
+            if not registry.git_is_modern:  # pragma: no cover  # simulating old git seems not worth it for coverage
+                log_error(_('Your enviroment has an outdated git version. This prevents InvenTree from loading plugin details.'), 'load')
diff --git a/InvenTree/plugin/helpers.py b/InvenTree/plugin/helpers.py
--- a/InvenTree/plugin/helpers.py
+++ b/InvenTree/plugin/helpers.py
@@ -94,21 +94,46 @@ def get_git_log(path):
     """
     Get dict with info of the last commit to file named in path
     """
-    path = path.replace(os.path.dirname(settings.BASE_DIR), '')[1:]
-    command = ['git', 'log', '-n', '1', "--pretty=format:'%H%n%aN%n%aE%n%aI%n%f%n%G?%n%GK'", '--follow', '--', path]
+    from plugin import registry
+
     output = None
-    try:
-        output = str(subprocess.check_output(command, cwd=os.path.dirname(settings.BASE_DIR)), 'utf-8')[1:-1]
-        if output:
-            output = output.split('\n')
-    except subprocess.CalledProcessError:  # pragma: no cover
-        pass
+    if registry.git_is_modern:
+        path = path.replace(os.path.dirname(settings.BASE_DIR), '')[1:]
+        command = ['git', 'log', '-n', '1', "--pretty=format:'%H%n%aN%n%aE%n%aI%n%f%n%G?%n%GK'", '--follow', '--', path]
+        try:
+            output = str(subprocess.check_output(command, cwd=os.path.dirname(settings.BASE_DIR)), 'utf-8')[1:-1]
+            if output:
+                output = output.split('\n')
+        except subprocess.CalledProcessError:  # pragma: no cover
+            pass
 
     if not output:
         output = 7 * ['']  # pragma: no cover
+
     return {'hash': output[0], 'author': output[1], 'mail': output[2], 'date': output[3], 'message': output[4], 'verified': output[5], 'key': output[6]}
 
 
+def check_git_version():
+    """returns if the current git version supports modern features"""
+
+    # get version string
+    try:
+        output = str(subprocess.check_output(['git', '--version'], cwd=os.path.dirname(settings.BASE_DIR)), 'utf-8')
+    except subprocess.CalledProcessError:  # pragma: no cover
+        return False
+
+    # process version string
+    try:
+        version = output[12:-1].split(".")
+        if len(version) > 1 and version[0] == '2':
+            if len(version) > 2 and int(version[1]) >= 22:
+                return True
+    except ValueError:  # pragma: no cover
+        pass
+
+    return False
+
+
 class GitStatus:
     """
     Class for resolving git gpg singing state
diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py
--- a/InvenTree/plugin/registry.py
+++ b/InvenTree/plugin/registry.py
@@ -52,6 +52,7 @@ def __init__(self) -> None:
         # flags
         self.is_loading = False
         self.apps_loading = True        # Marks if apps were reloaded yet
+        self.git_is_modern = True       # Is a modern version of git available
 
         # integration specific
         self.installed_apps = []         # Holds all added plugin_paths


Test patch: