waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

run_py_script.py (3852B)


      1 #!/usr/bin/env python
      2 # encoding: utf-8
      3 # Hans-Martin von Gaudecker, 2012
      4 
      5 """
      6 Run a Python script in the directory specified by **ctx.bldnode**.
      7 
      8 Select a Python version by specifying the **version** keyword for
      9 the task generator instance as integer 2 or 3. Default is 3.
     10 
     11 If the build environment has an attribute "PROJECT_PATHS" with
     12 a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH.
     13 Same a string passed to the optional **add_to_pythonpath**
     14 keyword (appended after the PROJECT_ROOT).
     15 
     16 Usage::
     17 
     18     ctx(features='run_py_script', version=3,
     19         source='some_script.py',
     20         target=['some_table.tex', 'some_figure.eps'],
     21         deps='some_data.csv',
     22         add_to_pythonpath='src/some/library')
     23 """
     24 
     25 import os, re
     26 from waflib import Task, TaskGen, Logs
     27 
     28 
     29 def configure(conf):
     30 	"""TODO: Might need to be updated for Windows once
     31 	"PEP 397":http://www.python.org/dev/peps/pep-0397/ is settled.
     32 	"""
     33 	conf.find_program('python', var='PY2CMD', mandatory=False)
     34 	conf.find_program('python3', var='PY3CMD', mandatory=False)
     35 	if not conf.env.PY2CMD and not conf.env.PY3CMD:
     36 		conf.fatal("No Python interpreter found!")
     37 
     38 class run_py_2_script(Task.Task):
     39 	"""Run a Python 2 script."""
     40 	run_str = '${PY2CMD} ${SRC[0].abspath()}'
     41 	shell=True
     42 
     43 class run_py_3_script(Task.Task):
     44 	"""Run a Python 3 script."""
     45 	run_str = '${PY3CMD} ${SRC[0].abspath()}'
     46 	shell=True
     47 
     48 @TaskGen.feature('run_py_script')
     49 @TaskGen.before_method('process_source')
     50 def apply_run_py_script(tg):
     51 	"""Task generator for running either Python 2 or Python 3 on a single
     52 	script.
     53 
     54 	Attributes:
     55 
     56 		* source -- A **single** source node or string. (required)
     57 		* target -- A single target or list of targets (nodes or strings)
     58 		* deps -- A single dependency or list of dependencies (nodes or strings)
     59 		* add_to_pythonpath -- A string that will be appended to the PYTHONPATH environment variable
     60 
     61 	If the build environment has an attribute "PROJECT_PATHS" with
     62 	a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH.
     63 	"""
     64 
     65 	# Set the Python version to use, default to 3.
     66 	v = getattr(tg, 'version', 3)
     67 	if v not in (2, 3):
     68 		raise ValueError("Specify the 'version' attribute for run_py_script task generator as integer 2 or 3.\n Got: %s" %v)
     69 
     70 	# Convert sources and targets to nodes
     71 	src_node = tg.path.find_resource(tg.source)
     72 	tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)]
     73 
     74 	# Create the task.
     75 	tsk = tg.create_task('run_py_%d_script' %v, src=src_node, tgt=tgt_nodes)
     76 
     77 	# custom execution environment
     78 	# TODO use a list and  os.sep.join(lst) at the end instead of concatenating strings
     79 	tsk.env.env = dict(os.environ)
     80 	tsk.env.env['PYTHONPATH'] = tsk.env.env.get('PYTHONPATH', '')
     81 	project_paths = getattr(tsk.env, 'PROJECT_PATHS', None)
     82 	if project_paths and 'PROJECT_ROOT' in project_paths:
     83 		tsk.env.env['PYTHONPATH'] += os.pathsep + project_paths['PROJECT_ROOT'].abspath()
     84 	if getattr(tg, 'add_to_pythonpath', None):
     85 		tsk.env.env['PYTHONPATH'] += os.pathsep + tg.add_to_pythonpath
     86 
     87 	# Clean up the PYTHONPATH -- replace double occurrences of path separator
     88 	tsk.env.env['PYTHONPATH'] = re.sub(os.pathsep + '+', os.pathsep, tsk.env.env['PYTHONPATH'])
     89 
     90 	# Clean up the PYTHONPATH -- doesn't like starting with path separator
     91 	if tsk.env.env['PYTHONPATH'].startswith(os.pathsep):
     92 		 tsk.env.env['PYTHONPATH'] = tsk.env.env['PYTHONPATH'][1:]
     93 
     94 	# dependencies (if the attribute 'deps' changes, trigger a recompilation)
     95 	for x in tg.to_list(getattr(tg, 'deps', [])):
     96 		node = tg.path.find_resource(x)
     97 		if not node:
     98 			tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath()))
     99 		tsk.dep_nodes.append(node)
    100 	Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath())
    101 
    102 	# Bypass the execution of process_source by setting the source to an empty list
    103 	tg.source = []
    104