Esempio n. 1
0
def hwaf_ishell(ctx):
    # make sure we build first"
    # waflib.Scripting.run_command('install')

    import os
    import tempfile
    import textwrap

    #env = ctx.env
    cwd = os.getcwd()
    root = os.path.realpath(ctx.options.prefix)
    root = os.path.abspath(os.path.realpath(ctx.env['INSTALL_AREA']))
    bindir = os.path.join(root, 'bin')
    libdir = os.path.join(root, 'lib')
    pydir  = os.path.join(root, 'python')

    # get the runtime...
    env = _hwaf_get_runtime_env(ctx)

    # retrieve the directory from which to run the shell
    ishell_cwd = os.environ.get('HWAF_WAF_SHELL_CWD', cwd)

    ## handle the shell flavours...
    if ctx.is_linux():
        shell = os.environ.get("SHELL", "/bin/sh")
    elif ctx.is_darwin():
        shell = os.environ.get("SHELL", "/bin/sh")
        shell = shell.strip()
        if shell.startswith('-'):
            shell = shell[1:]
    elif ctx.is_windows():
        ## FIXME: ???
        shell = None
    else:
        shell = None
        pass

    # catch-all
    if not shell or "(deleted)" in shell:
        # fallback on the *login* shell
        shell = os.environ.get("SHELL", "/bin/sh")

    tmpdir = tempfile.mkdtemp(prefix='hwaf-env-')
    dotrc = None
    dotrc_fname = None
    shell_cmd = [shell,]
    msg.info("---> shell: %s" % shell)

    shell_alias = '='
    if 'zsh' in os.path.basename(shell):
        env['ZDOTDIR'] = tmpdir
        dotrc_fname = os.path.join(tmpdir, '.zshrc')
        shell_cmd.append('-i')

    elif 'bash' in os.path.basename(shell):
        dotrc_fname = os.path.join(tmpdir, '.bashrc')
        shell_cmd += [
            '--init-file',
            dotrc_fname,
            '-i',
            ]
    elif 'csh' in os.path.basename(shell):
        msg.info('sorry, c-shells not handled at the moment: fallback to bash')
        dotrc_fname = os.path.join(tmpdir, '.bashrc')
        shell_cmd += [
            '--init-file',
            dotrc_fname,
            '-i',
            ]
        # FIXME: when c-shells are supported...
        # c-shells use a space as an alias separation token
        # in c-shell:
        #   alias ll 'ls -l'
        # in s-shell:
        #   alias ll='ls -l'
        #shell_alias = ' ' 
    else:
        # default to dash...
        dotrc_fname = os.path.join(tmpdir, '.bashrc')
        shell_cmd += [
            #'--init-file',
            #dotrc_fname,
            '-i',
            ]
        env['ENV'] = dotrc_fname
        pass

    ###

    hwaf_runtime_aliases = ";\n".join([
        "alias %s%s'%s'" % (alias[0], shell_alias, alias[1])
        for alias in ctx.env.HWAF_RUNTIME_ALIASES
        ])
    
    dotrc = open(dotrc_fname, 'w')
    dotrc.write(textwrap.dedent(
        '''
        ## automatically generated by hwaf-shell
        echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
        echo ":: launching a sub-shell with the correct environment..."
        echo ":: sourcing ${HOME}/%(dotrc_fname)s..."
        source ${HOME}/%(dotrc_fname)s
        echo ":: sourcing ${HOME}/%(dotrc_fname)s... [done]"

        # adjust env. variables
        export PATH=%(hwaf_path)s
        export LD_LIBRARY_PATH=%(hwaf_ld_library_path)s
        export DYLD_LIBRARY_PATH=%(hwaf_dyld_library_path)s
        export PYTHONPATH=%(hwaf_pythonpath)s

        # customize PS1 so we know we are in a hwaf subshell
        export PS1="[hwaf] ${PS1}"

        # setup aliases
        %(hwaf_runtime_aliases)s
        
        echo ":: hwaf environment... [setup]"
        echo ":: hit ^D or exit to go back to the parent shell"
        echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
        ''' % {
            'dotrc_fname' : os.path.basename(dotrc_fname),
            'hwaf_path': env['PATH'],
            'hwaf_ld_library_path': env['LD_LIBRARY_PATH'],
            'hwaf_dyld_library_path': env['DYLD_LIBRARY_PATH'],
            'hwaf_pythonpath': env['PYTHONPATH'],
            'hwaf_runtime_aliases': hwaf_runtime_aliases,
            }
        ))
    dotrc.flush()
    dotrc.close()

    for k in env:
        v = env[k]
        if not isinstance(v, str):
            ctx.fatal('env[%s]=%r (%s)' % (k,v,type(v)))
            pass
        pass
    
    retval = subprocess.Popen(
        shell_cmd,
        env=env,
        cwd=ishell_cwd,
        shell=True,
        ).wait()

    try:
        import shutil
        shutil.rmtree(tmpdir)
    except Exception:
        msg.verbose('could not remove directory [%s]' % tmpdir)
        pass

    if retval:
        signame = None
        if retval < 0: # signal?
            import signal
            for name, val in vars(signal).items():
                if len(name) > 3 and name[:3] == 'SIG' and name[3] != '_':
                    if val == -retval:
                        signame = name
                        break
        if signame:
            raise waflib.Errors.WafError(
                "Command %s terminated with signal %s." % (shell_cmd, signame))
        else:
            raise waflib.Errors.WafError(
                "Command %s exited with code %i" % (shell_cmd, retval))
    return retval