misc.py :  » Build » Waf » waf-1.5.17 » wafadmin » Tools » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Build » Waf 
Waf » waf 1.5.17 » wafadmin » Tools » misc.py
#!/usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2006 (ita)

"""
Custom objects:
 - execute a function everytime
 - copy a file somewhere else
"""

import shutil, re, os
import TaskGen, Node, Task, Utils, Build, Constants
from TaskGen import feature,taskgen,after,before
from Logs import debug

def copy_func(tsk):
  "Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
  env = tsk.env
  infile = tsk.inputs[0].abspath(env)
  outfile = tsk.outputs[0].abspath(env)
  try:
    shutil.copy2(infile, outfile)
  except (OSError, IOError):
    return 1
  else:
    if tsk.chmod: os.chmod(outfile, tsk.chmod)
    return 0

def action_process_file_func(tsk):
  "Ask the function attached to the task to process it"
  if not tsk.fun: raise Utils.WafError('task must have a function attached to it for copy_func to work!')
  return tsk.fun(tsk)

class cmd_taskgen(TaskGen.task_gen):
  def __init__(self, *k, **kw):
    TaskGen.task_gen.__init__(self, *k, **kw)

@feature('cmd')
def apply_cmd(self):
  "call a command everytime"
  if not self.fun: raise Utils.WafError('cmdobj needs a function!')
  tsk = Task.TaskBase()
  tsk.fun = self.fun
  tsk.env = self.env
  self.tasks.append(tsk)
  tsk.install_path = self.install_path

class copy_taskgen(TaskGen.task_gen):
  "By default, make a file copy, if fun is provided, fun will make the copy (or call a compiler, etc)"
  def __init__(self, *k, **kw):
    TaskGen.task_gen.__init__(self, *k, **kw)

@feature('copy')
@before('apply_core')
def apply_copy(self):
  Utils.def_attrs(self, fun=copy_func)
  self.default_install_path = 0

  lst = self.to_list(self.source)
  self.meths.remove('apply_core')

  for filename in lst:
    node = self.path.find_resource(filename)
    if not node: raise Utils.WafError('cannot find input file %s for processing' % filename)

    target = self.target
    if not target or len(lst)>1: target = node.name

    # TODO the file path may be incorrect
    newnode = self.path.find_or_declare(target)

    tsk = self.create_task('copy', node, newnode)
    tsk.fun = self.fun
    tsk.chmod = self.chmod
    tsk.install_path = self.install_path

    if not tsk.env:
      tsk.debug()
      raise Utils.WafError('task without an environment')

def subst_func(tsk):
  "Substitutes variables in a .in file"

  m4_re = re.compile('@(\w+)@', re.M)

  env = tsk.env
  infile = tsk.inputs[0].abspath(env)
  outfile = tsk.outputs[0].abspath(env)

  code = Utils.readf(infile)

  # replace all % by %% to prevent errors by % signs in the input file while string formatting
  code = code.replace('%', '%%')

  s = m4_re.sub(r'%(\1)s', code)

  di = tsk.dict or {}
  if not di:
    names = m4_re.findall(code)
    for i in names:
      di[i] = env.get_flat(i) or env.get_flat(i.upper())

  file = open(outfile, 'w')
  file.write(s % di)
  file.close()
  if tsk.chmod: os.chmod(outfile, tsk.chmod)

class subst_taskgen(TaskGen.task_gen):
  def __init__(self, *k, **kw):
    TaskGen.task_gen.__init__(self, *k, **kw)

@feature('subst')
@before('apply_core')
def apply_subst(self):
  Utils.def_attrs(self, fun=subst_func)
  self.default_install_path = 0
  lst = self.to_list(self.source)
  self.meths.remove('apply_core')

  self.dict = getattr(self, 'dict', {})

  for filename in lst:
    node = self.path.find_resource(filename)
    if not node: raise Utils.WafError('cannot find input file %s for processing' % filename)

    if self.target:
      newnode = self.path.find_or_declare(self.target)
    else:
      newnode = node.change_ext('')

    try:
      self.dict = self.dict.get_merged_dict()
    except AttributeError:
      pass

    if self.dict and not self.env['DICT_HASH']:
      self.env = self.env.copy()
      keys = list(self.dict.keys())
      keys.sort()
      lst = [self.dict[x] for x in keys]
      self.env['DICT_HASH'] = str(Utils.h_list(lst))

    tsk = self.create_task('copy', node, newnode)
    tsk.fun = self.fun
    tsk.dict = self.dict
    tsk.dep_vars = ['DICT_HASH']
    tsk.install_path = self.install_path
    tsk.chmod = self.chmod

    if not tsk.env:
      tsk.debug()
      raise Utils.WafError('task without an environment')

