Coverage for apio/commands/apio_clean.py: 84%
43 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
1# -*- coding: utf-8 -*-
2# -- This file is part of the Apio project
3# -- (C) 2016-2024 FPGAwars
4# -- Authors
5# -- * Jesús Arroyo (2016-2019)
6# -- * Juan Gonzalez (obijuan) (2019-2024)
7# -- License GPLv2
8"""Implementation of 'apio clean' command"""
10import os
11import shutil
12from pathlib import Path
13import click
14from apio.commands import options
15from apio.utils import cmd_util
16from apio.common.debug_util import is_debug
17from apio.common.apio_console import cout, fatal_error
18from apio.common.apio_styles import SUCCESS
19from apio.common.common_util import PROJECT_BUILD_PATH
20from apio.apio_context import (
21 ApioContext,
22 PackagesPolicy,
23 ProjectPolicy,
24 RemoteConfigPolicy,
25)
28# ----------- apio clean
31def _delete_candidates(candidates: list[str]):
32 """Delete given files and dirs."""
34 # pylint: disable=broad-exception-caught
36 # -- Dump for debugging.
37 if is_debug(1): 37 ↛ 38line 37 didn't jump to line 38 because the condition on line 37 was never true
38 cout(f"\nDeletion candidates: {candidates}")
40 # -- Delete candidates that exists.
41 items_deleted = False
42 for path in candidates:
43 item_deleted = False
44 try:
45 # -- Delete a file.
46 if os.path.isfile(path): 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 os.remove(path)
48 item_deleted = True
50 # -- Delete a directory.
51 elif os.path.isdir(path):
52 # -- Sanity check to make sure we don't delete the entire
53 # -- hard drive.
54 assert "_build" in str(path), path
55 shutil.rmtree(path)
56 item_deleted = True
58 # -- Handle deletion exceptions, e.g. permissions issues.
59 except Exception as e:
60 fatal_error(cause=e)
62 # -- Check that the item was indeed deleted (e.g if it's not a file
63 # -- neither a directory).
64 if os.path.exists(path): 64 ↛ 65line 64 didn't jump to line 65 because the condition on line 64 was never true
65 fatal_error(f"Failed to delete '{path}'")
67 # -- Report item deletion.
68 if item_deleted:
69 items_deleted = True
70 cout(f"- Removed {path}")
72 # -- Print a summary.
73 if items_deleted:
74 cout("Cleanup completed", style=SUCCESS)
75 else:
76 cout("Already clean", style=SUCCESS)
79# -- Text in the rich-text format of the python rich library.
80APIO_CLEAN_HELP = """
81The command 'apio clean' removes all the output files previously generated \
82by apio commands.
84Example:[code]
85 apio clean[/code]
86"""
89@click.command(
90 name="clean",
91 cls=cmd_util.ApioCommand,
92 short_help="Delete the apio generated files.",
93 help=APIO_CLEAN_HELP,
94)
95@options.project_dir_option
96def cli(
97 *,
98 # Options
99 project_dir: Path | None,
100):
101 """Implements the apio clean command. It deletes temporary files generated
102 by apio commands.
103 """
105 # -- Create the apio context.
106 # -- We suppress the message with the env and board ids since it's
107 # -- not relevant for this command.
108 apio_ctx = ApioContext(
109 project_policy=ProjectPolicy.PROJECT_REQUIRED,
110 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
111 packages_policy=PackagesPolicy.ENSURE_PACKAGES,
112 project_dir_arg=project_dir,
113 report_env=False,
114 )
116 # -- Change to the project's folder.
117 os.chdir(apio_ctx.project_dir)
119 # -- Clean the root build directory.
120 candidates = [str(PROJECT_BUILD_PATH)]
122 # -- Clean and report.
123 _delete_candidates(candidates)