81 lines
3.1 KiB
Python
81 lines
3.1 KiB
Python
"""Demo script showing how to use `pyinstallerguiwrapper.spec_editor` to
|
|
inspect and modify a .spec AST.
|
|
|
|
Usage: run from repository root:
|
|
python tools/spec_editor_demo.py
|
|
|
|
It uses a small embedded sample spec (the same used previously) to show the
|
|
API and writes a modified .spec to a temp file named `modified_demo.spec`.
|
|
"""
|
|
|
|
import pathlib
|
|
import tempfile
|
|
from pyinstallerguiwrapper import spec_editor
|
|
|
|
|
|
SAMPLE_SPEC = '''# sample
|
|
block_cipher = None
|
|
a = Analysis(
|
|
pathex=['pyucc', '.', 'external\\python-tkinter-logger', 'external\\python-resource-monitor'],
|
|
binaries=[],
|
|
datas=[('PyUcc.ico', '.'), ('external\\python-tkinter-logger\\tkinter_logger.py', '.'), ('external\\python-resource-monitor\\resource_monitor.py', '.')],
|
|
hiddenimports=['tkinter_logger','resource_monitor','pyucc.core.differ'],
|
|
hookspath=[], runtime_hooks=[], excludes=[], cipher=block_cipher, noarchive=False, scripts=['pyucc\\__main__.py']
|
|
)
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='PyUcc', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=True, icon='PyUcc.ico', exclude_binaries=True)
|
|
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='PyUcc')
|
|
'''
|
|
|
|
|
|
def run_demo():
|
|
print('Parsing embedded sample spec...')
|
|
tree = spec_editor.parse_spec_from_string(SAMPLE_SPEC)
|
|
# Note: helper below expects ast.Module; parse_spec_to_ast_from_string returns that
|
|
print('Summary before change:')
|
|
print(spec_editor.inspect_spec_summary(tree))
|
|
|
|
# Add a hiddenimport entry (demonstrate modification)
|
|
print('\nAdding hiddenimport "my.added.module" to Analysis...')
|
|
# Retrieve existing hiddenimports node
|
|
analysis_calls = spec_editor.find_calls(tree, 'Analysis')
|
|
if analysis_calls:
|
|
call = analysis_calls[0]
|
|
# Build new hiddenimports list by inspecting existing or creating fresh
|
|
existing_node = spec_editor.get_keyword_value(call, 'hiddenimports')
|
|
if existing_node is None:
|
|
new_list = ['my.added.module']
|
|
else:
|
|
py_existing = spec_editor.ast_node_to_python(existing_node)
|
|
if isinstance(py_existing, list):
|
|
new_list = py_existing + ['my.added.module']
|
|
else:
|
|
new_list = ['my.added.module']
|
|
spec_editor.set_call_keyword(tree, 'Analysis', 'hiddenimports', new_list)
|
|
print('Modification applied.')
|
|
|
|
print('\nSummary after change:')
|
|
print(spec_editor.inspect_spec_summary(tree))
|
|
|
|
# Write out modified spec
|
|
out_path = pathlib.Path('modified_demo.spec')
|
|
src = spec_editor.ast_to_source(tree)
|
|
spec_editor.write_source_to_file(src, str(out_path))
|
|
print(f'Wrote modified spec to: {out_path.resolve()}')
|
|
|
|
|
|
def ast_unparse(node):
|
|
import ast
|
|
if hasattr(ast, 'unparse'):
|
|
return ast.unparse(node)
|
|
else:
|
|
try:
|
|
import astor
|
|
return astor.to_source(node)
|
|
except Exception:
|
|
return '<unparse unavailable>'
|
|
|
|
|
|
if __name__ == '__main__':
|
|
run_demo()
|