Skip to content

Commit

Permalink
fix --settings= and --pythonpath= passthrough for bash and zsh, start…
Browse files Browse the repository at this point in the history
… work on powershell test #156
  • Loading branch information
bckohan committed Jan 3, 2025
1 parent 14db8e1 commit 53d46d7
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 21 deletions.
12 changes: 8 additions & 4 deletions django_typer/templates/shell_complete/bash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@

for ((i=0; i<COMP_CWORD; i++)); do
case "${COMP_WORDS[i]}" in
--settings)
--settings|--settings=*)
# Ensure the next word exists and is not another flag
if [[ $((i + 1)) -lt $COMP_CWORD ]]; then
if [[ "${COMP_WORDS[i]}" == --settings=* ]]; then
settings_option="${COMP_WORDS[i]}"
elif [[ $((i + 1)) -lt $COMP_CWORD ]]; then
settings_option="--settings=${COMP_WORDS[i+1]}"
fi
;;
--pythonpath)
--pythonpath|--pythonpath=*)
# Ensure the next word exists and is not another flag
if [[ $((i + 1)) -lt $COMP_CWORD ]]; then
if [[ "${COMP_WORDS[i]}" == --pythonpath=* ]]; then
pythonpath_option="${COMP_WORDS[i]}"
elif [[ $((i + 1)) -lt $COMP_CWORD ]]; then
pythonpath_option="--pythonpath=${COMP_WORDS[i+1]}"
fi
;;
Expand Down
12 changes: 8 additions & 4 deletions django_typer/templates/shell_complete/zsh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@

for ((i=1; i<$CURRENT; i++)); do
case "${words[i]}" in
--settings)
--settings|--settings=*)
# Only pass settings to completion script if we're sure it's value does not itself need completion!
if (( i + 1 < CURRENT )) && [[ -n "${words[i+1]}" ]] && [[ "${words[i+1]}" != --* ]]; then
if [[ "${words[i]}" == --settings=* ]]; then
settings_option="${words[i]}"
elif (( i + 1 < CURRENT )) && [[ -n "${words[i+1]}" ]] && [[ "${words[i+1]}" != --* ]]; then
settings_option="--settings=${words[i+1]}"
fi
;;
--pythonpath)
--pythonpath|--pythonpath=*)
# Only pass pythonpath to completion script if we're sure it's value does not itself need completion!
if (( i + 1 < CURRENT )) && [[ -n "${words[i+1]}" ]] && [[ "${words[i+1]}" != --* ]]; then
if [[ "${words[i]}" == --pythonpath=* ]]; then
pythonpath_option="${words[i]}"
elif (( i + 1 < CURRENT )) && [[ -n "${words[i+1]}" ]] && [[ "${words[i+1]}" != --* ]]; then
pythonpath_option="--pythonpath=${words[i+1]}"
fi
;;
Expand Down
17 changes: 16 additions & 1 deletion tests/shellcompletion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
pass


def read_all_from_fd_with_timeout(fd, timeout=1):
def read_all_from_fd_with_timeout(fd, timeout=2):
all_data = bytearray()
start_time = time.time()

Expand Down Expand Up @@ -277,6 +277,13 @@ def test_settings_pass_through(self):
" ",
)
self.assertIn("django_typer", completions)
completions = self.get_completions(
self.launch_script,
"app_labels",
"--settings=tests.settings.examples",
" ",
)
self.assertIn("django_typer", completions)

def test_pythonpath_pass_through(self):
# https://github.com/django-commons/django-typer/issues/68
Expand All @@ -294,6 +301,14 @@ def test_pythonpath_pass_through(self):
" ",
)
self.assertIn("working", completions)
completions = self.get_completions(
self.launch_script,
"python_path",
"--pythonpath=tests/off_path",
"--option",
" ",
)
self.assertIn("working", completions)


class _InstalledScriptTestCase(_DefaultCompleteTestCase):
Expand Down
6 changes: 2 additions & 4 deletions tests/shellcompletion/test_bash.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@


@pytest.mark.skipif(shutil.which("bash") is None, reason="Bash not available")
class BashShellTests(_DefaultCompleteTestCase, TestCase):
class BashTests(_DefaultCompleteTestCase, TestCase):
shell = "bash"
directory = Path("~/.bash_completions").expanduser()

