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

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""" 

9 

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) 

26 

27 

28# ----------- apio clean 

29 

30 

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

32 """Delete given files and dirs.""" 

33 

34 # pylint: disable=broad-exception-caught 

35 

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}") 

39 

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 

49 

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 

57 

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

59 except Exception as e: 

60 fatal_error(cause=e) 

61 

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}'") 

66 

67 # -- Report item deletion. 

68 if item_deleted: 

69 items_deleted = True 

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

71 

72 # -- Print a summary. 

73 if items_deleted: 

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

75 else: 

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

77 

78 

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. 

83 

84Example:[code] 

85 apio clean[/code] 

86""" 

87 

88 

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 """ 

104 

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 ) 

115 

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

117 os.chdir(apio_ctx.project_dir) 

118 

119 # -- Clean the root build directory. 

120 candidates = [str(PROJECT_BUILD_PATH)] 

121 

122 # -- Clean and report. 

123 _delete_candidates(candidates)