예제 #1
0
def create_project(identifier, dest, pros_cli=None, require_empty=False, overwrite=False):
    if pros_cli is None or not pros_cli:
        pros_cli = CliConfig()
    filename = os.path.join(pros_cli.directory, identifier.depot,
                            '{}-{}'.format(identifier.name, identifier.version),
                            'template.pros')
    if not os.path.isfile(filename):
        click.echo('Error: template.pros not found for {}-{}'.format(identifier.name, identifier.version))
        click.get_current_context().abort()
        sys.exit()
    if require_empty:
        if os.path.isfile(dest) or (os.path.isdir(dest) and len(os.listdir(dest)) > 0):
            click.echo('Error! Destination is a file or a nonempty directory! Delete the file(s) and try again.')
            click.get_current_context().abort()
            sys.exit()
    config = TemplateConfig(file=filename)
    copytree(config.directory, dest, overwrite=overwrite)
    for root, dirs, files in os.walk(dest):
        for d in dirs:
            d = os.path.relpath(os.path.join(root, d), dest)
            if any([fnmatch.fnmatch(d, p) for p in config.template_ignore]):
                verbose('Removing {}'.format(d))
                os.rmdir(os.path.join(root, d))
        for f in files:
            f = os.path.relpath(os.path.join(root, f), dest)
            if any([fnmatch.fnmatch(f, p) for p in config.template_ignore]):
                verbose('Removing {}'.format(f))
                os.remove(os.path.join(root, f))
    proj_config = prosconfig.ProjectConfig(dest, create=True)
    proj_config.kernel = identifier.version
    proj_config.save()
예제 #2
0
def install_lib(identifier, dest, pros_cli, overwrite=False):
    if pros_cli is None or not pros_cli:
        pros_cli = CliConfig()
    filename = os.path.join(pros_cli.directory, identifier.depot,
                            '{}-{}'.format(identifier.name, identifier.version),
                            'template.pros')
    if not os.path.isfile(filename):
        click.echo('Error: template.pros not found for {}-{}'.format(identifier.name, identifier.version))
        click.get_current_context().abort()
        sys.exit()
    proj_config = prosconfig.ProjectConfig(dest)
    config = TemplateConfig(file=filename)
    copytree(config.directory, dest, overwrite=overwrite)
    for root, dirs, files in os.walk(dest):
        for d in dirs:
            if any([fnmatch.fnmatch(d, p) for p in config.template_ignore]):
                verbose('Removing {}'.format(d))
                os.rmdir(os.path.join(root, d))
        for f in files:
            if any([fnmatch.fnmatch(f, p) for p in config.template_ignore]):
                verbose('Removing {}'.format(f))
                os.remove(os.path.join(root, f))
    if type(proj_config.libraries) is list:
        proj_config.libraries = dict()
    proj_config.libraries[identifier.name] = identifier.version
    proj_config.save()
예제 #3
0
def make(ctx, build_args):
    """Invokes make.

    If on Windows, will invoke make located in on the PROS_TOOLCHAIN.

    Also has the added benefit of looking for the config.pros file"""
    try:
        cfg = prosconfig.ProjectConfig(
            prosconfig.ProjectConfig.find_project('.'))
        cwd = cfg.directory
    except prosconfig.ConfigNotFoundException:
        cwd = '.'
    env = os.environ.copy()
    if os.name == 'nt':
        env['PATH'] += ';' + os.path.join(os.environ.get('PROS_TOOLCHAIN'),
                                          'bin')
        cmd = os.path.join(os.environ.get('PROS_TOOLCHAIN'), 'bin', 'make.exe')
    else:
        cmd = 'make'
    build_args = ['make'] + list(build_args)  # prepend 'make' because of magic
    click.echo('Invoking {} in {}...'.format(' '.join(build_args), cwd))
    p = subprocess.Popen(executable=cmd,
                         args=build_args,
                         cwd=cwd,
                         env=env,
                         stdout=sys.stdout,
                         stderr=sys.stderr)
    p.wait()
    if p.returncode != 0:
        ctx.exit(1)
