Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove obselete files.
[simgrid.git] / buildtools / scripts / change-svn-wc-format.py
diff --git a/buildtools/scripts/change-svn-wc-format.py b/buildtools/scripts/change-svn-wc-format.py
deleted file mode 100755 (executable)
index 796adb0..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-#!/usr/bin/env python
-#
-# change-svn-wc-format.py: Change the format of a Subversion working copy.
-#
-# ====================================================================
-#    Licensed to the Subversion Corporation (SVN Corp.) under one
-#    or more contributor license agreements.  See the NOTICE file
-#    distributed with this work for additional information
-#    regarding copyright ownership.  The SVN Corp. 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
-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.collab.net/repos/svn/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, 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, 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, 0600)
-    output = open(self.path, "r+", 0)
-    output.write(format_string % format_nbr)
-    output.close()
-    os.chmod(self.path, 0400)
-
-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,0600)
-    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, 0400)
-
-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, 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()