comparison mxtool/mx.py @ 15236:c8d4ace5b78c

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 18 Apr 2014 14:14:48 +0200
parents 7be43cbf3568
children 1ea79f17ab95
comparison
equal deleted inserted replaced
15235:27afd57655ba 15236:c8d4ace5b78c
83 return self.name 83 return self.name
84 84
85 def add_update_listener(self, listener): 85 def add_update_listener(self, listener):
86 self.update_listeners.add(listener) 86 self.update_listeners.add(listener)
87 87
88 def make_archive(self):
89 # are sources combined into main archive?
90 unified = self.path == self.sourcesPath
91
92 with Archiver(self.path) as arc, Archiver(None if unified else self.sourcesPath) as srcArcRaw:
93 srcArc = arc if unified else srcArcRaw
94 services = {}
95 def overwriteCheck(zf, arcname, source):
96 if not hasattr(zf, '_provenance'):
97 zf._provenance = {}
98 existingSource = zf._provenance.get(arcname, None)
99 if existingSource and existingSource != source and not arcname.endswith('/'):
100 log('warning: ' + self.path + ': overwriting ' + arcname + '\n new: ' + source + '\n old: ' + existingSource)
101 zf._provenance[arcname] = source
102
103 for dep in self.sorted_deps(includeLibs=True):
104 if dep.isLibrary():
105 l = dep
106 # merge library jar into distribution jar
107 logv('[' + self.path + ': adding library ' + l.name + ']')
108 lpath = l.get_path(resolve=True)
109 libSourcePath = l.get_source_path(resolve=True)
110 if lpath:
111 with zipfile.ZipFile(lpath, 'r') as lp:
112 for arcname in lp.namelist():
113 if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/':
114 service = arcname[len('META-INF/services/'):]
115 assert '/' not in service
116 services.setdefault(service, []).extend(lp.read(arcname).splitlines())
117 else:
118 overwriteCheck(arc.zf, arcname, lpath + '!' + arcname)
119 arc.zf.writestr(arcname, lp.read(arcname))
120 if srcArc.zf and libSourcePath:
121 with zipfile.ZipFile(libSourcePath, 'r') as lp:
122 for arcname in lp.namelist():
123 overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname)
124 srcArc.zf.writestr(arcname, lp.read(arcname))
125 else:
126 p = dep
127 # skip a Java project if its Java compliance level is "higher" than the configured JDK
128 jdk = java(p.javaCompliance)
129 if not jdk:
130 log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, self.path))
131 continue
132
133 logv('[' + self.path + ': adding project ' + p.name + ']')
134 outputDir = p.output_dir()
135 for root, _, files in os.walk(outputDir):
136 relpath = root[len(outputDir) + 1:]
137 if relpath == join('META-INF', 'services'):
138 for service in files:
139 with open(join(root, service), 'r') as fp:
140 services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
141 elif relpath == join('META-INF', 'providers'):
142 for provider in files:
143 with open(join(root, provider), 'r') as fp:
144 for service in fp:
145 services.setdefault(service.strip(), []).append(provider)
146 else:
147 for f in files:
148 arcname = join(relpath, f).replace(os.sep, '/')
149 overwriteCheck(arc.zf, arcname, join(root, f))
150 arc.zf.write(join(root, f), arcname)
151 if srcArc.zf:
152 sourceDirs = p.source_dirs()
153 if p.source_gen_dir():
154 sourceDirs.append(p.source_gen_dir())
155 for srcDir in sourceDirs:
156 for root, _, files in os.walk(srcDir):
157 relpath = root[len(srcDir) + 1:]
158 for f in files:
159 if f.endswith('.java'):
160 arcname = join(relpath, f).replace(os.sep, '/')
161 overwriteCheck(srcArc.zf, arcname, join(root, f))
162 srcArc.zf.write(join(root, f), arcname)
163
164 for service, providers in services.iteritems():
165 arcname = 'META-INF/services/' + service
166 arc.zf.writestr(arcname, '\n'.join(providers))
167
168 self.notify_updated()
169
170
88 def notify_updated(self): 171 def notify_updated(self):
89 for l in self.update_listeners: 172 for l in self.update_listeners:
90 l(self) 173 l(self)
91 174
92 """ 175 """
356 os.mkdir(dirname(currentApsFile)) 439 os.mkdir(dirname(currentApsFile))
357 with open(currentApsFile, 'w') as fp: 440 with open(currentApsFile, 'w') as fp:
358 for ap in aps: 441 for ap in aps:
359 print >> fp, ap 442 print >> fp, ap
360 return outOfDate 443 return outOfDate
444
445 def make_archive(self, path=None):
446 outputDir = self.output_dir()
447 if not path:
448 path = join(self.dir, self.name + '.jar')
449 with Archiver(path) as arc:
450 for root, _, files in os.walk(outputDir):
451 for f in files:
452 relpath = root[len(outputDir) + 1:]
453 arcname = join(relpath, f).replace(os.sep, '/')
454 arc.zf.write(join(root, f), arcname)
455 return path
361 456
362 def _make_absolute(path, prefix): 457 def _make_absolute(path, prefix):
363 """ 458 """
364 Makes 'path' absolute if it isn't already by prefixing 'prefix' 459 Makes 'path' absolute if it isn't already by prefixing 'prefix'
365 """ 460 """
2183 2278
2184 for pyfile in pyfiles: 2279 for pyfile in pyfiles:
2185 log('Running pylint on ' + pyfile + '...') 2280 log('Running pylint on ' + pyfile + '...')
2186 run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env) 2281 run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env)
2187 2282
2283 """
2284 Utility for creating and updating a zip file atomically.
2285 """
2286 class Archiver:
2287 def __init__(self, path):
2288 self.path = path
2289
2290 def __enter__(self):
2291 if self.path:
2292 fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(self.path) + '.', dir=dirname(self.path))
2293 self.tmpFd = fd
2294 self.tmpPath = tmp
2295 self.zf = zipfile.ZipFile(tmp, 'w')
2296 else:
2297 self.tmpFd = None
2298 self.tmpPath = None
2299 self.zf = None
2300 return self
2301
2302 def __exit__(self, exc_type, exc_value, traceback):
2303 if self.zf:
2304 self.zf.close()
2305 os.close(self.tmpFd)
2306 # Correct the permissions on the temporary file which is created with restrictive permissions
2307 os.chmod(self.tmpPath, 0o666 & ~currentUmask)
2308 # Atomic on Unix
2309 shutil.move(self.tmpPath, self.path)
2310
2188 def archive(args): 2311 def archive(args):
2189 """create jar files for projects and distributions""" 2312 """create jar files for projects and distributions"""
2190 parser = ArgumentParser(prog='mx archive') 2313 parser = ArgumentParser(prog='mx archive')
2191 parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...') 2314 parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...')
2192 args = parser.parse_args(args) 2315 args = parser.parse_args(args)
2193 2316
2194
2195 class Archive:
2196 def __init__(self, path):
2197 self.path = path
2198
2199 def __enter__(self):
2200 if self.path:
2201 fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(self.path) + '.', dir=dirname(self.path))
2202 self.tmpFd = fd
2203 self.tmpPath = tmp
2204 self.zf = zipfile.ZipFile(tmp, 'w')
2205 else:
2206 self.tmpFd = None
2207 self.tmpPath = None
2208 self.zf = None
2209 return self
2210
2211 def __exit__(self, exc_type, exc_value, traceback):
2212 if self.zf:
2213 self.zf.close()
2214 os.close(self.tmpFd)
2215 # Correct the permissions on the temporary file which is created with restrictive permissions
2216 os.chmod(self.tmpPath, 0o666 & ~currentUmask)
2217 # Atomic on Unix
2218 shutil.move(self.tmpPath, self.path)
2219
2220 archives = [] 2317 archives = []
2221 for name in args.names: 2318 for name in args.names:
2222 if name.startswith('@'): 2319 if name.startswith('@'):
2223 dname = name[1:] 2320 dname = name[1:]
2224 d = distribution(dname) 2321 d = distribution(dname)
2225 with Archive(d.path) as arc, Archive(d.sourcesPath) as srcArc: 2322 d.make_archive()
2226 services = {}
2227 def overwriteCheck(zf, arcname, source):
2228 if arcname in zf.namelist():
2229 log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']')
2230
2231 for dep in d.sorted_deps(includeLibs=True):
2232 if dep.isLibrary():
2233 l = dep
2234 # merge library jar into distribution jar
2235 logv('[' + d.path + ': adding library ' + l.name + ']')
2236 lpath = l.get_path(resolve=True)
2237 libSourcePath = l.get_source_path(resolve=True)
2238 if lpath:
2239 with zipfile.ZipFile(lpath, 'r') as lp:
2240 for arcname in lp.namelist():
2241 if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/':
2242 service = arcname[len('META-INF/services/'):]
2243 assert '/' not in service
2244 services.setdefault(service, []).extend(lp.read(arcname).splitlines())
2245 else:
2246 overwriteCheck(arc.zf, arcname, lpath + '!' + arcname)
2247 arc.zf.writestr(arcname, lp.read(arcname))
2248 if srcArc.zf and libSourcePath:
2249 with zipfile.ZipFile(libSourcePath, 'r') as lp:
2250 for arcname in lp.namelist():
2251 overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname)
2252 srcArc.zf.writestr(arcname, lp.read(arcname))
2253 else:
2254 p = dep
2255 # skip a Java project if its Java compliance level is "higher" than the configured JDK
2256 jdk = java(p.javaCompliance)
2257 if not jdk:
2258 log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path))
2259 continue
2260
2261 logv('[' + d.path + ': adding project ' + p.name + ']')
2262 outputDir = p.output_dir()
2263 for root, _, files in os.walk(outputDir):
2264 relpath = root[len(outputDir) + 1:]
2265 if relpath == join('META-INF', 'services'):
2266 for service in files:
2267 with open(join(root, service), 'r') as fp:
2268 services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
2269 elif relpath == join('META-INF', 'providers'):
2270 for provider in files:
2271 with open(join(root, provider), 'r') as fp:
2272 for service in fp:
2273 services.setdefault(service.strip(), []).append(provider)
2274 else:
2275 for f in files:
2276 arcname = join(relpath, f).replace(os.sep, '/')
2277 overwriteCheck(arc.zf, arcname, join(root, f))
2278 arc.zf.write(join(root, f), arcname)
2279 if srcArc.zf:
2280 for srcDir in p.source_dirs():
2281 for root, _, files in os.walk(srcDir):
2282 relpath = root[len(srcDir) + 1:]
2283 for f in files:
2284 if f.endswith('.java'):
2285 arcname = join(relpath, f).replace(os.sep, '/')
2286 overwriteCheck(srcArc.zf, arcname, join(root, f))
2287 srcArc.zf.write(join(root, f), arcname)
2288
2289 for service, providers in services.iteritems():
2290 arcname = 'META-INF/services/' + service
2291 arc.zf.writestr(arcname, '\n'.join(providers))
2292
2293 d.notify_updated()
2294 archives.append(d.path) 2323 archives.append(d.path)
2295
2296 else: 2324 else:
2297 p = project(name) 2325 p = project(name)
2298 outputDir = p.output_dir() 2326 archives.append(p.make_archive())
2299 with Archive(join(p.dir, p.name + '.jar')) as arc:
2300 for root, _, files in os.walk(outputDir):
2301 for f in files:
2302 relpath = root[len(outputDir) + 1:]
2303 arcname = join(relpath, f).replace(os.sep, '/')
2304 arc.zf.write(join(root, f), arcname)
2305 archives.append(arc.path)
2306 2327
2307 return archives 2328 return archives
2308 2329
2309 def canonicalizeprojects(args): 2330 def canonicalizeprojects(args):
2310 """process all project files to canonicalize the dependencies 2331 """process all project files to canonicalize the dependencies