####################
## command-output ####
####################

class cmd_arg(object):
  """command-output arguments for representing files or folders"""
  def __init__(self, name, template='%s'):
    self.name = name
    self.template = template
    self.node = None

class input_file(cmd_arg):
  def find_node(self, base_path):
    assert isinstance(base_path, Node.Node)
    self.node = base_path.find_resource(self.name)
    if self.node is None:
      raise Utils.WafError("Input file %s not found in " % (self.name, base_path))

  def get_path(self, env, absolute):
    if absolute:
      return self.template % self.node.abspath(env)
    else:
      return self.template % self.node.srcpath(env)

class output_file(cmd_arg):
  def find_node(self, base_path):
    assert isinstance(base_path, Node.Node)
    self.node = base_path.find_or_declare(self.name)
    if self.node is None:
      raise Utils.WafError("Output file %s not found in " % (self.name, base_path))

  def get_path(self, env, absolute):
    if absolute:
      return self.template % self.node.abspath(env)
    else:
      return self.template % self.node.bldpath(env)

class cmd_dir_arg(cmd_arg):
  def find_node(self, base_path):
    assert isinstance(base_path, Node.Node)
    self.node = base_path.find_dir(self.name)
    if self.node is None:
      raise Utils.WafError("Directory %s not found in " % (self.name, base_path))

class input_dir(cmd_dir_arg):
  def get_path(self, dummy_env, dummy_absolute):
    return self.template % self.node.abspath()

class output_dir(cmd_dir_arg):
  def get_path(self, env, dummy_absolute):
    return self.template % self.node.abspath(env)


class command_output(Task.Task):
  color = "BLUE"
  def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
    Task.Task.__init__(self, env, normal=1)
    assert isinstance(command, (str, Node.Node))
    self.command = command
    self.command_args = command_args
    self.stdin = stdin
    self.stdout = stdout
    self.cwd = cwd
    self.os_env = os_env
    self.stderr = stderr

    if command_node is not None: self.dep_nodes = [command_node]
    self.dep_vars = [] # additional environment variables to look

  def run(self):
    task = self
    #assert len(task.inputs) > 0

    def input_path(node, template):
      if task.cwd is None:
        return template % node.bldpath(task.env)
      else:
        return template % node.abspath()
    def output_path(node, template):
      fun = node.abspath
      if task.cwd is None: fun = node.bldpath
      return template % fun(task.env)

    if isinstance(task.command, Node.Node):
      argv = [input_path(task.command, '%s')]
    else:
      argv = [task.command]

    for arg in task.command_args:
      if isinstance(arg, str):
        argv.append(arg)
      else:
        assert isinstance(arg, cmd_arg)
        argv.append(arg.get_path(task.env, (task.cwd is not None)))

    if task.stdin:
      stdin = open(input_path(task.stdin, '%s'))
    else:
      stdin = None

    if task.stdout:
      stdout = open(output_path(task.stdout, '%s'), "w")
    else:
      stdout = None

    if task.stderr:
      stderr = open(output_path(task.stderr, '%s'), "w")
    else:
      stderr = None

    if task.cwd is None:
      cwd = ('None (actually %r)' % os.getcwd())
    else:
      cwd = repr(task.cwd)
    debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
           (cwd, stdin, stdout, argv))

    if task.os_env is None:
      os_env = os.environ
    else:
      os_env = task.os_env
    command = Utils.pproc.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
    return command.wait()

class cmd_output_taskgen(TaskGen.task_gen):
  def __init__(self, *k, **kw):
    TaskGen.task_gen.__init__(self, *k, **kw)

