prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  baseline output can change resource order for each run
  If I generate a baseline file and I have then made some improvements to my Terraform code and I run the baseline again. What I am finding is that the order of the resources for each file can often change which then shows up as a diff against the prevous baseline file - when in reality nothing has change but the order of the resources in the findings array in the baseline output file 
  
  I was wondering could the findings array just be sorted before being output? Then the resource order should be fixed and any actual diffs should be real changes to check_ids (which is sorted already) or new resources being added?
  
  e.g. this is a diff from two runs of generating a baseline file nothing has actually change just resources moved around in the array.
  
  ```
  @@ -100,13 +100,12 @@
               "file": "/main.tf",
               "findings": [
                   {
  -                    "resource": "aws_s3_bucket.canary_artifacts",
  +                    "resource": "aws_s3_bucket.backups",
                       "check_ids": [
                           "CKV2_AWS_6",
                           "CKV_AWS_144",
                           "CKV_AWS_145",
  -                        "CKV_AWS_18",
  -                        "CKV_AWS_21"
  +                        "CKV_AWS_18"
                       ]
                   },
                   {
  @@ -119,12 +118,13 @@
                       ]
                   },
                   {
  -                    "resource": "aws_s3_bucket.lambdas",
  +                    "resource": "aws_s3_bucket.canary_artifacts",
                       "check_ids": [
                           "CKV2_AWS_6",
                           "CKV_AWS_144",
                           "CKV_AWS_145",
  -                        "CKV_AWS_18"
  +                        "CKV_AWS_18",
  +                        "CKV_AWS_21"
                       ]
                   },
                   {
  @@ -137,7 +137,7 @@
                       ]
                   },
                   {
  -                    "resource": "aws_s3_bucket.backups",
  +                    "resource": "aws_s3_bucket.lambdas",
                       "check_ids": [
                           "CKV2_AWS_6",
                           "CKV_AWS_144",
  ```
  
  </issue>
  <code>
  [start of checkov/common/output/baseline.py]
  1 from __future__ import annotations
  2 
  3 import json
  4 from collections import defaultdict
  5 from checkov.common.models.enums import CheckResult
  6 from typing import Any, TYPE_CHECKING
  7 
  8 if TYPE_CHECKING:
  9     from checkov.common.output.record import Record
  10     from checkov.common.output.report import Report
  11     from checkov.common.typing import _BaselineFinding, _BaselineFailedChecks
  12 
  13 
  14 class Baseline:
  15     def __init__(self, output_skipped: bool = False) -> None:
  16         self.path = ""
  17         self.path_failed_checks_map: dict[str, list[_BaselineFinding]] = defaultdict(list)
  18         self.failed_checks: list[_BaselineFailedChecks] = []
  19         self.output_skipped = output_skipped
  20 
  21     def add_findings_from_report(self, report: Report) -> None:
  22         for check in report.failed_checks:
  23             try:
  24                 existing = next(
  25                     x for x in self.path_failed_checks_map[check.file_path] if x["resource"] == check.resource
  26                 )
  27             except StopIteration:
  28                 existing = {"resource": check.resource, "check_ids": []}
  29                 self.path_failed_checks_map[check.file_path].append(existing)
  30             existing["check_ids"].append(check.check_id)
  31             existing["check_ids"].sort()  # Sort the check IDs to be nicer to the eye
  32 
  33     def to_dict(self) -> dict[str, Any]:
  34         """
  35         The output of this class needs to be very explicit, hence the following structure of the dict:
  36         {
  37             "failed_checks": [
  38                 {
  39                     "file": "path/to/file",
  40                     "findings: [
  41                         {
  42                             "resource": "aws_s3_bucket.this",
  43                             "check_ids": [
  44                                 "CKV_AWS_1",
  45                                 "CKV_AWS_2",
  46                                 "CKV_AWS_3"
  47                             ]
  48                         }
  49                     ]
  50                 }
  51             ]
  52         }
  53         """
  54         failed_checks_list = []
  55         for file, findings in self.path_failed_checks_map.items():
  56             formatted_findings = []
  57             for finding in findings:
  58                 formatted_findings.append({"resource": finding["resource"], "check_ids": finding["check_ids"]})
  59             failed_checks_list.append({"file": file, "findings": formatted_findings})
  60 
  61         resp = {"failed_checks": failed_checks_list}
  62         return resp
  63 
  64     def compare_and_reduce_reports(self, scan_reports: list[Report]) -> None:
  65         for scan_report in scan_reports:
  66             scan_report.passed_checks = [
  67                 check for check in scan_report.passed_checks if self._is_check_in_baseline(check)
  68             ]
  69             scan_report.skipped_checks = [
  70                 check for check in scan_report.skipped_checks if self._is_check_in_baseline(check)
  71             ]
  72             if self.output_skipped:
  73                 for check in scan_report.failed_checks:
  74                     if self._is_check_in_baseline(check):
  75                         check.check_result["suppress_comment"] = "baseline-skipped"
  76                         check.check_result["result"] = CheckResult.SKIPPED
  77                         scan_report.skipped_checks.append(check)
  78             scan_report.failed_checks = [
  79                 check for check in scan_report.failed_checks if not self._is_check_in_baseline(check)
  80             ]
  81 
  82     def _is_check_in_baseline(self, check: Record) -> bool:
  83         failed_check_id = check.check_id
  84         failed_check_resource = check.resource
  85         for baseline_failed_check in self.failed_checks:
  86             for finding in baseline_failed_check["findings"]:
  87                 if finding["resource"] == failed_check_resource and failed_check_id in finding["check_ids"]:
  88                     return True
  89         return False
  90 
  91     def from_json(self, file_path: str) -> None:
  92         self.path = file_path
  93         with open(file_path, "r") as f:
  94             baseline_raw = json.load(f)
  95             self.failed_checks = baseline_raw.get("failed_checks", {})
  96
  [end of checkov/common/output/baseline.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/checkov/common/output/baseline.py b/checkov/common/output/baseline.py
  --- a/checkov/common/output/baseline.py
  +++ b/checkov/common/output/baseline.py
  @@ -2,6 +2,8 @@
   
   import json
   from collections import defaultdict
  +from operator import itemgetter
  +
   from checkov.common.models.enums import CheckResult
   from typing import Any, TYPE_CHECKING
   
  @@ -56,9 +58,9 @@
               formatted_findings = []
               for finding in findings:
                   formatted_findings.append({"resource": finding["resource"], "check_ids": finding["check_ids"]})
  -            failed_checks_list.append({"file": file, "findings": formatted_findings})
  +            failed_checks_list.append({"file": file, "findings": sorted(formatted_findings, key=itemgetter("resource"))})
   
  -        resp = {"failed_checks": failed_checks_list}
  +        resp = {"failed_checks": sorted(failed_checks_list, key=itemgetter("file"))}
           return resp
   
       def compare_and_reduce_reports(self, scan_reports: list[Report]) -> None:
  
verification_info: {"golden_diff": "diff --git a/checkov/common/output/baseline.py b/checkov/common/output/baseline.py\n--- a/checkov/common/output/baseline.py\n+++ b/checkov/common/output/baseline.py\n@@ -2,6 +2,8 @@\n \n import json\n from collections import defaultdict\n+from operator import itemgetter\n+\n from checkov.common.models.enums import CheckResult\n from typing import Any, TYPE_CHECKING\n \n@@ -56,9 +58,9 @@\n             formatted_findings = []\n             for finding in findings:\n                 formatted_findings.append({\"resource\": finding[\"resource\"], \"check_ids\": finding[\"check_ids\"]})\n-            failed_checks_list.append({\"file\": file, \"findings\": formatted_findings})\n+            failed_checks_list.append({\"file\": file, \"findings\": sorted(formatted_findings, key=itemgetter(\"resource\"))})\n \n-        resp = {\"failed_checks\": failed_checks_list}\n+        resp = {\"failed_checks\": sorted(failed_checks_list, key=itemgetter(\"file\"))}\n         return resp\n \n     def compare_and_reduce_reports(self, scan_reports: list[Report]) -> None:\n", "issue": "baseline output can change resource order for each run\nIf I generate a baseline file and I have then made some improvements to my Terraform code and I run the baseline again. What I am finding is that the order of the resources for each file can often change which then shows up as a diff against the prevous baseline file - when in reality nothing has change but the order of the resources in the findings array in the baseline output file \r\n\r\nI was wondering could the findings array just be sorted before being output? Then the resource order should be fixed and any actual diffs should be real changes to check_ids (which is sorted already) or new resources being added?\r\n\r\ne.g. this is a diff from two runs of generating a baseline file nothing has actually change just resources moved around in the array.\r\n\r\n```\r\n@@ -100,13 +100,12 @@\r\n             \"file\": \"/main.tf\",\r\n             \"findings\": [\r\n                 {\r\n-                    \"resource\": \"aws_s3_bucket.canary_artifacts\",\r\n+                    \"resource\": \"aws_s3_bucket.backups\",\r\n                     \"check_ids\": [\r\n                         \"CKV2_AWS_6\",\r\n                         \"CKV_AWS_144\",\r\n                         \"CKV_AWS_145\",\r\n-                        \"CKV_AWS_18\",\r\n-                        \"CKV_AWS_21\"\r\n+                        \"CKV_AWS_18\"\r\n                     ]\r\n                 },\r\n                 {\r\n@@ -119,12 +118,13 @@\r\n                     ]\r\n                 },\r\n                 {\r\n-                    \"resource\": \"aws_s3_bucket.lambdas\",\r\n+                    \"resource\": \"aws_s3_bucket.canary_artifacts\",\r\n                     \"check_ids\": [\r\n                         \"CKV2_AWS_6\",\r\n                         \"CKV_AWS_144\",\r\n                         \"CKV_AWS_145\",\r\n-                        \"CKV_AWS_18\"\r\n+                        \"CKV_AWS_18\",\r\n+                        \"CKV_AWS_21\"\r\n                     ]\r\n                 },\r\n                 {\r\n@@ -137,7 +137,7 @@\r\n                     ]\r\n                 },\r\n                 {\r\n-                    \"resource\": \"aws_s3_bucket.backups\",\r\n+                    \"resource\": \"aws_s3_bucket.lambdas\",\r\n                     \"check_ids\": [\r\n                         \"CKV2_AWS_6\",\r\n                         \"CKV_AWS_144\",\r\n```\n", "before_files": [{"content": "from __future__ import annotations\n\nimport json\nfrom collections import defaultdict\nfrom checkov.common.models.enums import CheckResult\nfrom typing import Any, TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from checkov.common.output.record import Record\n    from checkov.common.output.report import Report\n    from checkov.common.typing import _BaselineFinding, _BaselineFailedChecks\n\n\nclass Baseline:\n    def __init__(self, output_skipped: bool = False) -> None:\n        self.path = \"\"\n        self.path_failed_checks_map: dict[str, list[_BaselineFinding]] = defaultdict(list)\n        self.failed_checks: list[_BaselineFailedChecks] = []\n        self.output_skipped = output_skipped\n\n    def add_findings_from_report(self, report: Report) -> None:\n        for check in report.failed_checks:\n            try:\n                existing = next(\n                    x for x in self.path_failed_checks_map[check.file_path] if x[\"resource\"] == check.resource\n                )\n            except StopIteration:\n                existing = {\"resource\": check.resource, \"check_ids\": []}\n                self.path_failed_checks_map[check.file_path].append(existing)\n            existing[\"check_ids\"].append(check.check_id)\n            existing[\"check_ids\"].sort()  # Sort the check IDs to be nicer to the eye\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"\n        The output of this class needs to be very explicit, hence the following structure of the dict:\n        {\n            \"failed_checks\": [\n                {\n                    \"file\": \"path/to/file\",\n                    \"findings: [\n                        {\n                            \"resource\": \"aws_s3_bucket.this\",\n                            \"check_ids\": [\n                                \"CKV_AWS_1\",\n                                \"CKV_AWS_2\",\n                                \"CKV_AWS_3\"\n                            ]\n                        }\n                    ]\n                }\n            ]\n        }\n        \"\"\"\n        failed_checks_list = []\n        for file, findings in self.path_failed_checks_map.items():\n            formatted_findings = []\n            for finding in findings:\n                formatted_findings.append({\"resource\": finding[\"resource\"], \"check_ids\": finding[\"check_ids\"]})\n            failed_checks_list.append({\"file\": file, \"findings\": formatted_findings})\n\n        resp = {\"failed_checks\": failed_checks_list}\n        return resp\n\n    def compare_and_reduce_reports(self, scan_reports: list[Report]) -> None:\n        for scan_report in scan_reports:\n            scan_report.passed_checks = [\n                check for check in scan_report.passed_checks if self._is_check_in_baseline(check)\n            ]\n            scan_report.skipped_checks = [\n                check for check in scan_report.skipped_checks if self._is_check_in_baseline(check)\n            ]\n            if self.output_skipped:\n                for check in scan_report.failed_checks:\n                    if self._is_check_in_baseline(check):\n                        check.check_result[\"suppress_comment\"] = \"baseline-skipped\"\n                        check.check_result[\"result\"] = CheckResult.SKIPPED\n                        scan_report.skipped_checks.append(check)\n            scan_report.failed_checks = [\n                check for check in scan_report.failed_checks if not self._is_check_in_baseline(check)\n            ]\n\n    def _is_check_in_baseline(self, check: Record) -> bool:\n        failed_check_id = check.check_id\n        failed_check_resource = check.resource\n        for baseline_failed_check in self.failed_checks:\n            for finding in baseline_failed_check[\"findings\"]:\n                if finding[\"resource\"] == failed_check_resource and failed_check_id in finding[\"check_ids\"]:\n                    return True\n        return False\n\n    def from_json(self, file_path: str) -> None:\n        self.path = file_path\n        with open(file_path, \"r\") as f:\n            baseline_raw = json.load(f)\n            self.failed_checks = baseline_raw.get(\"failed_checks\", {})\n", "path": "checkov/common/output/baseline.py"}]}