#coding:utf-8 import traceback import os import json from zipfile import ZipFile from xml.dom.minidom import parse import xml.dom.minidom import shutil '''用于比对出APP的依赖与平台的commmonlib的脚本''' class CompareDependency(object): #appname:app名称,如bsa_ata #apppath:打包平台上此时app的绝对路径 #jarpath:需比对的app jar文件的绝对路径 #depath:平台de文件所在的绝对路径 #name:文件名;启动job/进程时的依赖需要从中读取 def __init__(self, appname, apppath, jarpath, depath, name): self.bsaroot = "${BSA_HOME}" self.platform_libpath = self.bsaroot + "/libs/Java/commonLibs" self.jarpath = jarpath self.depath = depath self.name = name self.pom_path = os.path.dirname(os.path.dirname(self.jarpath)) + "/pom.xml" self.lib_path = os.path.dirname(self.jarpath) + "/lib" self.apppath = apppath self.appname = appname def parse_manifest(self, cpath): '''解析MANIFEST.MF文件''' ls = list() f = ZipFile(cpath) try: content = f.read("META-INF/MANIFEST.MF").split("\n") content_ls = list() start = False for line in content: if line.startswith("Class-Path:"): content_ls.append(line.replace("Class-Path:", "").replace("\r", "").replace("\n", "")) start = True else: if start: if line.find(':') != -1: break else: content_ls.append(line.replace("\r", "").replace("\n", "")[1:]) ls = ("".join(content_ls)).strip().split(" ") except Exception, e: traceback.print_exc() raise e finally: f.close() return ls def get_de_fullpath(self): '''根据依赖的dm版本得到de.jar的版本,从而得到绝对路径''' de_path = None try: if os.path.exists(self.pom_path): domtree = xml.dom.minidom.parse(self.pom_path) root = domtree.documentElement node1 = root.getElementsByTagName("dependencyManagement") node2 = node1[0].getElementsByTagName("dependencies") node3 = node2[0].getElementsByTagName("dependency") for item in node3: group = item.getElementsByTagName("groupId")[0].childNodes[0].nodeValue artifact = item.getElementsByTagName("artifactId")[0].childNodes[0].nodeValue if group == 'com.nsfocus.bsa' and artifact == 'dm': version = item.getElementsByTagName("version")[0].childNodes[0].nodeValue de_path = self.depath + "/de-%s.jar"%(version,) break except Exception, e: traceback.print_exc() raise e return de_path def compare(self): '''进行比对,并且输出结果;用于spark job和普通java进程''' app_de = self.parse_manifest(self.jarpath) platform_de_fullpath = self.get_de_fullpath() if platform_de_fullpath is not None: confdic = {"common":[], "privacy":[]} platform_de = self.parse_manifest(platform_de_fullpath) #可以使用平台的jar,取交集 common_jars = list(set(app_de) & set(platform_de)) #只能使用app自己的jar,取差集 diff_jars = list(set(app_de).difference(set(platform_de))) #app jar依赖的私有jar路径 privacy_jar_path = os.path.normpath(self.apppath + "/bin/lib/" + \ os.path.basename(self.jarpath).replace(".jar", "").replace("-","_").replace(".","")) if not os.path.exists(self.apppath + "/bin/lib"): os.mkdir(self.apppath + "/bin/lib") if not os.path.exists(privacy_jar_path): os.mkdir(privacy_jar_path) for item in diff_jars: items = item.split("@") srcpath = os.path.normpath(self.lib_path + "/" + items[0] + "." \ + items[1] + "-" + items[2] + ".jar") dstpath = os.path.normpath(privacy_jar_path + "/" + items[0] + "." \ + items[1] + "-" + items[2] + ".jar") shutil.copy(srcpath, dstpath) confdic["privacy"].append(os.path.normpath(dstpath.replace(os.path.normpath(self.apppath), \ self.bsaroot + "/apps/" + self.appname)).replace("\\", "/")) for item in common_jars: items = item.split("@") confdic["common"].append(self.platform_libpath + "/" + items[0] + "." \ + items[1]) confpath = self.apppath + "/conf/" + self.name open(confpath, "w").write(json.dumps(confdic)) print "write conf file:", confpath