Source

xenv / xenv / main.py

'''
This defines the main 'xe' entry point to the xenv. Below, the parser
definition describes the usage and UI for interacting with an xenv.
'''
import os
import sys
from subprocess import call

from argparse import ArgumentParser
from xenv.models import Xenv, Package


def with_root(f):
    def wrap(args):
        xenv = Xenv(root=args.root)
        f(xenv, args)
    return wrap


@with_root
def run_cmd(xenv, args):
    xenv.run(args.cmd.pop())

@with_root
def create_xenv_cmd(xenv, args):
    xenv.create()

@with_root
def install_package_cmd(xenv, args):
    pkg = Package(args.name, args.version, args.repo)
    xenv.install(pkg)

@with_root
def uninstall_package_cmd(xenv, args):
    pkg = Package(args.name, args.version)
    xenv.uninstall(pkg)

    

class CLI(object):
    description = '''Utilize a specific executable environment (xenv) for running applications'''

    def __init__(self):
        self.parser = ArgumentParser(description=self.description)
        self.parser.add_argument('--root', '-r', default=os.environ.get('XE_ROOT'),
                                 help='The xenv root. This will override using the XE_ROOT env var.')
        
        self.subs = self.parser.add_subparsers(help='sub command help')

        # Create a new xenv
        create = self.subs.add_parser('create', help='Create a new xenv')
        create.add_argument('root', help='The root of the xenv')
        create.set_defaults(func=create_xenv_cmd)

        # run a command via the xenv
        run = self.subs.add_parser('run', prefix_chars='!',
                                   help='Run a command from the xenv')
        run.add_argument('cmd', type=str, nargs='*', action='append',
                         help='The command and flags to run via the xenv')
        run.set_defaults(func=run_cmd)


        # install a package
        install_pkg = self.subs.add_parser('install',
                                           help='Install a package in an xenv')
        install_pkg.add_argument('name', help='The package to install')
        install_pkg.add_argument('version', help='The version to install')    
        install_pkg.add_argument('--repo', '-b', default='file://',
                         help='The base URL of the package. \
                               The default is the current directory')
        install_pkg.set_defaults(func=install_package_cmd)

        # uninstall a package
        uninstall_pkg = self.subs.add_parser('uninstall',
                                             help='Install a package in an xenv')
        uninstall_pkg.add_argument('name', help='The package to uninstall')
        uninstall_pkg.add_argument('version', help='The version to uninstall')    
        uninstall_pkg.set_defaults(func=uninstall_package_cmd)

    def run(self, args=None):
        if args:
            return self.parser.parse_args(args)
        return self.parser.parse_known_args()
    

def _run(args):
    if args.root:
        args.root = os.path.abspath(args.root)
    if args.func:
        args.func(args)
    
def xe():
    cli = CLI()
    args, extras = cli.run()
    _run(args)
        
def xepython():
    cli = CLI()
    cargs = ['run', 'python']
    if len(sys.argv) > 1:
        cargs.extend(sys.argv[1:])
    args = cli.run(cargs)
    _run(args)