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 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 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, _, args): '''Executes the default command.''' link = get_default_ws_link(args.root) if args.default_ws is None: # Just report what the default currently is. dest = os.path.basename(os.path.realpath(link)) print(dest) return ws_dir = get_ws_dir(args.root, args.default_ws) remove(link) if not os.path.exists(ws_dir): raise WSError('Cannot make non-existent workspace %s the default' % args.default_ws) symlink(args.default_ws, link)
def do(cls, _, args): '''Executes the init command.''' if args.root is None: root = '.ws' else: root = args.root if args.init_ws is None: ws = 'ws' else: reserved = (get_default_ws_name(), get_manifest_link_name()) for name in reserved: if args.init_ws == name: raise WSError('%s is a reserved name; please choose a ' 'different name' % name) ws = args.init_ws if '.' in ws or '/' in ws: raise WSError('Workspace name "%s" contains an illegal ' 'character (. or /). Please use a different ' 'name.' % ws) ws_dir = get_ws_dir(root, ws) if os.path.exists(ws_dir): raise WSError('Cannot initialize already existing workspace %s' % ws) if args.manifest_source == 'repo': parent = os.path.join(root, os.pardir) repo_manifest = os.path.realpath( os.path.join(parent, '.repo', 'manifest.xml')) base = os.path.dirname(repo_manifest) elif args.manifest_source == 'fs': base = '.' else: raise NotImplementedError('Manifest source %s should be ' 'implemented' % args.manifest_source) manifest = os.path.join(base, args.manifest) if os.path.isdir(manifest): # If -m points to a directory instead of a file, assume there is a # file with the default manifest name inside. manifest = os.path.join(manifest, get_default_manifest_name()) # Use a relative path for anything inside the parent of .ws and an # absolute path for anything outside. This is to maximize # relocatability for groups of git repos (e.g. using submodules, # repo-tool, etc.). manifest = os.path.abspath(manifest) parent = os.path.realpath(os.path.join(root, os.pardir)) if _is_subdir(manifest, parent): manifest = os.path.relpath(manifest, root) else: manifest = os.path.abspath(manifest) # Make sure the given manifest is sane. if os.path.isabs(manifest): abs_manifest = manifest else: abs_manifest = os.path.abspath(os.path.join(root, manifest)) d = parse_manifest_file(root, abs_manifest) try: mkdir(root) new_root = True except OSError as e: if e.errno != errno.EEXIST: raise new_root = False try: mkdir(ws_dir) new_ws = True except OSError as e: if e.errno != errno.EEXIST: raise new_ws = False if new_ws: # This is a brand-new workspace, so populate the initial workspace # directories. mkdir(get_toplevel_build_dir(ws_dir)) mkdir(get_checksum_dir(ws_dir)) proj_map = dict((proj, {}) for proj in d) for proj in proj_map: proj_map[proj] = get_new_config(proj) config = {'type': args.type, 'projects': proj_map} write_config(ws_dir, config) if new_root: # This is a brand new root .ws directory, so populate the initial # symlink defaults. symlink(ws, get_default_ws_link(root)) symlink(manifest, get_manifest_link(root))