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