Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
    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))
Exemple #5
0
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