예제 #1
0
def globpattern(dir, pattern):
    """
    Return leaf names in the specified directory which match the pattern.
    """

    if not hasglob(pattern):
        if pattern == '':
            if os.path.isdir(dir):
                return ['']
            return []

        if os.path.exists(util.normaljoin(dir, pattern)):
            return [pattern]
        return []

    leaves = os.listdir(dir) + ['.', '..']

    # "hidden" filenames are a bit special
    if not pattern.startswith('.'):
        leaves = [leaf for leaf in leaves if not leaf.startswith('.')]

    leaves = fnmatch.filter(leaves, pattern)
    leaves = [l for l in leaves if os.path.exists(util.normaljoin(dir, l))]

    leaves.sort()
    return leaves
예제 #2
0
def glob(fsdir, path):
    """
    Yield paths matching the path glob. Sorts as a bonus. Excludes '.' and '..'
    """

    dir, leaf = os.path.split(path)
    if dir == '':
        return globpattern(fsdir, leaf)

    if hasglob(dir):
        dirsfound = glob(fsdir, dir)
    else:
        dirsfound = [dir]

    r = []

    for dir in dirsfound:
        fspath = util.normaljoin(fsdir, dir)
        if not os.path.isdir(fspath):
            continue

        r.extend((util.normaljoin(dir, found)
                  for found in globpattern(fspath, leaf)))

    return r
예제 #3
0
 def resolve(self, makefile, variables, fd, setting):
     assert os.path.isabs(makefile.workdir)
     fd.write(' '.join([
         util.normaljoin(makefile.workdir, path).replace('\\', '/')
         for path in self._arguments[0].resolvesplit(
             makefile, variables, setting)
     ]))
예제 #4
0
def prepare_command(cline, cwd, loc):
    """
    Returns a list of command and arguments for the given command line string.
    If the command needs to be run through a shell for some reason, the
    returned list contains the shell invocation.
    """

    #TODO: call this once up-front somewhere and save the result?
    shell, msys = util.checkmsyscompat()

    shellreason = None
    executable = None
    if msys and cline.startswith('/'):
        shellreason = "command starts with /"
    else:
        argv, badchar = clinetoargv(cline, cwd)
        if argv is None:
            shellreason = "command contains shell-special character '%s'" % (
                badchar, )
        elif len(argv) and argv[0] in shellwords:
            shellreason = "command starts with shell primitive '%s'" % (
                argv[0], )
        elif argv and (os.sep in argv[0]
                       or os.altsep and os.altsep in argv[0]):
            executable = util.normaljoin(cwd, argv[0])
            # Avoid "%1 is not a valid Win32 application" errors, assuming
            # that if the executable path is to be resolved with PATH, it will
            # be a Win32 executable.
            if sys.platform == 'win32' and os.path.isfile(executable) and open(
                    executable, 'rb').read(2) == "#!":
                shellreason = "command executable starts with a hashbang"

    if shellreason is not None:
        _log.debug("%s: using shell: %s: '%s'", loc, shellreason, cline)
        if msys:
            if len(cline) > 3 and cline[1] == ':' and cline[2] == '/':
                cline = '/' + cline[0] + cline[2:]
        argv = [shell, "-c", cline]
        executable = None

    return executable, argv
예제 #5
0
파일: command.py 프로젝트: grnydawn/langlab
def main(args, env, cwd, cb):
    """
    Start a single makefile execution, given a command line, working directory, and environment.

    @param cb a callback to notify with an exit code when make execution is finished.
    """

    try:
        makelevel = int(env.get('MAKELEVEL', '0'))

        op = OptionParser()
        op.add_option('-f',
                      '--file',
                      '--makefile',
                      action='append',
                      dest='makefiles',
                      default=[])
        op.add_option('-d', action="store_true", dest="verbose", default=False)
        op.add_option('-k',
                      '--keep-going',
                      action="store_true",
                      dest="keepgoing",
                      default=False)
        op.add_option('--debug-log', dest="debuglog", default=None)
        op.add_option('-C', '--directory', dest="directory", default=None)
        op.add_option('-v',
                      '--version',
                      action="store_true",
                      dest="printversion",
                      default=False)
        op.add_option('-j', '--jobs', type="int", dest="jobcount", default=1)
        op.add_option('-w',
                      '--print-directory',
                      action="store_true",
                      dest="printdir")
        op.add_option('--no-print-directory',
                      action="store_false",
                      dest="printdir",
                      default=True)
        op.add_option('-s',
                      '--silent',
                      action="store_true",
                      dest="silent",
                      default=False)
        op.add_option('-n',
                      '--just-print',
                      '--dry-run',
                      '--recon',
                      action="store_true",
                      dest="justprint",
                      default=False)

        options, arguments1 = op.parse_args(parsemakeflags(env))
        options, arguments2 = op.parse_args(args, values=options)

        op.destroy()

        arguments = arguments1 + arguments2

        if options.printversion:
            _version()
            cb(0)
            return

        shortflags = []
        longflags = []

        if options.keepgoing:
            shortflags.append('k')

        if options.printdir:
            shortflags.append('w')

        if options.silent:
            shortflags.append('s')
            options.printdir = False

        if options.justprint:
            shortflags.append('n')

        loglevel = logging.WARNING
        if options.verbose:
            loglevel = logging.DEBUG
            shortflags.append('d')

        logkwargs = {}
        if options.debuglog:
            logkwargs['filename'] = options.debuglog
            longflags.append('--debug-log=%s' % options.debuglog)

        if options.directory is None:
            workdir = cwd
        else:
            workdir = util.normaljoin(cwd, options.directory)

        if options.jobcount != 1:
            longflags.append('-j%i' % (options.jobcount, ))

        makeflags = ''.join(shortflags)
        if len(longflags):
            makeflags += ' ' + ' '.join(longflags)

        logging.basicConfig(level=loglevel, **logkwargs)

        context = process.getcontext(options.jobcount)

        if options.printdir:
            print("make.py[%i]: Entering directory '%s'" %
                  (makelevel, workdir))
            sys.stdout.flush()

        if len(options.makefiles) == 0:
            if os.path.exists(util.normaljoin(workdir, 'Makefile')):
                options.makefiles.append('Makefile')
            else:
                print("No makefile found")
                cb(2)
                return

        ostmts, targets, overrides = parserdata.parsecommandlineargs(arguments)

        _MakeContext(makeflags, makelevel, workdir, context, env, targets,
                     options, ostmts, overrides, cb)
    except errors.MakeError as e:
        print(e)
        if options.printdir:
            print("make.py[%i]: Leaving directory '%s'" % (makelevel, workdir))
        sys.stdout.flush()
        cb(2)
        return
예제 #6
0
파일: command.py 프로젝트: grnydawn/langlab
"""
Makefile execution.

Multiple `makes` can be run within the same process. Each one has an entirely data.Makefile and .Target
structure, environment, and working directory. Typically they will all share a parallel execution context,
except when a submake specifies -j1 when the parent make is building in parallel.
"""

import os, subprocess, sys, logging, time, traceback, re
from optparse import OptionParser
from langlab.pymake import data, parserdata, process, util, errors

# TODO: If this ever goes from relocatable package to system-installed, this may need to be
# a configured-in path.

makepypath = util.normaljoin(os.path.dirname(__file__), '../make.py')

_simpleopts = re.compile(r'^[a-zA-Z]+(\s|$)')


def parsemakeflags(env):
    """
    Parse MAKEFLAGS from the environment into a sequence of command-line arguments.
    """

    makeflags = env.get('MAKEFLAGS', '')
    makeflags = makeflags.strip()

    if makeflags == '':
        return []