126 lines
4.1 KiB
Python
126 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script to extract binary names from setup.py files and create placeholder files.
|
|
Usage: setup_binaries.py /path/to/setup.py
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import ast
|
|
|
|
|
|
class SetupVisitor(ast.NodeVisitor):
|
|
"""AST visitor that finds setup() function calls and extracts scripts."""
|
|
|
|
def __init__(self):
|
|
self.scripts = []
|
|
|
|
def visit_Call(self, node):
|
|
# Check if this is a call to setup()
|
|
if getattr(node.func, 'id', None) == 'setup':
|
|
# Look through keyword arguments for scripts
|
|
for kw in node.keywords:
|
|
if kw.arg == 'scripts':
|
|
self._extract_scripts(kw.value)
|
|
# Also check entry_points which might contain console_scripts
|
|
elif kw.arg == 'entry_points':
|
|
self._extract_entry_points(kw.value)
|
|
|
|
# Continue traversing the AST
|
|
self.generic_visit(node)
|
|
|
|
def _extract_scripts(self, node):
|
|
"""Extract script paths from a list or list comprehension."""
|
|
if isinstance(node, ast.List):
|
|
for elt in node.elts:
|
|
if isinstance(elt, ast.Str):
|
|
if elt.s.startswith('bin/'):
|
|
self.scripts.append(elt.s)
|
|
# Handle variables and other expressions by looking for string literals
|
|
else:
|
|
# This is a simple fallback for complex expressions
|
|
script_finder = StringLiteralFinder('bin/')
|
|
script_finder.visit(node)
|
|
self.scripts.extend(script_finder.matching_strings)
|
|
|
|
|
|
def _extract_entry_points(self, node):
|
|
"""Extract console_scripts from entry_points argument."""
|
|
# This would need more complex parsing based on how entry_points is specified
|
|
# Often it's a dict with 'console_scripts' key or a string with [console_scripts] section
|
|
# For this example, we'll just log that we found it
|
|
pass
|
|
|
|
|
|
class StringLiteralFinder(ast.NodeVisitor):
|
|
"""Find string literals that start with a specific prefix."""
|
|
|
|
def __init__(self, prefix):
|
|
self.prefix = prefix
|
|
self.matching_strings = []
|
|
|
|
def visit_Str(self, node):
|
|
if node.s.startswith(self.prefix):
|
|
self.matching_strings.append(node.s)
|
|
|
|
|
|
def extract_setup_binaries(setup_path):
|
|
"""Extract binary names from a setup.py file and create placeholder files."""
|
|
try:
|
|
# Read the setup.py file
|
|
with open(setup_path, 'r') as f:
|
|
setup_content = f.read()
|
|
|
|
# Parse the file
|
|
tree = ast.parse(setup_content)
|
|
|
|
# Find setup() calls and extract scripts
|
|
visitor = SetupVisitor()
|
|
visitor.visit(tree)
|
|
|
|
# Get the scripts
|
|
scripts = visitor.scripts
|
|
|
|
if not scripts:
|
|
print(f"No bin scripts found in {setup_path}")
|
|
return True # Not an error, just no scripts
|
|
|
|
# Create placeholder files
|
|
base_dir = os.path.dirname(setup_path)
|
|
created_count = 0
|
|
|
|
for script in scripts:
|
|
script_path = os.path.join(base_dir, script)
|
|
script_dir = os.path.dirname(script_path)
|
|
|
|
# Create directory if it doesn't exist
|
|
os.makedirs(script_dir, exist_ok=True)
|
|
|
|
# Create an empty file
|
|
with open(script_path, 'w') as f:
|
|
pass
|
|
|
|
# Make the file executable
|
|
os.chmod(script_path, 0o755)
|
|
created_count += 1
|
|
|
|
print(f"Created {created_count} placeholder binary files from {setup_path}")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"Error processing {setup_path}: {e}")
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 2:
|
|
print(f"Usage: {sys.argv[0]} /path/to/setup.py")
|
|
sys.exit(1)
|
|
|
|
setup_path = sys.argv[1]
|
|
if not os.path.exists(setup_path):
|
|
print(f"Error: {setup_path} not found")
|
|
sys.exit(1)
|
|
|
|
success = extract_setup_binaries(setup_path)
|
|
sys.exit(0 if success else 1)
|