Move cpp/docs to docs

This commit is contained in:
Oliver Hamlet
2025-06-11 19:06:08 +01:00
parent 57c8959da9
commit f4511b99bb
42 changed files with 33 additions and 22 deletions
-183
View File
@@ -1,183 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This script expects cargo-attribution
# <https://github.com/ameknite/cargo-attribution> to be installed.
import argparse
import datetime
import json
import os
import re
import shutil
import subprocess
import tomllib
def process_licenses(attribution_dir, destination_dir):
# CC0, Unlicense and Zlib don't need licenses to be included.
# MPL doesn't need the license included with binary distributions, and
# allows distribution under a compatible license.
# cargo attribution's GPL-3.0 download doesn't contain the license text.
# The ISC license is skipped because its dependency gets filtered out, same
# with the exceptions.
skip_entries = [
'exceptions',
'CC0-1.0',
'GPL-3.0',
'ISC',
'MPL-2.0',
'Unlicense',
'Zlib'
]
for entry in os.scandir(os.path.join(attribution_dir, 'licenses')):
if entry.name not in skip_entries:
destination_path = os.path.join(destination_dir, entry.name)
if entry.is_dir():
shutil.copytree(entry.path, destination_path, dirs_exist_ok=True)
else:
shutil.copy2(entry.path, destination_path)
def recurse_dependencies(packages, package, dependency_names):
for dependency in package['dependencies']:
name = dependency['name']
if name in dependency_names:
continue
dependency_names.add(name)
for package in packages:
if package['name'] == name:
recurse_dependencies(packages, package, dependency_names)
def get_target_dependency_names(target_package_name):
result = subprocess.run(
[
'cargo',
'metadata',
'--manifest-path',
cargo_toml_path,
'--filter-platform',
'x86_64-pc-windows-msvc',
'--format-version',
'1'
],
capture_output=True,
text=True,
check=True
)
json_output = json.loads(result.stdout[:-1])
packages = json_output['packages']
target_dependency_names = set()
for package in packages:
if package['name'] == 'libloot-cpp':
recurse_dependencies(packages, package, target_dependency_names)
return target_dependency_names
if __name__ == "__main__":
target_package_name = 'libloot-cpp'
cargo_toml_path = 'Cargo.toml'
attribution_dir = 'build/attribution'
output_dir = 'docs/licenses'
subprocess.run(
[
'cargo',
'attribution',
'--manifest-path',
cargo_toml_path,
'--output-dir',
attribution_dir,
'--filter-platform',
'x86_64-pc-windows-msvc',
'--only-normal-dependencies'
],
check=True
)
process_licenses(attribution_dir, output_dir)
target_dependency_names = get_target_dependency_names(target_package_name)
dependencies_toml_path = os.path.join(attribution_dir, 'dependencies.toml')
with open(dependencies_toml_path, 'rb') as f:
data = tomllib.load(f)
dependencies = data['dependencies']
# esplugin's and libloadorder's notices are nonsense, but they're my
# libraries so I give myself permission to skip providing the notices.
skip_dependencies = [
'libloot',
'libloot-ffi-errors',
'libloot-cpp',
'libloot-nodejs',
'libloot-python',
'parameterized-test',
'esplugin',
'libloadorder'
]
notices_rst = f'.. This file was generated by scripts/licenses.py at {datetime.datetime.now().isoformat()}.\n\n'
heading = 'Dependency Copyright Notices'
notices_rst += heading
notices_rst += '\n'
notices_rst += '=' * len(heading)
notices_rst += '\n\n'
for dependency in dependencies:
if dependency['name'] not in target_dependency_names:
continue
if dependency['name'] in skip_dependencies:
continue
if 'license' not in dependency:
print(f'Found dependency with no license: {dependency['name']}')
exit(1)
if 'ISC' in dependency['license']:
print(f'Found dependency that may require the ISC license: {dependency['name']}')
exit(1)
if 'exception' in dependency['license']:
print(f'Found dependency that may require an exception: {dependency['name']}')
exit(1)
if 'CC0-1.0' in dependency['license']:
print(f'Skipping {dependency['name']} because it uses the CC0-1.0 license: {dependency['license']}')
continue
if 'Unlicense' in dependency['license']:
print(f'Skipping {dependency['name']} because it uses the Unlicense license: {dependency['license']}')
continue
if 'Zlib' in dependency['license']:
print(f'Skipping {dependency['name']} because it uses the Zlib license: {dependency['license']}')
continue
if 'notices' not in dependency:
print(f'Skipping dependency with no notices: {dependency['name']}')
continue
if 'repository' not in dependency:
print(f'Found dependency with no repository: {dependency['name']}')
exit(1)
if dependency['name'] == 'hashlink':
# The notice for hashlink is mangled so correcting it here.
dependency['notices'] = ['Copyright (c) 2015 The Rust Project Developers']
link_rst = f'`{dependency['name']} <{dependency['repository']}>`_'
underline_rst = '-' * len(link_rst)
dep_notices_rst = '\n '.join(dependency['notices'])
section_rst = f'{link_rst}\n{underline_rst}\n\n::\n\n {dep_notices_rst}\n\n'
notices_rst += section_rst
notices_rst_path = os.path.join(output_dir, 'dependency-notices.rst')
with open(notices_rst_path, 'w', encoding="utf-8") as outfile:
outfile.write(notices_rst)