Coverage for apio/commands/apio_raw.py: 72%

35 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-06 10:20 +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 raw' command""" 

9 

10import sys 

11import subprocess 

12from typing import Tuple, List 

13import click 

14from apio.common.apio_console import cout 

15from apio.common.apio_styles import SUCCESS, ERROR 

16from apio.apio_context import ( 

17 ApioContext, 

18 PackagesPolicy, 

19 ProjectPolicy, 

20 RemoteConfigPolicy, 

21) 

22from apio.commands import options 

23from apio.utils import cmd_util 

24from apio.utils.cmd_util import ApioCommand 

25 

26# ----------- apio raw 

27 

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

29APIO_RAW_HELP = """ 

30The command 'apio raw' allows you to bypass Apio and run underlying tools \ 

31directly. This is an advanced command that requires familiarity with the \ 

32underlying tools. 

33 

34Before running the command, Apio temporarily modifies system environment \ 

35variables such as '$PATH' to provide access to its packages. To view these \ 

36environment changes, run the command with the '-v' option. 

37 

38Examples:[code] 

39 apio raw -- yosys --version # Yosys version 

40 apio raw -v -- yosys --version # Verbose apio info. 

41 apio raw -- yosys # Yosys interactive mode. 

42 apio raw -- icepll -i 12 -o 30 # Calc ICE PLL. 

43 apio raw -- which yosys # Lookup a command. 

44 apio raw -v # Show apio env setting. 

45 apio raw -h # Show this help info.[/code] 

46 

47The marker '--' is used to separate between the arguments of the apio \ 

48command itself and those of the executed command. 

49""" 

50 

51 

52@click.command( 

53 name="raw", 

54 cls=ApioCommand, 

55 short_help="Execute commands directly from the Apio packages.", 

56 help=APIO_RAW_HELP, 

57 context_settings={"ignore_unknown_options": True}, 

58) 

59@click.pass_context 

60@click.argument("cmd", metavar="COMMAND", nargs=-1, type=click.UNPROCESSED) 

61@options.verbose_option 

62def cli( 

63 cmd_ctx: click.Context, 

64 # Arguments 

65 cmd: Tuple[str], 

66 # Options 

67 verbose: bool, 

68): 

69 """Implements the apio raw command which executes user 

70 specified commands from apio installed tools. 

71 """ 

72 # -- At lease one of -v and cmd should be specified. 

73 cmd_util.check_at_least_one_param(cmd_ctx, ["verbose", "cmd"]) 

74 

75 # -- Create an apio context. We don't care about an apio project. 

76 # -- Using config and packages because we want the binaries in the apio 

77 # -- packages to be available for the 'apio raw' command. 

78 apio_ctx = ApioContext( 

79 project_policy=ProjectPolicy.NO_PROJECT, 

80 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

81 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

82 ) 

83 

84 # -- Set the env for packages. If verbose, also dumping the env changes 

85 # -- in a user friendly way. 

86 apio_ctx.set_env_for_packages(quiet=not verbose, verbose=verbose) 

87 

88 # -- If no command, we are done. 

89 if not cmd: 

90 sys.exit(0) 

91 

92 # -- Convert the tuple of strings to a list of strings. 

93 cmd: List[str] = list(cmd) 

94 

95 # -- Echo the commands. The apio raw command is platform dependent 

96 # -- so this may help us and the user diagnosing issues. 

97 if verbose: 97 ↛ 98line 97 didn't jump to line 98 because the condition on line 97 was never true

98 cout(f"\n---- Executing {cmd}:") 

99 

100 # -- Invoke the command. 

101 try: 

102 exit_code = subprocess.call(cmd, shell=False) 

103 except FileNotFoundError as e: 

104 cout(f"{e}", style=ERROR) 

105 sys.exit(1) 

106 

107 if verbose: 107 ↛ 108line 107 didn't jump to line 108 because the condition on line 107 was never true

108 cout("----\n") 

109 if exit_code == 0: 

110 cout("Exit status [0] OK", style=SUCCESS) 

111 

112 else: 

113 cout(f"Exist status [{exit_code}] ERROR", style=ERROR) 

114 

115 # -- Return the command's status code. 

116 sys.exit(exit_code)