Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/python
      2 
      3 """
      4 Packages a new maven release.
      5 """
      6 
      7 import os
      8 import re
      9 import shutil
     10 import subprocess
     11 import sys
     12 import xml.dom.minidom
     13 
     14 def mime_type_from_path(path):
     15   if path.endswith(".pom"):
     16     return "text/xml;charset=UTF-8"
     17   elif path.endswith(".jar"):
     18     return "application/java-archive"
     19   return None
     20 
     21 if "__main__" == __name__:
     22   # Compute directories relative to tools.
     23   trunk_directory_path = os.path.realpath(os.path.join(
     24     os.path.dirname(sys.argv[0]),
     25     ".."))
     26   maven_directory_path = os.path.realpath(os.path.join(
     27     os.path.dirname(sys.argv[0]),
     28     "..",
     29     "..",
     30     "maven",
     31     "owasp-java-html-sanitizer",
     32     "owasp-java-html-sanitizer"))
     33   maven_metadata_path = os.path.join(
     34     maven_directory_path,
     35     "maven-metadata.xml")
     36   version_template_directory_path = os.path.join(
     37     maven_directory_path,
     38     "+++version+++")
     39   jar_path = os.path.join(
     40     trunk_directory_path,
     41     "distrib",
     42     "lib",
     43     "owasp-java-html-sanitizer.jar")
     44   src_jar_path = os.path.join(
     45     trunk_directory_path,
     46     "distrib",
     47     "lib",
     48     "owasp-java-html-sanitizer-sources.jar")
     49   doc_jar_path = os.path.join(
     50     trunk_directory_path,
     51     "distrib",
     52     "lib",
     53     "owasp-java-html-sanitizer-javadoc.jar")
     54 
     55   # Make sure the directory_structures we expect exist.
     56   assert os.path.isdir(maven_directory_path), maven_directory_path
     57   assert os.path.isdir(trunk_directory_path), trunk_directory_path
     58   assert os.path.isfile(maven_metadata_path), maven_metadata_path
     59   assert os.path.isdir(version_template_directory_path), (
     60          version_template_directory_path)
     61   assert os.path.isfile(jar_path), jar_path
     62   assert os.path.isfile(src_jar_path), src_jar_path
     63   assert os.path.isfile(doc_jar_path), doc_jar_path
     64 
     65   # Get svn info of the trunk directory.
     66   svn_info_xml = (
     67      subprocess.Popen(["svn", "info", "--xml", trunk_directory_path],
     68                       stdout=subprocess.PIPE)
     69     .communicate()[0])
     70   svn_info = xml.dom.minidom.parseString(svn_info_xml)
     71 
     72   # Process SVN output XML to find fields.
     73   date_element = svn_info.getElementsByTagName("date")[0]
     74   entry_element = svn_info.getElementsByTagName("entry")[0]
     75   def inner_text(node):
     76     if node.nodeType == 3: return node.nodeValue
     77     if node.nodeType == 1:
     78       return "".join([inner_text(child) for child in node.childNodes])
     79     return ""
     80 
     81   # Create a list of fields to use in substitution.
     82   fields = {
     83     "version": "r%s" % entry_element.getAttribute("revision"),
     84     "timestamp": re.sub(r"[^.\d]|\.\d+", "", inner_text(date_element))
     85   }
     86 
     87   def replace_fields(s):
     88     return re.sub(r"\+\+\+(\w+)\+\+\+", lambda m: fields[m.group(1)], s)
     89 
     90   # List of files that need to have ##DUPE## and ##REPLACE## sections expanded
     91   # NOTE(12 February 2013): We no longer rewrite maven_metadata_path since this
     92   # project is now hosted in Maven Central, and maven_metadata used a
     93   # groupId/artifactId pair that is incompatible with the convention used by
     94   # Maven Central.
     95   # All maven versions after 12 February are undiscoverable by looking at
     96   # maven_metadata.
     97   files_to_rewrite = []
     98   new_file_paths = []
     99 
    100   def copy_directory_structure_template(src_path, container_path):
    101     dest_path = os.path.join(
    102       container_path,
    103       replace_fields(os.path.basename(src_path)))
    104     if os.path.isdir(src_path):
    105       os.mkdir(dest_path)
    106       for child in os.listdir(src_path):
    107         # Skip .svn directories.
    108         if "." == child[0:1]: continue
    109         copy_directory_structure_template(
    110           os.path.join(src_path, child), dest_path)
    111     else:
    112       shutil.copyfile(src_path, dest_path)
    113       mime_type = mime_type_from_path(dest_path)
    114       if mime_type is None or mime_type.startswith("text/"):
    115         files_to_rewrite.append(dest_path)
    116       new_file_paths.append(dest_path)
    117     return dest_path
    118 
    119   def rewrite_file(path):
    120     lines = []
    121     in_file = open(path, "r")
    122     try:
    123       file_content = in_file.read()
    124     finally:
    125       in_file.close()
    126     for line in file_content.split("\n"):
    127       indentation = re.match(r"^\s*", line).group()
    128       matches = re.findall(r"(<!--##REPLACE##(.*)##END##-->)", line)
    129       if len(matches) >= 2: raise Error("%s: %s" % (path, line))
    130       if len(matches):
    131         match = matches[0]
    132         line = "%s%s %s" % (indentation, replace_fields(match[1]), match[0])
    133       else:
    134         matches = re.findall("##DUPE##(.*)##END##", line)
    135         if len(matches) >= 2: raise Error("%s: %s" % (path, line))
    136         if len(matches):
    137           match = matches[0]
    138           lines.append("%s%s" % (indentation, replace_fields(match)))
    139       lines.append(line)
    140     out_file = open(path, "w")
    141     try:
    142       out_file.write("\n".join(lines))
    143     finally:
    144       out_file.close()
    145 
    146   versioned_jar_path = os.path.join(
    147     version_template_directory_path,
    148     "owasp-java-html-sanitizer-+++version+++.jar")
    149   versioned_src_jar_path = os.path.join(
    150     version_template_directory_path,
    151     "owasp-java-html-sanitizer-+++version+++-sources.jar")
    152   versioned_doc_jar_path = os.path.join(
    153     version_template_directory_path,
    154     "owasp-java-html-sanitizer-+++version+++-javadoc.jar")
    155 
    156   shutil.copyfile(jar_path, versioned_jar_path)
    157   shutil.copyfile(src_jar_path, versioned_src_jar_path)
    158   shutil.copyfile(doc_jar_path, versioned_doc_jar_path)
    159   ok = False
    160   version_directory_path = None
    161   try:
    162     version_directory_path = copy_directory_structure_template(
    163       version_template_directory_path, maven_directory_path)
    164     for file_to_rewrite in files_to_rewrite:
    165       rewrite_file(file_to_rewrite)
    166     ok = True
    167   finally:
    168     os.unlink(versioned_jar_path)
    169     os.unlink(versioned_src_jar_path)
    170     os.unlink(versioned_doc_jar_path)
    171     if not ok and version_directory_path is not None:
    172       shutil.rmtree(version_directory_path)
    173 
    174   print "svn add '%s'" % version_directory_path
    175 
    176   for new_file_path in new_file_paths:
    177     mime_type = mime_type_from_path(new_file_path)
    178     if mime_type is not None:
    179       print "svn propset svn:mime-type '%s' '%s'" % (mime_type, new_file_path)
    180