#!/usr/bin/env python
#
# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
# ====================================================================

"""\
__SCRIPTNAME__: checkout utility for sparse Subversion working copies

Usage: 1. __SCRIPTNAME__ checkout VIEWSPEC-FILE TARGET-DIR
       2. __SCRIPTNAME__ examine VIEWSPEC-FILE
       3. __SCRIPTNAME__ help
       4. __SCRIPTNAME__ help-format

VIEWSPEC-FILE is the path of a file whose contents describe a
Subversion sparse checkouts layout, or '-' if that description should
be read from stdin.  TARGET-DIR is the working copy directory created
by this script as it checks out the specified layout.

1. Parse VIEWSPEC-FILE and execute the necessary 'svn' command-line
   operations to build out a working copy tree at TARGET-DIR.

2. Parse VIEWSPEC-FILE and dump out a human-readable representation of
   the tree described in the specification.

3. Show this usage message.

4. Show information about the file format this program expects.

"""

FORMAT_HELP = """\
Viewspec File Format
====================

The viewspec file format used by this tool is a collection of headers
(using the typical one-per-line name:value syntax), followed by an
empty line, followed by a set of one-per-line rules.

The headers must contain at least the following:

    Format   - version of the viewspec format used throughout the file
    Url      - base URL applied to all rules; tree checkout location

The following headers are optional:

    Revision - version of the tree items to checkout

Following the headers and blank line separator are the path rules.
The rules are list of URLs -- relative to the base URL stated in the
headers -- with optional annotations to specify the desired working
copy depth of each item:

    PATH/**  - checkout PATH and all its children to infinite depth
    PATH/*   - checkout PATH and its immediate children
    PATH/~   - checkout PATH and its file children
    PATH     - checkout PATH non-recursively

By default, the top-level directory (associated with the base URL) is
checked out with empty depth.  You can override this using the special
rules '**', '*', and '~' as appropriate.

It is not necessary to explicitly list the parent directories of each
path associated with a rule.  If the parent directory of a given path
is not "covered" by a previous rule, it will be checked out with empty
depth.

Examples
========

Here's a sample viewspec file:

    Format: 1
    Url: http://svn.apache.org/repos/asf/subversion
    Revision: 36366

    trunk/**
    branches/1.5.x/**
    branches/1.6.x/**
    README
    branches/1.4.x/STATUS
    branches/1.4.x/subversion/tests/cmdline/~

You may wish to version your viewspec files.  If so, you can use this
script in conjunction with 'svn cat' to fetch, parse, and act on a
versioned viewspec file:

    $ svn cat http://svn.example.com/specs/dev-spec.txt |
         __SCRIPTNAME__ checkout - /path/to/target/directory

"""

#########################################################################
###  Possible future improvements that could be made:
###
###    - support for excluded paths (PATH!)
###    - support for static revisions of individual paths (PATH@REV/**)
###

import sys
import os
import urllib

DEPTH_EMPTY      = 'empty'
DEPTH_FILES      = 'files'
DEPTH_IMMEDIATES = 'immediates'
DEPTH_INFINITY   = 'infinity'

os_system = None
args = None

class TreeNode:
    """A representation of a single node in a Subversion sparse
    checkout tree."""

    def __init__(self, name, depth):
        self.name = name    # the basename of this tree item
        self.depth = depth  # its depth (one of the DEPTH_* values)
        self.children = {}  # its children (basename -> TreeNode)

    def add_child(self, child_node):
        child_name = child_node.name
        assert not self.children.has_key(child_node)
        self.children[child_name] = child_node

    def dump(self, recurse=False, indent=0):
        sys.stderr.write(" " * indent)
        sys.stderr.write("Path: %s (depth=%s)\n" % (self.name, self.depth))
        if recurse:
            child_names = self.children.keys()
            child_names.sort(svn_path_compare_paths)
            for child_name in child_names:
                self.children[child_name].dump(recurse, indent + 2)

class SubversionViewspec:
    """A representation of a Subversion sparse checkout specification."""

    def __init__(self, base_url, revision, tree):
        self.base_url = base_url  # base URL of the checkout
        self.revision = revision  # revision of the checkout (-1 == HEAD)
        self.tree = tree          # the top-most TreeNode item

def svn_path_compare_paths(path1, path2):
    """Compare PATH1 and PATH2 as paths, sorting depth-first-ily.

    NOTE: Stolen unapologetically from Subversion's Python bindings
    module svn.core."""

    path1_len = len(path1)
    path2_len = len(path2)
    min_len = min(path1_len, path2_len)
    i = 0

    # Are the paths exactly the same?
    if path1 == path2:
        return 0

    # Skip past common prefix
    while (i < min_len) and (path1[i] == path2[i]):
        i = i + 1

    # Children of paths are greater than their parents, but less than
    # greater siblings of their parents
    char1 = '\0'
    char2 = '\0'
    if (i < path1_len):
        char1 = path1[i]
    if (i < path2_len):
        char2 = path2[i]

    if (char1 == '/') and (i == path2_len):
        return 1
    if (char2 == '/') and (i == path1_len):
        return -1
    if (i < path1_len) and (char1 == '/'):
        return -1
    if (i < path2_len) and (char2 == '/'):
        return 1

    # Common prefix was skipped above, next character is compared to
    # determine order
    return cmp(char1, char2)

