#!/usr/bin/env python
#
# change-svn-wc-format.py: Change the format of a Subversion working copy.
#
# ====================================================================
#    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.
# ====================================================================

import sys
import os
import getopt
import stat
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt

### The entries file parser in subversion/tests/cmdline/svntest/entry.py
### handles the XML-based WC entries file format used by Subversion
### 1.3 and lower.  It could be rolled into this script.

LATEST_FORMATS = { "1.4" : 8,
                   "1.5" : 9,
                   "1.6" : 10,
                   # Do NOT add format 11 here.  See comment in must_retain_fields
                   # for why.
                 }

def usage_and_exit(error_msg=None):
  """Write usage information and exit.  If ERROR_MSG is provide, that
  error message is printed first (to stderr), the usage info goes to
  stderr, and the script exits with a non-zero status.  Otherwise,
  usage info goes to stdout and the script exits with a zero status."""
  progname = os.path.basename(sys.argv[0])

  stream = error_msg and sys.stderr or sys.stdout
  if error_msg:
    stream.write("ERROR: %s\n\n" % error_msg)
  stream.write("""\
usage: %s WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format]
       %s --help

Change the format of a Subversion working copy to that of SVN_VERSION.

  --skip-unknown-format    : skip directories with unknown working copy
                             format and continue the update

""" % (progname, progname))
  stream.flush()
  sys.exit(error_msg and 1 or 0)

def get_adm_dir():
  """Return the name of Subversion's administrative directory,
  adjusted for the SVN_ASP_DOT_NET_HACK environment variable.  See
  <http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt>
  for details."""
  return "SVN_ASP_DOT_NET_HACK" in os.environ and "_svn" or ".svn"

class WCFormatConverter:
  "Performs WC format conversions."
  root_path = None
  error_on_unrecognized = True
  force = False
  verbosity = 0

  def write_dir_format(self, format_nbr, dirname, paths):
    """Attempt to write the WC format FORMAT_NBR to the entries file
    for DIRNAME.  Throws LossyConversionException when not in --force
    mode, and unconvertable WC data is encountered."""

    # Avoid iterating in unversioned directories.
    if not (get_adm_dir() in paths):
      del paths[:]
      return

    # Process the entries file for this versioned directory.
    if self.verbosity:
      print("Processing directory '%s'" % dirname)
    entries = Entries(os.path.join(dirname, get_adm_dir(), "entries"))
    entries_parsed = True
    if self.verbosity:
      print("Parsing file '%s'" % entries.path)
    try:
      entries.parse(self.verbosity)
    except UnrecognizedWCFormatException as e:
      if self.error_on_unrecognized:
        raise
      sys.stderr.write("%s, skipping\n" % e)
      sys.stderr.flush()
      entries_parsed = False

    if entries_parsed:
      format = Format(os.path.join(dirname, get_adm_dir(), "format"))
      if self.verbosity:
        print("Updating file '%s'" % format.path)
      format.write_format(format_nbr, self.verbosity)
    else:
      if self.verbosity:
        print("Skipping file '%s'" % format.path)

    if self.verbosity:
      print("Checking whether WC format can be converted")
    try:
      entries.assert_valid_format(format_nbr, self.verbosity)
    except LossyConversionException as e:
      # In --force mode, ignore complaints about lossy conversion.
      if self.force:
        print("WARNING: WC format conversion will be lossy. Dropping "\
              "field(s) %s " % ", ".join(e.lossy_fields))
      else:
        raise

    if self.verbosity:
      print("Writing WC format")
    entries.write_format(format_nbr)

  def change_wc_format(self, format_nbr):
    """Walk all paths in a WC tree, and change their format to
    FORMAT_NBR.  Throw LossyConversionException or NotImplementedError
    if the WC format should not be converted, or is unrecognized."""
    for dirpath, dirs, files in os.walk(self.root_path):
      self.write_dir_format(format_nbr, dirpath, dirs + files)

