Skip to content

Commit f453bbe

Browse files
committed
Add tue-install-add-text
1 parent 2a438c3 commit f453bbe

File tree

3 files changed

+152
-53
lines changed

3 files changed

+152
-53
lines changed

src/tue_get/install_yaml_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ def get_distro_item(item: Mapping, key: str, release_version: str, release_type:
211211
if __name__ == "__main__":
212212
import sys
213213
from tue_get.installer_impl import InstallerImpl
214+
214215
if len(sys.argv) < 2:
215216
print("Provide yaml file to parse")
216217
exit(1)

src/tue_get/installer_impl.py

Lines changed: 150 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ def _write_stdin(msg) -> None:
185185
_write_stdin(not success)
186186
elif line.startswith("tue-install-system: "):
187187
pkgs = line[20:].split()
188-
self.tue_install_system(pkgs)
189-
_write_stdin(0)
188+
success = self.tue_install_system(pkgs)
189+
_write_stdin(not success)
190190
elif line.startswith("tue-install-system-now: "):
191191
pkgs = line[24:].split()
192192
success = self.tue_install_system_now(pkgs)
@@ -196,40 +196,40 @@ def _write_stdin(msg) -> None:
196196
_write_stdin(0)
197197
elif line.startswith("tue-install-ppa: "):
198198
ppas = line[17:].split()
199-
self.tue_install_ppa(ppas)
200-
_write_stdin(0)
199+
success = self.tue_install_ppa(ppas)
200+
_write_stdin(not success)
201201
elif line.startswith("tue-install-ppa-now: "):
202202
ppas = line[21:].split()
203203
success = self.tue_install_ppa_now(ppas)
204204
_write_stdin(not success)
205205
elif line.startswith("tue-install-pip: "):
206206
pkgs = line[17:].split()
207-
self.tue_install_pip(pkgs)
208-
_write_stdin(0)
207+
success = self.tue_install_pip(pkgs)
208+
_write_stdin(not success)
209209
elif line.startswith("tue-install-pip-now: "):
210210
pkgs = line[20:].split()
211211
success = self.tue_install_pip_now(pkgs)
212212
_write_stdin(not success)
213213
elif line.startswith("tue-install-snap: "):
214214
pkgs = line[18:].split()
215-
self.tue_install_snap(pkgs)
216-
_write_stdin(0)
215+
success = self.tue_install_snap(pkgs)
216+
_write_stdin(not success)
217217
elif line.startswith("tue-install-snap-now: "):
218218
pkgs = line[22:].split()
219219
success = self.tue_install_snap_now(pkgs)
220220
_write_stdin(not success)
221221
elif line.startswith("tue-install-gem: "):
222222
pkgs = line[17:].split(" ")
223-
self.tue_install_gem(pkgs)
224-
_write_stdin(0)
223+
success = self.tue_install_gem(pkgs)
224+
_write_stdin(not success)
225225
elif line.startswith("tue-install-gem-now: "):
226226
pkgs = line[21:].split(" ")
227227
success = self.tue_install_gem_now(pkgs)
228228
_write_stdin(not success)
229229
else:
230230
self.tue_install_tee(line)
231231

232-
def _err_handler_sudo_password(self, sub: BackgroundPopen, line: Union[bytes, str]) -> None:
232+
def _err_handler(self, sub: BackgroundPopen, line: Union[bytes, str]) -> None:
233233
line = line.strip()
234234
if line.startswith("[sudo] password for"):
235235
if self._sudo_password is None:
@@ -302,7 +302,7 @@ def tue_install_target_now(self, target: str) -> bool:
302302
def tue_install_target(self, target: str, now: bool = False) -> bool:
303303
self.tue_install_debug(f"tue-install-target {target=} {now=}")
304304

305-
self.tue_install_debug("Installing target: {target}")
305+
self.tue_install_debug(f"Installing target: {target}")
306306

307307
# Check if valid target received as input
308308
if not os.path.isdir(os.path.join(self._targets_dir, target)):
@@ -352,7 +352,7 @@ def tue_install_target(self, target: str, now: bool = False) -> bool:
352352
)
353353

354354
if execution_needed:
355-
self.tue_install_debug("Starting installation")
355+
self.tue_install_debug(f"Starting installation of target: {target}")
356356
install_file = os.path.join(self._current_target_dir, "install")
357357

