Example #1
0
    def build(self):
        debug3('running build job for %r\n', self.target.name)

        (dodir, dofile, basedir, basename, ext) = (
            self.dodir, self.dofile, self.dobasedir, self.dobasename, self.doext)

        # this will run in the dofile's directory, so use only basenames here
        if vars.OLD_ARGS:
            arg1 = basename  # target name (no extension)
            arg2 = ext       # extension (if any), including leading dot
        else:
            arg1 = basename + ext  # target name (including extension)
            arg2 = basename        # target name (without extension)
        argv = ['sh', '-e',
                dofile,
                arg1,
                arg2,
                # temp output file name
                os.path.relpath(self.tmpname_arg3, dodir),
                ]
        if vars.VERBOSE: argv[1] += 'v'
        if vars.XTRACE: argv[1] += 'x'
        if vars.VERBOSE or vars.XTRACE: log_e('\n')

        firstline = open(os.path.join(dodir, dofile)).readline().strip()
        if firstline.startswith('#!.../'):
            _, _, interp_argv = firstline.partition("/")
            interp_argv = interp_argv.split(' ')
            interpreter = _find_interpreter(self.dodir, interp_argv[0])
            if not interpreter:
                err('%s unable to find interpreter %s.\n', self.dofile, interp_argv[0])
                os._exit(208)
            self.target.add_dep(state.File(interpreter))
            argv[0:2] = [interpreter] + interp_argv[1:]
        elif firstline.startswith('#!/'):
            argv[0:2] = firstline[2:].split(' ')
        log('%s\n', self.target.printable_name())
        log_cmd("redo", self.target.name + "\n")

        try:
            dn = dodir
            os.environ['REDO_PWD'] = os.path.join(vars.PWD, dn)
            os.environ['REDO_TARGET'] = basename + ext
            os.environ['REDO_DEPTH'] = vars.DEPTH + '  '
            if dn:
                os.chdir(dn)
            l = logger.Logger(self.log_fd, self.tmp_sout_fd)
            l.fork()
            os.close(self.tmp_sout_fd)
            close_on_exec(1, False)
            if vars.VERBOSE or vars.XTRACE: log_e('* %s\n' % ' '.join(argv))
            os.execvp(argv[0], argv)
        except:
            import traceback
            sys.stderr.write(traceback.format_exc())
            err('internal exception - see above\n')
            raise
        finally:
            # returns only if there's an exception (exec in other case)
            os._exit(127)
Example #2
0
    def done(self, t, rv):
        assert self.target.dolock().owned == state.LOCK_EX
        log_cmd("redo_done", self.target.name + "\n")
        try:
            after_t = _try_stat(self.target.name)
            st1 = os.fstat(self.tmp_sout_f.fileno())
            st2 = _try_stat(self.tmpname_arg3)

            if (
                after_t
                and (not self.before_t or self.before_t.st_ctime != after_t.st_ctime)
                and not stat.S_ISDIR(after_t.st_mode)
            ):
                err("%s modified %s directly!\n", self.dofile, self.target.name)
                err("...you should update $3 (a temp file) or stdout, not $1.\n")
                rv = 206

            elif vars.OLD_STDOUT and st2 and st1.st_size > 0:
                err("%s wrote to stdout *and* created $3.\n", self.dofile)
                err("...you should write status messages to stderr, not stdout.\n")
                rv = 207

            elif vars.WARN_STDOUT and st1.st_size > 0:
                err("%s wrote to stdout, this is not longer supported.\n", self.dofile)
                err("...you should write status messages to stderr, not stdout.\n")
                err('...you should write target content to $3 using for example \'exec >"$3"`.\n')
                if not vars.OLD_STDOUT:
                    rv = 207

            if rv == 0:
                if st2:
                    os.rename(self.tmpname_arg3, self.target.name)
                    os.unlink(self.tmpname_sout)
                elif vars.OLD_STDOUT and st1.st_size > 0:
                    try:
                        os.rename(self.tmpname_sout, self.target.name)
                    except OSError, e:
                        if e.errno == errno.ENOENT:
                            unlink(self.target.name)
                        else:
                            raise
                else:  # no output generated at all; that's ok
                    unlink(self.tmpname_sout)
                    unlink(self.target.name)
                if vars.VERBOSE or vars.XTRACE or vars.DEBUG:
                    log("%s (done)\n\n", self.target.printable_name())
            else: