#!/usr/bin/env python

# To do:
# 1) Switch to using the Subversion Python bindings.
#
# $HeadURL$
# $LastChangedRevision$
# $LastChangedDate$
# $LastChangedBy$
#
# Copyright (C) 2005,2006 Blair Zajac <blair@orcaware.com>
#
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This script is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# A copy of the GNU General Public License can be obtained by writing
# to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA.

import getopt
import fnmatch
import os
import re
import sys

# The default path to the Subversion configuration file.
SVN_CONFIG_FILENAME = os.path.expandvars('$HOME/.subversion/config')

# The name of Subversion's private directory in working copies.
SVN_WC_ADM_DIR_NAME = '.svn'

# The name this script was invoked as.
PROGNAME = os.path.basename(sys.argv[0])

def usage():
  print("""This script reads the auto-properties defined in the file
'%s'
and applies them recursively to all the files and directories in the
current working copy.  It may behave differently than the Subversion
command line; where the subversion command line may only apply a single
matching auto-property to a single pathname, this script will apply all
matching lines to a single pathname.

Usage:
  %s [options] [WC_PATH]
where WC_PATH is the path to a working copy.
If WC_PATH is not specified, '.' is assumed.

Valid options are:
  --help, -h         : Print this help text.
  --config ARG       : Read the Subversion config file at path ARG
                       instead of '%s'.
""" % (SVN_CONFIG_FILENAME, PROGNAME, SVN_CONFIG_FILENAME))

def get_autoprop_lines(fd):
  lines = []
  reading_autoprops = 0

  re_start_autoprops = re.compile('^\s*\[auto-props\]\s*')
  re_end_autoprops = re.compile('^\s*\[\w+\]\s*')

  for line in fd.xreadlines():
    if reading_autoprops:
      if re_end_autoprops.match(line):
        reading_autoprops = 0
        continue
    else:
      if re_start_autoprops.match(line):
        reading_autoprops = 1
        continue

    if reading_autoprops:
      lines += [line]

  return lines

def process_autoprop_lines(lines):
  result = []

  for line in lines:
    # Split the line on the = separating the fnmatch string from the
    # properties.
    try:
      (fnmatch, props) = line.split('=', 1)
    except ValueError:
      continue

    # Remove leading and trailing whitespace from the fnmatch and
    # properties.
    fnmatch = fnmatch.strip()
    props = props.strip()

    # Create a list of property name and property values.  Remove all
    # leading and trailing whitespce from the propery names and
    # values.
    props_list = []
    for prop in props.split(';'):
      prop = prop.strip()
      if not len(prop):
        continue
      try:
        (prop_name, prop_value) = prop.split('=', 1)
        prop_name = prop_name.strip()
        prop_value = prop_value.strip()
      except ValueError:
        prop_name = prop
        prop_value = '*'
      if len(prop_name):
        props_list += [(prop_name, prop_value)]

    result += [(fnmatch, props_list)]

  return result

def filter_walk(autoprop_lines, dirname, filenames):
  # Do not descend into a .svn directory.
  try:
    filenames.remove(SVN_WC_ADM_DIR_NAME)
  except ValueError:
    pass

  filenames.sort()

  # Find those filenames that match each fnmatch.
  for autoprops_line in autoprop_lines:
    fnmatch_str = autoprops_line[0]
    prop_list = autoprops_line[1]

    matching_filenames = fnmatch.filter(filenames, fnmatch_str)
    matching_filenames = [f for f in matching_filenames \
      if not os.path.islink(os.path.join(dirname, f))]
    if not matching_filenames:
      continue

    for prop in prop_list:
      command = ['svn', 'propset', prop[0], prop[1]]
      for f in matching_filenames:
        command += ["%s/%s" % (dirname, f)]

      status = os.spawnvp(os.P_WAIT, 'svn', command)
      if status:
        print('Command %s failed with exit status %s' \
              % (command, status))

def main():
  try:
    opts, args = getopt.getopt(sys.argv[1:], 'h', ['help', 'config='])
  except getopt.GetoptError as e:
    usage()
    return 1

  config_filename = None
  for (o, a) in opts:
    if o == '-h' or o == '--help':
      usage()
      return 0
    elif o == '--config':
      config_filename = os.path.abspath(a)

  if not config_filename:
    config_filename = SVN_CONFIG_FILENAME

  if len(args) == 0:
    wc_path = '.'
  elif len(args) == 1:
    wc_path = args[0]
  else:
    usage()
    print("Too many arguments: %s" % ' '.join(args))
    return 1

  try:
    fd = file(config_filename)
  except IOError:
    print("Cannot open svn configuration file '%s' for reading: %s" \
          % (config_filename, sys.exc_value.strerror))
    return 1

  autoprop_lines = get_autoprop_lines(fd)

  fd.close()

  autoprop_lines = process_autoprop_lines(autoprop_lines)

  os.path.walk(wc_path, filter_walk, autoprop_lines)

if __name__ == '__main__':
  sys.exit(main())