358358
# Empty the target's dependency file
@@ -401,16 +401,14 @@ def tue_install_target(self, target: str, now: bool = False) -> bool:
401401
sub = BackgroundPopen(
402402
args=cmds,
403403
out_handler=self._out_handler,
404-
err_handler=self._err_handler_sudo_password,
404+
err_handler=self._err_handler,
405405
stdin=subprocess.PIPE,
406406
text=True,
407407
)
408408
sub.wait()
409409
if sub.returncode != 0:
410410
# stderr = sub.stderr.read()
411-
self.tue_install_error(
412-
f"Error while running({sub.returncode}):\n {' '.join(cmds)}" f"\n\n{stderr}"
413-
)
411+
self.tue_install_error(f"Error while running({sub.returncode}):\n {' '.join(cmds)}")
414412
# ToDo: This depends on behaviour of tue-install-error
415413
return False
416414

@@ -452,11 +450,10 @@ def tue_install_apply_patch(self, patch_file: str, target_dir: str) -> bool:
452450
cmd = f"patch -s -N -r - -p0 -d {target_dir} < {patch_file_path}"
453451
cmds = _which_split_cmd(cmd)
454452
self.tue_install_echo(" ".join(cmds))
455-
sub = BackgroundPopen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
453+
sub = BackgroundPopen(args=cmds, out_handler=self._out_handler, err_handler=self._err_handler, text=True)
456454
sub.wait()
457455
if sub.returncode != 0:
458-
stderr = sub.stderr.read()
459-
self.tue_install_error(f"Error while running({sub.returncode}):\n{' '.join(cmds)}\n\n{stderr}")
456+
self.tue_install_error(f"Error while running({sub.returncode}):\n{' '.join(cmds)}")
460457
# ToDo: This depends on behaviour of tue-install-error
461458
return False
462459

@@ -511,17 +508,14 @@ def tue_install_cp(self, source: str, target: str) -> bool:
511508
self.tue_install_echo(" ".join(cmds))
512509
sub = BackgroundPopen(
513510
args=cmds,
514-
err_handler=self._err_handler_sudo_password,
515-
stderr=subprocess.PIPE,
511+
out_handler=self._out_handler,
512+
err_handler=self._err_handler,
516513
stdin=subprocess.PIPE,
517514
text=True,
518515
)
519516
sub.wait()
520517
if sub.returncode != 0:
521-
# stderr = sub.stderr.read()
522-
self.tue_install_error(
523-
f"Error while creating the directory({sub.returncode}):\n{' '.join(cmds)}" # f"\n\n{stderr}"
524-
)
518+
self.tue_install_error(f"Error while creating the directory({sub.returncode}):\n{' '.join(cmds)}")
525519
# ToDo: This depends on behaviour of tue-install-error
526520
return False
527521

@@ -530,56 +524,162 @@ def tue_install_cp(self, source: str, target: str) -> bool:
530524
self.tue_install_echo(" ".join(cmds))
531525
sub = BackgroundPopen(
532526
args=cmds,
533-
err_handler=self._err_handler_sudo_password,
534-
stderr=subprocess.PIPE,
527+
out_handler=self._out_handler,
528+
err_handler=self._err_handler,
535529
stdin=subprocess.PIPE,
536530
text=True,
537531
)
538532
sub.wait()
539533
if sub.returncode != 0:
540-
stderr = sub.stderr.read()
541-
self.tue_install_error(f"Error while copying({sub.returncode}):\n{' '.join(cmds)}\n\n{stderr}")
534+
self.tue_install_error(f"Error while copying({sub.returncode}):\n{' '.join(cmds)}")
542535
# ToDo: This depends on behaviour of tue-install-error
543536
return False
544537

