def do(cls, ws, args): '''Executes the build subcmd.''' ws_config = get_ws_config(get_ws_dir(args.root, ws)) d = parse_manifest(args.root) # Validate. for project in args.projects: if project not in d: raise WSError('unknown project %s' % project) if len(args.projects) == 0: projects = d.keys() else: projects = args.projects # Build in reverse-dependency order. order = dependency_closure(d, projects) # Get all checksums; since this is a nop build bottle-neck, do it in # parallel. On my machine, this produces a ~20% speedup on a nop # "build-all". pool = multiprocessing.Pool(multiprocessing.cpu_count()) src_dirs = [get_source_dir(args.root, d, proj) for proj in order] checksums = pool.map(calculate_checksum, src_dirs) for i, proj in enumerate(order): log('building %s' % proj) checksum = checksums[i] success = _build(args.root, ws, proj, d, checksum, ws_config, args.force) if not success: raise WSError('%s build failed' % proj)
def do(cls, ws, args): '''Executes the rename command.''' if args.old_ws == 'default': raise WSError('cannot rename the default workspace; please use ws ' 'default if you want to change it') old_ws_dir = get_ws_dir(args.root, args.old_ws) if not os.path.exists(old_ws_dir): raise WSError('workspace %s does not exist' % args.old_ws) d = parse_manifest(args.root) for proj in d: build_dir = get_build_dir(old_ws_dir, proj) if os.path.exists(build_dir): raise WSError('cannot rename a workspace that contains build ' 'artifacts, as some builds contain absolute ' 'paths and are thus not relocatable. Please ' 'force-clean this workspace first and then ' 'rename it.') new_ws_dir = get_ws_dir(args.root, args.new_ws) if os.path.exists(new_ws_dir): raise WSError('workspace %s already exists; please delete it ' 'first if you want to do this rename' % args.new_ws) rename(old_ws_dir, new_ws_dir) default_link = get_default_ws_link(args.root) if os.readlink(default_link) == args.old_ws: remove(default_link) symlink(args.new_ws, default_link)
def do(cls, ws, args): '''Executes the test subcmd.''' d = parse_manifest(args.root) # Validate. for project in args.projects: if project not in d: raise WSError('unknown project %s' % project) if len(args.projects) == 0: projects = d.keys() else: projects = args.projects for proj in projects: build_dir = get_build_dir(ws, proj) if not os.path.isdir(build_dir): raise WSError('build directory for %s doesn\'t exist; have ' 'you built it yet?' % proj) if 'tests' not in d[proj]: raise WSError('no test configured for %s' % proj) for proj in projects: log('testing %s' % proj) build_env = get_build_env(ws, d, proj) cmds = d[proj]['tests'] _test(args.root, ws, proj, cmds, build_env)
def do(cls, _, args): '''Executes the list subcmd.''' if args.list_workspaces: dirs = os.listdir(args.root) for ws in dirs: if ws == get_default_ws_name(): continue if ws == get_manifest_link_name(): continue print(ws) else: d = parse_manifest(args.root) for proj in d: print(proj)
def do(cls, ws, args): '''Executes the clean command.''' # Validate. d = parse_manifest(args.root) for project in args.projects: if project not in d: raise WSError('unknown project %s' % project) if len(args.projects) == 0: projects = d.keys() else: projects = args.projects for project in projects: clean(args.root, ws, project, d, args.force)
def do(cls, ws, args): '''Executes the env command.''' build_dir = get_build_dir(ws, args.project) if not os.path.isdir(build_dir): raise WSError('build directory for %s doesn\'t exist; have you ' 'built it yet?' % args.project) d = parse_manifest(args.root) build_env = get_build_env(ws, d, args.project, True) # Add the build directory to the path for convenience of running # non-installed binaries, such as unit tests. merge_var(build_env, 'PATH', [build_dir]) if len(args.command) > 0: cmd = args.command else: cmd = [get_shell()] exe = os.path.basename(cmd[0]) if exe == 'bash': # Tweak the prompt to make it obvious we're in a special env. prompt = ( '\\[\033[1;32m\\][ws:%s env]\\[\033[m\\] \\u@\\h:\\w\\$ ' # noqa: E501 % args.project) build_env['PS1'] = prompt cmd.insert(1, '--norc') # Set an env var so the user can easily cd $WSBUILD and run tests or # similar inside the build directory. build_env['WSBUILD'] = build_dir log('execing with %s build environment: %s' % (args.project, cmd)) if args.build_dir: args.current_dir = build_dir if args.current_dir is not None: os.chdir(args.current_dir) os.execvpe(cmd[0], cmd, build_env)
def do(cls, ws, args): '''Executes the config command.''' config = get_ws_config(ws) if args.list: print(yaml.dump(config, default_flow_style=False), end='') return for arg in args.options: split = arg.split('=') split_len = len(split) key = split[0] if split_len == 1: val = None elif split_len == 2: val = split[1] else: val = '='.join(split[1:]) project = args.project if project is not None: # Project-specific option. d = parse_manifest(args.root) if project not in d: raise WSError('project "%s" not found' % project) can_taint = False if key == 'enable': val = parse_bool_val(val) can_taint = True elif key == 'args': val = parse_build_args(val) if val is None: raise WSError('build args are not in the right format ' '("args=key=val")') can_taint = True else: raise WSError('project key "%s" not found' % key) try: proj_config = config['projects'][project] except KeyError: proj_config = {} config['projects'][project] = proj_config if can_taint and proj_config[key] != val: log('tainting project %s' % project) proj_config['taint'] = True proj_config[key] = val else: # Global option. if key == 'type': if val is None or val not in BUILD_TYPES: raise WSError('"type" key must be one of %s' % str(BUILD_TYPES)) if config[key] != val: for proj_config in config['projects'].values(): proj_config['taint'] = True config[key] = val