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()
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()
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)
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))
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()
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))
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
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))