yt-dlp-dags/package_client.py

118 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Packages the client-side scripts and their dependencies into a distributable .tar.gz archive.
This script should be run from the root of the project repository.
"""
import argparse
import os
import shutil
import sys
import tarfile
from pathlib import Path
try:
# Assumes yt_ops_services/version.py exists and is importable
from yt_ops_services.version import get_version as get_api_version
except ImportError:
print("Error: Could not import get_version from yt_ops_services.version.", file=sys.stderr)
print("Please ensure yt_ops_services/version.py exists and run this script from the project root.", file=sys.stderr)
sys.exit(1)
def get_client_version():
"""Reads the client version from the VERSION.client file."""
try:
return Path('VERSION.client').read_text(encoding='utf-8').strip()
except FileNotFoundError:
print("Error: VERSION.client file not found in the project root.", file=sys.stderr)
sys.exit(1)
# --- Configuration ---
# Defines the content of the package.
# Keys are source paths relative to the project root.
# Values are destination paths inside the archive.
PACKAGE_CONTENT = {
'get_info_json_client.py': 'get_info_json_client.py',
'list_formats.py': 'list_formats.py',
'format_download.py': 'format_download.py',
'stress_test_formats.py': 'stress_test_formats.py',
'cli.config': 'cli.config',
'README.client.md': 'README.md', # Rename for convention
'formats.md': 'formats.md',
'VERSION.client': 'VERSION.client',
'yt_ops_services': 'yt_ops_services',
'thrift_model/gen_py': 'thrift_model/gen_py',
}
# Client-side Python requirements
CLIENT_REQUIREMENTS = [
'thrift==0.16.0',
]
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(description="Package the yt-ops-services client tools.")
parser.add_argument('--output-dir', default='dist', help='Directory to save the package file (default: dist).')
args = parser.parse_args()
api_version = get_api_version()
client_version = get_client_version()
package_name = f"yt-ops-services-client-{api_version}-{client_version}"
archive_filename = f"{package_name}.tar.gz"
os.makedirs(args.output_dir, exist_ok=True)
archive_path = os.path.join(args.output_dir, archive_filename)
staging_dir = Path(args.output_dir) / f"{package_name}-staging"
print(f"Creating client package: {archive_filename}")
if staging_dir.exists():
shutil.rmtree(staging_dir)
staging_dir.mkdir(parents=True)
package_root = staging_dir / package_name
package_root.mkdir()
try:
print("Staging files...")
for src, dest in PACKAGE_CONTENT.items():
src_path = Path(src)
dest_path = package_root / dest
if not src_path.exists():
print(f"Warning: Source not found, skipping: {src_path}", file=sys.stderr)
continue
dest_path.parent.mkdir(parents=True, exist_ok=True)
if src_path.is_dir():
shutil.copytree(src_path, dest_path)
else:
shutil.copy2(src_path, dest_path)
# Create __init__.py to ensure thrift_model is a package
(package_root / 'thrift_model/__init__.py').touch()
print("Creating requirements.txt...")
(package_root / 'requirements.txt').write_text('\n'.join(CLIENT_REQUIREMENTS) + '\n', encoding='utf-8')
print(f"Creating archive at {archive_path}...")
with tarfile.open(archive_path, "w:gz") as tar:
tar.add(package_root, arcname=package_name)
print("\nPackage created successfully!")
print(f" -> {archive_path}")
finally:
if staging_dir.exists():
print("Cleaning up staging directory...")
shutil.rmtree(staging_dir)
if __name__ == "__main__":
main()