def jar(path, manifest, sourcedir, options, preserveManifestFormatting=False, update=False, outputHandler=None): """ Create a jar file containing a manifest and some other files @param path: jar file to create. Typically this file does not already exist, but if it does then the specified files or manifest will be merged into it. @param manifest: path to the manifest.mf file (or None to disable manifest entirely) @param sourcedir: the directory to pack everything from (this method may add extra files to this dir) @param options: options map. jar.options is a list of additional arguments @param preserveManifestFormatting: an advanced option that prevents that jar executable from reformatting the specified manifest file to comply with Java conventions (also prevents manifest merging if jar already exists) """ # work out if we need to create a parent directory dir = os.path.dirname(path) if dir and not os.path.exists(dir): mkdir(dir) # location of jar if options['java.home']: binary = os.path.join(options['java.home'], "bin/jar") else: binary = "jar" # build up arguments args = [binary] args.extend(options['jar.options']) if update: mode = '-u' else: mode = '-c' if not manifest: args.extend([mode + "fM", path]) elif preserveManifestFormatting: mkdir(sourcedir + '/META-INF') srcf = normLongPath(sourcedir + '/META-INF/manifest.mf') with open(manifest, 'rb') as s: with openForWrite(srcf, 'wb') as d: d.write(s.read()) args.extend([mode + "f", path]) else: args.extend([mode + "fm", path, manifest]) if sourcedir: args.extend(["-C", sourcedir, "."]) # actually call jar call(args, outputHandler=outputHandler, timeout=options['process.timeout'])
def jar(path, manifest, sourcedir, options, preserveManifestFormatting=False, update=False, outputHandler=None): """ Create a jar file containing a manifest and some other files @param path: jar file to create. Typically this file does not already exist, but if it does then the specified files or manifest will be merged into it. @param manifest: path to the manifest.mf file (or None to disable manifest entirely) @param sourcedir: the directory to pack everything from (this method may add extra files to this dir) @param options: options map. jar.options is a list of additional arguments @param preserveManifestFormatting: an advanced option that prevents that jar executable from reformatting the specified manifest file to comply with Java conventions (also prevents manifest merging if jar already exists) """ # work out if we need to create a parent directory dir = os.path.dirname(path) if dir and not os.path.exists(dir): mkdir(dir) # location of jar if options['java.home']: binary = os.path.join(options['java.home'], "bin/jar") else: binary = "jar" # build up arguments args = [binary] args.extend(options['jar.options']) if update: mode='-u' else: mode='-c' if not manifest: args.extend([mode+"fM", path]) elif preserveManifestFormatting: mkdir(sourcedir+'/META-INF') srcf = normLongPath(sourcedir+'/META-INF/manifest.mf') with open(manifest, 'rb') as s: with openForWrite(srcf, 'wb') as d: d.write(s.read()) args.extend([mode+"f", path]) else: args.extend([mode+"fm", path, manifest]) if sourcedir: args.extend(["-C", sourcedir, "."]) # actually call jar call(args, outputHandler=outputHandler, timeout=options['process.timeout'])
def javadoc(path, sources, classpath, options, outputHandler): """ Create javadoc from sources and a set of options @param path: The directory under which to create the javadoc @param sources: a list of source files @param classpath: a list of jars for the classpath @param options: the current set of options to use @param outputHandler: the output handler (optional) """ deleteDir(path) mkdir(path) # location of javadoc if options['java.home']: binary = os.path.join(options['java.home'], "bin/javadoc") else: binary = "javadoc" # store the list of files in a temporary file, then build from that. mkdir(options['tmpdir']) inputlistfile = os.path.join(options['tmpdir'], "javadoc.inputs") with openForWrite(inputlistfile, 'wb') as f: f.writelines( map(lambda x: '"' + x.replace('\\', '\\\\') + '"' + os.linesep, sources)) # build up arguments args = [binary] args.extend(options['javadoc.options']) if options['javadoc.ignoreSourceFilesFromClasspath']: args.extend(['-sourcepath', path + '/xpybuild_fake_sourcepath']) args.extend([ "-d", path, "-classpath", classpath, "-windowtitle", options['javadoc.title'], "-doctitle", options['javadoc.title'], "-%s" % options['javadoc.access'], "@%s" % inputlistfile ]) # actually call javadoc call(args, outputHandler=outputHandler, timeout=options['process.timeout'])
def javadoc(path, sources, classpath, options, outputHandler): """ Create javadoc from sources and a set of options @param path: The directory under which to create the javadoc @param sources: a list of source files @param classpath: a list of jars for the classpath @param options: the current set of options to use @param outputHandler: the output handler (optional) """ deleteDir(path) mkdir(path) # location of javadoc if options['java.home']: binary = os.path.join(options['java.home'], "bin/javadoc") else: binary = "javadoc" # store the list of files in a temporary file, then build from that. mkdir(options['tmpdir']) inputlistfile = os.path.join(options['tmpdir'], "javadoc.inputs") with openForWrite(inputlistfile, 'wb') as f: f.writelines(map(lambda x: '"'+x.replace('\\','\\\\')+'"'+os.linesep, sources)) # build up arguments args = [binary] args.extend(options['javadoc.options']) args.extend([ "-d", path, "-classpath", classpath, "-windowtitle", options['javadoc.title'], "-doctitle", options['javadoc.title'], "-%s" % options['javadoc.access'], "@%s" % inputlistfile ]) # actually call javadoc call(args, outputHandler=outputHandler, timeout=options['process.timeout'])
def create_manifest(path, properties, options): """ Create a manifest file in path from the map properties. path: The path in which to create a manifest file properties: A map of manifest keys to values options: The options to use for creating the manifest (prefix: jar.manifest) >>> create_manifest(None, {"Class-path":"foo.jar", "Implementation-name":"Progress Apama"}, {'jar.manifest.defaults':[]}).replace('\\r\\n','\\n') 'Class-path: foo.jar\\nImplementation-name: Progress Apama\\n' >>> create_manifest(None, {"Class-path":"foo.jar bar.jar wibble-12.3-r12345.jar third-party/ant2.jar third-party/ant-internal.jar", "Implementation-name":"Progress Apama"}, {'jar.manifest.defaults':[]}).replace('\\r\\n','\\n') 'Class-path: foo.jar bar.jar wibble-12.3-r12345.jar third-party/ant2.ja\\n r third-party/ant-internal.jar\\nImplementation-name: Progress Apama\\n' """ # merge in the defaults to the map (properties will already have been expanded fullmap = {} for source in [options['jar.manifest.defaults'], properties]: for key in source: fullmap[key] = source[key] # build up the list of lines lines = [] for key in sorted(fullmap.keys()): # select a deterministic order line = ("%s: %s"+os.linesep) % (key, fullmap[key]) while len(line) > 70: # need to split long lines. Thanks Java. Thava. lines.append(line[:70]+os.linesep) line = " %s" % line[70:] lines.append(line) # nb: manifests are UTF-8 so if any of the lines are unicode strings # we probably should explicitly encode them to UTF-8 byte strings here # write out the file if path: with openForWrite(path, 'wb') as f: f.writelines(lines) else: # this case for docstrings tests return "".join(lines)
def javac(output, inputs, classpath, options, logbasename, targetname): """ Compile some java files to class files. Will raise BuildException if compilation fails. @param output: path to a directory in which to put the class files (will be created) @param inputs: list of paths (.java files) to be compiled @param classpath: classpath to compile with, as a string @param options: options map. javac.options is a list of additional arguments, javac.source is the source version, javac.target is the target version @param logbasename: absolute, expanded, path to a directory and filename prefix to use for files such as .err, .out, etc files @param targetname: to log appropriate error messages """ assert logbasename and '$' not in logbasename logbasename = os.path.normpath(logbasename) # make the output directory if not os.path.exists(output): mkdir(output) # location of javac if options['java.home']: javacpath = os.path.join(options['java.home'], "bin/javac") else: javacpath = "javac" # just get it from the path # store the list of files in a temporary file, then build from that. mkdir(options['tmpdir']) argsfile = os.path.join(options['tmpdir'], "javac_args.txt") # build up the arguments args = ["-d", output] if options["javac.source"]: args.extend(["-source", options["javac.source"]]) if options["javac.target"]: args.extend(["-source", options["javac.target"]]) if options["javac.encoding"]: args.extend(["-encoding", options["javac.encoding"]]) if options["javac.debug"]: args.append('-g') if options['javac.warningsAsErrors']: args.append('-Werror') # TODO: should add -Xlint options here I think args.extend(getStringList(options['javac.options'])) if classpath: args.extend(['-cp', classpath]) args.extend([x for x in inputs if x.endswith('.java')]) # automatically filter out non-java files with openForWrite(argsfile, 'wb') as f: for a in args: a = '"%s"'%a.replace('\\','\\\\') print >>f, a success=False try: log.info('Executing javac for %s, writing output to %s: %s', targetname, logbasename+'.out', ''.join(['\n\t"%s"'%x for x in [javacpath]+args])) # make sure we have no old ones hanging around still try: deleteFile(logbasename+'-errors.txt', allowRetry=True) deleteFile(logbasename+'-warnings.txt', allowRetry=True) deleteFile(logbasename+'.out', allowRetry=True) except Exception as e: log.info('Cleaning up file failed: %s' % e) outputHandler = JavacProcessOutputHandler(targetname, options=options) outputHandler.setJavacLogBasename(logbasename) call([javacpath, "@%s" % argsfile], outputHandler=outputHandler, outputEncoding='UTF-8', cwd=output, timeout=options['process.timeout']) if (not os.listdir(output)): # unlikely, but useful failsafe raise EnvironmentError('javac command failed to create any target files (but returned no error code); see output at "%s"'%(logbasename+'.out')) success = True finally: if not success and classpath: log.info('Classpath for failed javac was: \n %s', '\n '.join(classpath.split(os.pathsep)))