def handle()

in mozci/console/commands/push.py [0:0]


    def handle(self) -> None:
        self.branch = self.argument("branch")

        pushes = classify_commands_pushes(
            self.branch,
            self.option("from-date"),
            self.option("to-date"),
            self.option("rev"),
        )
        classify_parameters = retrieve_classify_parameters(self.option)

        output = self.option("output")
        if output and not os.path.isdir(output):
            os.makedirs(output)
            self.line(
                "<comment>Provided --output pointed to a inexistent directory that is now created.</comment>"
            )

        retriggerable_backfillable_patterns = config.get(
            "retriggerable-backfillable-task-names", []
        )

        try:
            retrigger_limit = int(self.option("retrigger-limit"))
        except ValueError:
            raise Exception("Provided --retrigger-limit should be an int.")

        try:
            backfill_limit = int(self.option("backfill-limit"))
        except ValueError:
            raise Exception("Provided --backfill-limit should be an int.")

        for push in pushes:
            try:
                classification, regressions, to_retrigger_or_backfill = push.classify(
                    **classify_parameters
                )

                self.backfill_and_retrigger_failures(
                    push,
                    retriggerable_backfillable_patterns,
                    classify_parameters,
                    retrigger_limit,
                    backfill_limit,
                    to_retrigger_or_backfill,
                )

                self.line(
                    f"Push associated with the head revision {push.rev} on "
                    f"the branch {self.branch} is classified as {classification.name}"
                )
            except Exception as e:
                self.line(
                    f"<error>Couldn't classify push {push.push_uuid}: {e}.</error>"
                )
                # Print the error stacktrace in red
                self.line(f"<error>{traceback.format_exc()}</error>")
                continue

            if self.option("show-intermittents"):
                self.line("-" * 50)
                self.line(
                    "Printing tasks that should be marked as intermittent failures:"
                )
                for task in regressions.intermittent:
                    self.line(task)
                self.line("-" * 50)

            if output:

                def _serialize_regressions(regressions):
                    return {
                        group: [
                            {
                                "task_id": task.id,
                                "label": task.label,
                                "autoclassify": is_autoclassifiable(task),
                                "tests": [
                                    test_name
                                    for group_failures in task.failure_types.values()
                                    for test_name, _ in group_failures
                                ],
                            }
                            for task in failing_tasks
                        ]
                        for group, failing_tasks in regressions.items()
                    }

                to_save = {
                    "push": {
                        "id": push.push_uuid,
                        "classification": classification.name,
                    },
                    "failures": {
                        "real": _serialize_regressions(regressions.real),
                        "intermittent": _serialize_regressions(
                            regressions.intermittent
                        ),
                        "unknown": _serialize_regressions(regressions.unknown),
                    },
                }

                filename = f"{output}/classify_output_{self.branch}_{push.rev}.json"
                with open(filename, "w") as file:
                    json.dump(to_save, file, indent=2)

                self.line(
                    f"Classification and regressions details for push {push.push_uuid} were saved in {filename} JSON file"
                )

            # Send a notification when some emails are declared in the config
            emails = config.get("emails", {}).get("classifications")
            matrix_room = config.get("matrix-room-id")
            if emails or matrix_room:
                # Load previous classification from taskcluster
                try:
                    previous = push.get_existing_classification(
                        self.option("environment")
                    )
                except SourcesNotFound:
                    # We still want to send a notification if the current one is bad
                    previous = None

                self.send_notifications(
                    emails, matrix_room, push, previous, classification, regressions
                )