def parse_viewspec_headers(viewspec_fp):
    """Parse the headers from the viewspec file, return them as a
    dictionary mapping header names to values."""

    headers = {}
    while 1:
        line = viewspec_fp.readline().strip()
        if not line:
            break
        name, value = [x.strip() for x in line.split(':', 1)]
        headers[name] = value
    return headers

def parse_viewspec(viewspec_fp):
    """Parse the viewspec file, returning a SubversionViewspec object
    that represents the specification."""

    headers = parse_viewspec_headers(viewspec_fp)
    format = headers['Format']
    assert format == '1'
    base_url = headers['Url']
    revision = int(headers.get('Revision', -1))
    root_depth = DEPTH_EMPTY
    rules = {}
    while 1:
        line = viewspec_fp.readline()
        if not line:
            break
        line = line.rstrip()

        # These are special rules for the top-most dir; don't fall thru.
        if line == '**':
            root_depth = DEPTH_INFINITY
            continue
        elif line == '*':
            root_depth = DEPTH_IMMEDIATES
            continue
        elif line == '~':
            root_depth = DEPTH_FILES
            continue

        # These are the regular per-path rules.
        elif line[-3:] == '/**':
            depth = DEPTH_INFINITY
            path = line[:-3]
        elif line[-2:] == '/*':
            depth = DEPTH_IMMEDIATES
            path = line[:-2]
        elif line[-2:] == '/~':
            depth = DEPTH_FILES
            path = line[:-2]
        else:
            depth = DEPTH_EMPTY
            path = line

        # Add our rule to the set thereof.
        assert not rules.has_key(path)
        rules[path] = depth

    tree = TreeNode('', root_depth)
    paths = rules.keys()
    paths.sort(svn_path_compare_paths)
    for path in paths:
        depth = rules[path]
        path_parts = filter(None, path.split('/'))
        tree_ptr = tree
        for part in path_parts[:-1]:
            child_node = tree_ptr.children.get(part, None)
            if not child_node:
                child_node = TreeNode(part, DEPTH_EMPTY)
                tree_ptr.add_child(child_node)
            tree_ptr = child_node
        tree_ptr.add_child(TreeNode(path_parts[-1], depth))
    return SubversionViewspec(base_url, revision, tree)

def checkout_tree(base_url, revision, tree_node, target_dir, is_top=True):
    """Checkout from BASE_URL, and into TARGET_DIR, the TREE_NODE
    sparse checkout item.  IS_TOP is set iff this node represents the
    root of the checkout tree.  REVISION is the revision to checkout,
    or -1 if checking out HEAD."""

    depth = tree_node.depth
    revision_str = ''
    if revision != -1:
        revision_str = "--revision=%d " % (revision)
    if is_top:
        os_system('svn checkout "%s" "%s" --depth=%s %s'
                  % (base_url, target_dir, depth, revision_str))
    else:
        os_system('svn update "%s" --set-depth=%s %s'
                  % (target_dir, depth, revision_str))
    child_names = tree_node.children.keys()
    child_names.sort(svn_path_compare_paths)
    for child_name in child_names:
        checkout_tree(base_url + '/' + child_name,
                      revision,
                      tree_node.children[child_name],
                      os.path.join(target_dir, urllib.unquote(child_name)),
                      False)

def checkout_spec(viewspec, target_dir):
    """Checkout the view specification VIEWSPEC into TARGET_DIR."""

    checkout_tree(viewspec.base_url,
                  viewspec.revision,
                  viewspec.tree,
                  target_dir)

def usage_and_exit(errmsg=None):
    stream = errmsg and sys.stderr or sys.stdout
    msg = __doc__.replace("__SCRIPTNAME__", os.path.basename(args[0]))
    stream.write(msg)
    if errmsg:
        stream.write("ERROR: %s\n" % (errmsg))
        return 1
    return 0

def main(os_sys, args_in):
    global os_system
    global args
    os_system = os_sys
    args = args_in

    argc = len(args)
    if argc < 2:
        return usage_and_exit('Not enough arguments.')
    subcommand = args[1]
    if subcommand == 'help':
        return usage_and_exit()
    elif subcommand == 'help-format':
        msg = FORMAT_HELP.replace("__SCRIPTNAME__",
                                  os.path.basename(args[0]))
        sys.stdout.write(msg)
        return 1
    elif subcommand == 'examine':
        if argc < 3:
            return usage_and_exit('No viewspec file specified.')
        fp = (args[2] == '-') and sys.stdin or open(args[2], 'r')
        viewspec = parse_viewspec(fp)
        sys.stdout.write("Url: %s\n" % (viewspec.base_url))
        revision = viewspec.revision
        if revision != -1:
            sys.stdout.write("Revision: %s\n" % (revision))
        else:
            sys.stdout.write("Revision: HEAD\n")
        sys.stdout.write("\n")
        viewspec.tree.dump(True)
    elif subcommand == 'checkout':
        if argc < 3:
            return usage_and_exit('No viewspec file specified.')
        if argc < 4:
            return usage_and_exit('No target directory specified.')
        fp = (args[2] == '-') and sys.stdin or open(args[2], 'r')
        checkout_spec(parse_viewspec(fp), args[3])
    else:
        return usage_and_exit('Unknown subcommand "%s".' % (subcommand))

if __name__ == "__main__":
    if main(os.system, sys.argv):
        sys.exit(1)
