123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/usr/bin/env python3
- import os
- import shutil
- import argparse
- from bs4 import BeautifulSoup
- # Function to recursively search for the "Source" directory
- def find_source_dir(starting_path, source_dir):
- for root, dirs, files in os.walk(starting_path):
- if source_dir in dirs:
- source_path = os.path.join(root, source_dir)
- before_source = os.path.relpath(source_path, starting_path)
- after_source = os.path.relpath(starting_path, source_path)
- return before_source
- return None, None
- def check_for_siblings(docs_root, source_dir):
- all_dirs = [os.path.join(docs_root, d) for d in os.listdir(docs_root) if os.path.isdir(os.path.join(docs_root, d))]
- if not os.path.exists(docs_root):
- return 1, None
- source_path = os.path.abspath(os.path.join(docs_root, source_dir))
- if not os.path.exists(source_path):
- return 2, all_dirs
- sibling_dirs = [d for d in all_dirs if not os.path.samefile(d, source_path)]
- if sibling_dirs:
- return 3, sibling_dirs
- return 0, None
- def has_files(path):
- for root, _, files in os.walk(path):
- if files:
- return True
- return False
- def delete_empty_directory(relative_path):
- absolute_path = os.path.abspath(relative_path)
- if not os.path.exists(absolute_path):
- print(f"Directory does not exist: {relative_path}")
- return
- if has_files(absolute_path):
- print(f"Directory is not empty: {relative_path}")
- return
- try:
- shutil.rmtree(absolute_path)
- print(f"Deleted: {relative_path}")
- except OSError as e:
- print(f"Error deleting directory: {e}")
- def remove_directory_if_exists(relative_path):
- absolute_path = os.path.abspath(relative_path)
- if os.path.exists(absolute_path) and os.path.isdir(absolute_path):
- try:
- shutil.rmtree(absolute_path)
- print(f"Removed directory and its contents: {relative_path}")
- except OSError as e:
- print(f"Error removing directory: {e}")
- else:
- print(f"Directory does not exist: {relative_path}")
- def process_docs(source_dir, docs_root):
- # Define the path to the index.html file
- index_html_path = os.path.join(docs_root, "index.html")
- # Read the index.html file
- with open(index_html_path, "r") as html_file:
- index_html_content = html_file.read()
- html = BeautifulSoup(index_html_content, "html.parser")
- # Modify links and associated html files within each tr.light-row
- for tr in html.find_all("tr", class_="light-row"):
- link = tr.find("a", href=True)
- if link:
- href = link["href"]
- # Fix linked file title and css href
- filepath = os.path.join(docs_root, href)
- fix_code_html(filepath, source_dir)
- source_root_index = href.find(source_dir)
- if source_root_index != -1:
- trimmed_href = href[source_root_index:]
- link["href"] = f"coverage/{trimmed_href}"
- # Save the modified HTML content back to the index.html file
- with open(index_html_path, "w") as modified_html_file:
- modified_html_file.write(str(html))
- def fix_code_html(path_filename, source_dir):
- with open(path_filename, "r") as html_file:
- html_content = html_file.read()
- html = BeautifulSoup(html_content, "html.parser")
- # fix css href
- link = html.find("link")
- css = link["href"].split('/')[-1]
- depth = path_filename.split("Source")[-1].count('/')
- parent_nav = "../" * (depth + 1)
- link["href"] = f"{parent_nav}{css}"
- # fix title
- title = html.select_one('.source-name-title pre')
- fixed_title = f".../{source_dir}{title.text.split(source_dir)[-1]}"
- title.string = fixed_title
- # resave
- with open(path_filename, "w") as html_file:
- html_file.write(str(html))
- # Parse command line arguments
- parser = argparse.ArgumentParser(description="Transmogrify a llvm-cov report to use relative paths to source.")
- parser.add_argument("--source-dir", required=True, help="Name of Source directory within the report coverage/ path")
- parser.add_argument("--docs-root", required=True, help="Path to the docs folder containing index.html and coverage/ path.")
- args = parser.parse_args()
- coverage_path = os.path.join(args.docs_root, "coverage")
- status, dirs = check_for_siblings(coverage_path, args.source_dir)
- if status == 1:
- print(f"{args.docs_root} does not exist.")
- exit(1)
- if status == 3:
- remove_directory_if_exists(os.path.join(coverage_path, args.source_dir))
- process_docs(args.source_dir, args.docs_root)
- source_path = os.path.join(args.docs_root, "coverage", find_source_dir(coverage_path, args.source_dir))
- shutil.move(source_path, coverage_path)
- # We can assume the original folder tree starts
- # with Users so we will delete that carefully
- disgraced_former_cov_docs_path = os.path.join(coverage_path, "Users")
- # Delete the original path, if it's tree is empty.
- delete_empty_directory(disgraced_former_cov_docs_path)
|