예제 #4
0
def info_project(cfg, location):
    project = prosconfig.ProjectConfig(path=location)
    details = dict()
    details['kernel'] = project.kernel
    templates = local.get_local_templates(
        pros_cfg=cfg.pros_cfg, template_types=[TemplateTypes.kernel])
    details['kernelUpToDate'] = semver.compare(project.kernel,
                                               sorted(templates, key=lambda t: semver.Version(t.version))[-1].version) \
                                >= 0
    templates = local.get_local_templates(
        pros_cfg=cfg.pros_cfg, template_types=[TemplateTypes.library])
    details['libraries'] = dict()
    if project.libraries.__class__ is dict:
        for (lib, ver) in project.libraries.items():
            details['libraries'][lib] = dict()
            details['libraries'][lib]['version'] = ver
            sorted_versions = sorted(
                [t.version for t in templates if t.name == lib],
                key=lambda v: semver.Version(v))
            if len(sorted_versions) > 0:
                latest = semver.compare(ver, sorted_versions[-1]) >= 0
            else:
                latest = True
            details['libraries'][lib]['latest'] = latest
    click.echo(json.dumps(details))
예제 #5
0
def register(cfg, location, kernel):
    first_run(cfg)
    kernel_version = kernel
    if kernel_version == 'latest':
        templates = local.get_local_templates(pros_cfg=cfg.pros_cfg,
                                              template_types=[
                                                  TemplateTypes.kernel
                                              ])  # type: List[Identifier]
        if not templates or len(templates) == 0:
            click.echo(
                'No templates have been downloaded! Use `pros conduct download` to download the latest kernel or'
                ' specify a kernel manually.')
            click.get_current_context().abort()
            sys.exit()
        kernel_version = sorted(
            templates, key=lambda t: semver.Version(t.version))[-1].version
        proscli.utils.debug('Resolved version {} to {}'.format(
            kernel, kernel_version))

    cfg = prosconfig.ProjectConfig(location, create=True, raise_on_error=True)
    cfg.kernel = kernel_version
    if not location:
        click.echo('Location not specified, registering current directory.')
    click.echo('Registering {} with kernel {}'.format(
        location or os.path.abspath('.'), kernel_version))
    cfg.save()
예제 #6
0
def upgrade_project(identifier: Identifier,
                    dest: str,
                    pros_cli: CliConfig = None):
    if pros_cli is None or not pros_cli:
        pros_cli = CliConfig()
    filename = os.path.join(
        pros_cli.directory, identifier.depot,
        '{}-{}'.format(identifier.name, identifier.version), 'template.pros')

    if not os.path.isfile(filename):
        click.echo('Error: template.pros not found for {}-{}'.format(
            identifier.name, identifier.version))
        click.get_current_context().abort()
        sys.exit()
    proj_config = prosconfig.ProjectConfig(dest, raise_on_error=True)
    config = TemplateConfig(file=filename)

    for root, dirs, files in os.walk(config.directory):
        for d in dirs:
            if any([fnmatch.fnmatch(d, p) for p in config.upgrade_paths]):
                verbose('Upgrading {}'.format(d))
                relpath = os.path.relpath(os.path.join(root, d),
                                          config.directory)
                shutil.copytree(os.path.join(config.directory, relpath),
                                os.path.join(proj_config.directory, relpath))
        for f in files:
            if any([fnmatch.fnmatch(f, p) for p in config.upgrade_paths]):
                verbose('Upgrading {}'.format(f))
                relpath = os.path.relpath(os.path.join(root, f),
                                          config.directory)
                shutil.copyfile(os.path.join(config.directory, relpath),
                                os.path.join(proj_config.directory, relpath))