@feature('command-output')
def init_cmd_output(self):
  Utils.def_attrs(self,
    stdin = None,
    stdout = None,
    stderr = None,
    # the command to execute
    command = None,

    # whether it is an external command; otherwise it is assumed
    # to be an executable binary or script that lives in the
    # source or build tree.
    command_is_external = False,

    # extra parameters (argv) to pass to the command (excluding
    # the command itself)
    argv = [],

    # dependencies to other objects -> this is probably not what you want (ita)
    # values must be 'task_gen' instances (not names!)
    dependencies = [],

    # dependencies on env variable contents
    dep_vars = [],

    # input files that are implicit, i.e. they are not
    # stdin, nor are they mentioned explicitly in argv
    hidden_inputs = [],

    # output files that are implicit, i.e. they are not
    # stdout, nor are they mentioned explicitly in argv
    hidden_outputs = [],

    # change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
    cwd = None,

    # OS environment variables to pass to the subprocess
    # if None, use the default environment variables unchanged
    os_env = None)

@feature('command-output')
@after('init_cmd_output')
def apply_cmd_output(self):
  if self.command is None:
    raise Utils.WafError("command-output missing command")
  if self.command_is_external:
    cmd = self.command
    cmd_node = None
  else:
    cmd_node = self.path.find_resource(self.command)
    assert cmd_node is not None, ('''Could not find command '%s' in source tree.
Hint: if this is an external command,
use command_is_external=True''') % (self.command,)
    cmd = cmd_node

  if self.cwd is None:
    cwd = None
  else:
    assert isinstance(cwd, CmdDirArg)
    self.cwd.find_node(self.path)

  args = []
  inputs = []
  outputs = []

  for arg in self.argv:
    if isinstance(arg, cmd_arg):
      arg.find_node(self.path)
      if isinstance(arg, input_file):
        inputs.append(arg.node)
      if isinstance(arg, output_file):
        outputs.append(arg.node)

  if self.stdout is None:
    stdout = None
  else:
    assert isinstance(self.stdout, str)
    stdout = self.path.find_or_declare(self.stdout)
    if stdout is None:
      raise Utils.WafError("File %s not found" % (self.stdout,))
    outputs.append(stdout)

  if self.stderr is None:
    stderr = None
  else:
    assert isinstance(self.stderr, str)
    stderr = self.path.find_or_declare(self.stderr)
    if stderr is None:
      raise Utils.WafError("File %s not found" % (self.stderr,))
    outputs.append(stderr)

  if self.stdin is None:
    stdin = None
  else:
    assert isinstance(self.stdin, str)
    stdin = self.path.find_resource(self.stdin)
    if stdin is None:
      raise Utils.WafError("File %s not found" % (self.stdin,))
    inputs.append(stdin)

  for hidden_input in self.to_list(self.hidden_inputs):
    node = self.path.find_resource(hidden_input)
    if node is None:
      raise Utils.WafError("File %s not found in dir %s" % (hidden_input, self.path))
    inputs.append(node)

  for hidden_output in self.to_list(self.hidden_outputs):
    node = self.path.find_or_declare(hidden_output)
    if node is None:
      raise Utils.WafError("File %s not found in dir %s" % (hidden_output, self.path))
    outputs.append(node)

  if not (inputs or getattr(self, 'no_inputs', None)):
    raise Utils.WafError('command-output objects must have at least one input file or give self.no_inputs')
  if not (outputs or getattr(self, 'no_outputs', None)):
    raise Utils.WafError('command-output objects must have at least one output file or give self.no_outputs')

  task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
  Utils.copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
  self.tasks.append(task)

  task.inputs = inputs
  task.outputs = outputs
  task.dep_vars = self.to_list(self.dep_vars)

  for dep in self.dependencies:
    assert dep is not self
    dep.post()
    for dep_task in dep.tasks:
      task.set_run_after(dep_task)

  if not task.inputs:
    # the case for svnversion, always run, and update the output nodes
    task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
    task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)

  # TODO the case with no outputs?

def post_run(self):
  for x in self.outputs:
    h = Utils.h_file(x.abspath(self.env))
    self.generator.bld.node_sigs[self.env.variant()][x.id] = h

def runnable_status(self):
  return Constants.RUN_ME

Task.task_type_from_func('copy', vars=[], func=action_process_file_func)
TaskGen.task_gen.classes['command-output'] = cmd_output_taskgen

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.