chore(bf-3nsde): remove tracked repo-root debris and compiled binaries
This commit is contained in:
parent
06714eacc1
commit
b2ec99072a
8 changed files with 0 additions and 4404 deletions
|
|
@ -1,116 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Assess rustdoc coverage for pdftract-core public API."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class DocStats:
|
||||
total_items: int = 0
|
||||
with_docs: int = 0
|
||||
with_examples: int = 0
|
||||
items: list = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.items is None:
|
||||
self.items = []
|
||||
|
||||
def extract_public_items(file_path: Path) -> DocStats:
|
||||
"""Extract public items and their documentation status."""
|
||||
content = file_path.read_text()
|
||||
lines = content.split('\n')
|
||||
|
||||
stats = DocStats()
|
||||
|
||||
# Pattern to match public items
|
||||
patterns = {
|
||||
'pub fn': r'pub\s+fn\s+(\w+)',
|
||||
'pub struct': r'pub\s+struct\s+(\w+)',
|
||||
'pub enum': r'pub\s+enum\s+(\w+)',
|
||||
'pub trait': r'pub\s+trait\s+(\w+)',
|
||||
'pub const': r'pub\s+const\s+(\w+)',
|
||||
'pub type': r'pub\s+type\s+(\w+)',
|
||||
'pub mod': r'pub\s+mod\s+(\w+)',
|
||||
}
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
for item_type, pattern in patterns.items():
|
||||
match = re.search(pattern, line)
|
||||
if match:
|
||||
name = match.group(1)
|
||||
stats.total_items += 1
|
||||
|
||||
# Check for doc comment above
|
||||
has_doc = False
|
||||
has_example = False
|
||||
|
||||
# Look back for doc comments (/// or //!)
|
||||
j = i - 1
|
||||
doc_lines = []
|
||||
while j >= 0 and (lines[j].strip().startswith('///') or lines[j].strip().startswith('//!') or lines[j].strip() == ''):
|
||||
if lines[j].strip().startswith('///') or lines[j].strip().startswith('//!'):
|
||||
doc_lines.append(lines[j])
|
||||
j -= 1
|
||||
|
||||
has_doc = len(doc_lines) > 0
|
||||
has_example = any('```rust' in dl or '```no_run' in dl or '```ignore' in dl for dl in doc_lines)
|
||||
|
||||
if has_doc:
|
||||
stats.with_docs += 1
|
||||
if has_example:
|
||||
stats.with_examples += 1
|
||||
|
||||
stats.items.append({
|
||||
'name': name,
|
||||
'type': item_type,
|
||||
'file': str(file_path),
|
||||
'line': i + 1,
|
||||
'has_doc': has_doc,
|
||||
'has_example': has_example,
|
||||
})
|
||||
|
||||
return stats
|
||||
|
||||
def main():
|
||||
src_dir = Path('/home/coding/pdftract/crates/pdftract-core/src')
|
||||
|
||||
all_stats = DocStats()
|
||||
module_docs = {}
|
||||
|
||||
for rs_file in src_dir.rglob('*.rs'):
|
||||
# Skip files in tests/ and examples/
|
||||
if 'tests' in rs_file.parts or 'examples' in rs_file.parts:
|
||||
continue
|
||||
|
||||
stats = extract_public_items(rs_file)
|
||||
|
||||
if stats.total_items > 0:
|
||||
module_name = rs_file.relative_to(src_dir)
|
||||
module_docs[module_name] = stats
|
||||
all_stats.total_items += stats.total_items
|
||||
all_stats.with_docs += stats.with_docs
|
||||
all_stats.with_examples += stats.with_examples
|
||||
|
||||
print(f"Total public items: {all_stats.total_items}")
|
||||
print(f"With documentation: {all_stats.with_docs} ({all_stats.with_docs/all_stats.total_items*100:.1f}%)")
|
||||
print(f"With examples: {all_stats.with_examples} ({all_stats.with_examples/all_stats.total_items*100:.1f}%)")
|
||||
print()
|
||||
|
||||
# Show modules with worst coverage
|
||||
print("Modules needing documentation (sorted by items without examples):")
|
||||
for module, stats in sorted(module_docs.items(), key=lambda x: x[1].total_items - x[1].with_examples, reverse=True):
|
||||
if stats.total_items > 0:
|
||||
coverage = stats.with_examples / stats.total_items * 100 if stats.total_items > 0 else 0
|
||||
print(f" {module}: {stats.with_examples}/{stats.total_items} ({coverage:.0f}%)")
|
||||
|
||||
# List items without docs
|
||||
print("\nItems WITHOUT any documentation:")
|
||||
for module, stats in module_docs.items():
|
||||
for item in stats.items:
|
||||
if not item['has_doc']:
|
||||
print(f" {module}:{item['line']} - {item['type']} {item['name']}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
110
audit_docs.py
110
audit_docs.py
|
|
@ -1,110 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Audit script to find public items in pdftract-core that are missing documentation.
|
||||
"""
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
|
||||
PUBLIC_PATTERNS = [
|
||||
(r'pub fn (\w+)', 'function'),
|
||||
(r'pub struct (\w+)', 'struct'),
|
||||
(r'pub enum (\w+)', 'enum'),
|
||||
(r'pub trait (\w+)', 'trait'),
|
||||
(r'pub type (\w+)', 'type'),
|
||||
(r'pub const (\w+)', 'const'),
|
||||
(r'pub mod (\w+)', 'module'),
|
||||
(r'pub (?:static|async) (\w+)', 'other'),
|
||||
]
|
||||
|
||||
def has_doc_comment(lines, line_idx):
|
||||
"""Check if there's a doc comment before the given line."""
|
||||
for i in range(line_idx - 1, -1, -1):
|
||||
line = lines[i].strip()
|
||||
if line.startswith('///') or line.startswith('//!'):
|
||||
return True
|
||||
if line and not line.startswith('//') and not line.startswith('#'):
|
||||
break
|
||||
return False
|
||||
|
||||
def audit_file(filepath):
|
||||
"""Audit a single Rust file for missing documentation."""
|
||||
items = []
|
||||
lines = filepath.read_text(encoding='utf-8').split('\n')
|
||||
|
||||
for line_idx, line in enumerate(lines):
|
||||
for pattern, item_type in PUBLIC_PATTERNS:
|
||||
match = re.search(pattern, line)
|
||||
if match:
|
||||
item_name = match.group(1)
|
||||
has_docs = has_doc_comment(lines, line_idx)
|
||||
items.append({
|
||||
'name': item_name,
|
||||
'type': item_type,
|
||||
'has_docs': has_docs,
|
||||
'line': line_idx + 1,
|
||||
'file': str(filepath.relative_to('/home/coding/pdftract/crates/pdftract-core/src'))
|
||||
})
|
||||
return items
|
||||
|
||||
def main():
|
||||
src_dir = Path('/home/coding/pdftract/crates/pdftract-core/src')
|
||||
|
||||
all_items = []
|
||||
for rs_file in sorted(src_dir.rglob('*.rs')):
|
||||
all_items.extend(audit_file(rs_file))
|
||||
|
||||
# Group by type and coverage
|
||||
by_type = defaultdict(lambda: {'total': 0, 'with_docs': 0, 'missing': []})
|
||||
for item in all_items:
|
||||
by_type[item['type']]['total'] += 1
|
||||
if item['has_docs']:
|
||||
by_type[item['type']]['with_docs'] += 1
|
||||
else:
|
||||
by_type[item['type']]['missing'].append(item)
|
||||
|
||||
# Print summary
|
||||
print("=" * 60)
|
||||
print("PDFTRACT-CORE DOCUMENTATION AUDIT")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
total_items = len(all_items)
|
||||
total_with_docs = sum(1 for i in all_items if i['has_docs'])
|
||||
|
||||
print(f"TOTAL PUBLIC ITEMS: {total_items}")
|
||||
print(f"WITH DOCUMENTATION: {total_with_docs} ({100 * total_with_docs / total_items:.1f}%)")
|
||||
print(f"MISSING DOCUMENTATION: {total_items - total_with_docs} ({100 * (total_items - total_with_docs) / total_items:.1f}%)")
|
||||
print()
|
||||
|
||||
print("BY TYPE:")
|
||||
print("-" * 40)
|
||||
for item_type, data in sorted(by_type.items()):
|
||||
coverage = 100 * data['with_docs'] / data['total'] if data['total'] > 0 else 0
|
||||
print(f"{item_type:12}: {data['with_docs']:4}/{data['total']:<4} ({coverage:5.1f}%)")
|
||||
print()
|
||||
|
||||
# Print top missing items
|
||||
if any(by_type[t]['missing'] for t in by_type):
|
||||
print("TOP ITEMS MISSING DOCS (first 20 by type):")
|
||||
print("-" * 40)
|
||||
for item_type in sorted(by_type.keys()):
|
||||
missing = by_type[item_type]['missing'][:10]
|
||||
for item in missing:
|
||||
print(f" [{item_type}] {item['name']} at {item['file']}:{item['line']}")
|
||||
|
||||
print()
|
||||
print("=" * 60)
|
||||
|
||||
# Return exit code based on 80% threshold
|
||||
coverage = 100 * total_with_docs / total_items if total_items > 0 else 0
|
||||
if coverage >= 80:
|
||||
print(f"✓ PASS: {coverage:.1f}% coverage meets 80% threshold")
|
||||
return 0
|
||||
else:
|
||||
print(f"✗ FAIL: {coverage:.1f}% coverage below 80% threshold")
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys
|
||||
try:
|
||||
import pikepdf
|
||||
except ImportError:
|
||||
sys.exit("pikepdf not available")
|
||||
|
||||
def extract_text(path):
|
||||
with pikepdf.open(path) as pdf:
|
||||
for page in pdf.pages:
|
||||
if "/Contents" in page:
|
||||
contents = page["/Contents"]
|
||||
if hasattr(contents, "read_bytes"):
|
||||
data = contents.read_bytes()
|
||||
else:
|
||||
data = bytes(contents)
|
||||
print(f"{path}: {data[:200]}")
|
||||
break
|
||||
|
||||
extract_text("tests/fingerprint/fixtures/content_edit_one_glyph/v1.pdf")
|
||||
extract_text("tests/fingerprint/fixtures/content_edit_one_glyph/v2.pdf")
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
import re
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def count_public_items(file_path):
|
||||
with open(file_path, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
items = []
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
# Check for public items
|
||||
if re.match(r'^pub (fn|struct|enum|trait|type|const|static)', line):
|
||||
item = {'line': i + 1, 'type': line.strip(), 'has_doc': False}
|
||||
# Check for doc comments in the 3 lines before
|
||||
j = max(0, i - 3)
|
||||
while j < i:
|
||||
if lines[j].strip().startswith('///'):
|
||||
item['has_doc'] = True
|
||||
break
|
||||
j += 1
|
||||
items.append(item)
|
||||
i += 1
|
||||
|
||||
return items
|
||||
|
||||
src_dir = Path('crates/pdftract-core/src')
|
||||
all_items = []
|
||||
for rs_file in src_dir.rglob('*.rs'):
|
||||
items = count_public_items(rs_file)
|
||||
all_items.extend(items)
|
||||
|
||||
total = len(all_items)
|
||||
with_docs = sum(1 for item in all_items if item['has_doc'])
|
||||
|
||||
print(f"Total public items: {total}")
|
||||
print(f"Items with docs: {with_docs}")
|
||||
print(f"Coverage: {with_docs/total*100:.1f}%")
|
||||
|
||||
# Show which modules need work
|
||||
modules = {}
|
||||
for item in all_items:
|
||||
module = item.get('module', 'unknown')
|
||||
if module not in modules:
|
||||
modules[module] = {'total': 0, 'with_docs': 0}
|
||||
modules[module]['total'] += 1
|
||||
if item['has_doc']:
|
||||
modules[module]['with_docs'] += 1
|
||||
|
||||
print("\nModules needing work:")
|
||||
for mod, counts in sorted(modules.items(), key=lambda x: x[1]['total'] - x[1]['with_docs'], reverse=True):
|
||||
if counts['total'] > 0:
|
||||
coverage = counts['with_docs']/counts['total']*100
|
||||
if coverage < 80:
|
||||
print(f" {mod}: {coverage:.0f}% ({counts['with_docs']}/{counts['total']})")
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
import re
|
||||
from pathlib import Path
|
||||
|
||||
def count_items_with_examples(file_path):
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
lines = f.readlines()
|
||||
|
||||
items = []
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
# Check for public items
|
||||
if re.match(r'^pub (fn|struct|enum|trait|type|const|static)', line):
|
||||
item = {'line': i + 1, 'type': line.strip(), 'has_doc': False, 'has_example': False}
|
||||
# Look back up to 10 lines for doc comments
|
||||
j = max(0, i - 10)
|
||||
doc_lines = []
|
||||
while j < i:
|
||||
if lines[j].strip().startswith('///'):
|
||||
doc_lines.append(lines[j])
|
||||
elif not lines[j].strip().startswith('///') and doc_lines:
|
||||
# Non-doc comment breaks the doc block
|
||||
break
|
||||
j += 1
|
||||
|
||||
if doc_lines:
|
||||
item['has_doc'] = True
|
||||
# Check for example in doc (```rust)
|
||||
doc_text = '\n'.join(doc_lines)
|
||||
if '```rust' in doc_text:
|
||||
item['has_example'] = True
|
||||
|
||||
items.append(item)
|
||||
i += 1
|
||||
|
||||
return items
|
||||
|
||||
src_dir = Path('crates/pdftract-core/src')
|
||||
all_items = []
|
||||
for rs_file in src_dir.rglob('*.rs'):
|
||||
items = count_items_with_examples(rs_file)
|
||||
all_items.extend(items)
|
||||
|
||||
total = len(all_items)
|
||||
with_docs = sum(1 for item in all_items if item['has_doc'])
|
||||
with_examples = sum(1 for item in all_items if item['has_example'])
|
||||
|
||||
print(f"Total public items: {total}")
|
||||
print(f"Items with docs: {with_docs} ({with_docs/total*100:.1f}%)")
|
||||
print(f"Items with examples: {with_examples} ({with_examples/total*100:.1f}%)")
|
||||
|
||||
# Show items missing docs
|
||||
print("\nItems missing documentation:")
|
||||
for item in sorted(all_items, key=lambda x: x['line']):
|
||||
if not item['has_doc']:
|
||||
print(f" {item['type']}")
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Fix malformed PDF fixtures with incorrect startxref offsets."""
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
fixtures = [
|
||||
"tests/document_model/fixtures/ocg_default_off.pdf",
|
||||
"tests/document_model/fixtures/tagged_3_level_outline.pdf",
|
||||
"tests/document_model/fixtures/multi_revision_3.pdf",
|
||||
"tests/document_model/fixtures/inheritance_grandparent_mediabox.pdf",
|
||||
"tests/document_model/fixtures/missing_mediabox.pdf",
|
||||
"tests/document_model/fixtures/partial_resource_override.pdf",
|
||||
"tests/document_model/fixtures/js_in_openaction.pdf",
|
||||
"tests/document_model/fixtures/xfa_form.pdf",
|
||||
"tests/document_model/fixtures/pdfa_1b_conformance.pdf",
|
||||
"tests/document_model/fixtures/page_labels_roman_arabic.pdf",
|
||||
"tests/document_model/fixtures/encrypted_unknown_handler.pdf",
|
||||
]
|
||||
|
||||
for fixture_path in fixtures:
|
||||
try:
|
||||
# Read the file
|
||||
with open(fixture_path, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
# Find the first "xref" (the correct one)
|
||||
xref_match = re.search(b'xref\n', data)
|
||||
if not xref_match:
|
||||
print(f"Skipping {fixture_path}: no xref found")
|
||||
continue
|
||||
|
||||
correct_offset = xref_match.start()
|
||||
|
||||
# Fix the startxref value
|
||||
new_data = re.sub(rb'startxref\n\d+', f'startxref\n{correct_offset}'.encode(), data)
|
||||
|
||||
# Write back
|
||||
with open(fixture_path, 'wb') as f:
|
||||
f.write(new_data)
|
||||
|
||||
print(f"Fixed {fixture_path}: startxref now points to {correct_offset}")
|
||||
except Exception as e:
|
||||
print(f"Error fixing {fixture_path}: {e}")
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,59 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Generate content_edit fixtures using pikepdf."""
|
||||
|
||||
import pikepdf
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def create_simple_pdf(content, output_path):
|
||||
"""Create a simple PDF with minimal text content."""
|
||||
pdf = pikepdf.new()
|
||||
pdf.add_blank_page(page_size=(612, 792))
|
||||
page = pdf.pages[0]
|
||||
|
||||
content_stream = f"""
|
||||
BT
|
||||
/F1 12 Tf
|
||||
50 700 Td
|
||||
({content}) Tj
|
||||
ET
|
||||
"""
|
||||
stream = pikepdf.Stream(pdf, content_stream.encode())
|
||||
page["/Contents"] = stream
|
||||
page["/Resources"] = pikepdf.Dictionary({
|
||||
"/Font": pikepdf.Dictionary({
|
||||
"/F1": pikepdf.Dictionary({
|
||||
"/Type": "/Font",
|
||||
"/Subtype": "/Type1",
|
||||
"/BaseFont": "/Helvetica"
|
||||
})
|
||||
})
|
||||
})
|
||||
pdf.save(output_path)
|
||||
|
||||
|
||||
def main():
|
||||
# Use absolute path since we may run from different directories
|
||||
import os
|
||||
script_dir = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
fixtures_dir = script_dir / "tests" / "fingerprint" / "fixtures"
|
||||
|
||||
# Generate content_edit_one_glyph fixtures
|
||||
dir = fixtures_dir / "content_edit_one_glyph"
|
||||
dir.mkdir(exist_ok=True)
|
||||
create_simple_pdf("Hello World", dir / "v1.pdf")
|
||||
create_simple_pdf("Hello Worl", dir / "v2.pdf")
|
||||
print("Generated content_edit_one_glyph fixtures")
|
||||
|
||||
# Generate content_edit_one_paragraph fixtures
|
||||
dir = fixtures_dir / "content_edit_one_paragraph"
|
||||
dir.mkdir(exist_ok=True)
|
||||
original_text = "This is the first paragraph. " * 5
|
||||
variant_text = "This is the second paragraph. " + "This is the first paragraph. " * 4
|
||||
create_simple_pdf(original_text, dir / "v1.pdf")
|
||||
create_simple_pdf(variant_text, dir / "v2.pdf")
|
||||
print("Generated content_edit_one_paragraph fixtures")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Reference in a new issue