class Entries:
  """Represents a .svn/entries file.

  'The entries file' section in subversion/libsvn_wc/README is a
  useful reference."""

  # The name and index of each field composing an entry's record.
  entry_fields = (
    "name",
    "kind",
    "revision",
    "url",
    "repos",
    "schedule",
    "text-time",
    "checksum",
    "committed-date",
    "committed-rev",
    "last-author",
    "has-props",
    "has-prop-mods",
    "cachable-props",
    "present-props",
    "conflict-old",
    "conflict-new",
    "conflict-wrk",
    "prop-reject-file",
    "copied",
    "copyfrom-url",
    "copyfrom-rev",
    "deleted",
    "absent",
    "incomplete",
    "uuid",
    "lock-token",
    "lock-owner",
    "lock-comment",
    "lock-creation-date",
    "changelist",
    "keep-local",
    "working-size",
    "depth",
    "tree-conflicts",
    "file-external",
  )

  # The format number.
  format_nbr = -1

  # How many bytes the format number takes in the file.  (The format number
  # may have leading zeroes after using this script to convert format 10 to
  # format 9 -- which would write the format number as '09'.)
  format_nbr_bytes = -1

  def __init__(self, path):
    self.path = path
    self.entries = []

  def parse(self, verbosity=0):
    """Parse the entries file.  Throw NotImplementedError if the WC
    format is unrecognized."""

    input = open(self.path, "r")

    # Read WC format number from INPUT.  Validate that it
    # is a supported format for conversion.
    format_line = input.readline()
    try:
      self.format_nbr = int(format_line)
      self.format_nbr_bytes = len(format_line.rstrip()) # remove '\n'
    except ValueError:
      self.format_nbr = -1
      self.format_nbr_bytes = -1
    if not self.format_nbr in LATEST_FORMATS.values():
      raise UnrecognizedWCFormatException(self.format_nbr, self.path)

    # Parse file into individual entries, to later inspect for
    # non-convertable data.
    entry = None
    while True:
      entry = self.parse_entry(input, verbosity)
      if entry is None:
        break
      self.entries.append(entry)

    input.close()

  def assert_valid_format(self, format_nbr, verbosity=0):
    if verbosity >= 2:
      print("Validating format for entries file '%s'" % self.path)
    for entry in self.entries:
      if verbosity >= 3:
        print("Validating format for entry '%s'" % entry.get_name())
      try:
        entry.assert_valid_format(format_nbr)
      except LossyConversionException:
        if verbosity >= 3:
          sys.stderr.write("Offending entry:\n%s\n" % entry)
          sys.stderr.flush()
        raise

  def parse_entry(self, input, verbosity=0):
    "Read an individual entry from INPUT stream."
    entry = None

    while True:
      line = input.readline()
      if line in ("", "\x0c\n"):
        # EOF or end of entry terminator encountered.
        break

      if entry is None:
        entry = Entry()

      # Retain the field value, ditching its field terminator ("\x0a").
      entry.fields.append(line[:-1])

    if entry is not None and verbosity >= 3:
      sys.stdout.write(str(entry))
      print("-" * 76)
    return entry

  def write_format(self, format_nbr):
    # Overwrite all bytes of the format number (which are the first bytes in
    # the file).  Overwrite format '10' by format '09', which will be converted
    # to '9' by Subversion when it rewrites the file.  (Subversion 1.4 and later
    # ignore leading zeroes in the format number.)
    assert len(str(format_nbr)) <= self.format_nbr_bytes
    format_string = '%0' + str(self.format_nbr_bytes) + 'd'

    os.chmod(self.path, stat.S_IRUSR | stat.S_IWUSR)
    output = open(self.path, "r+", 0)
    output.write(format_string % format_nbr)
    output.close()
    os.chmod(self.path, stat.S_IRUSR)

