Coverage for src/jobs/scripts.py: 100.00%
65 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-10-18 15:02 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-10-18 15:02 +0000
1#!/usr/bin/env python3
3# Standard libraries
4from pathlib import Path
5from sys import exc_info
6from typing import Dict, List
8# Components
9from ..types.files import Files, TempFile
10from ..types.paths import Paths
12# ScriptsFile class
13class ScriptsFile:
15 # Constants
16 __SEPARATOR: str = '\n'
17 SHEBANG_MARKER_BASH: str = '__GITLAB_CI_LOCAL_SHEBANG_MARKER_BASH__'
19 # Members
20 __file: TempFile # type: ignore[type-arg]
21 __folder: str
22 __ready: bool
23 __target: str
25 # Constructor
26 def __init__(
27 self,
28 paths: Dict[str, str],
29 prefix: str = '.tmp.',
30 ) -> None:
32 # Variables
33 error = ''
35 # Initialize members
36 self.__folder = ''
37 self.__ready = False
38 self.__target = ''
40 # Iterate through paths
41 for path in paths:
43 # Prepare temporary script
44 try:
45 self.__file = Files.temp(path=path, prefix=prefix)
46 self.__folder = path
47 if paths[path]:
48 self.__target = Paths.get(
49 Path(paths[path]) / Path(self.__file.name).name)
50 self.__ready = True
51 break
52 except PermissionError:
53 error = str(exc_info()[1])
55 # Failed temporary script
56 if not self.__ready:
57 raise PermissionError(error)
59 # Configure
60 def configure(
61 self,
62 errors: bool = True,
63 verbose: bool = True,
64 ) -> None:
66 # Write configuration
67 self.writelines([
68 ' # Configurations',
69 f" set -{'e' if errors else ''}{'x' if verbose else ''}",
70 '',
71 ])
73 # Close
74 def close(self) -> None:
76 # Flush file
77 self.flush()
79 # Close file
80 self.__file.close()
82 # Flush
83 def flush(self) -> None:
85 # Flush file
86 if not self.__file.closed:
87 self.__file.flush()
89 # Folder
90 @property
91 def folder(self) -> str:
93 # Result
94 return self.__folder
96 # Name
97 @property
98 def name(self) -> str:
100 # Result
101 return self.__file.name
103 # Print
104 def print(self) -> None:
106 # Flush file
107 self.flush()
109 # Print content
110 with open(self.__file.name, encoding='utf8', mode='r') as file:
111 print(file.read())
113 # Shebang
114 def shebang(self) -> None:
116 # Write shebang
117 self.write('#!/bin/sh')
118 self.write('')
120 # Write shebang wrapper
121 self.writelines([
122 '# Bash shebang wrapper',
123 f'if [ -z "${{{self.SHEBANG_MARKER_BASH}}}" ] && type bash >/dev/null 2>&1; then',
124 f' {self.SHEBANG_MARKER_BASH}=true bash "${0}"',
125 ' exit "${?}"',
126 'fi',
127 '',
128 ])
130 # Subgroup start
131 def subgroup_start(self) -> None:
133 # Write subgroup start
134 self.write('{')
136 # Subgroup stop
137 def subgroup_stop(self) -> None:
139 # Write subgroup stop
140 self.write('}')
142 # Subshell start
143 def subshell_start(
144 self,
145 section: str,
146 ) -> None:
148 # Write subshell start
149 self.write(f'# Section {section}')
150 self.write('(')
152 # Subshell stop
153 def subshell_stop(
154 self,
155 section: str,
156 ) -> None:
158 # Write subshell stop
159 self.write(') 2>&1')
160 self.write(f'# Section {section}')
162 # Target
163 def target(self) -> str:
165 # Result
166 return self.__target
168 # Write
169 def write(self, line: str = '') -> None:
171 # Write line
172 self.__file.write(line)
173 self.__file.write(self.__SEPARATOR)
175 # Write lines
176 def writelines(
177 self,
178 lines: List[str],
179 ) -> None:
181 # Write line
182 self.__file.write(self.__SEPARATOR.join(lines))
183 self.__file.write(self.__SEPARATOR)