Skip to content

Commit

Permalink
Added download_cli management command as requested in #109. Documenta…
Browse files Browse the repository at this point in the history
…tion and more testing still missing.
  • Loading branch information
oliverandrich committed Mar 12, 2024
1 parent 70bfbcd commit 2c11ff3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
42 changes: 27 additions & 15 deletions src/django_tailwind_cli/management/commands/tailwind.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ def init(self):

# Before running the actual subcommand, we need to make sure that the CLI is installed and
# the config file exists.
self._download_cli_if_not_exists()
if self.config.automatic_download:
self.download_cli()
self._create_tailwind_config_if_not_exists()

@command(help="Build a minified production ready CSS file.")
def build(self):
if not self.config.get_full_cli_path().exists():
raise CommandError("Tailwind CSS CLI not found.")

build_cmd = [
str(self.config.get_full_cli_path()),
"--output",
Expand All @@ -63,6 +67,9 @@ def build(self):

@command(help="Start Tailwind CLI in watch mode during development.")
def watch(self):
if not self.config.get_full_cli_path().exists():
raise CommandError("Tailwind CSS CLI not found.")

watch_cmd = [
str(self.config.get_full_cli_path()),
"--output",
Expand Down Expand Up @@ -234,22 +241,27 @@ def _runserver(self, debug_server_cmd: List[str]) -> None:
watch_process.terminate()
debugserver_process.terminate()

def _download_cli_if_not_exists(self) -> None:
@command(name="download_cli", help="Download the Tailwind CSS CLI to .")
def download_cli(self) -> None:
dest_file = self.config.get_full_cli_path()

if not dest_file.exists() and self.config.automatic_download:
download_url = self.config.get_download_url()
self.stdout.write(self.style.ERROR("Tailwind CSS CLI not found."))
self.stdout.write(self.style.WARNING(f"Downloading Tailwind CSS CLI from '{download_url}'"))
dest_file.parent.mkdir(parents=True, exist_ok=True)
certifi_context = ssl.create_default_context(cafile=certifi.where())
with urllib.request.urlopen(download_url, context=certifi_context) as source, dest_file.open( # noqa: S310
mode="wb"
) as dest:
shutil.copyfileobj(source, dest)
# make cli executable
dest_file.chmod(0o755)
self.stdout.write(self.style.SUCCESS(f"Downloaded Tailwind CSS CLI to '{dest_file}'"))
if dest_file.exists():
self._write_success(f"Tailwind CSS CLI already exists at '{dest_file}'")
return

download_url = self.config.get_download_url()
self._write_error("Tailwind CSS CLI not found.")
self._write_success(f"Downloading Tailwind CSS CLI from '{download_url}'")
dest_file.parent.mkdir(parents=True, exist_ok=True)
certifi_context = ssl.create_default_context(cafile=certifi.where())
with (
urllib.request.urlopen(download_url, context=certifi_context) as source,
dest_file.open(mode="wb") as dest, # noqa: S310
):
shutil.copyfileobj(source, dest)
# make cli executable
dest_file.chmod(0o755)
self._write_success(f"Downloaded Tailwind CSS CLI to '{dest_file}'")

def _create_tailwind_config_if_not_exists(self) -> None:
tailwind_config_file = self.config.get_full_config_file_path()
Expand Down
25 changes: 24 additions & 1 deletion tests/test_management_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,39 @@ def test_download_cli(settings, tmp_path, config):
settings.BASE_DIR = tmp_path
settings.TAILWIND_CLI_PATH = str(tmp_path)
assert not config.get_full_cli_path().exists()
call_command("tailwind", "build")
call_command("tailwind", "download_cli")
assert config.get_full_cli_path().exists()


def test_download_cli_without_tailwind_cli_path(settings, tmp_path, config):
settings.BASE_DIR = tmp_path
settings.TAILWIND_CLI_PATH = None
assert not config.get_full_cli_path().exists()
call_command("tailwind", "download_cli")
assert config.get_full_cli_path().exists()


def test_automatic_download_enabled(settings, tmp_path, config):
settings.BASE_DIR = tmp_path
settings.TAILWIND_CLI_PATH = str(tmp_path)
settings.TAILWIND_CLI_AUTOMATIC_DOWNLOAD = True
assert not config.get_full_cli_path().exists()
call_command("tailwind", "build")
assert config.get_full_cli_path().exists()


def test_automatic_download_disabled(settings, tmp_path, config):
settings.BASE_DIR = tmp_path
settings.TAILWIND_CLI_PATH = str(tmp_path)
settings.TAILWIND_CLI_AUTOMATIC_DOWNLOAD = False
assert not config.get_full_cli_path().exists()
with pytest.raises(CommandError, match="Tailwind CSS CLI not found."):
call_command("tailwind", "build")
with pytest.raises(CommandError, match="Tailwind CSS CLI not found."):
call_command("tailwind", "watch")
assert not config.get_full_cli_path().exists()


def test_create_tailwind_config_if_non_exists(settings, tmp_path, config):
settings.BASE_DIR = tmp_path
settings.TAILWIND_CLI_PATH = str(tmp_path)
Expand Down Expand Up @@ -80,6 +101,7 @@ def test_build_output_of_first_run(settings, tmp_path, capsys):
call_command("tailwind", "build")
captured = capsys.readouterr()
assert "Tailwind CSS CLI not found." in captured.out
assert "Tailwind CSS CLI already exists at" not in captured.out
assert "Downloading Tailwind CSS CLI from " in captured.out
assert "Built production stylesheet" in captured.out

Expand All @@ -92,6 +114,7 @@ def test_build_output_of_second_run(settings, tmp_path, capsys):
call_command("tailwind", "build")
captured = capsys.readouterr()
assert "Tailwind CSS CLI not found." not in captured.out
assert "Tailwind CSS CLI already exists at" in captured.out
assert "Downloading Tailwind CSS CLI from " not in captured.out
assert "Built production stylesheet" in captured.out

Expand Down

0 comments on commit 2c11ff3

Please sign in to comment.