Repository: kedro-org/kedro
File: kedro/framework/cli/cli.py (Python)

Code before:
                )
                result = (
                    click.style("Project specific commands such as ")
                    + click.style("'run' ", fg="cyan")
                    + "or "
                    + click.style("'jupyter' ", fg="cyan")
                    + "are only available within a project directory."
                )
                message = warn + result
                hint = (
                    click.style(
                        "\nHint: Kedro is looking for a file called ", fg=BRIGHT_BLACK
                    )
                    + click.style("'pyproject.toml", fg="magenta")
                    + click.style(
                        ", is one present in your current working directory?",
                        fg=BRIGHT_BLACK,
                    )
                )
                click.echo(message)
                click.echo(hint)
            sys.exit(exc.code)
        except Exception as error:
            logger.error(f"An error has occurred: {error}")
            exit_code = 1
            self._cli_hook_manager.hook.after_command_run(
                project_metadata=self._metadata, command_args=args, exit_code=1
            )
            hook_called = True
        finally:
            if not hook_called:
                self._cli_hook_manager.hook.after_command_run(
                    project_metadata=self._metadata, command_args=args, exit_code=0
                )
            sys.exit(exit_code)

    @property
    def global_groups(self) -> Sequence[click.MultiCommand]:
        """Property which loads all global command groups from plugins and
        combines them with the built-in ones (eventually overriding the
        built-in ones if they are redefined by plugins).
        """
        return [*load_entry_points("global"), cli, global_commands]

    @property
    def project_groups(self) -> Sequence[click.MultiCommand]:
        """Property which loads all project command groups from the
        project and the plugins, then combines them with the built-in ones.
        Built-in commands can be overridden by plugins, which can be
        overridden by a custom project cli.py.
        See https://kedro.readthedocs.io/en/stable/extend_kedro/common_use_cases.html#use-case-3-how-to-add-or-modify-cli-commands

Review comment (bug):
Thank you for the PR, @lrcouto! Could you please explain how this is possible? It looks like `hook_called` will be set to `True` in the try block or, if it fails, in the except block, so this line will never be executed?

Code after:
                    + click.style("'jupyter' ", fg="cyan")
                    + "are only available within a project directory."
                )
                message = warn + result
                hint = (
                    click.style(
                        "\nHint: Kedro is looking for a file called ", fg=BRIGHT_BLACK
                    )
                    + click.style("'pyproject.toml", fg="magenta")
                    + click.style(
                        ", is one present in your current working directory?",
                        fg=BRIGHT_BLACK,
                    )
                )
                click.echo(message)
                click.echo(hint)
                sys.exit(exc.code)
        except Exception as error:
            logger.error(f"An error has occurred: {error}")
            self._cli_hook_manager.hook.after_command_run(
                project_metadata=self._metadata, command_args=args, exit_code=1
            )
            hook_called = True
            sys.exit(1)
        finally:
            if not hook_called:
                self._cli_hook_manager.hook.after_command_run(
                    project_metadata=self._metadata, command_args=args, exit_code=0
                )

    @property
    def global_groups(self) -> Sequence[click.MultiCommand]:
        """Property which loads all global command groups from plugins and
        combines them with the built-in ones (eventually overriding the
        built-in ones if they are redefined by plugins).
        """
        return [*load_entry_points("global"), cli, global_commands]

    @property
    def project_groups(self) -> Sequence[click.MultiCommand]:
        """Property which loads all project command groups from the
        project and the plugins, then combines them with the built-in ones.
        Built-in commands can be overridden by plugins, which can be
        overridden by a custom project cli.py.
        See https://kedro.readthedocs.io/en/stable/extend_kedro/common_use_cases.html#use-case-3-how-to-add-or-modify-cli-commands
        on how to add this.
        """
        if not self._metadata:
            return []

        plugins = load_entry_points("project")