pax_global_header00006660000000000000000000000064135347275770014536gustar00rootroot0000000000000052 comment=5de24564bde5d9b6edf23ad30caf1cba91994ad1 argparse-manpage-1.2.2/000077500000000000000000000000001353472757700147525ustar00rootroot00000000000000argparse-manpage-1.2.2/.gitignore000066400000000000000000000000701353472757700167370ustar00rootroot00000000000000*.pyc *.1 i build *.egg-info .cache MANIFEST dist/ man/ argparse-manpage-1.2.2/.travis.yml000066400000000000000000000002451353472757700170640ustar00rootroot00000000000000language: python python: - 2.7 - 3.5 - 3.6 - 3.7-dev install: - "pip install -r requirements.txt" script: "PYTHON=python$TRAVIS_PYTHON_VERSION ./check" argparse-manpage-1.2.2/AUTHORS000066400000000000000000000002101353472757700160130ustar00rootroot00000000000000Andi Albrecht Pavel Raiskup René 'Necoro' Neumann (seealso option) argparse-manpage-1.2.2/LICENSE000066400000000000000000000261351353472757700157660ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. argparse-manpage-1.2.2/MANIFEST.in000066400000000000000000000010771353472757700165150ustar00rootroot00000000000000include AUTHORS include LICENSE include NEWS recursive-include examples *.py *.txt *.cfg *.md recursive-include unittests *.py include examples/copr/expected-output.1 include examples/old_format/expected-output.1 include examples/raw-description/expected-output.1 include examples/resalloc/expected/man/resalloc-maint.1 include examples/resalloc/expected/man/resalloc.1 include examples/copr/fake-deps/HACK include examples/copr/fake-deps/copr/README include examples/raw-description/bin/dg include examples/resalloc/bin/resalloc include examples/resalloc/bin/resalloc-maint argparse-manpage-1.2.2/NEWS000066400000000000000000000006101353472757700154460ustar00rootroot00000000000000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New in version 1.2 * Fixed shebang in /bin/argparse-manpage script so it works on Debian/Ubuntu as well as on Fedora. * LICENSE file included in release tarball. * Command-line executable now takes an optional '--output' argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ argparse-manpage-1.2.2/README.md000066400000000000000000000067511353472757700162420ustar00rootroot00000000000000# Automatically build manpage from argparse This repository contains a command for `setup.py` to build a manpage for your project. The initial code was developed for CrunchyFrog, a database query tool for Gnome. The [frog] is now retired and [RunSQLRun] is it's successor. Then, the `build_manpage` command was developed in [andialbrecht] and edited slightly in [gabrielegiammatteo]. There's even an [old blog post] about this command. Since some useful work has been done in [python pull request], the code from the PR has been used here too (with a belief that upstream merges this, some day). Then, some more flexibility has been added. The `build_manpages` command for `setup.py` is on it's own way (right here). The old usage from `build_manpage` is still supported, documented in [old documentation](examples/old\_format/README.md). # Usage Download `./build_manpages` directory and place it somewhere where Python can find it. E.g. by: ```bash git submodule add --name build_manpages https://github.com/praiskup/build_manpages git submodule update --init ``` In your `setup.py` add: ```python [...] from build_manpages import build_manpages, get_build_py_cmd, get_install_cmd from setuptools.command.build_py import build_py from setuptools.command.install import install setup( [...] cmdclass={ 'build_manpages': build_manpages, # Re-define build_py and install commands so the manual pages # are automatically re-generated and installed (optional) 'build_py': get_build_py_cmd(build_py), 'install': get_install_cmd(install), } ) ``` In your `setup.cfg` add: ``` [build_manpages] manpages = man/foo.1:object=parser:pyfile=bin/foo.py man/bar.1:function=get_parser:pyfile=bin/bar ``` where each line means one manual page to be generated. The format of the lines is colon separated set of arguments/options. The first argument determines the filename of the generated manual page. Then follows a list of options of format `option=value`; and are about "how to get the particular argparse object". Supported values are: - pyfile - what python file the argparse object resides in - object - the name of arparse object in "pyfile" to import - function - the name of function in pyfile to call to get the argparse object Then run `setup.py build_manpages` to build a manpages for your project. Also, if you used `get_build_py` helper, `setup.py build` then transitively builds the manual pages. # Command-line usage You can also use `argparse-manpage` command on a command-line. Example: bin/argparse-manpage --pyfile ./pythonfile --function get_parser --author me --author-email me@domain.com --project-name myproject --url https://pagure.io/myproject > cool-manpage.1 This reads `./pythonfile` and executes function `get_parser` from it. The function should be programmed to return an `ArgumentParser` instance which is then used together with the other info supplied on the command-line to generate the man page. See `bin/argparse-manpage --help` for full info. # License This work is released under the terms of the Apache License v2.0. See LICENSE for details. [gabrielegiammatteo]: https://github.com/andialbrecht/build\_manpage [andialbrecht]: https://github.com/andialbrecht/build\_manpage [frog]: http://crunchyfrog.googlecode.com/svn/ [RunSQLRun]: https://github.com/andialbrecht/runsqlrun [old blog post]: https://andialbrecht.wordpress.com/2009/03/17/creating-a-man-page-with-distutils-and-optparse/ [python pull request]: https://github.com/python/cpython/pull/1169 argparse-manpage-1.2.2/argparse-manpage000077700000000000000000000000001353472757700207762wrapustar00rootroot00000000000000argparse-manpage-1.2.2/bin/000077500000000000000000000000001353472757700155225ustar00rootroot00000000000000argparse-manpage-1.2.2/bin/argparse-manpage000077500000000000000000000002031353472757700206550ustar00rootroot00000000000000#! /usr/bin/python # Copyright (C) 2017 Red Hat, Inc. from build_manpages.cli import main if __name__ == "__main__": main() argparse-manpage-1.2.2/build_manpages/000077500000000000000000000000001353472757700177245ustar00rootroot00000000000000argparse-manpage-1.2.2/build_manpages/__init__.py000066400000000000000000000000261353472757700220330ustar00rootroot00000000000000__version__ = '1.2.2' argparse-manpage-1.2.2/build_manpages/build_manpage.py000066400000000000000000000213121353472757700230640ustar00rootroot00000000000000# -*- coding: utf-8 -*- """build_manpage command -- Generate man page from setup()""" import os import datetime import optparse import argparse from distutils.core import Command from distutils.errors import DistutilsOptionError from .manpage import Manpage def get_obj(obj, objtype): if objtype == 'object': return obj return obj() def environ_hack(): os.environ['BUILD_MANPAGES_RUNNING'] = 'TRUE' def get_parser_from_module(module, objname, objtype='object'): environ_hack() import importlib mod = importlib.import_module(module) obj = getattr(mod, objname) return get_obj(obj, objtype) def get_parser_from_file(filename, objname, objtype='object'): environ_hack() from runpy import run_path filedict = run_path(filename) return get_obj(filedict[objname], objtype) def get_parser(import_type, import_from, objname, objtype): if import_type == 'pyfile': return get_parser_from_file(import_from, objname, objtype) return get_parser_from_module(import_from, objname, objtype) class ManPageWriter(object): _parser = None _command = None _type = None def __init__(self, parser, command): self._parser = parser self.distribution = command.distribution self._today = datetime.date.today() self._parser.formatter = ManPageFormatter() self._parser.formatter.set_parser(self._parser) if isinstance(parser, argparse.ArgumentParser): self._type = 'argparse' def _markup(self, txt): return txt.replace('-', '\\-') def _write_header(self): version = self.distribution.get_version() appname = self.distribution.get_name() ret = [] ret.append('.TH %s 1 %s "%s v.%s"\n' % (self._markup(appname), self._today.strftime('%Y\\-%m\\-%d'), appname, version)) description = self.distribution.get_description() if description: name = self._markup('%s - %s' % (appname, description.splitlines()[0])) else: name = self._markup(appname) ret.append('.SH NAME\n%s\n' % name) if getattr(self._parser, 'format_usage', None): synopsis = self._parser.format_usage() else: synopsis = self._parser.get_usage() if synopsis: synopsis = synopsis.replace('%s ' % appname, '') ret.append('.SH SYNOPSIS\n.B %s\n%s\n' % (self._markup(appname), synopsis)) long_desc = self.distribution.get_long_description() if long_desc: ret.append('.SH DESCRIPTION\n%s\n' % self._markup(long_desc)) return ''.join(ret) def _write_options(self, action_name=None, parser=None): if not parser: parser = self._parser if not action_name: ret = ['.SH OPTIONS\n'] else: ret = ['.SH OPTIONS ' + action_name.upper() + '\n'] ret.append(parser.format_option_help()) if self._type != 'argparse': return ''.join(ret) subparsers_actions = [ action for action in parser._actions if isinstance(action, argparse._SubParsersAction)] for subparser_action in subparsers_actions: for name, obj in subparser_action.choices.items(): if action_name: an = action_name + " " + name else: an = name ret.append(self._write_options(an, obj)) return ''.join(ret) def _write_seealso(self, text): ret = [] ret.append('.SH "SEE ALSO"\n') for i in text: name, sect = i.split(":") if len(ret) > 1: ret.append(',\n') ret.append('.BR %s (%s)' % (name, sect)) return ''.join(ret) def _write_footer(self): ret = [] appname = self.distribution.get_name() author = '%s <%s>' % (self.distribution.get_author(), self.distribution.get_author_email()) ret.append(('.SH AUTHORS\n.B %s\nwas written by %s.\n' % (self._markup(appname), self._markup(author)))) homepage = self.distribution.get_url() ret.append(('.SH DISTRIBUTION\nThe latest version of %s may ' 'be downloaded from\n' '.UR %s\n.UE\n' % (self._markup(appname), self._markup(homepage),))) return ''.join(ret) def _write_filename(self, filename, what): filename = filename if filename != '-' else '/dev/stdout' dirname = os.path.dirname(filename) if dirname and not os.path.exists(dirname): os.makedirs(dirname) with open(filename, 'w') as stream: stream.write(what) def write(self, filename, seealso=None): manpage = [] manpage.append(self._write_header()) manpage.append(self._write_options()) manpage.append(self._write_footer()) if seealso: manpage.append(self._write_seealso(seealso)) self._write_filename(filename, ''.join(manpage)) def write_with_manpage(self, filename): man = Manpage(self._parser) man = str(man) + "\n" + self._write_footer() self._write_filename(filename, man) class build_manpage(Command): description = 'Generate man page from setup().' user_options = [ ('output=', 'O', 'output file'), ('parser=', None, 'module path to optparser (e.g. mymod:func'), ('parser-file=', None, 'file to the parser module'), ('file-and-object=', None, 'import parser object from file, e.g. "bin/blah.py:fooparser"'), ('seealso=', None, 'list of manpages to put into the SEE ALSO section (e.g. bash:1)') ] def initialize_options(self): self.output = None self.parser = None self.seealso = None self.parser_file = None self.file_and_object = None def get_parser_from_module(self): mod_name, func_name = self.parser.split(':') fromlist = mod_name.split('.') try: if self.parser_file: # # Alternative method to load the module. We use the path to the module file (if the user provide it). # This beacuse, if the module uses namespaces, the original method does not work # # inspired from https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path # # praiskup: this is not working for python2, and is pretty # hacky. Kept for compat option parser-file.. import importlib.util spec = importlib.util.spec_from_file_location(mod_name, self.parser_file) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) else: mod = __import__(mod_name, fromlist=fromlist) return getattr(mod, func_name)() except ImportError as err: raise def finalize_options(self): if self.output is None: raise DistutilsOptionError('\'output\' option is required') if self.parser is None and self.file_and_object is None: raise DistutilsOptionError('\'parser\' or \'file-and-object\' option is required') self.ensure_string_list('seealso') if self.file_and_object: filename, objname = self.file_and_object.split(':') self._parser = get_parser_from_file(filename, objname) else: self._parser = self.get_parser_from_module() def run(self): self.announce('Writing man page %s' % self.output) mpw = ManPageWriter(self._parser, self) mpw.write(self.output, seealso=self.seealso) class ManPageFormatter(optparse.HelpFormatter): def __init__(self, indent_increment=2, max_help_position=24, width=None, short_first=1): optparse.HelpFormatter.__init__(self, indent_increment, max_help_position, width, short_first) def _markup(self, txt): return txt.replace('-', '\\-') def format_usage(self, usage): return self._markup(usage) def format_heading(self, heading): if self.level == 0: return '' return '.TP\n%s\n' % self._markup(heading.upper()) def format_option(self, option): result = [] opts = self.option_strings[option] result.append('.TP\n.B %s\n' % self._markup(opts)) if option.help: help_text = '%s\n' % self._markup(self.expand_default(option)) result.append(help_text) return ''.join(result) argparse-manpage-1.2.2/build_manpages/build_manpages.py000066400000000000000000000061441353472757700232550ustar00rootroot00000000000000""" build_manpages command -- generate set of manual pages by the setup() command. """ import os DEFAULT_CMD_NAME = 'build_manpages' from distutils.core import Command from distutils.errors import DistutilsOptionError import shutil try: from configparser import ConfigParser except ImportError: from ConfigParser import SafeConfigParser as ConfigParser from .build_manpage import ManPageWriter, get_parser def parse_manpages_spec(string): manpages_parsed = {} for spec in string.strip().split('\n'): manpagedata = {} output = True for option in spec.split(':'): if output: outputfile = option output = False continue oname, ovalue = option.split('=') if oname == 'function' or oname == 'object': assert(not 'objtype' in manpagedata) manpagedata['objtype'] = oname manpagedata['objname'] = ovalue elif oname == 'pyfile' or oname == 'module': assert(not 'import_type' in manpagedata) manpagedata['import_type'] = oname manpagedata['import_from'] = ovalue elif oname == 'format': assert(not 'format' in manpagedata) manpagedata[oname] = ovalue manpages_parsed[outputfile] = manpagedata return manpages_parsed class build_manpages(Command): description = 'Generate set of man pages from setup().' user_options = [ ('manpages=', 'O', 'list man pages specifications'), ] def initialize_options(self): self.manpages = None def finalize_options(self): if not self.manpages: raise DistutilsOptionError('\'manpages\' option is required') self.manpages_parsed = parse_manpages_spec(self.manpages) def run(self): for page, data in self.manpages_parsed.items(): print ("generating " + page) parser = get_parser(data['import_type'], data['import_from'], data['objname'], data['objtype']) mw = ManPageWriter(parser, self) if not 'format' in data or data['format'] == 'pretty': mw.write_with_manpage(page) elif data['format'] == 'old': mw.write(page) def get_build_py_cmd(command): class build_py(command): def run(self): self.run_command(DEFAULT_CMD_NAME) command.run(self) return build_py def get_install_cmd(command): class install(command): def install_manual_pages(self): config = ConfigParser() config.read('setup.cfg') spec = config.get(DEFAULT_CMD_NAME, 'manpages') data = parse_manpages_spec(spec) mandir = os.path.join(self.install_data, 'share/man/man1') if not os.path.exists(mandir): os.makedirs(mandir) for key, _ in data.items(): print ('installing {0}'.format(key)) shutil.copy(key, mandir) def run(self): command.run(self) self.install_manual_pages() return install argparse-manpage-1.2.2/build_manpages/cli/000077500000000000000000000000001353472757700204735ustar00rootroot00000000000000argparse-manpage-1.2.2/build_manpages/cli/__init__.py000066400000000000000000000033521353472757700226070ustar00rootroot00000000000000# Copyright (C) 2017 Red Hat, Inc. import argparse from build_manpages.build_manpage import ManPageWriter, get_parser from build_manpages.cli import hack description = """ Build manual page from Python's argparse.ArgumentParser object. """.strip() fake_cmd = hack.FakeCommand() ap = argparse.ArgumentParser( prog='argparse-manpage', description=description, ) src_group = ap.add_mutually_exclusive_group(required=True) src_group.add_argument( "--module", help="search the OBJECT/FUNCTION in MODULE" ) src_group.add_argument( "--pyfile", help="search the OBJECT/FUNCTION in FILE" ) obj_group = ap.add_mutually_exclusive_group(required=True) obj_group.add_argument( "--function", help="call FUNCTION from MODULE/FILE to obtain ArgumentParser object", ) obj_group.add_argument( "--object", help="obtain ArgumentParser OBJECT from FUNCTION (to get argparse object) from MODULE or FILE", ) ap.add_argument("--author", action=fake_cmd.getAction()) ap.add_argument("--author-email", action=fake_cmd.getAction()) ap.add_argument("--project-name", dest='name', action=fake_cmd.getAction()) ap.add_argument("--url", action=fake_cmd.getAction()) ap.add_argument("--output", dest='outfile', default='-', help="output file; default to stdout") def main(): args = ap.parse_args() import_type = 'pyfile' import_from = args.pyfile if args.module: import_type = 'module' import_from = args.module obj_type = 'object' obj_name = args.object if args.function: obj_type = 'function' obj_name = args.function parser = get_parser(import_type, import_from, obj_name, obj_type) mw = ManPageWriter(parser, fake_cmd) mw.write_with_manpage(args.outfile) argparse-manpage-1.2.2/build_manpages/cli/hack.py000066400000000000000000000024251353472757700217560ustar00rootroot00000000000000# Copyright (C) 2017 Red Hat, Inc. # Darn, this needs to go away! import argparse class _FixMap(object): opt_to_conf = {} conf_to_opt = {} def set(self, opt, conf): self.conf_to_opt[conf] = opt self.opt_to_conf[opt] = conf def __init__(self): self.set('project-name', 'name') def opt(self, conf): return self.conf_to_opt.get(conf, conf) def conf(self, opt): return self.opt_to_conf.get(opt, opt) _fix_map = _FixMap() class FakeDistribution: values = {} def __getattr__(self, key): key = key.lstrip('get_') key = key.replace('-', '_') if not key in self.values: return lambda : '<>' return lambda : self.values[key] class FakeCommand(): def __init__(self): self.distribution = FakeDistribution() def getAction(self): parent = self class A(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): option_string = option_string.lstrip('--') option_string = _fix_map.conf(option_string) option_string = option_string.replace('-', '_') parent.distribution.values[option_string] = values return A argparse-manpage-1.2.2/build_manpages/manpage.py000066400000000000000000000137111353472757700217110ustar00rootroot00000000000000from argparse import SUPPRESS, HelpFormatter, _SubParsersAction, _HelpAction from collections import OrderedDict class Manpage(object): def __init__(self, parser): self.prog = parser.prog self.parser = parser if not getattr(parser, '_manpage', None): self.parser._manpage = [] self.formatter = self.parser._get_formatter() self.mf = _ManpageFormatter(self.prog, self.formatter) self.synopsis = self.parser.format_usage().split(':')[-1].split() self.description = self.parser.description def format_text(self, text): # Wrap by parser formatter and convert to manpage format return self.mf.format_text(self.formatter._format_text(text)).strip('\n') def _has_options(self): for action in self.parser._actions: if isinstance(action, _HelpAction): continue return True return False def __str__(self): lines = [] # Header lines.append('.TH {prog} "1" Manual'.format(prog=self.prog)) # Name lines.append('.SH NAME') line = self.prog if getattr(self.parser, 'man_short_description', None): line += " \\- " + self.parser.man_short_description lines.append(line) # Synopsis if self.synopsis: lines.append('.SH SYNOPSIS') lines.append('.B {}'.format(self.synopsis[0])) lines.append(' '.join(self.synopsis[1:])) # Description if self.description: lines.append('.SH DESCRIPTION') lines.append(self.format_text(self.description)) # Options if self._has_options(): lines.append('.SH OPTIONS') for action_group in self.parser._action_groups: lines.append(self.mf.format_action_group(action_group, self.parser.prog)) # Additional Section for section in self.parser._manpage: lines.append('.SH {}'.format(section['heading'].upper())) lines.append(self.format_text(section['content'])) return '\n'.join(lines).strip('\n') + '\n' class _ManpageFormatter(HelpFormatter): def __init__(self, prog, old_formatter): super(HelpFormatter, self).__init__() self._prog = prog self.of = old_formatter def _markup(self, text): if isinstance(text, str): return text.replace('-', r'\-') return text def _underline(self, text): return r'\fI\,{}\/\fR'.format(text) def _bold(self, text): if not text.strip().startswith(r'\fB'): text = r'\fB{}'.format(text) if not text.strip().endswith(r'\fR'): text = r'{}\fR'.format(text) return text def _format_action_invocation(self, action): if not action.option_strings: metavar, = self._metavar_formatter(action, action.dest)(1) metavar = self._bold(metavar) return metavar else: parts = [] # if the Optional doesn't take a value, format is: # -s, --long if action.nargs == 0: parts.extend(map(self._bold, action.option_strings)) # if the Optional takes a value, format is: # -s ARGS, --long ARGS else: default = self._underline(action.dest.upper()) args_string = self._format_args(action, default) for option_string in action.option_strings: parts.append('{} {}'.format(self._bold(option_string), args_string)) return ', '.join(parts) def _format_parser(self, parser, name): lines = [] lines.append(".SH OPTIONS '{0}'".format(name)) lines.append(parser.format_usage()) if parser.description: lines.append(self.format_text(parser.description)) groups = parser._action_groups if len(groups): for group in groups: lines.append(self._format_action_group(group, name)) return lines def _format_action(self, action): if '--help' in action.option_strings: return "" parts = [] parts.append('.TP') action_header = self._format_action_invocation(action) parts.append(self._markup(action_header)) # if there was help for the action, add lines of help text if action.help: help_text = self.of._format_text(self._expand_help(action)).strip('\n') parts.append(self.format_text(help_text)) return parts def _format_ag_subcommands(self, actions, prog): lines = [ '.SS', self._bold('Sub-commands'), ] for action in actions: lines.append('.TP') lines.append(self._bold(prog) + ' ' + self._underline(action.dest)) if hasattr(action, 'help'): lines.append(action.help) return '\n'.join(lines) def _format_action_group(self, action_group, prog): lines = [] actions = action_group._group_actions for action in actions: if action.help == SUPPRESS: continue if isinstance(action, _SubParsersAction): lines.append(self._format_ag_subcommands( action._choices_actions, prog)) for name, choice in action.choices.items(): lines.extend(self._format_parser(choice, prog + ' ' + name)) continue lines.extend(self._format_action(action)) return '\n'.join(lines) def format_action(self, action): return self._format_action(action) def format_action_group(self, action_group, prog): return self._format_action_group(action_group, prog) def format_text(self, text): return self._markup(text.strip('\n')\ .replace('\\', '\\\\')\ .replace('\n', '\n.br\n') + '\n') argparse-manpage-1.2.2/check000077500000000000000000000002011353472757700157460ustar00rootroot00000000000000#! /bin/bash -x for python in ${PYTHON-python2 python3}; do PYTHONPATH=$(pwd) ${python/-dev/} -m pytest "$@" || exit 1 done argparse-manpage-1.2.2/examples/000077500000000000000000000000001353472757700165705ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/000077500000000000000000000000001353472757700175335ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/.gitignore000066400000000000000000000000061353472757700215170ustar00rootroot00000000000000build argparse-manpage-1.2.2/examples/copr/copr_cli/000077500000000000000000000000001353472757700213255ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/copr_cli/__init__.py000066400000000000000000000000001353472757700234240ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/copr_cli/build_config.py000066400000000000000000000020531353472757700243230ustar00rootroot00000000000000# coding: utf-8 from jinja2 import Environment template_string = """\ # This is development/testing only mock profile, not exactly the same as # is used on copr builders; but it is basically similar. If you need an # exact mock configuration (because you e.g. try to reproduce failed # build), such configuration is put alongside the built RPMs. include('/etc/mock/{{chroot}}.cfg') config_opts['root'] = '{{project_id}}_{{chroot}}' config_opts['chroot_additional_packages'] = ' {%- for pkg in additional_packages -%} {%- if loop.last -%} {{ pkg }} {%- else -%} {{ pkg }} {% endif -%} {%- endfor -%}' {% if repos %} config_opts['yum.conf'] += \"\"\" {% for repo in repos %} [{{ repo.id }}] name="{{ repo.name }}" baseurl={{ repo.url }} gpgcheck=0 enabled=1 skip_if_unavailable=1 metadata_expire=0 cost=1 best=1 {% endfor %} \"\"\" {% endif %} """ class MockProfile(object): def __init__(self, data): self.data = data def __str__(self): template = Environment().from_string(template_string) return template.render(self.data) argparse-manpage-1.2.2/examples/copr/copr_cli/main.py000066400000000000000000001376271353472757700226430ustar00rootroot00000000000000#!/usr/bin/python3 # -*- coding: UTF-8 -*- import os import re import subprocess import argparse import sys import datetime import time import six import simplejson from collections import defaultdict import logging if six.PY2: from urlparse import urlparse else: from urllib.parse import urlparse if sys.version_info < (2, 7): class NullHandler(logging.Handler): def emit(self, record): pass else: from logging import NullHandler log = logging.getLogger(__name__) log.addHandler(NullHandler()) from copr import CoprClient from copr.client.responses import CoprResponse import copr.exceptions as copr_exceptions from .util import ProgressBar from .build_config import MockProfile import pkg_resources ON_OFF_MAP = { 'on': True, 'off': False, None: None, } no_config_warning = """ ================= WARNING: ======================= File '{0}' is missing or incorrect. See documentation: man copr-cli. Any operation requiring credentials will fail! ================================================== """ class Commands(object): def __init__(self, config): self.config = config try: self.client = CoprClient.create_from_file_config(config) except (copr_exceptions.CoprNoConfException, copr_exceptions.CoprConfigException): sys.stderr.write(no_config_warning.format(config or "~/.config/copr")) self.client = CoprClient( copr_url=u"http://copr.fedoraproject.org", no_config=True ) def requires_api_auth(func): """ Decorator that checks config presence """ def wrapper(self, args): if self.client.no_config: sys.stderr.write("Error: Operation requires api authentication\n") sys.exit(6) return func(self, args) wrapper.__doc__ = func.__doc__ wrapper.__name__ = func.__name__ return wrapper def check_username_presence(func): """ Decorator that checks if username was provided """ def wrapper(self, args): if self.client.no_config and args.username is None: sys.stderr.write( "Error: Operation requires username\n" "Pass username to command or create `~/.config/copr`\n") sys.exit(6) if args.username is None and self.client.username is None: sys.stderr.write( "Error: Operation requires username\n" "Pass username to command or add it to `~/.config/copr`\n") sys.exit(6) return func(self, args) wrapper.__doc__ = func.__doc__ wrapper.__name__ = func.__name__ return wrapper def _watch_builds(self, build_ids): """ :param build_ids: list of build IDs """ print("Watching build(s): (this may be safely interrupted)") prevstatus = defaultdict(lambda: None) failed_ids = [] watched = set(build_ids) done = set() try: while watched != done: for build_id in watched: if build_id in done: continue build_details = self.client.get_build_details(build_id) if build_details.output != "ok": errmsg = " Build {1}: Unable to get build status: {0}". \ format(build_details.error, build_id) raise copr_exceptions.CoprRequestException(errmsg) now = datetime.datetime.now() if prevstatus[build_id] != build_details.status: prevstatus[build_id] = build_details.status print(" {0} Build {2}: {1}".format( now.strftime("%H:%M:%S"), build_details.status, build_id)) if build_details.status in ["failed"]: failed_ids.append(build_id) if build_details.status in ["succeeded", "skipped", "failed", "canceled"]: done.add(build_id) if build_details.status == "unknown": raise copr_exceptions.CoprBuildException( "Unknown status.") if watched == done: break time.sleep(30) if failed_ids: raise copr_exceptions.CoprBuildException( "Build(s) {0} failed.".format( ", ".join(str(x) for x in failed_ids))) except KeyboardInterrupt: pass def action_whoami(self, args): """ Simply print out the current user as defined in copr config. """ print(self.client.username) @requires_api_auth def action_build(self, args): """ Method called when the 'build' action has been selected by the user. :param args: argparse arguments provided by the user """ self.client.authentication_check() bar = None progress_callback = None builds = [] for pkg in args.pkgs: if os.path.exists(pkg): bar = ProgressBar(max=os.path.getsize(pkg)) # pylint: disable=function-redefined def progress_callback(monitor): bar.next(n=8192) print('Uploading package {0}'.format(pkg)) data = { "pkgs": [pkg], "progress_callback": progress_callback, } builds.append(self.process_build(args, self.client.create_new_build, data, bar=bar)) return builds @requires_api_auth def action_build_pypi(self, args): """ Method called when the 'buildpypi' action has been selected by the user. :param args: argparse arguments provided by the user """ username, copr = parse_name(args.copr) data = { "pypi_package_name": args.packagename, "pypi_package_version": args.packageversion, "python_versions": args.pythonversions, } return self.process_build(args, self.client.create_new_build_pypi, data) @requires_api_auth def action_build_tito(self, args): """ Method called when the 'buildtito' action has been selected by the user. :param args: argparse arguments provided by the user """ data = { "git_url": args.git_url, "git_dir": args.git_dir, "git_branch": args.git_branch, "tito_test": args.tito_test, } return self.process_build(args, self.client.create_new_build_tito, data) @requires_api_auth def action_build_mock(self, args): """ Method called when the 'build-mock' action has been selected by the user. :param args: argparse arguments provided by the user """ data = { "scm_type": args.scm_type, "scm_url": args.scm_url, "scm_branch": args.scm_branch, "spec": args.spec, } return self.process_build(args, self.client.create_new_build_mock, data) @requires_api_auth def action_build_rubygems(self, args): """ Method called when the 'buildgem' action has been selected by the user. :param args: argparse arguments provided by the user """ data = {"gem_name": args.gem_name} return self.process_build(args, self.client.create_new_build_rubygems, data) @requires_api_auth def action_build_distgit(self, args): """ Method called when the 'buildfedpkg' action has been selected by the user. :param args: argparse arguments provided by the user """ data = {"clone_url": args.clone_url, "branch": args.branch} return self.process_build(args, self.client.create_new_build_distgit, data) def process_build(self, args, build_function, data, bar=None): username, copr = parse_name(args.copr) result = build_function(username=username, projectname=copr, chroots=args.chroots, memory=args.memory, timeout=args.timeout, background=args.background, **data) if bar: bar.finish() if result.output != "ok": sys.stderr.write(result.error + "\n") return print(result.message) build_ids = [bw.build_id for bw in result.builds_list] print("Created builds: {0}".format(" ".join(map(str, build_ids)))) if not args.nowait: self._watch_builds(build_ids) @requires_api_auth def action_create(self, args): """ Method called when the 'create' action has been selected by the user. :param args: argparse arguments provided by the user """ username, copr = parse_name(args.name) result = self.client.create_project( username=username, projectname=copr, description=args.description, instructions=args.instructions, chroots=args.chroots, repos=args.repos, initial_pkgs=args.initial_pkgs, disable_createrepo=args.disable_createrepo, unlisted_on_hp=ON_OFF_MAP[args.unlisted_on_hp], enable_net=ON_OFF_MAP[args.enable_net], persistent=args.persistent, auto_prune=ON_OFF_MAP[args.auto_prune] ) print(result.message) @requires_api_auth def action_modify_project(self, args): """ Method called when the 'modify' action has been selected by the user. :param args: argparse arguments provided by the user """ username, copr = parse_name(args.name) result = self.client.modify_project( username=username, projectname=copr, description=args.description, instructions=args.instructions, repos=args.repos, disable_createrepo=args.disable_createrepo, unlisted_on_hp=ON_OFF_MAP[args.unlisted_on_hp], enable_net=ON_OFF_MAP[args.enable_net], auto_prune=ON_OFF_MAP[args.auto_prune], chroots=args.chroots, ) @requires_api_auth def action_delete(self, args): """ Method called when the 'delete' action has been selected by the user. :param args: argparse arguments provided by the user """ username, copr = parse_name(args.copr) result = self.client.delete_project(username=username, projectname=copr) print(result.message) @requires_api_auth def action_fork(self, args): """ Method called when the 'fork' action has been selected by the user. :param args: argparse arguments provided by the user """ username, copr = parse_name(args.dst) result = self.client.fork_project(source=args.src, username=username, projectname=copr, confirm=args.confirm) print(result.message) def action_mock_config(self, args): """ Method called when the 'list' action has been selected by the user. :param args: argparse arguments provided by the user """ username = self.client.username project = args.project.split("/") if len(project) != 2: args.project = username + "/" + args.project result = self.client.get_build_config(args.project, args.chroot) if result.output != "ok": sys.stderr.write(result.error + "\n") sys.stderr.write("Un-expected data returned, please report this issue\n") print(MockProfile(result.build_config)) @check_username_presence def action_list(self, args): """ Method called when the 'list' action has been selected by the user. :param args: argparse arguments provided by the user """ username = args.username or self.client.username result = self.client.get_projects_list(username) # import ipdb; ipdb.set_trace() if result.output != "ok": sys.stderr.write(result.error + "\n") sys.stderr.write("Un-expected data returned, please report this issue\n") elif not result.projects_list: sys.stderr.write("No copr retrieved for user: '{0}'\n".format(username)) return for prj in result.projects_list: print(prj) def action_status(self, args): result = self.client.get_build_details(args.build_id) print(result.status) def action_download_build(self, args): result = self.client.get_build_details(args.build_id) base_len = len(os.path.split(result.results)) for chroot, url in result.results_by_chroot.items(): if args.chroots and chroot not in args.chroots: continue cmd = "wget -r -nH --no-parent --reject 'index.html*'".split(' ') cmd.extend(['-P', os.path.join(args.dest, chroot)]) cmd.extend(['--cut-dirs', str(base_len + 4)]) cmd.append(url) subprocess.call(cmd) @requires_api_auth def action_cancel(self, args): """ Method called when the 'cancel' action has been selected by the user. :param args: argparse arguments provided by the user """ result = self.client.cancel_build(args.build_id) print(result.status) def action_watch_build(self, args): self._watch_builds(args.build_id) def action_delete_build(self, args): result = self.client.delete_build(args.build_id) print(result.status) ######################################################### ### Chroot actions ### ######################################################### @requires_api_auth def action_edit_chroot(self, args): """ Method called when the 'edit-chroot' action has been selected by the user. :param args: argparse arguments provided by the user """ owner, copr, chroot = parse_chroot_path(args.coprchroot) result = self.client.edit_chroot( ownername=owner, projectname=copr, chrootname=chroot, upload_comps=args.upload_comps, delete_comps=args.delete_comps, packages=args.packages, repos=args.repos ) print(result.message) def action_get_chroot(self, args): """ Method called when the 'get-chroot' action has been selected by the user. :param args: argparse arguments provided by the user """ owner, copr, chroot = parse_chroot_path(args.coprchroot) result = self.client.get_chroot( ownername=owner, projectname=copr, chrootname=chroot ) print(simplejson.dumps(result.chroot, indent=4, sort_keys=True, for_json=True)) ######################################################### ### Package actions ### ######################################################### @requires_api_auth def action_add_or_edit_package_tito(self, args): ownername, projectname = parse_name(args.copr) data = { "package_name": args.name, "git_url": args.git_url, "git_dir": args.git_dir, "git_branch": args.git_branch, "tito_test": ON_OFF_MAP[args.tito_test], "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild], } if args.create: result = self.client.add_package_tito(ownername=ownername, projectname=projectname, **data) else: result = self.client.edit_package_tito(ownername=ownername, projectname=projectname, **data) print(result.message) @requires_api_auth def action_add_or_edit_package_pypi(self, args): ownername, projectname = parse_name(args.copr) data = { "package_name": args.name, "pypi_package_name": args.packagename, "pypi_package_version": args.packageversion, "python_versions": args.pythonversions, "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild], } if args.create: result = self.client.add_package_pypi(ownername=ownername, projectname=projectname, **data) else: result = self.client.edit_package_pypi(ownername=ownername, projectname=projectname, **data) print(result.message) @requires_api_auth def action_add_or_edit_package_mockscm(self, args): ownername, projectname = parse_name(args.copr) data = { "package_name": args.name, "scm_type": args.scm_type, "scm_url": args.scm_url, "scm_branch": args.scm_branch, "spec": args.spec, "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild], } if args.create: result = self.client.add_package_mockscm(ownername=ownername, projectname=projectname, **data) else: result = self.client.edit_package_mockscm(ownername=ownername, projectname=projectname, **data) print(result.message) @requires_api_auth def action_add_or_edit_package_rubygems(self, args): ownername, projectname = parse_name(args.copr) data = { "package_name": args.name, "gem_name": args.gem_name, "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild], } if args.create: result = self.client.add_package_rubygems(ownername=ownername, projectname=projectname, **data) else: result = self.client.edit_package_rubygems(ownername=ownername, projectname=projectname, **data) print(result.message) def action_list_packages(self, args): ownername, projectname = parse_name(args.copr) data = { "with_latest_build": args.with_latest_build, "with_latest_succeeded_build": args.with_latest_succeeded_build, "with_all_builds": args.with_all_builds, } result = self.client.get_packages_list(ownername=ownername, projectname=projectname, **data) print(simplejson.dumps(result.packages_list, indent=4, sort_keys=True, for_json=True)) def action_list_package_names(self, args): ownername, projectname = parse_name(args.copr) result = self.client.get_packages_list(ownername=ownername, projectname=projectname) for package in result.packages_list: print(package.name) def action_get_package(self, args): ownername, projectname = parse_name(args.copr) data = { "pkg_name": args.name, "with_latest_build": args.with_latest_build, "with_latest_succeeded_build": args.with_latest_succeeded_build, "with_all_builds": args.with_all_builds, } result = self.client.get_package(ownername=ownername, projectname=projectname, **data) print(simplejson.dumps(result.package, indent=4, sort_keys=True, for_json=True)) def action_delete_package(self, args): ownername, projectname = parse_name(args.copr) data = { "pkg_name": args.name } result = self.client.delete_package(ownername=ownername, projectname=projectname, **data) print(result.message) def action_reset_package(self, args): ownername, projectname = parse_name(args.copr) data = { "pkg_name": args.name } result = self.client.reset_package(ownername=ownername, projectname=projectname, **data) print(result.message) def action_build_package(self, args): ownername, projectname = parse_name(args.copr) data = { "pkg_name": args.name, "chroots": args.chroots, #"memory": args.memory, "timeout": args.timeout } result = self.client.build_package(ownername=ownername, projectname=projectname, **data) if result.output != "ok": sys.stderr.write(result.error + "\n") return print(result.message) build_ids = [bw.build_id for bw in result.builds_list] print("Created builds: {0}".format(" ".join(map(str, build_ids)))) if not args.nowait: self._watch_builds(build_ids) def action_build_module(self, args): """ Build module via Copr MBS """ ownername, projectname = parse_name(args.copr or "") modulemd = open(args.yaml, "rb") if args.yaml else args.url response = self.client.build_module(modulemd, ownername, projectname) print(response.message if response.output == "ok" else response.error) def version(): if 'BUILD_MANPAGES_RUNNING' in os.environ: # pkg_resources magic doesn't work during 'setup.py build', but it # doesn't matter as the version in the manual page is read directly from # setuptools. return 'fake' return pkg_resources.require('copr-cli')[0].version def setup_parser(): """ Set the main arguments. """ ######################################################### ### General options ### ######################################################### parser = argparse.ArgumentParser(prog="copr") # General connection options parser.add_argument("--debug", dest="debug", action="store_true", help="Enable debug output") parser.add_argument("--config", dest="config", help="Path to an alternative configuration file") parser.add_argument("--version", action="version", version="%(prog)s version " + version()) subparsers = parser.add_subparsers(title="actions") ######################################################### ### Project options ### ######################################################### parser_whoami = subparsers.add_parser( "whoami", help="Print username that the client authenticates with against copr-frontend" ) parser_whoami.set_defaults(func="action_whoami") # create the parser for the "list" command parser_list = subparsers.add_parser( "list", help="List all the copr of the " "provided " ) parser_list.add_argument( "username", metavar="username|@groupname", nargs="?", help="The username or @groupname that you would like to " "list the coprs of (defaults to current user)" ) parser_list.set_defaults(func="action_list") parser_mock_config = subparsers.add_parser( "mock-config", help="Get the mock profile (similar to koji mock-config)" ) parser_mock_config.add_argument( "project", help="Expected format is /, / (including '@') or (name of project you own)." ) parser_mock_config.add_argument( "chroot", help="chroot id, e.g. 'fedora-rawhide-x86_64'" ) parser_mock_config.set_defaults(func="action_mock_config") # create the parser for the "create" command parser_create = subparsers.add_parser("create", help="Create a new copr") parser_create.add_argument("name", help="The name of the copr to create") parser_create.add_argument("--chroot", dest="chroots", action="append", help="Chroot to use for this copr") parser_create.add_argument("--repo", dest="repos", action="append", help="Repository to add to this copr") parser_create.add_argument("--initial-pkgs", dest="initial_pkgs", action="append", help="List of packages URL to build in this " "new copr") parser_create.add_argument("--description", help="Description of the copr") parser_create.add_argument("--instructions", help="Instructions for the copr") parser_create.add_argument("--disable_createrepo", help="Disable metadata auto generation") parser_create.add_argument("--enable-net", choices=["on", "off"], default="off", help="If net should be enabled for builds in this project (default is off)") parser_create.add_argument("--unlisted-on-hp", choices=["on", "off"], help="The project will not be shown on COPR home page") parser_create.add_argument("--persistent", action="store_true", help="Project and its builds will be undeletable. This option can only be specified by a COPR admin.") parser_create.add_argument("--auto-prune", choices=["on", "off"], default="on", help="If auto-deletion of project's obsoleted builds should be enabled (default is on).\ This option can only be specified by a COPR admin.") parser_create.set_defaults(func="action_create") # create the parser for the "modify_project" command parser_modify = subparsers.add_parser("modify", help="Modify existing copr") parser_modify.add_argument("name", help="The name of the copr to modify") parser_modify.add_argument("--chroot", dest="chroots", action="append", help="Chroot to use for this copr") parser_modify.add_argument("--description", help="Description of the copr") parser_modify.add_argument("--instructions", help="Instructions for the copr") parser_modify.add_argument("--repo", dest="repos", action="append", help="Repository to add to this copr") parser_modify.add_argument("--disable_createrepo", help="Disable metadata auto generation") parser_modify.add_argument("--enable-net", choices=["on", "off"], help="If net should be enabled for builds in this project (default is \"don't change\")") parser_modify.add_argument("--unlisted-on-hp", choices=["on", "off"], help="The project will not be shown on COPR home page") parser_modify.add_argument("--auto-prune", choices=["on", "off"], help="If auto-deletion of project's obsoleted builds should be enabled.\ This option can only be specified by a COPR admin.") parser_modify.set_defaults(func="action_modify_project") # create the parser for the "delete" command parser_delete = subparsers.add_parser("delete", help="Deletes the entire project") parser_delete.add_argument("copr", help="Name of your project to be deleted.") parser_delete.set_defaults(func="action_delete") # create the parser for the "fork" command parser_delete = subparsers.add_parser("fork", help="Fork the project and builds in it") parser_delete.add_argument("src", help="Which project should be forked") parser_delete.add_argument("dst", help="Name of the new project") parser_delete.add_argument("--confirm", action="store_true", help="Confirm forking into existing project") parser_delete.set_defaults(func="action_fork") ######################################################### ### Source-type related options ### ######################################################### parser_tito_args_parent = argparse.ArgumentParser(add_help=False) parser_tito_args_parent.add_argument("--git-url", metavar="URL", dest="git_url", required=True, help="URL to a project managed by Tito") parser_tito_args_parent.add_argument("--git-dir", metavar="DIRECTORY", dest="git_dir", help="Relative path from Git root to directory containing .spec file") parser_tito_args_parent.add_argument("--git-branch", metavar="BRANCH", dest="git_branch", help="Git branch that you want to build from") parser_tito_args_parent.add_argument("--test", dest="tito_test", choices=["on", "off"], help="Build the last commit instead of the last release tag") parser_pypi_args_parent = argparse.ArgumentParser(add_help=False) parser_pypi_args_parent.add_argument("--pythonversions", nargs="*", type=int, metavar="VERSION", default=[3, 2], help="For what Python versions to build (by default: 3 2)") parser_pypi_args_parent.add_argument("--packageversion", metavar = "PYPIVERSION", help="Version of the PyPI package to be built (by default latest)") parser_pypi_args_parent.add_argument("--packagename", required=True, metavar="PYPINAME", help="Name of the PyPI package to be built, required.") parser_mockscm_args_parent = argparse.ArgumentParser(add_help=False) parser_mockscm_args_parent.add_argument("--scm-type", metavar="TYPE", dest="scm_type", choices=["git", "svn"], default="git", help="specify versioning tool, default is 'git'") parser_mockscm_args_parent.add_argument("--scm-url", metavar="URL", dest="scm_url", help="url to a project versioned by Git or SVN, required") parser_mockscm_args_parent.add_argument("--scm-branch", metavar="BRANCH", dest="scm_branch", help="") parser_mockscm_args_parent.add_argument("--spec", dest="spec", metavar="FILE", help="relative path from SCM root to .spec file, required") parser_rubygems_args_parent = argparse.ArgumentParser(add_help=False) parser_rubygems_args_parent.add_argument("--gem", metavar="GEM", dest="gem_name", help="Specify gem name") parser_distgit_args_parent = argparse.ArgumentParser(add_help=False) parser_distgit_args_parent.add_argument("--clone-url", metavar="URL", dest="clone_url", required=True, help="Specify clone url for the distgit repository") parser_distgit_args_parent.add_argument("--branch", metavar="BRANCH", dest="branch", help="Specify branch to be used") ######################################################### ### Build options ### ######################################################### # parent parser for the builds commands below parser_build_parent = argparse.ArgumentParser(add_help=False) parser_build_parent.add_argument("copr", help="The copr repo to build the package in. Can be just name of project or even in format username/project or @groupname/project.") parser_build_parent.add_argument("--memory", dest="memory", help="") parser_build_parent.add_argument("--timeout", dest="timeout", help="") parser_build_parent.add_argument("--nowait", action="store_true", default=False, help="Don't wait for build") parser_build_parent.add_argument("-r", "--chroot", dest="chroots", action="append", help="If you don't need this build for all the project's chroots. You can use it several times for each chroot you need.") parser_build_parent.add_argument("--background", dest="background", action="store_true", default=False, help="Mark the build as a background job. It will have lesser priority than regular builds.") # create the parser for the "build" (url/upload) command parser_build = subparsers.add_parser("build", parents=[parser_build_parent], help="Build packages to a specified copr") parser_build.add_argument("pkgs", nargs="+", help="filename of SRPM or URL of packages to build") parser_build.set_defaults(func="action_build") # create the parser for the "buildpypi" command parser_build_pypi = subparsers.add_parser("buildpypi", parents=[parser_pypi_args_parent, parser_build_parent], help="Build PyPI package to a specified copr") parser_build_pypi.set_defaults(func="action_build_pypi") # create the parser for the "buildgem" command parser_build_rubygems = subparsers.add_parser("buildgem", parents=[parser_rubygems_args_parent, parser_build_parent], help="Build gem from rubygems.org to a specified copr") parser_build_rubygems.set_defaults(func="action_build_rubygems") # create the parser for the "buildfedpkg" command parser_build_distgit = subparsers.add_parser("buildfedpkg", parents=[parser_distgit_args_parent, parser_build_parent], help="Build package from pkgs.fedoraproject.org") parser_build_distgit.set_defaults(func="action_build_distgit") # create the parser for the "buildtito" command parser_build_tito = subparsers.add_parser("buildtito", parents=[parser_tito_args_parent, parser_build_parent], help="submit a build from Git repository via Tito to a specified copr") parser_build_tito.set_defaults(func="action_build_tito") # create the parser for the "buildmock" command parser_build_mock = subparsers.add_parser("buildmock", parents=[parser_mockscm_args_parent, parser_build_parent], help="submit a build from SCM repository via Mock to a specified copr") parser_build_mock.set_defaults(func="action_build_mock") # create the parser for the "status" command parser_status = subparsers.add_parser("status", help="Get build status of build specified by its ID") parser_status.add_argument("build_id", help="Build ID", type=int) parser_status.set_defaults(func="action_status") # create the parser for the "download-build" command parser_download_build = subparsers.add_parser("download-build", help="Fetches built packages") parser_download_build.add_argument("build_id", help="Build ID") parser_download_build.add_argument("-r", "--chroot", dest="chroots", action="append", help="Select chroots to fetch") parser_download_build.add_argument("--dest", "-d", dest="dest", help="Base directory to store packages", default=".") parser_download_build.set_defaults(func="action_download_build") # create the parser for the "cancel" command parser_cancel = subparsers.add_parser("cancel", help="Cancel build specified by its ID") parser_cancel.add_argument("build_id", help="Build ID") parser_cancel.set_defaults(func="action_cancel") # create the parser for the "watch-build" command parser_watch = subparsers.add_parser("watch-build", help="Watch status and progress of build(s)" " specified by their ID") parser_watch.add_argument("build_id", nargs="+", help="Build ID", type=int) parser_watch.set_defaults(func="action_watch_build") # create the parser for the "delete-build" command parser_delete = subparsers.add_parser("delete-build", help="Delete build specified by its ID") parser_delete.add_argument("build_id", help="Build ID", type=int) parser_delete.set_defaults(func="action_delete_build") ######################################################### ### Chroot options ### ######################################################### parser_edit_chroot = subparsers.add_parser("edit-chroot", help="Edit chroot of a project") parser_edit_chroot.add_argument("coprchroot", help="Path to a project chroot as owner/project/chroot or project/chroot") parser_edit_chroot_comps_group = parser_edit_chroot.add_mutually_exclusive_group() parser_edit_chroot_comps_group.add_argument("--upload-comps", metavar="FILEPATH", help="filepath to the comps.xml file to be uploaded") parser_edit_chroot_comps_group.add_argument("--delete-comps", action="store_true", help="deletes already existing comps.xml for the chroot") parser_edit_chroot.add_argument("--packages", help="space separated string of package names to be added to buildroot") parser_edit_chroot.add_argument("--repos", help="space separated string of additional repo urls for chroot") parser_edit_chroot.set_defaults(func="action_edit_chroot") parser_get_chroot = subparsers.add_parser("get-chroot", help="Get chroot of a project") parser_get_chroot.add_argument("coprchroot", help="Path to a project chroot as owner/project/chroot or project/chroot") parser_get_chroot.set_defaults(func="action_get_chroot") ######################################################### ### Package options ### ######################################################### # package edit/create parent parser_add_or_edit_package_parent = argparse.ArgumentParser(add_help=False) parser_add_or_edit_package_parent.add_argument("--name", help="Name of the package to be edited or created", metavar="PKGNAME", required=True) parser_add_or_edit_package_parent.add_argument("copr", help="The copr repo for the package. Can be just name of project or even in format username/project or @groupname/project.") parser_add_or_edit_package_parent.add_argument("--webhook-rebuild", choices=["on", "off"], help="Enable auto-rebuilding.") # Tito edit/create parser_add_package_tito = subparsers.add_parser("add-package-tito", help="Creates a new Tito package", parents=[parser_tito_args_parent, parser_add_or_edit_package_parent]) parser_add_package_tito.set_defaults(func="action_add_or_edit_package_tito", create=True) parser_edit_package_tito = subparsers.add_parser("edit-package-tito", help="Edits an existing Tito package", parents=[parser_tito_args_parent, parser_add_or_edit_package_parent]) parser_edit_package_tito.set_defaults(func="action_add_or_edit_package_tito", create=False) # PyPI edit/create parser_add_package_pypi = subparsers.add_parser("add-package-pypi", help="Creates a new PyPI package", parents=[parser_pypi_args_parent, parser_add_or_edit_package_parent]) parser_add_package_pypi.set_defaults(func="action_add_or_edit_package_pypi", create=True) parser_edit_package_pypi = subparsers.add_parser("edit-package-pypi", help="Edits an existing PyPI package", parents=[parser_pypi_args_parent, parser_add_or_edit_package_parent]) parser_edit_package_pypi.set_defaults(func="action_add_or_edit_package_pypi", create=False) # MockSCM edit/create parser_add_package_mockscm = subparsers.add_parser("add-package-mockscm", help="Creates a new Mock-SCM package", parents=[parser_mockscm_args_parent, parser_add_or_edit_package_parent]) parser_add_package_mockscm.set_defaults(func="action_add_or_edit_package_mockscm", create=True) parser_edit_package_mockscm = subparsers.add_parser("edit-package-mockscm", help="Edits an existing Mock-SCM package", parents=[parser_mockscm_args_parent, parser_add_or_edit_package_parent]) parser_edit_package_mockscm.set_defaults(func="action_add_or_edit_package_mockscm", create=False) # Rubygems edit/create parser_add_package_rubygems = subparsers.add_parser("add-package-rubygems", help="Creates a new RubyGems package", parents=[parser_rubygems_args_parent, parser_add_or_edit_package_parent]) parser_add_package_rubygems.set_defaults(func="action_add_or_edit_package_rubygems", create=True) parser_edit_package_rubygems = subparsers.add_parser("edit-package-rubygems", help="Edits a new RubyGems package", parents=[parser_rubygems_args_parent, parser_add_or_edit_package_parent]) parser_edit_package_rubygems.set_defaults(func="action_add_or_edit_package_rubygems", create=False) # package listing parser_list_packages = subparsers.add_parser("list-packages", help="Returns list of packages in the given copr") parser_list_packages.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.") parser_list_packages.add_argument("--with-latest-build", action="store_true", help="Also display data related to the latest build for the package.") parser_list_packages.add_argument("--with-latest-succeeded-build", action="store_true", help="Also display data related to the latest succeeded build for the package.") parser_list_packages.add_argument("--with-all-builds", action="store_true", help="Also display data related to the builds for the package.") parser_list_packages.set_defaults(func="action_list_packages") # package names listing parser_list_package_names = subparsers.add_parser("list-package-names", help="Returns list of package names in the given copr") parser_list_package_names.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.") parser_list_package_names.set_defaults(func="action_list_package_names") # single package fetching parser_get_package = subparsers.add_parser("get-package", help="Returns package of the given name in the given copr") parser_get_package.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.") parser_get_package.add_argument("--name", help="Name of a single package to be displayed", metavar="PKGNAME", required=True) parser_get_package.add_argument("--with-latest-build", action="store_true", help="Also display data related to the latest build for each package.") parser_get_package.add_argument("--with-latest-succeeded-build", action="store_true", help="Also display data related to the latest succeeded build for each package.") parser_get_package.add_argument("--with-all-builds", action="store_true", help="Also display data related to the builds for each package.") parser_get_package.set_defaults(func="action_get_package") # package deletion parser_delete_package = subparsers.add_parser("delete-package", help="Deletes the specified package") parser_delete_package.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.") parser_delete_package.add_argument("--name", help="Name of a package to be deleted", metavar="PKGNAME", required=True) parser_delete_package.set_defaults(func="action_delete_package") # package reseting parser_reset_package = subparsers.add_parser("reset-package", help="Resets (clears) default source of the specified package") parser_reset_package.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.") parser_reset_package.add_argument("--name", help="Name of a package to be reseted", metavar="PKGNAME", required=True) parser_reset_package.set_defaults(func="action_reset_package") # package building parser_build_package = subparsers.add_parser("build-package", parents=[parser_build_parent], help="Builds the package from its default source") parser_build_package.add_argument("--name", help="Name of a package to be built", metavar="PKGNAME", required=True) parser_build_package.set_defaults(func="action_build_package") # module building parser_build_module = subparsers.add_parser("build-module", help="Builds a given module in Copr") parser_build_module.add_argument("copr", help="The copr repo to list the packages of. Can be just name of project or even in format owner/project.", nargs="?") parser_build_module_mmd_source = parser_build_module.add_mutually_exclusive_group(required=True) parser_build_module_mmd_source.add_argument("--url", help="SCM with modulemd file in yaml format") parser_build_module_mmd_source.add_argument("--yaml", help="Path to modulemd file in yaml format") parser_build_module.set_defaults(func="action_build_module") return parser def parse_name(name): m = re.match(r"([^/]+)/(.*)", name) if m: owner = m.group(1) name = m.group(2) else: owner = None return owner, name def parse_chroot_path(path): m = re.match(r"(([^/]+)/)?([^/]+)/(.*)", path) if m: return m.group(2), m.group(3), m.group(4) return None def enable_debug(): logging.basicConfig( level=logging.DEBUG, format='[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', datefmt='%H:%M:%S' ) log.debug("# Debug log enabled #") def main(argv=sys.argv[1:]): try: # Set up parser for global args parser = setup_parser() # Parse the commandline arg = parser.parse_args(argv) if arg.debug: enable_debug() if not "func" in arg: parser.print_help() return commands = Commands(arg.config) getattr(commands, arg.func)(arg) except KeyboardInterrupt: sys.stderr.write("\nInterrupted by user.") sys.exit(1) except copr_exceptions.CoprBuildException as e: sys.stderr.write("\nBuild error: {0}\n".format(e)) sys.exit(4) except copr_exceptions.CoprUnknownResponseException as e: sys.stderr.write("\nError: {0}\n".format(e)) sys.exit(5) except copr_exceptions.CoprRequestException as e: sys.stderr.write("\nSomething went wrong:") sys.stderr.write("\nError: {0}\n".format(e)) sys.exit(1) except argparse.ArgumentTypeError as e: sys.stderr.write("\nError: {0}".format(e)) sys.exit(2) except copr_exceptions.CoprException as e: sys.stderr.write("\nError: {0}\n".format(e)) sys.exit(3) # except Exception as e: # print "Error: {0}".format(e) # sys.exit(100) if __name__ == "__main__": main() argparse-manpage-1.2.2/examples/copr/copr_cli/util.py000066400000000000000000000020531353472757700226540ustar00rootroot00000000000000# coding: utf-8 try: from progress.bar import Bar except ImportError: progress = False else: progress = True def format_size(bytes_in): if bytes_in > 1000 * 1000: return '%.1fMB' % (bytes_in / 1000.0 / 1000) elif bytes_in > 10 * 1000: return '%ikB' % (bytes_in / 1000) elif bytes_in > 1000: return '%.1fkB' % (bytes_in / 1000.0) else: return '%ibytes' % bytes_in class ProgressMixin(object): @property def download_speed(self): if self.avg == 0.0: return "..." return format_size(1 / self.avg) + "/s" @property def downloaded(self): return format_size(self.index) class DummyBar(object): # pylint: disable=redefined-builtin def __init__(self, max=None): pass def next(self, n=None): pass def finish(self): pass if progress: class ProgressBar(Bar, ProgressMixin): message = "%(percent)d%%" suffix = "%(downloaded)s %(download_speed)s eta %(eta_td)s" else: ProgressBar = DummyBar argparse-manpage-1.2.2/examples/copr/expected-output.1000066400000000000000000000571521353472757700227660ustar00rootroot00000000000000.TH copr "1" Manual .SH NAME copr .SH SYNOPSIS .B copr [-h] [--debug] [--config CONFIG] [--version] {whoami,list,mock-config,create,modify,delete,fork,build,buildpypi,buildgem,buildfedpkg,buildtito,buildmock,status,download-build,cancel,watch-build,delete-build,edit-chroot,get-chroot,add-package-tito,edit-package-tito,add-package-pypi,edit-package-pypi,add-package-mockscm,edit-package-mockscm,add-package-rubygems,edit-package-rubygems,list-packages,list-package-names,get-package,delete-package,reset-package,build-package,build-module} ... .SH OPTIONS .TP \fB\-\-debug\fR Enable debug output .TP \fB\-\-config\fR \fI\,CONFIG\/\fR Path to an alternative configuration file .TP \fB\-\-version\fR show program's version number and exit .SS \fBSub-commands\fR .TP \fBcopr\fR \fI\,whoami\/\fR Print username that the client authenticates with against copr-frontend .TP \fBcopr\fR \fI\,list\/\fR List all the copr of the provided .TP \fBcopr\fR \fI\,mock-config\/\fR Get the mock profile (similar to koji mock-config) .TP \fBcopr\fR \fI\,create\/\fR Create a new copr .TP \fBcopr\fR \fI\,modify\/\fR Modify existing copr .TP \fBcopr\fR \fI\,delete\/\fR Deletes the entire project .TP \fBcopr\fR \fI\,fork\/\fR Fork the project and builds in it .TP \fBcopr\fR \fI\,build\/\fR Build packages to a specified copr .TP \fBcopr\fR \fI\,buildpypi\/\fR Build PyPI package to a specified copr .TP \fBcopr\fR \fI\,buildgem\/\fR Build gem from rubygems.org to a specified copr .TP \fBcopr\fR \fI\,buildfedpkg\/\fR Build package from pkgs.fedoraproject.org .TP \fBcopr\fR \fI\,buildtito\/\fR submit a build from Git repository via Tito to a specified copr .TP \fBcopr\fR \fI\,buildmock\/\fR submit a build from SCM repository via Mock to a specified copr .TP \fBcopr\fR \fI\,status\/\fR Get build status of build specified by its ID .TP \fBcopr\fR \fI\,download-build\/\fR Fetches built packages .TP \fBcopr\fR \fI\,cancel\/\fR Cancel build specified by its ID .TP \fBcopr\fR \fI\,watch-build\/\fR Watch status and progress of build(s) specified by their ID .TP \fBcopr\fR \fI\,delete-build\/\fR Delete build specified by its ID .TP \fBcopr\fR \fI\,edit-chroot\/\fR Edit chroot of a project .TP \fBcopr\fR \fI\,get-chroot\/\fR Get chroot of a project .TP \fBcopr\fR \fI\,add-package-tito\/\fR Creates a new Tito package .TP \fBcopr\fR \fI\,edit-package-tito\/\fR Edits an existing Tito package .TP \fBcopr\fR \fI\,add-package-pypi\/\fR Creates a new PyPI package .TP \fBcopr\fR \fI\,edit-package-pypi\/\fR Edits an existing PyPI package .TP \fBcopr\fR \fI\,add-package-mockscm\/\fR Creates a new Mock-SCM package .TP \fBcopr\fR \fI\,edit-package-mockscm\/\fR Edits an existing Mock-SCM package .TP \fBcopr\fR \fI\,add-package-rubygems\/\fR Creates a new RubyGems package .TP \fBcopr\fR \fI\,edit-package-rubygems\/\fR Edits a new RubyGems package .TP \fBcopr\fR \fI\,list-packages\/\fR Returns list of packages in the given copr .TP \fBcopr\fR \fI\,list-package-names\/\fR Returns list of package names in the given copr .TP \fBcopr\fR \fI\,get-package\/\fR Returns package of the given name in the given copr .TP \fBcopr\fR \fI\,delete-package\/\fR Deletes the specified package .TP \fBcopr\fR \fI\,reset-package\/\fR Resets (clears) default source of the specified package .TP \fBcopr\fR \fI\,build-package\/\fR Builds the package from its default source .TP \fBcopr\fR \fI\,build-module\/\fR Builds a given module in Copr .SH OPTIONS 'copr whoami' usage: copr whoami [-h] .SH OPTIONS 'copr list' usage: copr list [-h] [username|@groupname] .TP \fBusername|@groupname\fR The username or @groupname that you would like to list the coprs of (defaults .br to current user) .SH OPTIONS 'copr mock-config' usage: copr mock-config [-h] project chroot .TP \fBproject\fR Expected format is /, / (including '@') or .br (name of project you own). .TP \fBchroot\fR chroot id, e.g. 'fedora\-rawhide\-x86_64' .SH OPTIONS 'copr create' usage: copr create [-h] [--chroot CHROOTS] [--repo REPOS] [--initial-pkgs INITIAL_PKGS] [--description DESCRIPTION] [--instructions INSTRUCTIONS] [--disable_createrepo DISABLE_CREATEREPO] [--enable-net {on,off}] [--unlisted-on-hp {on,off}] [--persistent] [--auto-prune {on,off}] name .TP \fBname\fR The name of the copr to create .TP \fB\-\-chroot\fR \fI\,CHROOTS\/\fR Chroot to use for this copr .TP \fB\-\-repo\fR \fI\,REPOS\/\fR Repository to add to this copr .TP \fB\-\-initial\-pkgs\fR \fI\,INITIAL_PKGS\/\fR List of packages URL to build in this new copr .TP \fB\-\-description\fR \fI\,DESCRIPTION\/\fR Description of the copr .TP \fB\-\-instructions\fR \fI\,INSTRUCTIONS\/\fR Instructions for the copr .TP \fB\-\-disable_createrepo\fR \fI\,DISABLE_CREATEREPO\/\fR Disable metadata auto generation .TP \fB\-\-enable\-net\fR {on,off} If net should be enabled for builds in this project (default is off) .TP \fB\-\-unlisted\-on\-hp\fR {on,off} The project will not be shown on COPR home page .TP \fB\-\-persistent\fR Project and its builds will be undeletable. This option can only be specified .br by a COPR admin. .TP \fB\-\-auto\-prune\fR {on,off} If auto\-deletion of project's obsoleted builds should be enabled (default is .br on). This option can only be specified by a COPR admin. .SH OPTIONS 'copr modify' usage: copr modify [-h] [--chroot CHROOTS] [--description DESCRIPTION] [--instructions INSTRUCTIONS] [--repo REPOS] [--disable_createrepo DISABLE_CREATEREPO] [--enable-net {on,off}] [--unlisted-on-hp {on,off}] [--auto-prune {on,off}] name .TP \fBname\fR The name of the copr to modify .TP \fB\-\-chroot\fR \fI\,CHROOTS\/\fR Chroot to use for this copr .TP \fB\-\-description\fR \fI\,DESCRIPTION\/\fR Description of the copr .TP \fB\-\-instructions\fR \fI\,INSTRUCTIONS\/\fR Instructions for the copr .TP \fB\-\-repo\fR \fI\,REPOS\/\fR Repository to add to this copr .TP \fB\-\-disable_createrepo\fR \fI\,DISABLE_CREATEREPO\/\fR Disable metadata auto generation .TP \fB\-\-enable\-net\fR {on,off} If net should be enabled for builds in this project (default is "don't .br change") .TP \fB\-\-unlisted\-on\-hp\fR {on,off} The project will not be shown on COPR home page .TP \fB\-\-auto\-prune\fR {on,off} If auto\-deletion of project's obsoleted builds should be enabled. This option .br can only be specified by a COPR admin. .SH OPTIONS 'copr delete' usage: copr delete [-h] copr .TP \fBcopr\fR Name of your project to be deleted. .SH OPTIONS 'copr fork' usage: copr fork [-h] [--confirm] src dst .TP \fBsrc\fR Which project should be forked .TP \fBdst\fR Name of the new project .TP \fB\-\-confirm\fR Confirm forking into existing project .SH OPTIONS 'copr build' usage: copr build [-h] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr pkgs [pkgs ...] .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fBpkgs\fR filename of SRPM or URL of packages to build .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr buildpypi' usage: copr buildpypi [-h] [--pythonversions [VERSION [VERSION ...]]] [--packageversion PYPIVERSION] --packagename PYPINAME [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-pythonversions\fR [VERSION [VERSION ...]] For what Python versions to build (by default: 3 2) .TP \fB\-\-packageversion\fR PYPIVERSION Version of the PyPI package to be built (by default latest) .TP \fB\-\-packagename\fR PYPINAME Name of the PyPI package to be built, required. .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr buildgem' usage: copr buildgem [-h] [--gem GEM] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-gem\fR GEM Specify gem name .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr buildfedpkg' usage: copr buildfedpkg [-h] --clone-url URL [--branch BRANCH] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-clone\-url\fR URL Specify clone url for the distgit repository .TP \fB\-\-branch\fR BRANCH Specify branch to be used .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr buildtito' usage: copr buildtito [-h] --git-url URL [--git-dir DIRECTORY] [--git-branch BRANCH] [--test {on,off}] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-git\-url\fR URL URL to a project managed by Tito .TP \fB\-\-git\-dir\fR DIRECTORY Relative path from Git root to directory containing .spec file .TP \fB\-\-git\-branch\fR BRANCH Git branch that you want to build from .TP \fB\-\-test\fR {on,off} Build the last commit instead of the last release tag .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr buildmock' usage: copr buildmock [-h] [--scm-type TYPE] [--scm-url URL] [--scm-branch BRANCH] [--spec FILE] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-scm\-type\fR TYPE specify versioning tool, default is 'git' .TP \fB\-\-scm\-url\fR URL url to a project versioned by Git or SVN, required .TP \fB\-\-scm\-branch\fR BRANCH .TP \fB\-\-spec\fR FILE relative path from SCM root to .spec file, required .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .SH OPTIONS 'copr status' usage: copr status [-h] build_id .TP \fBbuild_id\fR Build ID .SH OPTIONS 'copr download-build' usage: copr download-build [-h] [-r CHROOTS] [--dest DEST] build_id .TP \fBbuild_id\fR Build ID .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR Select chroots to fetch .TP \fB\-\-dest\fR \fI\,DEST\/\fR, \fB\-d\fR \fI\,DEST\/\fR Base directory to store packages .SH OPTIONS 'copr cancel' usage: copr cancel [-h] build_id .TP \fBbuild_id\fR Build ID .SH OPTIONS 'copr watch-build' usage: copr watch-build [-h] build_id [build_id ...] .TP \fBbuild_id\fR Build ID .SH OPTIONS 'copr delete-build' usage: copr delete-build [-h] build_id .TP \fBbuild_id\fR Build ID .SH OPTIONS 'copr edit-chroot' usage: copr edit-chroot [-h] [--upload-comps FILEPATH | --delete-comps] [--packages PACKAGES] [--repos REPOS] coprchroot .TP \fBcoprchroot\fR Path to a project chroot as owner/project/chroot or project/chroot .TP \fB\-\-upload\-comps\fR FILEPATH filepath to the comps.xml file to be uploaded .TP \fB\-\-delete\-comps\fR deletes already existing comps.xml for the chroot .TP \fB\-\-packages\fR \fI\,PACKAGES\/\fR space separated string of package names to be added to buildroot .TP \fB\-\-repos\fR \fI\,REPOS\/\fR space separated string of additional repo urls for chroot .SH OPTIONS 'copr get-chroot' usage: copr get-chroot [-h] coprchroot .TP \fBcoprchroot\fR Path to a project chroot as owner/project/chroot or project/chroot .SH OPTIONS 'copr add-package-tito' usage: copr add-package-tito [-h] --git-url URL [--git-dir DIRECTORY] [--git-branch BRANCH] [--test {on,off}] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-git\-url\fR URL URL to a project managed by Tito .TP \fB\-\-git\-dir\fR DIRECTORY Relative path from Git root to directory containing .spec file .TP \fB\-\-git\-branch\fR BRANCH Git branch that you want to build from .TP \fB\-\-test\fR {on,off} Build the last commit instead of the last release tag .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr edit-package-tito' usage: copr edit-package-tito [-h] --git-url URL [--git-dir DIRECTORY] [--git-branch BRANCH] [--test {on,off}] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-git\-url\fR URL URL to a project managed by Tito .TP \fB\-\-git\-dir\fR DIRECTORY Relative path from Git root to directory containing .spec file .TP \fB\-\-git\-branch\fR BRANCH Git branch that you want to build from .TP \fB\-\-test\fR {on,off} Build the last commit instead of the last release tag .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr add-package-pypi' usage: copr add-package-pypi [-h] [--pythonversions [VERSION [VERSION ...]]] [--packageversion PYPIVERSION] --packagename PYPINAME --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-pythonversions\fR [VERSION [VERSION ...]] For what Python versions to build (by default: 3 2) .TP \fB\-\-packageversion\fR PYPIVERSION Version of the PyPI package to be built (by default latest) .TP \fB\-\-packagename\fR PYPINAME Name of the PyPI package to be built, required. .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr edit-package-pypi' usage: copr edit-package-pypi [-h] [--pythonversions [VERSION [VERSION ...]]] [--packageversion PYPIVERSION] --packagename PYPINAME --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-pythonversions\fR [VERSION [VERSION ...]] For what Python versions to build (by default: 3 2) .TP \fB\-\-packageversion\fR PYPIVERSION Version of the PyPI package to be built (by default latest) .TP \fB\-\-packagename\fR PYPINAME Name of the PyPI package to be built, required. .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr add-package-mockscm' usage: copr add-package-mockscm [-h] [--scm-type TYPE] [--scm-url URL] [--scm-branch BRANCH] [--spec FILE] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-scm\-type\fR TYPE specify versioning tool, default is 'git' .TP \fB\-\-scm\-url\fR URL url to a project versioned by Git or SVN, required .TP \fB\-\-scm\-branch\fR BRANCH .TP \fB\-\-spec\fR FILE relative path from SCM root to .spec file, required .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr edit-package-mockscm' usage: copr edit-package-mockscm [-h] [--scm-type TYPE] [--scm-url URL] [--scm-branch BRANCH] [--spec FILE] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-scm\-type\fR TYPE specify versioning tool, default is 'git' .TP \fB\-\-scm\-url\fR URL url to a project versioned by Git or SVN, required .TP \fB\-\-scm\-branch\fR BRANCH .TP \fB\-\-spec\fR FILE relative path from SCM root to .spec file, required .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr add-package-rubygems' usage: copr add-package-rubygems [-h] [--gem GEM] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-gem\fR GEM Specify gem name .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr edit-package-rubygems' usage: copr edit-package-rubygems [-h] [--gem GEM] --name PKGNAME [--webhook-rebuild {on,off}] copr .TP \fBcopr\fR The copr repo for the package. Can be just name of project or even in format .br username/project or @groupname/project. .TP \fB\-\-gem\fR GEM Specify gem name .TP \fB\-\-name\fR PKGNAME Name of the package to be edited or created .TP \fB\-\-webhook\-rebuild\fR {on,off} Enable auto\-rebuilding. .SH OPTIONS 'copr list-packages' usage: copr list-packages [-h] [--with-latest-build] [--with-latest-succeeded-build] [--with-all-builds] copr .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .TP \fB\-\-with\-latest\-build\fR Also display data related to the latest build for the package. .TP \fB\-\-with\-latest\-succeeded\-build\fR Also display data related to the latest succeeded build for the package. .TP \fB\-\-with\-all\-builds\fR Also display data related to the builds for the package. .SH OPTIONS 'copr list-package-names' usage: copr list-package-names [-h] copr .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .SH OPTIONS 'copr get-package' usage: copr get-package [-h] --name PKGNAME [--with-latest-build] [--with-latest-succeeded-build] [--with-all-builds] copr .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .TP \fB\-\-name\fR PKGNAME Name of a single package to be displayed .TP \fB\-\-with\-latest\-build\fR Also display data related to the latest build for each package. .TP \fB\-\-with\-latest\-succeeded\-build\fR Also display data related to the latest succeeded build for each package. .TP \fB\-\-with\-all\-builds\fR Also display data related to the builds for each package. .SH OPTIONS 'copr delete-package' usage: copr delete-package [-h] --name PKGNAME copr .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .TP \fB\-\-name\fR PKGNAME Name of a package to be deleted .SH OPTIONS 'copr reset-package' usage: copr reset-package [-h] --name PKGNAME copr .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .TP \fB\-\-name\fR PKGNAME Name of a package to be reseted .SH OPTIONS 'copr build-package' usage: copr build-package [-h] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] [-r CHROOTS] [--background] --name PKGNAME copr .TP \fBcopr\fR The copr repo to build the package in. Can be just name of project or even in .br format username/project or @groupname/project. .TP \fB\-\-memory\fR \fI\,MEMORY\/\fR .TP \fB\-\-timeout\fR \fI\,TIMEOUT\/\fR .TP \fB\-\-nowait\fR Don't wait for build .TP \fB\-r\fR \fI\,CHROOTS\/\fR, \fB\-\-chroot\fR \fI\,CHROOTS\/\fR If you don't need this build for all the project's chroots. You can use it .br several times for each chroot you need. .TP \fB\-\-background\fR Mark the build as a background job. It will have lesser priority than regular .br builds. .TP \fB\-\-name\fR PKGNAME Name of a package to be built .SH OPTIONS 'copr build-module' usage: copr build-module [-h] (--url URL | --yaml YAML) [copr] .TP \fBcopr\fR The copr repo to list the packages of. Can be just name of project or even in .br format owner/project. .TP \fB\-\-url\fR \fI\,URL\/\fR SCM with modulemd file in yaml format .TP \fB\-\-yaml\fR \fI\,YAML\/\fR Path to modulemd file in yaml format .SH AUTHORS .B example was written by John Doe . .SH DISTRIBUTION The latest version of example may be downloaded from .UR http://example.com .UE argparse-manpage-1.2.2/examples/copr/fake-deps/000077500000000000000000000000001353472757700213725ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/HACK000066400000000000000000000000001353472757700220110ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/copr/000077500000000000000000000000001353472757700223355ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/copr/README000066400000000000000000000000431353472757700232120ustar00rootroot00000000000000Hack to work-around missing stuff. argparse-manpage-1.2.2/examples/copr/fake-deps/copr/__init__.py000066400000000000000000000000531353472757700244440ustar00rootroot00000000000000# Hack class CoprClient(object): pass argparse-manpage-1.2.2/examples/copr/fake-deps/copr/client/000077500000000000000000000000001353472757700236135ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/copr/client/__init__.py000066400000000000000000000000001353472757700257120ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/copr/client/responses.py000066400000000000000000000000351353472757700262040ustar00rootroot00000000000000class CoprResponse: pass argparse-manpage-1.2.2/examples/copr/fake-deps/copr/exceptions.py000066400000000000000000000000001353472757700250560ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/fake-deps/jinja2.py000066400000000000000000000000341353472757700231160ustar00rootroot00000000000000class Environment: pass argparse-manpage-1.2.2/examples/copr/fake-deps/simplejson.py000077700000000000000000000000001353472757700245532HACKustar00rootroot00000000000000argparse-manpage-1.2.2/examples/copr/setup.cfg000066400000000000000000000001261353472757700213530ustar00rootroot00000000000000[build_manpages] manpages = copr-cli.1:module=copr_cli.main:function=setup_parser argparse-manpage-1.2.2/examples/copr/setup.py000066400000000000000000000017051353472757700212500ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Example of argparse taken from: # https://pagure.io/copr/copr/blob/a4feb01bc35b8554f503d41795e7a184ff929dd4/f/cli/copr_cli import os import sys from setuptools import setup, find_packages # Just to make sure that build_manpage can be found. sys.path = [os.path.join(os.getcwd(), 'fake-deps')] + sys.path from build_manpages.build_manpages \ import build_manpages, get_build_py_cmd, get_install_cmd from setuptools.command.build_py import build_py from setuptools.command.install import install setup( name='example', description='This project does nothing.', long_description=('Long description of the project.'), author='John Doe', author_email='jd@example.com', version='0.1.0', url='http://example.com', cmdclass={ 'build_manpages': build_manpages, 'build_py': get_build_py_cmd(build_py), 'install': get_install_cmd(install), }, packages=find_packages(), ) argparse-manpage-1.2.2/examples/old_format/000077500000000000000000000000001353472757700207165ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/old_format/README.md000066400000000000000000000011111353472757700221670ustar00rootroot00000000000000# Usage Download `build_manpage.py` and place it somewhere where Python can find it. In your `setup.py` add: ```python [...] from build_manpage import build_manpage setup( [...] cmdclass={'build_manpage': build_manpage} ) ``` In your `setup.cfg` add: ``` [build_manpage] output=data/mymanpage.1 parser=myapp.somemod:get_parser ``` where `output` is the destination path for the generated manpage and `parser` is an import path pointing to a optparser instance or a function returning such an instance. Then run `setup.py build_manpage` to build a manpage for your project. argparse-manpage-1.2.2/examples/old_format/example.py000066400000000000000000000010071353472757700227210ustar00rootroot00000000000000from optparse import OptionParser # This function returns a OptionParser def get_parser(): parser = OptionParser( usage="The usage.", description="This program does nothing.") parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") return parser argparse-manpage-1.2.2/examples/old_format/expected-output.1000066400000000000000000000010461353472757700241400ustar00rootroot00000000000000.TH example 1 2017\-09\-24 "example v.0.1.0-dev" .SH NAME example \- This script does nothing. .SH SYNOPSIS .B example The usage. .SH DESCRIPTION Description and long description are both used by build_manpage. .SH OPTIONS .TP .B \-h, \-\-help show this help message and exit .TP .B \-f FILE, \-\-file=FILE write report to FILE .TP .B \-q, \-\-quiet don't print status messages to stdout .SH AUTHORS .B example was written by John Doe . .SH DISTRIBUTION The latest version of example may be downloaded from .UR http://example.com .UE argparse-manpage-1.2.2/examples/old_format/setup.cfg000066400000000000000000000000731353472757700225370ustar00rootroot00000000000000[build_manpage] output=example.1 parser=example:get_parser argparse-manpage-1.2.2/examples/old_format/setup.py000066400000000000000000000014251353472757700224320ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Example setup.py script # # The path tweaking at the top is just to make sure, that build_manpage # can be imported. # # 1. Run "setup.py build_manpage" # 2. Run "man ./example.1" to see the result. # import os import sys from distutils.core import setup # Just to make sure that build_manpage can be found. sys.path.insert(0, os.getcwd()) from build_manpages.build_manpage import build_manpage setup( name='example', description='This script does nothing.', long_description=( 'Description and long description are both used by build_manpage.'), author='John Doe', author_email='jd@example.com', version='0.1.0-dev', url='http://example.com', py_modules=['example'], cmdclass={'build_manpage': build_manpage} ) argparse-manpage-1.2.2/examples/raw-description/000077500000000000000000000000001353472757700217025ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/raw-description/bin/000077500000000000000000000000001353472757700224525ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/raw-description/bin/dg000077500000000000000000000105471353472757700230010ustar00rootroot00000000000000#!/bin/python from __future__ import print_function import sys import tempfile import shutil from argparse import ArgumentParser, RawDescriptionHelpFormatter def error(msg): print(msg, file=sys.stderr) def die(msg): error(msg) sys.exit(1) description = \ """ Generate script using predefined metadata about distribution and templates. As an example of 'dg' usage, to generate _Dockerfile_ for Fedora 21 64-bit system, you may use command(s): $ cd project/directory $ dg --spec docker-data.yaml \\ --template docker.tpl \\ --distro fedora-21-x86_64.yaml """ parser = ArgumentParser( description=description, formatter_class=RawDescriptionHelpFormatter, ) parser.man_short_description = "templating system/generator for distributions" parser.add_argument( '--projectdir', metavar='PROJECTDIR', type=str, help='Directory with project (defaults to CWD)', default="." ) parser.add_argument( '--distro', metavar='DIST', type=str, help='Use distribution metadata specified by DIST yaml file', default="fedora-21-x86_64.yaml", ) parser.add_argument( '--multispec', metavar='MULTISPEC', type=str, help='Use MULTISPEC yaml file to fill the TEMPLATE file', ) parser.add_argument( '--multispec-selector', metavar='MULTISPEC_SELECTOR', type=str, help='Selectors for the multispec file', action='append', default=[], ) parser.add_argument( '--spec', metavar='SPEC', type=str, help='Use SPEC yaml file to fill the TEMPLATE file', action='append', ) parser.add_argument( '--output', metavar='OUTPUT', type=str, help='Write result to OUTPUT file instead of stdout', ) parser.add_argument( '--macros-from', metavar='PROJECTDIR', type=str, action='append', help='Load variables from PROJECTDIR', ) parser.add_argument( '--container', metavar='CONTAINER_TYPE', type=str, help='Container type, e.g. \'docker\'', default=False, ) parser.add_argument( '--macro', metavar='MACRO', type=str, action='append', help='Define distgen\'s macro', ) parser.add_argument( '--max-passes', metavar='PASSES', type=int, default=1, help='Maximum number of rendering passes, defaults to 1 (== no re-rendering)', ) tpl_or_combinations = parser.add_mutually_exclusive_group(required=True) tpl_or_combinations.add_argument( '--template', metavar='TEMPLATE', type=str, help='Use TEMPLATE file, e.g. docker.tpl or a template string, ' 'e.g. "{{ config.docker.from }}"' ) tpl_or_combinations.add_argument( '--multispec-combinations', action='store_true', help='Print available multispec combinations', ) def print_multispec_combinations(args): ms = Multispec.from_path(args.projectdir, args.multispec) for c in ms.get_all_combinations(): to_print = ['--distro {0}'.format(c.pop('distro'))] [to_print.append('--multispec-selector {0}={1}'.format(k, v)) for k, v in c.items()] print(' '.join(to_print)) def render_template(args): temp_filename = False output = sys.stdout try: if args.output: _, temp_filename = tempfile.mkstemp(prefix="distgen-") output = open(temp_filename, 'w') except: die("can't create temporary file for '{0}'".format(args.output)) cmd_cfg = CommandsConfig() cmd_cfg.container = args.container explicit_macros = {} if args.macro: for i in args.macro: key, value = i.split(' ', 1) explicit_macros[key] = value if args.template == '-': args.template = "/proc/self/fd/0" generator = Generator() generator.load_project(args.projectdir) generator.render( args.spec, args.multispec, args.multispec_selector, args.template, args.distro, cmd_cfg, output, args.macros_from, explicit_macros, args.max_passes, ) if temp_filename: try: output.close() shutil.move(temp_filename, args.output) except: die("can't move '{0}' into '{1}'".format(temp_filename, args.output)) def main(): args = parser.parse_args() if args.multispec_combinations: print_multispec_combinations(args) else: render_template(args) if __name__ == "__main__": main() argparse-manpage-1.2.2/examples/raw-description/expected-output.1000066400000000000000000000036121353472757700251250ustar00rootroot00000000000000.TH dg "1" Manual .SH NAME dg \- templating system/generator for distributions .SH SYNOPSIS .B dg [-h] [--projectdir PROJECTDIR] [--distro DIST] [--multispec MULTISPEC] [--multispec-selector MULTISPEC_SELECTOR] [--spec SPEC] [--output OUTPUT] [--macros-from PROJECTDIR] [--container CONTAINER_TYPE] [--macro MACRO] [--max-passes PASSES] (--template TEMPLATE | --multispec-combinations) .SH DESCRIPTION Generate script using predefined metadata about distribution and .br templates. .br .br As an example of 'dg' usage, to generate _Dockerfile_ for Fedora .br 21 64\-bit system, you may use command(s): .br .br $ cd project/directory .br $ dg \-\-spec docker\-data.yaml \\ .br \-\-template docker.tpl \\ .br \-\-distro fedora\-21\-x86_64.yaml .SH OPTIONS .TP \fB\-\-projectdir\fR PROJECTDIR Directory with project (defaults to CWD) .TP \fB\-\-distro\fR DIST Use distribution metadata specified by DIST yaml file .TP \fB\-\-multispec\fR MULTISPEC Use MULTISPEC yaml file to fill the TEMPLATE file .TP \fB\-\-multispec\-selector\fR MULTISPEC_SELECTOR Selectors for the multispec file .TP \fB\-\-spec\fR SPEC Use SPEC yaml file to fill the TEMPLATE file .TP \fB\-\-output\fR OUTPUT Write result to OUTPUT file instead of stdout .TP \fB\-\-macros\-from\fR PROJECTDIR Load variables from PROJECTDIR .TP \fB\-\-container\fR CONTAINER_TYPE Container type, e.g. 'docker' .TP \fB\-\-macro\fR MACRO Define distgen's macro .TP \fB\-\-max\-passes\fR PASSES Maximum number of rendering passes, defaults to 1 (== no re\-rendering) .TP \fB\-\-template\fR TEMPLATE Use TEMPLATE file, e.g. docker.tpl or a template string, e.g. "{{ config.docker.from }}" .TP \fB\-\-multispec\-combinations\fR Print available multispec combinations .SH AUTHORS .B example was written by John Doe . .SH DISTRIBUTION The latest version of example may be downloaded from .UR http://example.com .UE argparse-manpage-1.2.2/examples/raw-description/setup.cfg000066400000000000000000000001051353472757700235170ustar00rootroot00000000000000[build_manpages] manpages = man/dg.1:object=parser:pyfile=bin/dg argparse-manpage-1.2.2/examples/raw-description/setup.py000066400000000000000000000017261353472757700234220ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Example of argparse taken from: # https://pagure.io/copr/copr/blob/a4feb01bc35b8554f503d41795e7a184ff929dd4/f/cli/copr_cli import os import sys from setuptools import setup, find_packages # Just to make sure that build_manpage can be found. sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..')) from build_manpages.build_manpages \ import build_manpages, get_build_py_cmd, get_install_cmd from setuptools.command.install import install from distutils.command.build import build setup( name='example', description='This project does nothing.', long_description=('Long description of the project.'), author='John Doe', author_email='jd@example.com', version='0.1.0', url='http://example.com', packages=find_packages(), scripts=['bin/dg'], cmdclass={ 'build_manpages': build_manpages, 'build': get_build_py_cmd(build), 'install': get_install_cmd(install), }, ) argparse-manpage-1.2.2/examples/resalloc/000077500000000000000000000000001353472757700203745ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/bin/000077500000000000000000000000001353472757700211445ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/bin/resalloc000077500000000000000000000060041353472757700226760ustar00rootroot00000000000000#!/usr/bin/env python # Resalloc client. # Copyright (C) 2017 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys import argparse from resalloc.client import Ticket, Connection from resalloc.version import resalloc_version parser = argparse.ArgumentParser() parser.add_argument( "--connection", dest="connection", default="http://localhost:49100") parser.add_argument( '--version', action='version', version='%(prog)s (client) {0}'.format(resalloc_version)) subparsers = parser.add_subparsers(title="actions", dest='subparser') subparsers.required = True parser_new_ticket = subparsers.add_parser( "ticket", help="Create ticket") parser_new_ticket.add_argument( "--tag", dest="tags", action="append", required=True, help="What tag the Resource should have") parser_get_ticket = subparsers.add_parser( "ticket-check", help="Obtain ticket") parser_get_ticket.add_argument( "ticket", help="Get the ticket") parser_wait_ticket = subparsers.add_parser( "ticket-wait", help="Wait till ticket is ready and write the output" ) parser_wait_ticket.add_argument( "ticket", help="ID of ticket to wait for") parser_close_ticket = subparsers.add_parser( "ticket-close", help="Close a ticket") parser_close_ticket.add_argument( "ticket", help="ID of ticket to be closed") def main(): try: arg = parser.parse_args() conn = Connection(arg.connection) if 'ticket' == arg.subparser: ticket = conn.newTicket(arg.tags) print(ticket.id) elif 'ticket-check' == arg.subparser: ticket = conn.getTicket(arg.ticket) if ticket.collect(): sys.stdout.write(str(ticket.output)) else: sys.stderr.write("ticket is still not processed\n") return 1 elif 'ticket-wait' == arg.subparser: ticket = conn.getTicket(arg.ticket) output = ticket.wait() print(str(output)) elif 'ticket-close' == arg.subparser: ticket = conn.getTicket(arg.ticket) ticket.close() else: assert(0) except KeyboardInterrupt: sys.stderr.write("\nInterrupted by user.") sys.exit(1) if __name__ == "__main__": sys.exit(main()) argparse-manpage-1.2.2/examples/resalloc/bin/resalloc-maint000077500000000000000000000040261353472757700240060ustar00rootroot00000000000000#!/usr/bin/env python # Resalloc administrating tool. # Copyright (C) 2017 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys import argparse from resallocserver.maint import Maintainer parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title="actions", dest='subparser') subparsers.required = True parser.add_argument("--duh", help="huhh") p_list = subparsers.add_parser( "resource-list", help="List available resources") p_list.add_argument( "--up", dest='up', action='store_true', help="List only ready-to-take resources") parser_resource_delete = subparsers.add_parser( "resource-delete", help="Delete resource") parser_resource_delete.add_argument( "resource", help="The resource ID") p_t_list = subparsers.add_parser( "ticket-list", help="List not-yet-closed tickets") def main(): try: args = parser.parse_args() maint = Maintainer() if 'resource-list' in args.subparser: maint.resource_list(up=args.up) elif 'resource-delete' in args.subparser: maint.resource_delete(args.resource) elif 'ticket-list' in args.subparser: maint.ticket_list() except KeyboardInterrupt: sys.stderr.write("\nInterrupted by user.") sys.exit(1) if __name__ == "__main__": sys.exit(main()) argparse-manpage-1.2.2/examples/resalloc/expected/000077500000000000000000000000001353472757700221755ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/expected/man/000077500000000000000000000000001353472757700227505ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/expected/man/resalloc-maint.1000066400000000000000000000017431353472757700257510ustar00rootroot00000000000000.TH resalloc-maint "1" Manual .SH NAME resalloc-maint .SH SYNOPSIS .B resalloc-maint [-h] [--duh DUH] {resource-list,resource-delete,ticket-list} ... .SH OPTIONS .TP \fB\-\-duh\fR \fI\,DUH\/\fR huhh .SS \fBSub-commands\fR .TP \fBresalloc-maint\fR \fI\,resource-list\/\fR List available resources .TP \fBresalloc-maint\fR \fI\,resource-delete\/\fR Delete resource .TP \fBresalloc-maint\fR \fI\,ticket-list\/\fR List not-yet-closed tickets .SH OPTIONS 'resalloc-maint resource-list' usage: resalloc-maint resource-list [-h] [--up] .TP \fB\-\-up\fR List only ready\-to\-take resources .SH OPTIONS 'resalloc-maint resource-delete' usage: resalloc-maint resource-delete [-h] resource .TP \fBresource\fR The resource ID .SH OPTIONS 'resalloc-maint ticket-list' usage: resalloc-maint ticket-list [-h] .SH AUTHORS .B resalloc was written by Pavel Raiskup . .SH DISTRIBUTION The latest version of resalloc may be downloaded from .UR https://github.com/praiskup/resalloc .UE argparse-manpage-1.2.2/examples/resalloc/expected/man/resalloc.1000066400000000000000000000023311353472757700246350ustar00rootroot00000000000000.TH resalloc "1" Manual .SH NAME resalloc .SH SYNOPSIS .B resalloc [-h] [--connection CONNECTION] [--version] {ticket,ticket-check,ticket-wait,ticket-close} ... .SH OPTIONS .TP \fB\-\-connection\fR \fI\,CONNECTION\/\fR .TP \fB\-\-version\fR show program's version number and exit .SS \fBSub-commands\fR .TP \fBresalloc\fR \fI\,ticket\/\fR Create ticket .TP \fBresalloc\fR \fI\,ticket-check\/\fR Obtain ticket .TP \fBresalloc\fR \fI\,ticket-wait\/\fR Wait till ticket is ready and write the output .TP \fBresalloc\fR \fI\,ticket-close\/\fR Close a ticket .SH OPTIONS 'resalloc ticket' usage: resalloc ticket [-h] --tag TAGS .TP \fB\-\-tag\fR \fI\,TAGS\/\fR What tag the Resource should have .SH OPTIONS 'resalloc ticket-check' usage: resalloc ticket-check [-h] ticket .TP \fBticket\fR Get the ticket .SH OPTIONS 'resalloc ticket-wait' usage: resalloc ticket-wait [-h] ticket .TP \fBticket\fR ID of ticket to wait for .SH OPTIONS 'resalloc ticket-close' usage: resalloc ticket-close [-h] ticket .TP \fBticket\fR ID of ticket to be closed .SH AUTHORS .B resalloc was written by Pavel Raiskup . .SH DISTRIBUTION The latest version of resalloc may be downloaded from .UR https://github.com/praiskup/resalloc .UE argparse-manpage-1.2.2/examples/resalloc/requirements.txt000066400000000000000000000000001353472757700236460ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/resalloc/000077500000000000000000000000001353472757700222005ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/resalloc/__init__.py000066400000000000000000000000001353472757700242770ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/resalloc/client.py000066400000000000000000000000631353472757700240270ustar00rootroot00000000000000class Ticket: pass class Connection: pass argparse-manpage-1.2.2/examples/resalloc/resalloc/version.py000066400000000000000000000000271353472757700242360ustar00rootroot00000000000000resalloc_version = '0' argparse-manpage-1.2.2/examples/resalloc/resallocserver/000077500000000000000000000000001353472757700234275ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/resallocserver/__init__.py000066400000000000000000000000001353472757700255260ustar00rootroot00000000000000argparse-manpage-1.2.2/examples/resalloc/resallocserver/maint.py000066400000000000000000000000331353472757700251050ustar00rootroot00000000000000class Maintainer: pass argparse-manpage-1.2.2/examples/resalloc/setup.cfg000066400000000000000000000002221353472757700222110ustar00rootroot00000000000000[build_manpages] manpages = man/resalloc.1:object=parser:pyfile=bin/resalloc man/resalloc-maint.1:object=parser:pyfile=bin/resalloc-maint argparse-manpage-1.2.2/examples/resalloc/setup.py000066400000000000000000000043011353472757700221040ustar00rootroot00000000000000# Resalloc setup script. # Copyright (C) 2017 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os, sys from setuptools import setup, find_packages from resalloc.version import resalloc_version from os import listdir, path # For the manual pages generator. from setuptools.command.build_py import build_py from setuptools.command.install import install try: sys.path = [os.path.join(os.getcwd(), 'build_manpages')] + sys.path from build_manpages.build_manpages \ import build_manpages, get_build_py_cmd, get_install_cmd except: print("=======================================") print("Use 'git submodule update --init' first") print("=======================================") raise project = "resalloc" datadir = "share" pkgdatadir = datadir + "/" + project def get_requirements(): with open('requirements.txt') as f: return f.read().splitlines() long_description=""" Resource allocator """.strip() setup( name=project, version=resalloc_version, description='Client/server application for maintaining (expensive) resources', long_description=long_description, author='Pavel Raiskup', author_email='praiskup@redhat.com', license='GPLv2+', url='https://github.com/praiskup/resalloc', platforms=['any'], packages=find_packages(), scripts=['bin/resalloc', 'bin/resalloc-maint'], install_requires=get_requirements(), cmdclass={ 'build_manpages': build_manpages, 'build_py': get_build_py_cmd(build_py), 'install': get_install_cmd(install), }, ) argparse-manpage-1.2.2/pytest.ini000066400000000000000000000000351353472757700170010ustar00rootroot00000000000000[pytest] norecursedirs = rpm argparse-manpage-1.2.2/requirements.txt000066400000000000000000000000001353472757700202240ustar00rootroot00000000000000argparse-manpage-1.2.2/rpm/000077500000000000000000000000001353472757700155505ustar00rootroot00000000000000argparse-manpage-1.2.2/rpm/.gitignore000066400000000000000000000000651353472757700175410ustar00rootroot00000000000000*.spec *.tar.gz *.src.rpm noarch/ argparse-manpage*/ argparse-manpage-1.2.2/rpm/Makefile000066400000000000000000000013321353472757700172070ustar00rootroot00000000000000PYTHON := python3 BUILD_HELPER := ./build-helper VERSION = $(shell $(BUILD_HELPER) --version) RELEASE = $(shell $(BUILD_HELPER) --release) DATE = $(shell date +'%a %b %d %Y') TARBALL = argparse-manpage-$(VERSION).tar.gz all: argparse-manpage.spec argparse-manpage-$(VERSION).tar.gz .PHONY: $(TARBALL) $(TARBALL): rm -f $(TARBALL) ( cd .. && git archive --prefix argparse-manpage-$(VERSION)/ HEAD ) \ | gzip > "$@" argparse-manpage.spec: argparse-manpage.spec.tpl ../setup.py @echo " GEN $@" ; \ sed -e "s|@VERSION@|$(VERSION)|g" \ -e "s|@RELEASE@|$(RELEASE)|g" \ -e "s|@DATE@|$(DATE)|g" \ $< > $@.output ; \ mv "$@.output" "$@" # move when successful clean: rm -rf *.src.rpm *.tar.gz *.spec noarch argparse-manpage-1.2.2/rpm/argparse-manpage.spec.tpl000066400000000000000000000055451353472757700224450ustar00rootroot00000000000000%if 0%{?fedora} %bcond_without python2 %bcond_without python3 %else %if 0%{?rhel} > 7 %bcond_with python2 %bcond_without python3 %else %bcond_without python2 %bcond_with python3 %endif %endif %bcond_without check %global sum() Build manual page from %* ArgumentParser object %global desc \ Generate manual page an automatic way from ArgumentParser object, so the \ manpage 1:1 corresponds to the automatically generated --help output. The \ manpage generator needs to known the location of the object, user can \ specify that by (a) the module name or corresponding python filename and \ (b) the object name or the function name which returns the object. \ There is a limited support for (deprecated) optparse objects, too. Name: argparse-manpage Version: @VERSION@ Release: @RELEASE@%{?dist} Summary: %{sum Python} BuildArch: noarch License: ASL 2.0 URL: https://github.com/praiskup/%{name} Source0: https://github.com/praiskup/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz %if %{with python2} BuildRequires: python2-setuptools python2-devel %if %{with check} %if 0%{?rhel} && 0%{?rhel} == 7 BuildRequires: pytest python-six %else BuildRequires: python2-pytest python2-six %endif %endif %endif %if %{with python3} BuildRequires: python3-setuptools python3-devel %if %{with check} BuildRequires: python3-pytest python3-six %endif %endif %if %{with python3} Requires: python3-%name = %version-%release %else Requires: python2-%name = %version-%release %endif %description %desc %package -n python2-%name Summary: %{sum Python 2} %description -n python2-%name %{desc} %package -n python3-%name Summary: %{sum Python 3} %description -n python3-%name %{desc} %prep %setup -q %build %if %{with python2} %py2_build %endif %if %{with python3} %py3_build %endif %install %if %{with python2} %py2_install %endif %if %{with python3} %py3_install %endif %if %{with check} %check %if %{with python2} PYTHONPATH=%buildroot%python2_sitearch %__python2 -m pytest %endif %if %{with python3} PYTHONPATH=%buildroot%python3_sitearch %__python3 -m pytest %endif %endif %files %license LICENSE %{_bindir}/argparse-manpage %_mandir/man1/argparse-manpage.1.* %if %{with python3} %python3_sitelib/build_manpages/cli %else %python2_sitelib/build_manpages/cli %endif %if %{with python2} %files -n python2-%name %license LICENSE %python2_sitelib/build_manpages %python2_sitelib/argparse_manpage-%{version}*.egg-info %exclude %python2_sitelib/build_manpages/cli %endif %if %{with python3} %files -n python3-%name %license LICENSE %python3_sitelib/build_manpages %python3_sitelib/argparse_manpage-%{version}*.egg-info %exclude %python3_sitelib/build_manpages/cli %endif %changelog * @DATE@ Pavel Raiskup - @VERSION@-@RELEASE@ - built from upstream, changelog ignored argparse-manpage-1.2.2/rpm/build-helper000077500000000000000000000002611353472757700200510ustar00rootroot00000000000000#! /bin/sh case $1 in --version) cd .. ; ${PYTHON-python3} setup.py --version ;; --release) echo "git.$(date +"%Y%m%d_%H%M%S")" ;; esac argparse-manpage-1.2.2/setup.cfg000066400000000000000000000001471353472757700165750ustar00rootroot00000000000000[build_manpages] manpages = man/argparse-manpage.1:object=ap:pyfile=build_manpages/cli/__init__.py argparse-manpage-1.2.2/setup.py000066400000000000000000000022541353472757700164670ustar00rootroot00000000000000import os import sys from setuptools import setup, find_packages from setuptools.command.build_py import build_py from setuptools.command.install import install from build_manpages import __version__ from build_manpages.build_manpages \ import build_manpages, get_build_py_cmd, get_install_cmd ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) def get_readme(): with open(os.path.join(ROOT_DIR, 'README.md')) as fh: return ''.join(fh.readlines()) setup( name='argparse-manpage', version=__version__, url='https://github.com/praiskup/argparse-manpage', license='Apache 2.0', py_modules = ['build_manpage'], author='Gabriele Giammatteo', author_email='gabriele.giammatteo@eng.it', maintainer='Pavel Raiskup', maintainer_email='praiskup@redhat.com', packages=find_packages(), scripts=['bin/argparse-manpage'], description='Build manual page from python\'s ArgumentParser object.', long_description=get_readme(), long_description_content_type='text/markdown', cmdclass={ 'build_manpages': build_manpages, 'build_py': get_build_py_cmd(build_py), 'install': get_install_cmd(install), }, ) argparse-manpage-1.2.2/unittests/000077500000000000000000000000001353472757700170145ustar00rootroot00000000000000argparse-manpage-1.2.2/unittests/test_basic.py000066400000000000000000000005001353472757700215010ustar00rootroot00000000000000from build_manpages.manpage import Manpage import argparse class TestEscapes(object): def test_backslash_escape(self): parser = argparse.ArgumentParser('duh') parser.add_argument("--jej", help="c:\\something") man = Manpage(parser) assert 'c:\\\\something' in str(man).split('\n') argparse-manpage-1.2.2/unittests/test_examples.py000066400000000000000000000057051353472757700222520ustar00rootroot00000000000000import os, sys import re import subprocess from contextlib import contextmanager @contextmanager def pushd(path): old_dir = os.getcwd() os.chdir(path) try: yield finally: os.chdir(old_dir) @contextmanager def change_argv(argv): old_argv = sys.argv sys.argv = argv try: yield finally: sys.argv = old_argv def run_setup_py(args): with change_argv(['setup.py'] + args): subprocess.call([sys.executable, 'setup.py'] + args, env={'PYTHONPATH': ':'.join(sys.path)}) def file_cmp(file1, file2): with open(file1, 'r') as f1: with open(file2, 'r') as f2: a1 = f1.readlines() a2 = f2.readlines() assert len(a1) == len(a2) first = True for left, right in zip(a1, a2): if first: left = re.sub('[0-9]{4}\\\\-[0-9]{2}\\\\-[0-9]{2}', '!!DATE!!', left) right = re.sub('[0-9]{4}\\\\-[0-9]{2}\\\\-[0-9]{2}', '!!DATE!!', right) first = False assert left == right class TestAllExapmles(object): def test_old_example(self): with pushd('examples/old_format'): try: os.remove('example.1') except OSError: pass run_setup_py(['build_manpage']) file_cmp('example.1', 'expected-output.1') def test_copr(self): with pushd('examples/copr'): name = 'copr-cli.1' prefix = '/usr' try: os.remove(name) except OSError: pass idir = os.path.join(os.getcwd(), 'i') run_setup_py(['install', '--root', idir, '--prefix', prefix]) file_cmp('i/usr/share/man/man1/' + name, 'expected-output.1') file_cmp(name, 'expected-output.1') def test_distgen(self): with pushd('examples/raw-description'): name = 'man/dg.1' try: os.remove(name) except OSError: pass idir = os.path.join(os.getcwd(), 'i') run_setup_py (['install', '--root', idir, '--prefix', '/usr']) file_cmp('i/usr/share/man/man1/' + os.path.basename(name), 'expected-output.1') file_cmp(name, 'expected-output.1') def test_resalloc(self): with pushd('examples/resalloc'): prefix = '/usr' for name in ['man/resalloc.1', 'man/resalloc-maint.1']: try: os.remove(name) except OSError: pass idir = os.path.join(os.getcwd(), 'i') run_setup_py(['install', '--root', idir, '--prefix', prefix]) for name in ['man/resalloc.1', 'man/resalloc-maint.1']: file_cmp('i/usr/share/man/man1/' + os.path.basename(name), 'expected/' + name) file_cmp(name, 'expected/' + name) argparse-manpage-1.2.2/wrap000077500000000000000000000003171353472757700156520ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2017 Red Hat, Inc. srcdir=$(readlink -f "$(dirname "$0")") script_name=$(basename "$0") export PYTHONPATH=$srcdir/${PYTHONPATH+:$PYTHONPATH} exec "$srcdir/bin/$script_name" "$@"