|
23 | 23 | # imports
|
24 | 24 | import sys
|
25 | 25 | import os
|
| 26 | +import stat |
26 | 27 | import shutil
|
27 | 28 | import subprocess
|
28 | 29 | import fcntl
|
|
54 | 55 | "labwc": "W3",
|
55 | 56 | }
|
56 | 57 |
|
| 58 | +FILE_MODES = { |
| 59 | + "+x": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH, |
| 60 | + "+r": stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH, |
| 61 | + "+w": stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, |
| 62 | + "a+x": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH, |
| 63 | + "a+r": stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH, |
| 64 | + "a+w": stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, |
| 65 | + "u+x": stat.S_IXUSR, |
| 66 | + "u+r": stat.S_IRUSR, |
| 67 | + "u+w": stat.S_IWUSR, |
| 68 | + "g+x": stat.S_IXGRP, |
| 69 | + "g+r": stat.S_IRGRP, |
| 70 | + "g+w": stat.S_IWGRP, |
| 71 | + "o+x": stat.S_IXOTH, |
| 72 | + "o+r": stat.S_IROTH, |
| 73 | + "o+w": stat.S_IWOTH, |
| 74 | +} |
| 75 | + |
57 | 76 |
|
58 | 77 | # pylint: disable=too-many-public-methods
|
59 | 78 | class Shell:
|
@@ -142,6 +161,44 @@ def preexec():
|
142 | 161 | return False
|
143 | 162 | return True
|
144 | 163 |
|
| 164 | + def write_templated_file(self, output_path, template, **kwargs): |
| 165 | + """ |
| 166 | + Use a template file and render it with the given context and write it to the specified path. |
| 167 | + The template file should contain placeholders in the format {key} which will be replaced |
| 168 | + with the corresponding values from the kwargs dictionary. |
| 169 | + """ |
| 170 | + # if path is an existing directory, the template filename will be used |
| 171 | + output_path = self.path(output_path) |
| 172 | + if os.path.isdir(output_path): |
| 173 | + output_path = os.path.join(output_path, os.path.basename(template)) |
| 174 | + |
| 175 | + # Render the template with the provided context |
| 176 | + rendered_content = self.load_template(template, **kwargs) |
| 177 | + |
| 178 | + with open(output_path, "w") as output_file: |
| 179 | + output_file.write(rendered_content) |
| 180 | + |
| 181 | + return True |
| 182 | + |
| 183 | + def load_template(self, template, **kwargs): |
| 184 | + """ |
| 185 | + Load a template file and return its content with the placeholders replaced by the provided |
| 186 | + context. The template file should contain placeholders in the format {key} which will be |
| 187 | + replaced with the corresponding values from the kwargs dictionary. |
| 188 | + """ |
| 189 | + if not os.path.exists(template): |
| 190 | + self.error(f"Template file '{template}' does not exist") |
| 191 | + return None |
| 192 | + |
| 193 | + with open(template, "r") as template_file: |
| 194 | + template_content = template_file.read() |
| 195 | + |
| 196 | + # Render the template with the provided context |
| 197 | + for key in kwargs.items(): |
| 198 | + template_content = template_content.replace(f"{{{key}}}", str(kwargs[key])) |
| 199 | + |
| 200 | + return template_content |
| 201 | + |
145 | 202 | def info(self, message, **kwargs):
|
146 | 203 | """
|
147 | 204 | Display a message with the group in green
|
@@ -417,8 +474,13 @@ def chmod(self, location, mode):
|
417 | 474 | Change the permissions of a file or directory
|
418 | 475 | """
|
419 | 476 | location = self.path(location)
|
| 477 | + # Convert a text mode to an integer mode |
| 478 | + if isinstance(mode, str): |
| 479 | + if mode not in FILE_MODES: |
| 480 | + raise ValueError(f"Invalid mode string '{mode}'") |
| 481 | + mode = FILE_MODES[mode] |
420 | 482 | if not 0 <= mode <= 0o777:
|
421 |
| - raise ValueError("Invalid mode value") |
| 483 | + raise ValueError(f"Invalid mode value '{mode}'") |
422 | 484 | if os.path.exists(location):
|
423 | 485 | os.chmod(location, mode)
|
424 | 486 |
|
|
0 commit comments