def bundle(self, app): """Create a self-contained application bundle containing the target classes, dependencies and resources. """ assert(isinstance(app, BundleCreate.App)) bundledir = os.path.join(self.outdir, '%s-bundle' % app.basename) self.context.log.info('creating %s' % os.path.relpath(bundledir, get_buildroot())) safe_mkdir(bundledir, clean=True) classpath = OrderedSet() if not self.deployjar: libdir = os.path.join(bundledir, 'libs') os.mkdir(libdir) # Add external dependencies to the bundle. for basedir, externaljar in self.list_jar_dependencies(app.binary): path = os.path.join(basedir, externaljar) os.symlink(path, os.path.join(libdir, externaljar)) classpath.add(externaljar) # TODO: There should probably be a separate 'binary_jars' product type, # so we can more easily distinguish binary jars (that contain all the classes of their # transitive deps) and per-target jars. for basedir, jars in self.context.products.get('jars').get(app.binary).items(): if len(jars) != 1: raise TaskError('Expected 1 mapped binary for %s but found: %s' % (app.binary, jars)) binary = jars[0] binary_jar = os.path.join(basedir, binary) bundle_jar = os.path.join(bundledir, binary) # Add the internal classes into the bundle_jar. if not classpath: os.symlink(binary_jar, bundle_jar) else: # TODO: Can we copy the existing jar and inject the manifest in, instead of # laboriously copying the contents one by one? Would that be more efficient? with open_zip(binary_jar, 'r') as src: with open_zip(bundle_jar, 'w', compression=ZIP_DEFLATED) as dest: for item in src.infolist(): buf = src.read(item.filename) if Manifest.PATH == item.filename: manifest = Manifest(buf) manifest.addentry(Manifest.CLASS_PATH, ' '.join(os.path.join('libs', jar) for jar in classpath)) buf = manifest.contents() dest.writestr(item, buf) for bundle in app.bundles: for path, relpath in bundle.filemap.items(): bundlepath = os.path.join(bundledir, relpath) safe_mkdir(os.path.dirname(bundlepath)) os.symlink(path, bundlepath) return bundledir
def create_main_manifest(binary): """Creates a jar manifest for the given binary. If the binary declares a main then a 'Main-Class' manifest entry will be included. """ manifest = Manifest() manifest.addentry(Manifest.MANIFEST_VERSION, '1.0') manifest.addentry(Manifest.CREATED_BY, 'python %s pants %s' % (platform.python_version(), get_version())) main = binary.main or '*** java -jar not supported, please use -cp and pick a main ***' manifest.addentry(Manifest.MAIN_CLASS, main) return manifest
def create_main_manifest(binary): """Creates a jar manifest for the given binary. If the binary declares a main then a 'Main-Class' manifest entry will be included. """ manifest = Manifest() manifest.addentry(Manifest.MANIFEST_VERSION, '1.0') manifest.addentry( Manifest.CREATED_BY, 'python %s pants %s' % (platform.python_version(), get_version())) main = binary.main or '*** java -jar not supported, please use -cp and pick a main ***' manifest.addentry(Manifest.MAIN_CLASS, main) return manifest
def create_binary(self, binary): import platform safe_mkdir(self.outdir) jarmap = self.context.products.get('jars') binary_jarname = '%s.jar' % binary.basename binaryjarpath = os.path.join(self.outdir, binary_jarname) self.context.log.info('creating %s' % os.path.relpath(binaryjarpath, get_buildroot())) with open_jar(binaryjarpath, 'w', compression=self.compression, allowZip64=self.zip64) as jar: def add_jars(target): generated = jarmap.get(target) if generated: for basedir, jars in generated.items(): for internaljar in jars: self.dump(os.path.join(basedir, internaljar), jar) binary.walk(add_jars, lambda t: t.is_internal) if self.deployjar: for basedir, externaljar in self.list_jar_dependencies(binary): self.dump(os.path.join(basedir, externaljar), jar) def write_binary_data(product_type): data = self.context.products.get_data(product_type).get(binary) if data: for root, rel_paths in data.rel_paths(): for rel_path in rel_paths: jar.write(os.path.join(root, rel_path), arcname=rel_path) write_binary_data('classes_by_target') write_binary_data('resources_by_target') manifest = Manifest() manifest.addentry(Manifest.MANIFEST_VERSION, '1.0') manifest.addentry( Manifest.CREATED_BY, 'python %s pants %s' % (platform.python_version(), get_version()) ) main = binary.main or '*** java -jar not supported, please use -cp and pick a main ***' manifest.addentry(Manifest.MAIN_CLASS, main) jar.writestr(Manifest.PATH, manifest.contents()) jarmap.add(binary, self.outdir, [binary_jarname])
def write_agent_manifest(self, agent, jarfile): # TODO(John Sirois): refactor an agent model to suport 'Boot-Class-Path' properly. manifest = Manifest() manifest.addentry(Manifest.MANIFEST_VERSION, '1.0') if agent.premain: manifest.addentry('Premain-Class', agent.premain) if agent.agent_class: manifest.addentry('Agent-Class', agent.agent_class) if agent.can_redefine: manifest.addentry('Can-Redefine-Classes', 'true') if agent.can_retransform: manifest.addentry('Can-Retransform-Classes', 'true') if agent.can_set_native_method_prefix: manifest.addentry('Can-Set-Native-Method-Prefix', 'true') jarfile.writestr(Manifest.PATH, manifest.contents())
def bundle(self, app): """Create a self-contained application bundle containing the target classes, dependencies and resources. """ assert(isinstance(app, BundleCreate.App)) bundledir = os.path.join(self.outdir, '%s-bundle' % app.basename) self.context.log.info('creating %s' % os.path.relpath(bundledir, get_buildroot())) safe_mkdir(bundledir, clean=True) classpath = OrderedSet() if not self.deployjar: libdir = os.path.join(bundledir, 'libs') os.mkdir(libdir) # Add internal dependencies to the bundle. def add_jars(target): target_jars = self.context.products.get('jars').get(target) if target_jars is not None: for basedir, jars in target_jars.items(): for internaljar in jars: os.symlink(os.path.join(basedir, internaljar), os.path.join(libdir, internaljar)) classpath.add(internaljar) app.binary.walk(add_jars, lambda t: t.is_internal) # Add external dependencies to the bundle. for basedir, externaljar in self.list_jar_dependencies(app.binary): path = os.path.join(basedir, externaljar) os.symlink(path, os.path.join(libdir, externaljar)) classpath.add(externaljar) for basedir, jars in self.context.products.get('jars').get(app.binary).items(): if len(jars) != 1: raise TaskError('Expected 1 mapped binary for %s but found: %s' % (app.binary, jars)) binary = jars[0] binary_jar = os.path.join(basedir, binary) bundle_jar = os.path.join(bundledir, binary) if not classpath: os.symlink(binary_jar, bundle_jar) else: with open_zip(binary_jar, 'r') as src: with open_zip(bundle_jar, 'w', compression=ZIP_DEFLATED) as dest: for item in src.infolist(): buf = src.read(item.filename) if Manifest.PATH == item.filename: manifest = Manifest(buf) manifest.addentry(Manifest.CLASS_PATH, ' '.join(os.path.join('libs', jar) for jar in classpath)) buf = manifest.contents() dest.writestr(item, buf) for bundle in app.bundles: for path, relpath in bundle.filemap.items(): bundlepath = os.path.join(bundledir, relpath) safe_mkdir(os.path.dirname(bundlepath)) os.symlink(path, bundlepath) return bundledir