Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions .github/actions/init/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,15 @@ inputs:
runs:
using: "composite"
steps:
- name: "Ensure doxygen"
if: inputs.doc-tools
- name: "Ensure doxygen (Linux)"
if: inputs.doc-tools && runner.os == 'Linux'
run: sudo apt-get install graphviz doxygen -y
# latest doxygen (untested)
# run: |
# if ! command -v doxygen &> /dev/null
# then
# echo "doxygen wasn't found... installing now..."
# mkdir -p ~/.local/bin
# curl -sSL https://www.doxygen.nl/files/doxygen-1.9.4.linux.bin.tar.gz | \
# tar -xzvf - --strip-components=1 -C ~/.local/bin bin/doxygen;
# fi
shell: bash

- name: "Ensure doxygen (Windows)"
if: inputs.doc-tools && runner.os == 'Windows'
run: |
choco install doxygen.install graphviz --yes
shell: bash

- name: "Ensure poetry"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ permissions:

jobs:
test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest]

steps:
- name: "Checkout Code"
Expand All @@ -46,6 +47,7 @@ jobs:
run: |
mkdir -p docs/doxygen
poetry run pytest --emoji -v -s --md $GITHUB_STEP_SUMMARY
shell: bash

qa:
runs-on: ubuntu-latest
Expand Down
9 changes: 7 additions & 2 deletions doxysphinx/utils/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,13 @@ def copy_if_different(
source_file = file
target_file = target_dir / source_file.relative_to(source_dir)
target_file.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(source_file, target_file)
result.append(target_file)
if os.name == "nt":
# Use extended-length paths on Windows to support long file names
# Apply \\?\ prefix only to the shutil operation, not to pathlib operations
shutil.copy(rf"\\?\{source_file}", rf"\\?\{target_file}")
else:
shutil.copy(source_file, target_file)
result.append(target_file) # Return the original path without prefix

return result

Expand Down
74 changes: 70 additions & 4 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
# - Markus Braun, :em engineering methods AG (contracted by Robert Bosch GmbH)
# =====================================================================================

import os
from pathlib import Path
import shutil

from click.testing import CliRunner

Expand Down Expand Up @@ -39,9 +41,75 @@ def test_build_is_working_as_expected():
print("Build had errors - std output stream:")
print(result.stdout)
assert result.exit_code == 0
print("test2")
assert (repo_root / ".build/html/docs/doxygen/demo/html/doxygen.css").exists()
print("test3")


def test_longpath_build():
"""Test building with long paths"""
runner = CliRunner()
repo_root = path_resolve(Path())

# Copy our demo directory to a very long path
# The path needs to be over 255 characters long to trigger issues on Windows
# Windows has a max path length of 255 characters by default
# (see https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
long_dir_name = "a" * 250 # Single very long directory name
long_path = repo_root / long_dir_name

# Test if we can create the long path at all
if os.name == "nt":
# On Windows, use extended-length path support
try:
# Use \\?\ prefix for the actual copy operation
shutil.copytree(rf"\\?\{repo_root}", rf"\\?\{long_path}", dirs_exist_ok=True)
except OSError as e:
raise AssertionError(
f"Long path copy failed on Windows - this indicates the tool won't work with long paths: {e}")
else:
shutil.copytree(repo_root, long_path, dirs_exist_ok=True)

# Verify the copy worked by checking for key files
# On Windows with long paths, use os.path.exists with \\?\ prefix for verification
if os.name == "nt":
assert os.path.exists(rf"\\?\{long_path}"), f"Long path directory was not created: {long_path}"
assert os.path.exists(rf"\\?\{long_path}\pyproject.toml"), f"pyproject.toml not found in long path: {long_path}"
else:
assert long_path.exists(), f"Directory was not created: {long_path}"
assert (long_path / "pyproject.toml").exists(), f"pyproject.toml not found: {long_path}"

sphinx_source = long_path
sphinx_output = long_path / ".build/html"
doxyfile = long_path / "demo" / "demo.doxyfile"

result = runner.invoke(
cli,
[
"--verbosity=DEBUG",
"build",
"--doxygen_cwd",
str(long_path),
str(sphinx_source),
str(sphinx_output),
str(doxyfile),
],
)
if result.exit_code != 0:
print("Build had errors - std output stream:")
print(result.stdout)
assert result.exit_code == 0
# Check the final output file
css_file_path = long_path / ".build/html/docs/doxygen/demo/html/doxygen.css"
if os.name == "nt":
assert os.path.exists(rf"\\?\{css_file_path}"), f"Output CSS file missing: {css_file_path}"
else:
assert css_file_path.exists(), f"Output CSS file missing: {css_file_path}"

# Clean up - only if the directory was actually created
if long_path.exists():
if os.name == "nt":
shutil.rmtree(rf"\\?\{long_path}")
else:
shutil.rmtree(long_path)


def test_worker_limiting():
Expand Down Expand Up @@ -85,9 +153,7 @@ def test_worker_limiting():
print("Build had errors - std output stream:")
print(result.stdout)
assert result.exit_code == 0
print("test2")
assert (repo_root / ".build/html/docs/doxygen/demo/html/doxygen.css").exists()
print("test3")
assert f"running in parallel with limit of {worker_limit} workers" in result.stdout


Expand Down
Loading