def do(cls, _, args): '''Executes the remove command.''' ws_dir = get_ws_dir(args.root, args.remove_ws) if not os.path.exists(ws_dir): raise WSError('workspace %s does not exist' % args.remove_ws) if args.default is not None: default_ws_dir = get_ws_dir(args.root, args.default) if not os.path.exists(default_ws_dir): raise WSError('workspace %s does not exist' % args.default) default_link = get_default_ws_link(args.root) is_default = (os.readlink(default_link) == args.remove_ws) if is_default: # If the deleted workspace is the default, force the user to choose # a new one. if args.default is None: raise WSError('trying to remove the default workspace; must ' 'specify a new default via -d/--default') elif args.default: raise WSError('-d/--default is not applicable unless you are ' 'removing the default workspace') # We are good to go. rmtree(ws_dir) if is_default: remove(default_link) symlink(args.default, default_link)
def get_ws_config(ws): # noqa: E302 '''Parses the current workspace config, returning a dictionary of the state.''' global _WS_CONFIG if _WS_CONFIG is None: config_path = get_ws_config_path(ws) with open(config_path, 'r') as f: _WS_CONFIG = yaml.safe_load(f) global _ORIG_WS_CONFIG # Save a copy of the config so we know later whether or not to # write it out when someone asks to sync the config. _ORIG_WS_CONFIG = copy.deepcopy(_WS_CONFIG) # Check if projects were added or removed from the manifest. If so, the # config needs to be updated accordingly. d = parse_manifest(get_ws_root(ws)) deletions = [] for proj in _WS_CONFIG['projects']: if proj not in d: deletions.append(proj) for proj in deletions: del _WS_CONFIG['projects'][proj] checksum_file = get_checksum_file(ws, proj) proj_dir = get_proj_dir(ws, proj) log('removing project %s, which is not in the manifest' % proj, logging.INFO) remove(checksum_file, True) rmtree(proj_dir, True) for proj in d: if proj in _WS_CONFIG['projects']: continue # Project is not in the config, so add it in. _WS_CONFIG['projects'][proj] = get_new_config(proj) # Split all project arguments by spaces so that args like '-D something' # turn into ['-D', 'something'], which is what exec requires. We do this # at parse time rather than in the "config" command to allow the user to # hand-edit in a natural way and have the config still work properly. The # next time the config is saved, it will be split by spaces. for proj, proj_map in _WS_CONFIG['projects'].items(): parsed_args = [] args = proj_map['args'] for arg in args: parsed_args.extend(arg.split()) proj_map['args'] = parsed_args return _WS_CONFIG
def _force_clean(ws, proj): '''Performs a force-clean of a project, removing all files instead of politely calling the clean function of the underlying build system.''' build_dir = get_build_dir(ws, proj) log('removing %s' % build_dir) if dry_run(): return try: rmtree(build_dir) except OSError as e: if e.errno == errno.ENOENT: log('%s already removed' % build_dir) else: raise config = get_ws_config(ws) config['projects'][proj]['taint'] = False
def clean(cls, proj, prefix, source_dir, build_dir, env, builder_args): '''Calls clean using setuptools.''' # setuptools appears not to have a nicer way to do a "make clean" on a # dev-installed package. rmtree(build_dir)
def _build(root, ws, proj, d, current, ws_config, force): '''Builds a given project.''' if not ws_config['projects'][proj]['enable']: log('not building manually disabled project %s' % proj, logging.WARNING) return True if ws_config['projects'][proj]['taint']: log('force-cleaning tainted project %s' % proj, logging.WARNING) clean(root, ws, proj, d, True) source_dir = get_source_dir(root, d, proj) if not force: stored = get_stored_checksum(ws, proj) if current == stored: log('checksum for %s is current; skipping' % proj) return True else: log('forcing a build of %s' % proj) # Make the project directory if needed. proj_dir = get_proj_dir(ws, proj) try: mkdir(proj_dir) except OSError as e: if e.errno != errno.EEXIST: raise # Make the build directory if needed. build_dir = get_build_dir(ws, proj) try: mkdir(build_dir) except OSError as e: if e.errno != errno.EEXIST: raise needs_configure = False else: needs_configure = True # Populate the convenience source link. source_link = get_source_link(ws, proj) if not os.path.exists(source_link): source_dir = get_source_dir(root, d, proj) symlink(source_dir, source_link) # Invalidate the checksums for any downstream projects. for downstream_dep in d[proj]['downstream']: invalidate_checksum(ws, downstream_dep) # Add envs to find all projects on which this project is dependent. build_env = get_build_env(ws, d, proj) # Configure. builder = get_builder(d, proj) prefix = get_install_dir(ws, proj) extra_args = d[proj]['args'] + ws_config['projects'][proj]['args'] if needs_configure: try: success = builder.conf(proj, prefix, source_dir, build_dir, build_env, ws_config['type'], d[proj]['builder-args'], extra_args) except Exception as _e: success = False e = _e else: e = None if not success: # Remove the build directory if we failed so that we are forced to # re-run configure next time. rmtree(build_dir) if e is not None: raise e else: return False # Build. success = builder.build(proj, prefix, source_dir, build_dir, build_env, d[proj]['targets'], d[proj]['builder-args'], d[proj]['args']) if success: set_stored_checksum(ws, proj, current) return success