rolfedh-doc-utils 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/PKG-INFO +1 -1
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/topic_map_parser.py +10 -2
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/unused_adoc.py +3 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/unused_images.py +3 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/pyproject.toml +1 -1
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/PKG-INFO +1 -1
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/SOURCES.txt +2 -0
- rolfedh_doc_utils-0.1.4/setup.py +45 -0
- rolfedh_doc_utils-0.1.4/tests/test_symlink_handling.py +91 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/LICENSE +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/README.md +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/__init__.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/file_utils.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/scannability.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/doc_utils/unused_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/find_unused_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/dependency_links.txt +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/entry_points.txt +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/requires.txt +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/top_level.txt +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/setup.cfg +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_cli_entry_points.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_file_utils.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_parse_exclude_list.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_topic_map_parser.py +0 -0
- {rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_unused_attributes.py +0 -0
|
@@ -22,8 +22,16 @@ def detect_repo_type(base_path='.'):
|
|
|
22
22
|
if yml_files:
|
|
23
23
|
return 'topic_map'
|
|
24
24
|
|
|
25
|
-
# Check for master.adoc files
|
|
26
|
-
master_files =
|
|
25
|
+
# Check for master.adoc files using os.walk to avoid symlink issues
|
|
26
|
+
master_files = []
|
|
27
|
+
for root, dirs, files in os.walk(base_path):
|
|
28
|
+
# Skip symbolic link directories to prevent infinite recursion
|
|
29
|
+
dirs[:] = [d for d in dirs if not os.path.islink(os.path.join(root, d))]
|
|
30
|
+
|
|
31
|
+
# Check for master.adoc in this directory
|
|
32
|
+
if 'master.adoc' in files:
|
|
33
|
+
master_files.append(os.path.join(root, 'master.adoc'))
|
|
34
|
+
|
|
27
35
|
if master_files:
|
|
28
36
|
return 'master_adoc'
|
|
29
37
|
|
|
@@ -6,6 +6,9 @@ from .file_utils import collect_files, write_manifest_and_archive
|
|
|
6
6
|
from .topic_map_parser import detect_repo_type, get_all_topic_map_references
|
|
7
7
|
|
|
8
8
|
def find_unused_adoc(scan_dirs, archive_dir, archive=False, exclude_dirs=None, exclude_files=None):
|
|
9
|
+
# Print safety warning
|
|
10
|
+
print("\n⚠️ SAFETY: Work in a git branch! Run without --archive first to preview.\n")
|
|
11
|
+
|
|
9
12
|
# Detect repository type
|
|
10
13
|
repo_type = detect_repo_type()
|
|
11
14
|
print(f"Detected repository type: {repo_type}")
|
|
@@ -7,6 +7,9 @@ from .file_utils import collect_files, write_manifest_and_archive
|
|
|
7
7
|
IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.svg'}
|
|
8
8
|
|
|
9
9
|
def find_unused_images(scan_dirs, archive_dir, archive=False, exclude_dirs=None, exclude_files=None):
|
|
10
|
+
# Print safety warning
|
|
11
|
+
print("\n⚠️ SAFETY: Work in a git branch! Run without --archive first to preview.\n")
|
|
12
|
+
|
|
10
13
|
image_files = collect_files(scan_dirs, IMAGE_EXTENSIONS, exclude_dirs, exclude_files)
|
|
11
14
|
adoc_files = collect_files(['.'], {'.adoc'}, exclude_dirs, exclude_files)
|
|
12
15
|
referenced_images = set()
|
|
@@ -5,6 +5,7 @@ archive_unused_images.py
|
|
|
5
5
|
check_scannability.py
|
|
6
6
|
find_unused_attributes.py
|
|
7
7
|
pyproject.toml
|
|
8
|
+
setup.py
|
|
8
9
|
doc_utils/__init__.py
|
|
9
10
|
doc_utils/file_utils.py
|
|
10
11
|
doc_utils/scannability.py
|
|
@@ -27,5 +28,6 @@ tests/test_fixture_archive_unused_files.py
|
|
|
27
28
|
tests/test_fixture_archive_unused_images.py
|
|
28
29
|
tests/test_fixture_check_scannability.py
|
|
29
30
|
tests/test_parse_exclude_list.py
|
|
31
|
+
tests/test_symlink_handling.py
|
|
30
32
|
tests/test_topic_map_parser.py
|
|
31
33
|
tests/test_unused_attributes.py
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Setup script for doc-utils package.
|
|
4
|
+
This file is only needed if we want to customize the installation process.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from setuptools import setup
|
|
8
|
+
from setuptools.command.install import install
|
|
9
|
+
from setuptools.command.develop import develop
|
|
10
|
+
from setuptools.command.egg_info import egg_info
|
|
11
|
+
|
|
12
|
+
def custom_post_install():
|
|
13
|
+
"""Display safety message after installation."""
|
|
14
|
+
print("\n" + "="*60)
|
|
15
|
+
print("✅ doc-utils installed successfully!")
|
|
16
|
+
print("\n⚠️ IMPORTANT: Safety First")
|
|
17
|
+
print(" • Work in a git branch (never main/master)")
|
|
18
|
+
print(" • Run without --archive first to preview")
|
|
19
|
+
print(" • Review changes with git diff")
|
|
20
|
+
print("="*60 + "\n")
|
|
21
|
+
|
|
22
|
+
class CustomInstallCommand(install):
|
|
23
|
+
"""Customized setuptools install command."""
|
|
24
|
+
def run(self):
|
|
25
|
+
install.run(self)
|
|
26
|
+
custom_post_install()
|
|
27
|
+
|
|
28
|
+
class CustomDevelopCommand(develop):
|
|
29
|
+
"""Customized setuptools develop command."""
|
|
30
|
+
def run(self):
|
|
31
|
+
develop.run(self)
|
|
32
|
+
custom_post_install()
|
|
33
|
+
|
|
34
|
+
class CustomEggInfoCommand(egg_info):
|
|
35
|
+
"""Customized setuptools egg_info command."""
|
|
36
|
+
def run(self):
|
|
37
|
+
egg_info.run(self)
|
|
38
|
+
|
|
39
|
+
setup(
|
|
40
|
+
cmdclass={
|
|
41
|
+
'install': CustomInstallCommand,
|
|
42
|
+
'develop': CustomDevelopCommand,
|
|
43
|
+
'egg_info': CustomEggInfoCommand,
|
|
44
|
+
},
|
|
45
|
+
)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Test that topic_map_parser handles symbolic links correctly without freezing."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import tempfile
|
|
5
|
+
import pytest
|
|
6
|
+
from doc_utils.topic_map_parser import detect_repo_type
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_detect_repo_type_with_circular_symlinks(tmp_path):
|
|
10
|
+
"""Test that detect_repo_type doesn't freeze with circular symbolic links."""
|
|
11
|
+
|
|
12
|
+
# Create a directory structure with circular symlinks
|
|
13
|
+
modules_dir = tmp_path / "modules"
|
|
14
|
+
modules_dir.mkdir()
|
|
15
|
+
|
|
16
|
+
# Create a master.adoc file in modules
|
|
17
|
+
(modules_dir / "master.adoc").write_text("= Test Doc\n")
|
|
18
|
+
|
|
19
|
+
# Create a circular symlink: modules/modules -> ../modules
|
|
20
|
+
circular_link = modules_dir / "modules"
|
|
21
|
+
try:
|
|
22
|
+
os.symlink("../../modules", str(circular_link))
|
|
23
|
+
except OSError:
|
|
24
|
+
pytest.skip("Cannot create symbolic links on this system")
|
|
25
|
+
|
|
26
|
+
# This should not freeze - it should skip the symlink
|
|
27
|
+
repo_type = detect_repo_type(str(tmp_path))
|
|
28
|
+
assert repo_type == "master_adoc"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_detect_repo_type_with_nested_circular_symlinks(tmp_path):
|
|
32
|
+
"""Test detection with nested directories containing circular symlinks."""
|
|
33
|
+
|
|
34
|
+
# Create nested structure
|
|
35
|
+
(tmp_path / "assemblies").mkdir()
|
|
36
|
+
modules_dir = tmp_path / "modules"
|
|
37
|
+
modules_dir.mkdir()
|
|
38
|
+
|
|
39
|
+
# Create master.adoc
|
|
40
|
+
(tmp_path / "master.adoc").write_text("= Main Doc\n")
|
|
41
|
+
|
|
42
|
+
# Create archive directory with circular symlinks (similar to real case)
|
|
43
|
+
archive_dir = tmp_path / ".archive" / "archived-content" / "modules"
|
|
44
|
+
archive_dir.mkdir(parents=True)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Create circular symlink in archive
|
|
48
|
+
os.symlink("../../modules", str(archive_dir / "modules"))
|
|
49
|
+
except OSError:
|
|
50
|
+
pytest.skip("Cannot create symbolic links on this system")
|
|
51
|
+
|
|
52
|
+
# Should detect master_adoc without freezing
|
|
53
|
+
repo_type = detect_repo_type(str(tmp_path))
|
|
54
|
+
assert repo_type == "master_adoc"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_detect_repo_type_skips_symlink_directories(tmp_path):
|
|
58
|
+
"""Test that symlinked directories are skipped during traversal."""
|
|
59
|
+
|
|
60
|
+
# Create main directories
|
|
61
|
+
real_dir = tmp_path / "real_modules"
|
|
62
|
+
real_dir.mkdir()
|
|
63
|
+
(real_dir / "master.adoc").write_text("= Real Master\n")
|
|
64
|
+
|
|
65
|
+
# Create a symlink to real_dir
|
|
66
|
+
linked_dir = tmp_path / "linked_modules"
|
|
67
|
+
try:
|
|
68
|
+
os.symlink(str(real_dir), str(linked_dir))
|
|
69
|
+
except OSError:
|
|
70
|
+
pytest.skip("Cannot create symbolic links on this system")
|
|
71
|
+
|
|
72
|
+
# The function should find the master.adoc in real_dir but not traverse linked_dir
|
|
73
|
+
repo_type = detect_repo_type(str(tmp_path))
|
|
74
|
+
assert repo_type == "master_adoc"
|
|
75
|
+
|
|
76
|
+
# Test that symlinked directories are not traversed
|
|
77
|
+
only_symlink_path = tmp_path / "only_symlink_test"
|
|
78
|
+
only_symlink_path.mkdir()
|
|
79
|
+
|
|
80
|
+
# Create a directory outside that contains master.adoc
|
|
81
|
+
external_dir = tmp_path / "external"
|
|
82
|
+
external_dir.mkdir()
|
|
83
|
+
(external_dir / "master.adoc").write_text("= External Master\n")
|
|
84
|
+
|
|
85
|
+
# Create only a symlink to it inside our test directory
|
|
86
|
+
symlinked_dir = only_symlink_path / "linked_dir"
|
|
87
|
+
os.symlink(str(external_dir), str(symlinked_dir))
|
|
88
|
+
|
|
89
|
+
# Should not find master.adoc since it's only accessible via symlink
|
|
90
|
+
repo_type = detect_repo_type(str(only_symlink_path))
|
|
91
|
+
assert repo_type == "unknown"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/rolfedh_doc_utils.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_archive_unused_files.py
RENAMED
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_archive_unused_images.py
RENAMED
|
File without changes
|
{rolfedh_doc_utils-0.1.3 → rolfedh_doc_utils-0.1.4}/tests/test_fixture_check_scannability.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|