ci(static-checks): improve error messages in include order check

Provide more insightful messages linter messages for include order
errors. Include a link to the online documentation and identify the
erroneous files, not the files that follow it (as is the case
currently).

Signed-off-by: Harrison Mutai <harrison.mutai@arm.com>
Change-Id: I5ee65ca218e8341643338ce17a14142a20cf66d0
diff --git a/script/static-checks/check-include-order.py b/script/static-checks/check-include-order.py
index 53d355b..1ffe020 100755
--- a/script/static-checks/check-include-order.py
+++ b/script/static-checks/check-include-order.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 #
-# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,10 +14,8 @@
 import subprocess
 import sys
 import utils
-import yaml
 import logging
 
-
 # File extensions to check
 VALID_FILE_EXTENSIONS = (".c", ".S", ".h")
 
@@ -83,42 +81,61 @@
         commit_hash = commit_hash + ":"
 
     # First, check if all includes are in the appropriate group.
-    inc_group = "System"
+    inc_group = "System", "Project", "Platform"
     incs = collections.defaultdict(list)
     error_msgs = []
     plat_incs = dir_include_paths("plat") | dir_include_paths("include/plat")
     plat_common_incs = dir_include_paths("include/plat/common")
     plat_incs.difference_update(plat_common_incs)
     libc_incs = dir_include_paths("include/lib/libc")
+    indices = []
 
     for inc in inc_list:
         inc_path = inc[1:-1]
         if inc_path in libc_incs:
-            if inc_group != "System":
-                error_msgs.append(inc_path + " should be in system group, at the top")
+            inc_group_index = 0
         elif inc_path in plat_incs:
-            inc_group = "Platform"
-        elif inc_group in ("Project", "System"):
-            inc_group = "Project"
+            inc_group_index = 2
         else:
-            error_msgs.append(
-                inc_path + " should be in project group, after system group"
-            )
-        incs[inc_group].append(inc_path)
+            inc_group_index = 1
+
+        incs[inc_group_index].append(inc_path)
+        indices.append((inc_group_index, inc))
+
+    index_sorted_paths = sorted(indices, key=lambda x: x[0])
+
+    if indices != index_sorted_paths:
+        error_msgs.append("Group ordering error, order should be:")
+        for index_orig, index_new in zip(indices, index_sorted_paths):
+            # Right angle brackets are a special entity in html, convert the
+            # name to an html friendly format.
+            path_ = index_new[1]
+            if "<" in path_:
+                path_ = f"&lt{path_[1:-1]}&gt"
+
+            if index_orig[0] != index_new[0]:
+                error_msgs.append(
+                    f"\t** #include {path_:<30} --> " \
+                    f"{inc_group[index_new[0]].lower()} header, moved to group "\
+                    f"{index_new[0]+1}."
+                )
+            else:
+                error_msgs.append(f"\t#include {path_}")
 
     # Then, check alphabetic order (system, project and user separately).
     if not error_msgs:
-        for name, inc_list in incs.items():
+        for i, inc_list in incs.items():
             if sorted(inc_list) != inc_list:
                 error_msgs.append(
                     "{} includes not in order. Include order should be {}".format(
-                        name, ", ".join(sorted(inc_list))
+                        inc_group[i], ", ".join(sorted(inc_list))
                     )
                 )
 
     # Output error messages.
     if error_msgs:
-        print(yaml.dump({commit_hash + path: error_msgs}))
+        print(f"\n{commit_hash}:{path}:")
+        print(*error_msgs, sep="\n")
         return False
     else:
         return True