545538
def tue_install_add_text(self, source_file: str, target_file: str) -> bool:
546-
pass
539+
self.tue_install_debug(f"tue-install-add-text {source_file=} {target_file=}")
540+
541+
if not source_file:
542+
self.tue_install_error("Invalid tue-install-add-text call: needs source file as argument")
543+
# ToDo: This depends on behaviour of tue-install-error
544+
return False
545+
546+
if not target_file:
547+
self.tue_install_error("Invalid tue-install-add-text call: needs target file as argument")
548+
# ToDo: This depends on behaviour of tue-install-error
549+
return False
550+
551+
if source_file.startswith("/") or source_file.startswith("~"):
552+
self.tue_install_error(
553+
"Invalid tue-install-add-text call: source file must be relative to target directory"
554+
)
555+
# ToDo: This depends on behaviour of tue-install-error
556+
return False
557+
558+
if not target_file.startswith("/") and not target_file.startswith("~"):
559+
self.tue_install_error(
560+
"Invalid tue-install-add-text call: target file must be absolute or " "relative to the home directory"
561+
)
562+
# ToDo: This depends on behaviour of tue-install-error
563+
return False
564+
565+
root_required = True
566+
if os.access(target_file, os.W_OK):
567+
root_required = False
568+
self.tue_install_debug("tue-install-add-text: NO root required")
569+
else:
570+
self.tue_install_debug("tue-install-add-text: root required")
571+
572+
if root_required:
573+
sudo_cmd = "sudo "
574+
self.tue_install_debug("Using elevated privileges (sudo) to add text")
575+
else:
576+
sudo_cmd = ""
577+
578+
source_file_path = os.path.join(self._current_target_dir, source_file)
579+
if not os.path.isfile(source_file_path):
580+
self.tue_install_error(f"tue-install-add-text: source file {source_file_path} does not exist")
581+
# ToDo: This depends on behaviour of tue-install-error
582+
return False
583+
584+
target_file_path = os.path.expanduser(target_file)
585+
if not os.path.isfile(target_file_path):
586+
self.tue_install_error(f"tue-install-add-text: target file {target_file_path} does not exist")
587+
# ToDo: This depends on behaviour of tue-install-error
588+
return False
589+
590+
with open(source_file_path, "r") as f:
591+
source_text = f.read().splitlines()
592+
593+
begin_tag = source_text[0]
594+
end_tag = source_text[-1]
595+
source_body = source_text[1:-1]
596+
source_text = "\n".join(source_text)
597+
598+
self.tue_install_debug(f"tue-install-add-text: {begin_tag=}, {end_tag=}\n{source_body=}")
599+
600+
with open(target_file_path, "r") as f:
601+
target_text = f.read().splitlines()
602+
603+
if not begin_tag in target_text:
604+
self.tue_install_debug(
605+
f"tue-install-add-text: {begin_tag=} not found in {target_file_path=}, "
606+
"appending to {target_file_path}"
607+
)
608+
cmd = f"bash -c \"echo - e '{source_text}' | {sudo_cmd}tee -a {target_file_path} 1>/dev/null\""
609+
else:
610+
self.tue_install_debug(
611+
f"tue-install-add-text: {begin_tag=} found in {target_file_path=}, "
612+
"so comparing the files for changed lines"
613+
)
614+
615+
if filecmp.cmp(source_file_path, target_file_path):
616+
self.tue_install_debug(
617+
f"tue-install-add-text: {source_file_path=} and {target_file_path=} are " "identical, skipping"
618+
)
619+
return True
620+
621+
begin_index = target_text.index(begin_tag)
622+
end_index = target_text.index(end_tag)
623+
target_text = target_text[:begin_index] + source_text.splitlines() + target_text[end_index + 1 :]
624+
target_text = "\n".join(target_text)
625+
626+
cmd = f"bash -c \"echo -e '{target_text}' | {sudo_cmd}tee {target_file_path} 1>/dev/null\""
627+
628+
cmds = _which_split_cmd(cmd)
629+
self.tue_install_echo(" ".join(cmds))
630+
sub = BackgroundPopen(
631+
args=cmds,
632+
out_handler=self._out_handler,
633+
err_handler=self._err_handler,
634+
stdin=subprocess.PIPE,
635+
text=True,
636+
)
637+
sub.wait()
638+
if sub.returncode != 0:
639+
self.tue_install_error(f"Error while adding text({sub.returncode}):\n{' '.join(cmds)}")
640+
# ToDo: This depends on behaviour of tue-install-error
641+
return False
547642

548643
def tue_install_get_releases(self, url: str, filename: str, output_dir: str, tag: Optional[str] = None) -> bool:
549644
pass
550645

551-
def tue_install_system(self, pkgs: List[str]):
646+
def tue_install_system(self, pkgs: List[str]) -> bool:
552647
self._systems.extend(pkgs)
648+
return True
553649

554650
def tue_install_system_now(self, pkgs: List[str]) -> bool:
555-
pass
651+
return True
556652