예제 #7
0
def find_binary(path):
    """
    Helper function for finding the binary associated with a project

    The algorithm is as follows:
        - if it is a file, then check if the name of the file is 'pros.config':
            - if it is 'pros.config', then find the binary based off the pros.config value (or default 'bin/output.bin')
            - otherwise, can only assume it is the binary file to upload
        - if it is a directory, start recursively searching up until 'pros.config' is found. max 10 times
            - if the pros.config file was found, find binary based off of the pros.config value
            - if no pros.config file was found, start recursively searching up (from starting path) until a directory
                named bin is found
                - if 'bin' was found, return 'bin/output.bin'
    :param path: starting path to start the search
    :param ctx:
    :return:
    """
    # logger = logging.getLogger(ctx.log_key)
    # logger.debug('Finding binary for {}'.format(path))
    if os.path.isfile(path):
        if ntpath.basename(path) == 'pros.config':
            pros_cfg = prosconfig.ProjectConfig(path)
            return os.path.join(path, pros_cfg.output)
        return path
    elif os.path.isdir(path):
        try:
            cfg = prosconfig.ProjectConfig(path, raise_on_error=True)
            if cfg is not None and os.path.isfile(
                    os.path.join(cfg.directory, cfg.output)):
                return os.path.join(cfg.directory, cfg.output)
        except prosconfig.ConfigNotFoundException:
            search_dir = path
            for n in range(10):
                dirs = [
                    d for d in os.listdir(search_dir)
                    if os.path.isdir(os.path.join(path, search_dir, d))
                    and d == 'bin'
                ]
                if len(dirs) == 1:  # found a bin directory
                    if os.path.isfile(
                            os.path.join(path, search_dir, 'bin',
                                         'output.bin')):
                        return os.path.join(path, search_dir, 'bin',
                                            'output.bin')
                search_dir = ntpath.split(search_dir)[:-1][
                    0]  # move to parent dir
    return None
예제 #8
0
파일: conductor.py 프로젝트: iuyte/pros-cli
def upgradelib(cfg, location, library, version, depot):
    if not (version == 'latest') and len(version.split('.')) < 3:
        depot = version
        version = 'latest'
    first_run(cfg)
    templates = local.get_local_templates(pros_cfg=cfg.pros_cfg,
                                          template_types=[TemplateTypes.library])  # type: List[Identifier]
    selected = None
    to_remove = []
    if not templates or len(templates) == 0:
        click.echo('No templates have been downloaded! Use `pros conduct download` to download the latest kernel.')
        click.get_current_context().abort()
        sys.exit()
    for template in templates:
        if template.name != library:
            to_remove.append(template)
    for template in to_remove:
        templates.remove(template)
    to_remove = []
    if version == 'latest':
        lib_version = sorted(templates, key=lambda t: semver.Version(t.version))[-1].version
        highest = lib_version.split('.')
        for template in templates:
            curr = template.version.split('.')
            if len(highest) > len(curr):
                to_remove.append(template)
            for i in range(len(highest)):
                if curr[i] < highest[i]:
                    to_remove.append(template)
                    break

    else:
        for template in templates:
            if template.version != version:
                to_remove.append(template)
    for template in to_remove:
        templates.remove(template)
    to_remove = []
    if depot == 'auto':
        for template in templates:
            if template.depot == 'pros-mainline':
                selected = template
                break
        if selected == None:
            selected = templates[0]
    else:
        for template in templates:
            if template.depot != depot:
                to_remove.append(template)
        for template in to_remove:
            templates.remove(template)
        to_remove = []
        if len(templates) > 0:
            selected = templates[0]
        else:
            click.echo(
                'No local libraries match the specified name, version, and depot. Check your arguments and make sure the appropriate libraries are downloaded')
            click.get_current_context().abort()
            sys.exit()
    local.upgrade_project(selected, location, cfg.pros_cfg)
    proj_config = prosconfig.ProjectConfig(location)
    proj_config.libraries[selected.name] = selected.version
    proj_config.save()
    print('Updated library {} v. {} in {} from {}'.format(selected.name, selected.version, location, selected.depot))