def set_environment(self, fd):
# super().set_environment(fd)
os.write(fd, f"export PATH={Path(sys.executable).parent}:$PATH\n".encode())
os.write(
fd,
f"export DJANGO_SETTINGS_MODULE=tests.settings.completion\n".encode(),
Expand All @@ -43,5 +41,5 @@ def test_rich_output(self): ...


@pytest.mark.skipif(shutil.which("bash") is None, reason="Bash not available")
class BashExeShellTests(_InstalledScriptTestCase, BashShellTests):
class BashExeTests(_InstalledScriptTestCase, BashTests):
shell = "bash"
29 changes: 21 additions & 8 deletions tests/shellcompletion/test_powershell.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@

import pytest
from django.test import TestCase
from django_typer.management.commands.shells.powershell import PowerShellComplete

from tests.shellcompletion import (
_DefaultCompleteTestCase,
_InstalledScriptTestCase,
)


@pytest.mark.skipif(shutil.which("pwsh") is None, reason="Powershell not available")
@pytest.mark.skipif(
shutil.which("powershell") is None, reason="Powershell not available"
)
class PowerShellTests(_DefaultCompleteTestCase, TestCase):
shell = "pwsh"
directory = Path("~/.config/powershell").expanduser()
shell = "powershell"
profile: Path

@classmethod
def setUpClass(cls) -> None:
cls.profile = PowerShellComplete().get_user_profile()
return super().setUpClass()

@property
def interactive_opt(self):
Expand All @@ -30,6 +38,9 @@ def set_environment(self, fd):
fd,
f'$env:DJANGO_SETTINGS_MODULE="tests.settings.completion"\n'.encode(),
)
activate = Path(sys.executable).absolute().parent / "activate.ps1"
if activate.is_file():
os.write(fd, f"{activate}\n".encode())

def test_shell_complete(self):
# just verify that install/remove works. The actual completion is not tested
Expand All @@ -42,25 +53,27 @@ def test_shell_complete(self):
def verify_install(self, script=None):
if not script:
script = self.manage_script
self.assertTrue((self.directory / "Microsoft.PowerShell_profile.ps1").exists())
self.assertTrue(self.profile.exists())
self.assertTrue(
f"Register-ArgumentCompleter -Native -CommandName {script} -ScriptBlock $scriptblock"
in (self.directory / "Microsoft.PowerShell_profile.ps1").read_text()
in self.profile.read_text()
)

def verify_remove(self, script=None):
if not script:
script = self.manage_script
if (self.directory / "Microsoft.PowerShell_profile.ps1").exists():
contents = (self.directory / "Microsoft.PowerShell_profile.ps1").read_text()
if self.profile.exists():
contents = self.profile.read_text()
self.assertFalse(
f"Register-ArgumentCompleter -Native -CommandName {script} -ScriptBlock $scriptblock"
in contents
)
self.assertTrue(contents) # should have been deleted if it were empty


@pytest.mark.skipif(shutil.which("pwsh") is None, reason="Powershell not available")
@pytest.mark.skipif(
shutil.which("powershell") is None, reason="Powershell not available"
)
class PowerShellInstallRemoveTests(_InstalledScriptTestCase, PowerShellTests):
def test_shell_complete(self):
# the power shell completion script registration is all in one file
Expand Down
12 changes: 12 additions & 0 deletions tests/shellcompletion/test_zsh.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import pytest
from django.test import TestCase
import os
import sys

from tests.shellcompletion import _DefaultCompleteTestCase, _InstalledScriptTestCase

Expand All @@ -22,6 +24,16 @@ def verify_remove(self, script=None):
script = self.manage_script
self.assertFalse((self.directory / f"_{script}").exists())

# def set_environment(self, fd):
# os.write(
# fd,
# f"export DJANGO_SETTINGS_MODULE=tests.settings.completion\n".encode(),
# )
# os.write(fd, "source ~/.zshrc\n".encode())
# activate = Path(sys.executable).absolute().parent / "activate"
# if activate.is_file():
# os.write(fd, f"source {activate}\n".encode())


@pytest.mark.skipif(shutil.which("zsh") is None, reason="Z-Shell not available")
class ZshExeTests(_InstalledScriptTestCase, ZshTests, TestCase):
Expand Down

0 comments on commit 53d46d7

Please sign in to comment.