557653
def tue_install_apt_get_update(self):
558654
self.tue_install_debug("tue-install-apt-get-update")
559655
self.tue_install_debug("Requiring an update of apt-get before next 'apt-get install'")
560656
if os.path.isfile(self._apt_get_updated_file):
561657
os.remove(self._apt_get_updated_file)
562658

563-
def tue_install_ppa(self, ppas: List[str]):
659+
def tue_install_ppa(self, ppas: List[str]) -> bool:
564660
self._ppas.extend(ppas)
661+
return True
565662

566663
def tue_install_ppa_now(self, ppa: List[str]) -> bool:
567-
pass
664+
return True
568665

569-
def tue_install_pip(self, pkgs: List[str]):
666+
def tue_install_pip(self, pkgs: List[str]) -> bool:
570667
self._pips.extend(pkgs)
668+
return True
571669

572670
def tue_install_pip_now(self, pkgs: List[str]) -> bool:
573-
pass
671+
return True
574672

575-
def tue_install_snap(self, pkgs: List[str]):
673+
def tue_install_snap(self, pkgs: List[str]) -> bool:
576674
self._snaps.extend(pkgs)
675+
return True
577676

578677
def tue_install_snap_now(self, pkgs: List[str]) -> bool:
579-
pass
678+
return True
580679

581-
def tue_install_gem(self, pkgs: List[str]):
680+
def tue_install_gem(self, pkgs: List[str]) -> bool:
582681
self._gems.extend(pkgs)
682+
return True
583683

584684
def tue_install_gem_now(self, pkgs: List[str]) -> bool:
585685
self.tue_install_debug(f"tue-install-gem-now {pkgs=}")
@@ -592,12 +692,11 @@ def tue_install_gem_now(self, pkgs: List[str]) -> bool:
592692
cmd = "gem list"
593693
cmds = _which_split_cmd(cmd)
594694
self.tue_install_echo(" ".join(cmds))
595-
sub = BackgroundPopen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
695+
sub = BackgroundPopen(args=cmds, err_handler=self._err_handler, stdout=subprocess.PIPE, text=True)
596696
sub.wait()
597697
if sub.returncode != 0:
598-
stderr = sub.stderr.read()
599698
self.tue_install_error(
600-
f"Error while getting installed gem packages({sub.returncode}):\n {' '.join(cmds)}\n\n{stderr}"
699+
f"Error while getting installed gem packages({sub.returncode}):\n {' '.join(cmds)}"
601700
)
602701
# ToDo: This depends on behaviour of tue-install-error
603702
return False
@@ -615,29 +714,27 @@ def tue_install_gem_now(self, pkgs: List[str]) -> bool:
615714
if gems_to_install:
616715
cmd = f"gem install {' '.join(gems_to_install)}"
617716
cmds = _which_split_cmd(cmd)
618-
sub = BackgroundPopen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
717+
sub = BackgroundPopen(args=cmds, out_handler=self._out_handler, err_handler=self._err_handler, text=True)
619718
sub.wait()
620719
if sub.returncode != 0:
621-
stderr = sub.stderr.read()
622720
self.tue_install_error(
623721
f"An error occurred while installing gem packages({sub.returncode}):\n {' '.join(cmds)}"
624-
f"\n\n{stderr}"
625722
)
626723
# ToDo: This depends on behaviour of tue-install-error
627724
return False
628725

629726
return True
630727

631-
def tue_install_dpkg(self, pkg_file: str):
632-
pass
728+
def tue_install_dpkg(self, pkg_file: str) -> bool:
729+
return True
633730

634-
def tue_install_dpkg_now(self, pkg_file: str):
635-
pass
731+
def tue_install_dpkg_now(self, pkg_file: str) -> bool:
732+
return True
636733

637-
def tue_install_ros(self, source_type: str, **kwargs):
638-
pass
734+
def tue_install_ros(self, source_type: str, **kwargs) -> bool:
735+
return True
639736

640737

641738
if __name__ == "__main__":
642739
bla = InstallerImpl(debug=True)
643-
bla.tue_install_target("test")
740+
bla.tue_install_target("networking")

test/test_tue_get/test_install_yaml_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_empty_target():
104104
cmds = parse_target(target, True)
105105
assert not cmds
106106

107+
107108
def test_system_target():
108109
target = [{"type": "system", "name": "pkg_name"}]
109110
cmds = parse_target(target, False)

0 commit comments

Comments
 (0)