Coverage for apio/commands/apio_clean.py: 84%

43 statements  

« prev     ^ index     » next       coverage.py v7.17.2, created at 2026-11-07 05:08 +0000

1# This file is part of the Apio project 

2# (C) 2016-present FPGAwars 

3# Project authors: 

4# * Jesús Arroyo (Jesus89) (2016-2019) 

5# * Juan Gonzalez (obijuan) (2019-2024) 

6# * The Apio Team (2024-present) 

7# License: GPLv2 

8 

9"""Implementation of 'apio clean' command""" 

10 

11import os 

12import shutil 

13from pathlib import Path 

14import click 

15from apio.commands import options 

16from apio.utils import cmd_util 

17from apio.common.debug_util import is_debug 

18from apio.common.apio_console import cout, fatal_error 

19from apio.common.apio_styles import SUCCESS 

20from apio.common.common_util import PROJECT_BUILD_PATH 

21from apio.apio_context import ( 

22 ApioContext, 

23 PackagesPolicy, 

24 ProjectPolicy, 

25 RemoteConfigPolicy, 

26) 

27 

28 

29# ----------- apio clean 

30 

31 

32def _delete_candidates(candidates: list[str]): 

33 """Delete given files and dirs.""" 

34 

35 # pylint: disable=broad-exception-caught 

36 

37 # -- Dump for debugging. 

38 if is_debug(1): 38 ↛ 39line 38 didn't jump to line 39 because the condition on line 38 was never true

39 cout(f"\nDeletion candidates: {candidates}") 

40 

41 # -- Delete candidates that exists. 

42 items_deleted = False 

43 for path in candidates: 

44 item_deleted = False 

45 try: 

46 # -- Delete a file. 

47 if os.path.isfile(path): 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true

48 os.remove(path) 

49 item_deleted = True 

50 

51 # -- Delete a directory. 

52 elif os.path.isdir(path): 

53 # -- Sanity check to make sure we don't delete the entire 

54 # -- hard drive. 

55 assert "_build" in str(path), path 

56 shutil.rmtree(path) 

57 item_deleted = True 

58 

59 # -- Handle deletion exceptions, e.g. permissions issues. 

60 except Exception as e: 

61 fatal_error(cause=e) 

62 

63 # -- Check that the item was indeed deleted (e.g if it's not a file 

64 # -- neither a directory). 

65 if os.path.exists(path): 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true

66 fatal_error(f"Failed to delete '{path}'") 

67 

68 # -- Report item deletion. 

69 if item_deleted: 

70 items_deleted = True 

71 cout(f"- Removed {path}") 

72 

73 # -- Print a summary. 

74 if items_deleted: 

75 cout("Cleanup completed", style=SUCCESS) 

76 else: 

77 cout("Already clean", style=SUCCESS) 

78 

79 

80# -- Text in the rich-text format of the python rich library. 

81APIO_CLEAN_HELP = """ 

82The command 'apio clean' removes all the output files previously generated \ 

83by apio commands. 

84 

85Example:[code] 

86 apio clean[/code] 

87""" 

88 

89 

90@click.command( 

91 name="clean", 

92 cls=cmd_util.ApioCommand, 

93 short_help="Delete the apio generated files.", 

94 help=APIO_CLEAN_HELP, 

95) 

96@options.project_dir_option 

97def cli( 

98 *, 

99 # Options 

100 project_dir: Path | None, 

101): 

102 """Implements the apio clean command. It deletes temporary files generated 

103 by apio commands. 

104 """ 

105 

106 # -- Create the apio context. 

107 # -- We suppress the message with the env and board ids since it's 

108 # -- not relevant for this command. 

109 apio_ctx = ApioContext( 

110 project_policy=ProjectPolicy.PROJECT_REQUIRED, 

111 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

112 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

113 project_dir_arg=project_dir, 

114 report_env=False, 

115 ) 

116 

117 # -- Change to the project's folder. 

118 os.chdir(apio_ctx.project_dir) 

119 

120 # -- Clean the root build directory. 

121 candidates = [str(PROJECT_BUILD_PATH)] 

122 

123 # -- Clean and report. 

124 _delete_candidates(candidates)