class Entry:
  "Describes an entry in a WC."

  # Maps format numbers to indices of fields within an entry's record that must
  # be retained when downgrading to that format.
  must_retain_fields = {
      # Not in 1.4: changelist, keep-local, depth, tree-conflicts, file-externals
      8  : (30, 31, 33, 34, 35),
      # Not in 1.5: tree-conflicts, file-externals
      9  : (34, 35),
      10 : (),
      # Downgrading from format 11 (1.7-dev) to format 10 is not possible,
      # because 11 does not use has-props and cachable-props (but 10 does).
      # Naively downgrading in that situation causes properties to disappear
      # from the wc.
      #
      # Downgrading from the 1.7 SQLite-based format to format 10 is not
      # implemented.
      }

  def __init__(self):
    self.fields = []

  def assert_valid_format(self, format_nbr):
    "Assure that conversion will be non-lossy by examining fields."

    # Check whether lossy conversion is being attempted.
    lossy_fields = []
    for field_index in self.must_retain_fields[format_nbr]:
      if len(self.fields) - 1 >= field_index and self.fields[field_index]:
        lossy_fields.append(Entries.entry_fields[field_index])
    if lossy_fields:
      raise LossyConversionException(lossy_fields,
        "Lossy WC format conversion requested for entry '%s'\n"
        "Data for the following field(s) is unsupported by older versions "
        "of\nSubversion, and is likely to be subsequently discarded, and/or "
        "have\nunexpected side-effects: %s\n\n"
        "WC format conversion was cancelled, use the --force option to "
        "override\nthe default behavior."
        % (self.get_name(), ", ".join(lossy_fields)))

  def get_name(self):
    "Return the name of this entry."
    return len(self.fields) > 0 and self.fields[0] or ""

  def __str__(self):
    "Return all fields from this entry as a multi-line string."
    rep = ""
    for i in range(0, len(self.fields)):
      rep += "[%s] %s\n" % (Entries.entry_fields[i], self.fields[i])
    return rep

class Format:
  """Represents a .svn/format file."""

  def __init__(self, path):
    self.path = path

  def write_format(self, format_nbr, verbosity=0):
    format_string = '%d\n'
    if os.path.exists(self.path):
      if verbosity >= 1:
        print("%s will be updated." % self.path)
      os.chmod(self.path, stat.S_IRUSR | stat.S_IWUSR)
    else:
      if verbosity >= 1:
        print("%s does not exist, creating it." % self.path)
    format = open(self.path, "w")
    format.write(format_string % format_nbr)
    format.close()
    os.chmod(self.path, stat.S_IRUSR)

class LocalException(Exception):
  """Root of local exception class hierarchy."""
  pass

class LossyConversionException(LocalException):
  "Exception thrown when a lossy WC format conversion is requested."
  def __init__(self, lossy_fields, str):
    self.lossy_fields = lossy_fields
    self.str = str
  def __str__(self):
    return self.str

class UnrecognizedWCFormatException(LocalException):
  def __init__(self, format, path):
    self.format = format
    self.path = path
  def __str__(self):
    return ("Unrecognized WC format %d in '%s'; "
            "only formats 8, 9, and 10 can be supported") % (self.format, self.path)


def main():
  try:
    opts, args = my_getopt(sys.argv[1:], "vh?",
                           ["debug", "force", "skip-unknown-format",
                            "verbose", "help"])
  except:
    usage_and_exit("Unable to process arguments/options")

  converter = WCFormatConverter()

  # Process arguments.
  if len(args) == 2:
    converter.root_path = args[0]
    svn_version = args[1]
  else:
    usage_and_exit()

  # Process options.
  debug = False
  for opt, value in opts:
    if opt in ("--help", "-h", "-?"):
      usage_and_exit()
    elif opt == "--force":
      converter.force = True
    elif opt == "--skip-unknown-format":
      converter.error_on_unrecognized = False
    elif opt in ("--verbose", "-v"):
      converter.verbosity += 1
    elif opt == "--debug":
      debug = True
    else:
      usage_and_exit("Unknown option '%s'" % opt)

  try:
    new_format_nbr = LATEST_FORMATS[svn_version]
  except KeyError:
    usage_and_exit("Unsupported version number '%s'; "
                   "only 1.4, 1.5, and 1.6 can be supported" % svn_version)

  try:
    converter.change_wc_format(new_format_nbr)
  except LocalException as e:
    if debug:
      raise
    sys.stderr.write("%s\n" % e)
    sys.stderr.flush()
    sys.exit(1)

  print("Converted WC at '%s' into format %d for Subversion %s" % \
        (converter.root_path, new_format_nbr, svn_version))

if __name__ == "__main__":
  main()
