def synchronize_dir()

in contrib/client-side/svn_export_empty_files.py [0:0]


def synchronize_dir(ctx, url, dir_name, revision, client_ctx):
    """Synchronize a directory given by a URL to a Subversion
    repository with a local directory located by the dir_name
    argument."""

    status = True

    # Determine if there is a path in the filesystem and if the path
    # is a directory or non-directory.
    local_path_kind = get_local_path_kind(dir_name)

    # If the path on the local filesystem is not a directory, then
    # delete it if deletes are enabled, otherwise return.
    if LOCAL_PATH_NON_DIR == local_path_kind:
        msg = ("'%s' which is a local non-directory but remotely a " +
               "directory") % dir_name
        if ctx.delete_local_paths:
            print("Removing", msg)
            os.unlink(dir_name)
            local_path_kind = LOCAL_PATH_NONE
        else:
            print("Need to remove", msg)
            ctx.delete_needed = True
            return False

    if LOCAL_PATH_NONE == local_path_kind:
        print("Creating directory '%s'" % dir_name)
        os.mkdir(dir_name)

    remote_ls = svn.client.ls(url,
                              revision,
                              0,
                              client_ctx)

    if ctx.verbose:
        print("Syncing '%s' to '%s'" % (url, dir_name))

    remote_pathnames = remote_ls.keys()
    remote_pathnames.sort()

    local_pathnames = os.listdir(dir_name)

    for remote_pathname in remote_pathnames:
        # For each name in the remote list, remove it from the local
        # list so that the remaining names may be deleted.
        try:
            local_pathnames.remove(remote_pathname)
        except ValueError:
            pass

        full_remote_pathname = os.path.join(dir_name, remote_pathname)

        if remote_pathname in ctx.ignore_names or \
               full_remote_pathname in ctx.ignore_paths:
            print("Skipping '%s'" % full_remote_pathname)
            continue

        # Get the remote path kind.
        remote_path_kind = remote_ls[remote_pathname].kind

        # If the remote path is a directory, then recursively handle
        # that here.
        if svn.core.svn_node_dir == remote_path_kind:
            s = synchronize_dir(ctx,
                                os.path.join(url, remote_pathname),
                                full_remote_pathname,
                                revision,
                                client_ctx)
            status &= s

        else:
            # Determine if there is a path in the filesystem and if
            # the path is a directory or non-directory.
            local_path_kind = get_local_path_kind(full_remote_pathname)

            # If the path exists on the local filesystem but its kind
            # does not match the kind in the Subversion repository,
            # then either remove it if the local paths should be
            # deleted or continue to the next path if deletes should
            # not be done.
            if LOCAL_PATH_DIR == local_path_kind:
                msg = ("'%s' which is a local directory but remotely a " +
                       "non-directory") % full_remote_pathname
                if ctx.delete_local_paths:
                    print("Removing", msg)
                    recursive_delete(full_remote_pathname)
                    local_path_kind = LOCAL_PATH_NONE
                else:
                    print("Need to remove", msg)
                    ctx.delete_needed = True
                    continue

            if LOCAL_PATH_NONE == local_path_kind:
                print("Creating file '%s'" % full_remote_pathname)
                f = file(full_remote_pathname, 'w')
                f.close()

    # Any remaining local paths should be removed.
    local_pathnames.sort()
    for local_pathname in local_pathnames:
        full_local_pathname = os.path.join(dir_name, local_pathname)
        if os.path.isdir(full_local_pathname):
            if ctx.delete_local_paths:
                print("Removing directory '%s'" % full_local_pathname)
                recursive_delete(full_local_pathname)
            else:
                print("Need to remove directory '%s'" % full_local_pathname)
                ctx.delete_needed = True
        else:
            if ctx.delete_local_paths:
                print("Removing file '%s'" % full_local_pathname)
                os.unlink(full_local_pathname)
            else:
                print("Need to remove file '%s'" % full_local_pathname)
                ctx.delete_needed = True

    return status