class BuildMsiCommand(Command): long_descr = """\ Purpose: build MSI Usage: bentomaker build_msi [OPTIONS]""" short_descr = "build msi." common_options = Command.common_options \ + [Option("--output-dir", help="Output directory", default="dist"), Option("--output-file", help="Output filename")] def run(self, context): o, a = context.get_parsed_arguments() if o.help: p.print_help() return output_dir = o.output_dir output_file = o.output_file n = context.build_node.find_node(IPKG_PATH) manifest = BuildManifest.from_file(n.abspath()) msi_root = context.build_node.make_node("msi") build_msi_tree(manifest, context.build_node, msi_root) create_msi_installer(context.pkg, context.run_node, msi_root, o.output_file, o.output_dir)
class BuildWininstCommand(Command): long_descr = """\ Purpose: build wininst Usage: bentomaker build_wininst [OPTIONS]""" short_descr = "build wininst." common_options = Command.common_options \ + [Option("--output-dir", help="Output directory", default="dist"), Option("--output-file", help="Output filename")] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return n = ctx.build_node.make_node(IPKG_PATH) ipkg = BuildManifest.from_file(n.abspath()) create_wininst(ipkg, src_root_node=ctx.build_node, build_node=ctx.build_node, wininst=o.output_file, output_dir=o.output_dir)
class BuildCommand(Command): long_descr = """\ Purpose: build the project Usage: bentomaker build [OPTIONS].""" short_descr = "build the project." common_options = Command.common_options \ + [Option("-i", "--inplace", help="Build extensions in place", action="store_true"), Option("-j", "--jobs", help="Parallel builds (yaku build only - EXPERIMENTAL)", dest="jobs"), Option("-v", "--verbose", help="Verbose output (yaku build only)", action="store_true")] def run(self, ctx): p = ctx.options_context.parser o, a = p.parse_args(ctx.command_argv) if o.help: p.print_help() return ctx.compile() ctx.post_compile() def finish(self, ctx): super(BuildCommand, self).finish(ctx) n = ctx.build_node.make_node(IPKG_PATH) ctx.section_writer.store(n.abspath(), ctx.pkg)
def _setup_options_parser(options_context, package_options): """Setup the command options parser, merging standard options as well as custom options defined in the bento.info file, if any. """ scheme, scheme_opts_d = get_scheme(sys.platform) p = options_context # Create default path options scheme_opts = {} for name, opt_d in list(scheme_opts_d.items()): o = opt_d.pop("opts") opt = Option(*o, **opt_d) scheme_opts[name] = opt # Add custom path options (as defined in bento.info) to the path scheme for name, f in list(package_options.path_options.items()): scheme_opts[name] = \ Option('--%s' % f.name, help='%s [%s]' % (f.description, f.default_value)) p.add_group("installation_options", "Installation fine tuning") for opt in list(scheme_opts.values()): p.add_option(opt, "installation_options") flag_opts = {} if package_options.flag_options: p.add_group("optional_features", "Optional features") for name, v in list(package_options.flag_options.items()): flag_opts[name] = Option("--%s" % v.name, help="%s [default=%s]" % (v.description, v.default_value)) p.add_option(flag_opts[name], "optional_features")
class BuildEggCommand(Command): long_descr = """\ Purpose: build egg Usage: bentomaker build_egg [OPTIONS]""" short_descr = "build egg." common_options = Command.common_options \ + [Option("--output-dir", help="Output directory", default="dist"), Option("--output-file", help="Output filename")] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return output_dir = o.output_dir output_file = o.output_file n = ctx.build_node.make_node(BUILD_MANIFEST_PATH) build_manifest = BuildManifest.from_file(n.abspath()) build_egg(build_manifest, ctx.build_node, ctx.build_node, output_dir, output_file)
class UploadPyPI(Command): long_descr = """\ Purpose: register the package to pypi Usage: bentomaker register [OPTIONS] distribution_file""" short_descr = "register packages to pypi." common_options = Command.common_options \ + [Option("-r", "--repository", help="Repository to use in .pypirc"), Option("-u", "--username", help="Username to use for registration"), Option("-p", "--password", help="Password to use for registration"), Option("--repository-url", help="Repository URL to use for registration"), Option("-t", "--distribution-type", help="Force distribution type (sdist, bdist_wininst, etc...)"), ] def run(self, context): o, a = context.get_parsed_arguments() if len(a) < 1: context.options_context.parser.print_usage() # FIXME raise NotImplementedError("expected file argument") else: filename = a[0] if o.repository and (o.username or o.password or o.repository_url): raise bento.errors.UsageException( "Cannot specify repository and username/password/url at the same time" ) if not (o.repository or (o.username or o.password or o.repository_url)): # FIXME: why does distutils use DEFAULT_REPOSITORY (i.e. an url) # here ? config = _read_pypirc(DEFAULT_REPOSITORY) elif o.repository: config = _read_pypirc(o.repository) else: config = PyPIConfig(o.username, o.password, o.repository_url) if o.distribution_type is None: # FIXME raise NotImplementedError( "automatic distribution type not yet implemented") if not o.distribution_type in _SUPPORTED_DISTRIBUTIONS: raise bento.errors.BentoError( "Unsupported distribution type %r (supported types: %s)" % \ (o.distribution_type, ", ".join(repr(i) for i in _SUPPORTED_DISTRIBUTIONS))) upload_type = _SUPPORTED_DISTRIBUTIONS[o.distribution_type] upload(filename, upload_type, context.pkg, config=config)
class InstallCommand(Command): long_descr = """\ Purpose: install the project Usage: bentomaker install [OPTIONS].""" short_descr = "install the project." common_options = Command.common_options + \ [Option("-t", "--transaction", help="Do a transaction-based install", action="store_true"), Option("-n", "--dry-run", "--list-files", help="List installed files (do not install anything)", action="store_true", dest="list_files")] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return n = ctx.build_node.make_node(BUILD_MANIFEST_PATH) build_manifest = BuildManifest.from_file(n.abspath()) scheme = ctx.retrieve_configured_scheme() build_manifest.update_paths(scheme) node_sections = build_manifest.resolve_paths_with_destdir( ctx.build_node) if o.list_files: # XXX: this won't take into account action in post install scripts. # A better way would be to log install steps and display those, but # this will do for now. for kind, source, target in iter_files(node_sections): print(target.abspath()) return if o.transaction: trans = TransactionLog("transaction.log") try: for kind, source, target in iter_files(node_sections): trans.copy(source.abspath(), target.abspath(), kind) finally: trans.close() else: for kind, source, target in iter_files(node_sections): copy_installer(source.abspath(), target.abspath(), kind)
class RegisterPyPI(Command): long_descr = """\ Purpose: register the package to pypi Usage: bentomaker register [OPTIONS]""" short_descr = "register packages to pypi." common_options = Command.common_options \ + [Option("-r", "--repository", help="Repository to use in .pypirc"), Option("-u", "--username", help="Username to use for registration"), Option("-p", "--password", help="Password to use for registration"), Option( "--repository-url", help="Repository URL to use for registration"), ] def run(self, context): o, a = context.get_parsed_arguments() if o.repository and (o.username or o.password or o.repository_url): raise bento.errors.UsageException( "Cannot specify repository and username/password/url at the same time" ) if not (o.repository or (o.username or o.password or o.repository_url)): # FIXME: why does distutils use DEFAULT_REPOSITORY (i.e. an url) # here ? config = _read_pypirc(DEFAULT_REPOSITORY) elif o.repository: config = _read_pypirc(o.repository) else: config = PyPIConfig(o.username, o.password, o.repository_url) auth = HTTPPasswordMgr() host = urlparse(config.repository)[1] auth.add_password(config.realm, host, config.username, config.password) post_data = build_post_data(context.pkg, "submit") code, msg = post_to_server(post_data, config, auth) if code != 200: raise bento.errors.BentoError( "Error while submitting package metadata to server: %r" % msg)
class SdistCommand(Command): long_descr = """\ Purpose: create a tarball for the project Usage: bentomaker sdist [OPTIONS].""" short_descr = "create a tarball." common_options = Command.common_options \ + [Option("--output-dir", help="Output directory", default="dist"), Option("--format", help="Archive format (supported: 'gztar', 'zip')", default="gztar"), Option("--output-file", help="Archive filename (default: $pkgname-$version.$archive_extension)")] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return pkg = ctx.pkg format = o.format archive_root = "%s-%s" % (pkg.name, pkg.version) if not o.output_file: archive_name = archive_basename(pkg) + _FORMATS[format]["ext"] else: output = op.basename(o.output_file) if output != o.output_file: raise bento.errors.BentoError("Invalid output file: should not contain any directory") archive_name = output # XXX: find a better way to pass archive name from other commands (used # by distcheck ATM) self.archive_root, self.archive_node = create_archive(archive_name, archive_root, ctx._node_pkg, ctx.top_node, ctx.run_node, o.format, o.output_dir)
class BuildMpkgCommand(Command): long_descr = """\ Purpose: build Mac OS X mpkg Usage: bentomaker build_mpkg [OPTIONS]""" short_descr = "build mpkg." common_options = Command.common_options \ + [Option("--output-dir", help="Output directory", default="dist"), Option("--output-file", help="Output filename")] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return root = ctx.top_node while root.height() > 0: root = root.parent default_scheme = get_default_scheme(ctx.pkg.name) default_prefix = default_scheme["prefix"] default_sitedir = default_scheme["sitedir"] n = ctx.build_node.make_node(BUILD_MANIFEST_PATH) build_manifest = BuildManifest.from_file(n.abspath()) name = build_manifest.meta["name"] version = build_manifest.meta["version"] py_short = ".".join([str(i) for i in sys.version_info[:2]]) if o.output_file is None: mpkg_name = "%s-%s-py%s.mpkg" % (name, version, py_short) else: mpkg_name = o.output_file categories = set() file_sections = build_manifest.resolve_paths(ctx.build_node) for kind, source, target in iter_files(file_sections): categories.add(kind) # Mpkg metadata mpkg_root = os.path.join(os.getcwd(), o.output_dir, mpkg_name) mpkg_cdir = os.path.join(mpkg_root, "Contents") if os.path.exists(mpkg_root): shutil.rmtree(mpkg_root) os.makedirs(mpkg_cdir) f = open(os.path.join(mpkg_cdir, "PkgInfo"), "w") try: f.write("pmkrpkg1") finally: f.close() mpkg_info = MetaPackageInfo.from_build_manifest(build_manifest) purelib_pkg = "%s-purelib-%s-py%s.pkg" % (name, version, py_short) scripts_pkg = "%s-scripts-%s-py%s.pkg" % (name, version, py_short) datafiles_pkg = "%s-datafiles-%s-py%s.pkg" % (name, version, py_short) mpkg_info.packages = [purelib_pkg, scripts_pkg, datafiles_pkg] make_mpkg_plist(mpkg_info, os.path.join(mpkg_cdir, "Info.plist")) mpkg_rdir = os.path.join(mpkg_root, "Contents", "Resources") os.makedirs(mpkg_rdir) make_mpkg_description(mpkg_info, os.path.join(mpkg_rdir, "Description.plist")) # Package the stuff which ends up into site-packages pkg_root = os.path.join(mpkg_root, "Contents", "Packages", purelib_pkg) build_pkg_from_temp(ctx, build_manifest, pkg_root, root, "/", ["pythonfiles"], "Pure Python modules and packages") pkg_root = os.path.join(mpkg_root, "Contents", "Packages", scripts_pkg) build_pkg_from_temp(ctx, build_manifest, pkg_root, root, "/", ["executables"], "Scripts and binaries") pkg_root = os.path.join(mpkg_root, "Contents", "Packages", datafiles_pkg) build_pkg_from_temp(ctx, build_manifest, pkg_root, root, "/", ["bentofiles", "datafiles"], "Data files")
class ParseCommand(Command): long_descr = """\ Purpose: query the given package description file (debugging tool) Usage: bentomaker parse [OPTIONS]""" short_descr = "parse the package description file." common_options = Command.common_options + [ Option( "-f", "--flags", action="store_true", help="print flags variables"), Option( "-p", "--path", action="store_true", help="print paths variables"), Option("-m", "--meta-field", dest="meta_field", help="print given meta field") ] def run(self, ctx): argv = ctx.command_argv p = ctx.options_context.parser o, a = p.parse_args(argv) if o.help: p.print_help() return if len(a) < 1: filename = "bento.info" else: filename = a[0] if not os.path.exists(filename): raise UsageException("%s: error: file %s does not exist" % "bentomaker") f = open(filename, "r") try: data = f.read() try: parsed = build_ast_from_data(data) except ParseError: e = extract_exception() msg = "Error while parsing file %s\n" % filename e.args = (msg, ) + e.args raise e if o.flags: try: flags = parsed["flags"] for flag in flags: print((flags[flag])) except KeyError: pass elif o.path: try: paths = parsed["paths"] for path in paths: print((paths[path])) except KeyError: pass elif o.meta_field: try: print((parsed[o.meta_field])) except KeyError: raise ValueError("Field %s not found in metadata" % o.meta_field) else: pprint(parsed) finally: f.close()