"""Exercise the POSIX entry point with a fake Python; no services or real venv.""" import os from pathlib import Path import shutil import subprocess import tempfile import unittest def shell_path(path): value = Path(path).as_posix() if len(value) > 1 and value[1] == ':': return '/' + value[0].lower() + value[2:] return value class OfflineImportShellTests(unittest.TestCase): def setUp(self): self.shell = shutil.which('bash') or shutil.which('sh') if not self.shell and Path('C:/Program Files/Git/bin/bash.exe').is_file(): self.shell = 'C:/Program Files/Git/bin/bash.exe' if not self.shell: self.skipTest('POSIX shell unavailable') self.tmp = tempfile.TemporaryDirectory() self.addCleanup(self.tmp.cleanup) self.root = Path(self.tmp.name) self.shell_cwd = subprocess.run([self.shell, '-c', 'pwd'], cwd=self.root, capture_output=True, text=True, check=True).stdout.strip() self.repo = self.root / 'repo with spaces' self.repo.mkdir() self.script = self.repo / 'deploy-offline.sh' self.script.write_bytes((Path(__file__).parents[2]/'deploy-offline.sh').read_bytes().replace(b'\r\n', b'\n')) self.capture = self.root/'arguments.txt' python = self.repo/'.venv/bin/python' python.parent.mkdir(parents=True) python.write_text('#!/bin/sh\nprintf "%s\\n" "$@" > "$CAPTURE"\n', encoding='utf-8', newline='\n') python.chmod(0o755) self.bin = self.root/'bin' self.bin.mkdir() uname = self.bin/'uname' uname.write_text('#!/bin/sh\nprintf "Linux\\n"\n', encoding='utf-8', newline='\n') uname.chmod(0o755) def run_shell(self, *args): env = dict(os.environ, CAPTURE=shell_path(self.capture)) # An isolated PATH keeps this a syntax/argument test, including on Git Bash. return subprocess.run([self.shell, '-c', 'PATH="$1:/usr/bin:/bin"; export PATH; shift; exec /bin/sh "$@"', 'test', shell_path(self.bin), shell_path(self.script), *args], cwd=self.root, env=env, capture_output=True, text=True) def test_default_custom_relative_absolute_and_library(self): for args, tail in [ ([], ['import-knowledge']), (['a path/new.zip'], ['import-knowledge', self.shell_cwd+'/a path/new.zip']), (['/transfer/new.zip', 'article'], ['import-knowledge','/transfer/new.zip','article'])]: with self.subTest(args=args): result = self.run_shell('import-knowledge', *args) self.assertEqual(result.returncode,0,result.stderr) self.assertEqual(self.capture.read_text().splitlines(),['scripts/deploy.py',*tail]) def test_invalid_arguments_rejected_before_python(self): for args in [('x.zip','wrong'), ('',), ('x.zip','article','extra')]: with self.subTest(args=args): result = self.run_shell('import-knowledge', *args) self.assertEqual(result.returncode,2) self.assertFalse(self.capture.exists())