def _argparse(): """Pull args and repo paths out of argv. Return an args object. """ desc = "Runs 'p4 changes' and output DescInfo blocks as a table." parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument('-v', '--verbose', default=False, action="store_true", help="Report INFO-level progress.") parser.add_argument('--debug', default=False, action="store_true", help="Report DEBUG-level progress.") parser.add_argument('-p', '--p4port', metavar='p4port', help='Perforce server') parser.add_argument('-u', '--p4user', metavar='p4user', help='Admin-privileged Perforce user') parser.add_argument('p4changes_arg_list', metavar='<p4 changes arguments>', nargs='*') args = parser.parse_args() return args
def _argparse(): """Pull args and repo paths out of argv. Return an args object. """ desc = "Compare two Git repos. Identify what differs where." parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument('-v', '--verbose', default=False, action="store_true", help="Report INFO-level progress") parser.add_argument('--debug', default=False, action="store_true", help="Report DEBUG-level progress") parser.add_argument( '--ktext', default=False, action="store_true", help="Permit sha1 difference due to RCS $keyword: expansion $") parser.add_argument( '--branch', metavar='branch', nargs=1, help= 'one extra local branch to compare with master when branch lists do not match' ) parser.add_argument('repo_a', metavar='repo_a') parser.add_argument('repo_b', metavar='repo_b') args = parser.parse_args() return args
def _parse_argv(): '''Convert argv into a usable dict. Dump usage/help and exit if necessary.''' help_txt = p4gf_util.read_bin_file('p4gf_init_repo.help.txt') if help_txt is False: help_txt = _("Missing '{}' file!").format(NTR('p4gf_init_repo.help.txt')) parser = p4gf_util.create_arg_parser( desc = _('Configure and populate Git Fusion repo.') , epilog = None , usage = _('p4gf_init_repo.py [options] <name>') , help_custom = help_txt) parser.add_argument('--start', metavar="") parser.add_argument('--noclone', action=NTR('store_true')) parser.add_argument('--config') parser.add_argument('--p4client') parser.add_argument(NTR('view'), metavar=NTR('view')) parser.add_argument('--charset') parser.add_argument('--enablemismatchedrhs', action=NTR('store_true')) args = parser.parse_args() if args.noclone and args.start: _print_stderr(_('Cannot use both --start and --noclone')) sys.exit(1) if args.config and args.charset: _print_stderr(_('Cannot use both --config and --charset')) if args.config and args.p4client: _print_stderr(_('Cannot use both --config and --p4client')) LOG.debug("args={}".format(args)) return args
def main(): ''' Parse the command-line arguments and print a configuration. ''' p4gf_util.has_server_id_or_exit() p4gf_client = p4gf_util.get_object_client_name() p4 = p4gf_create_p4.create_p4(client=p4gf_client) if not p4: sys.exit(1) desc = _("""Display the effective global or repository configuration. All comment lines are elided and formatting is normalized per the default behavior of the configparser Python module. The default configuration options will be produced if either of the configuration files is missing. """) parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument( NTR('repo'), metavar=NTR('R'), nargs='?', default='', help=_('name of the repository, or none to display global.')) args = parser.parse_args() if args.repo: cfg = get_repo(p4, args.repo) else: cfg = get_global(p4) if not cfg: print(_('Unable to read configuration file!')) cfg.write(sys.stdout)
def parse_argv(): """Copy optional port/user args into global P4PORT/P4USER.""" parser = p4gf_util.create_arg_parser( "Creates Git Fusion user, depot, and protect entry.") parser.add_argument('--port', '-p', metavar='P4PORT', nargs=1, help='P4PORT of server') parser.add_argument('--user', '-u', metavar='P4USER', nargs=1, help='P4USER of user with super permissions.') parser.add_argument('--verbose', '-v', metavar='level', nargs='?', default='INFO', help='Reporting verbosity.') parser.add_argument('--quiet', '-q', action='store_true', help='Report only errors. Same as --verbose QUIET') args = parser.parse_args() # Handle verbosity first so that we can honor it when processing args. if args.quiet: args.verbose = QUIET elif not args.verbose: # -v with no arg means "debug" args.verbose = DEBUG # Convert text levels like "INFO" to numeric 2 if (str(args.verbose).upper() in VERBOSE_MAP.keys()): args.verbose = VERBOSE_MAP[str(args.verbose).upper()] elif not args.verbose in VERBOSE_MAP.values(): report(ERROR, "Unknown --verbose value '{val}'. Try {good}" .format(val=args.verbose, good=", ".join(VERBOSE_SEQUENCE))) exit(2) global VERBOSE_LEVEL, P4PORT, P4USER VERBOSE_LEVEL = args.verbose report(DEBUG, "args={}".format(args)) # Optional args, None if left unset if args.port: P4PORT = args.port[0] if args.user: P4USER = args.user[0]
def main(): """ Parses the command line arguments and performs a search for the given email address in the user map. """ p4gf_util.has_server_id_or_exit() log_l10n() # Set up argument parsing. parser = p4gf_util.create_arg_parser( _("Searches for an email address in the user map.")) parser.add_argument(NTR('email'), metavar='E', help=_('email address to find')) args = parser.parse_args() # make sure the world is sane ec = p4gf_init.main() if ec: print(_("p4gf_usermap initialization failed")) sys.exit(ec) with p4gf_create_p4.Closer(): p4 = p4gf_create_p4.create_p4(client=p4gf_util.get_object_client_name()) if not p4: sys.exit(1) usermap = UserMap(p4) user = usermap.lookup_by_email(args.email) if user: print(_("Found user '{}' <{}>").format(user[0], user[2])) sys.exit(0) else: sys.stderr.write(_("No such user found: '{}'\n").format(args.email)) sys.exit(1)
def _parse_argv(): '''Convert argv into a usable dict. Dump usage/help and exit if necessary.''' help_txt = p4gf_util.read_bin_file('p4gf_init_repo.help.txt') if help_txt is False: help_txt = _("Missing '{}' file!").format( NTR('p4gf_init_repo.help.txt')) parser = p4gf_util.create_arg_parser( desc=_('Configure and populate Git Fusion repo.'), epilog=None, usage=_('p4gf_init_repo.py [options] <name>'), help_custom=help_txt) parser.add_argument('--start', metavar="") parser.add_argument('--noclone', action=NTR('store_true')) parser.add_argument('--config') parser.add_argument('--p4client') parser.add_argument(NTR('view'), metavar=NTR('view')) parser.add_argument('--charset') parser.add_argument('--enablemismatchedrhs', action=NTR('store_true')) args = parser.parse_args() if args.noclone and args.start: _print_stderr(_('Cannot use both --start and --noclone')) sys.exit(1) if args.config and args.charset: _print_stderr(_('Cannot use both --config and --charset')) if args.config and args.p4client: _print_stderr(_('Cannot use both --config and --p4client')) LOG.debug("args={}".format(args)) return args
def main(): """Parses the command line arguments and performs a search for the given email address in the user map. """ # Set up argument parsing. parser = p4gf_util.create_arg_parser( "searches for an email address in the user map") parser.add_argument('email', metavar='E', help='email address to find') args = parser.parse_args() # make sure the world is sane ec = p4gf_init.main() if ec: print("p4gf_usermap initialization failed") sys.exit(ec) p4 = connect_p4(client=p4gf_util.get_object_client_name()) if not p4: sys.exit(1) usermap = UserMap(p4) user = usermap.lookup_by_email(args.email) if user: print("Found user {} <{}>".format(user[0], user[2])) sys.exit(0) else: sys.stderr.write("No such user found.\n") sys.exit(1)
def parse_argv(): """Convert command line into a usable dict.""" usage = _("""p4gf_rollback.py [options] --change-num NNN --repo <repo-name> options: --p4port/-p Perforce server --p4user/-u Perforce user --execute/-y yes, do it (normally just previews/reports) --obliterate delete history from Perforce --verbose/-v write more to console --quiet/-q write nothing but errors to console """) parser = p4gf_util.create_arg_parser( help_file = NTR('p4gf_rollback.help.txt') , usage = usage , add_p4_args = True , add_log_args = True , add_debug_arg= True ) parser.add_argument('--change-num', metavar="NNN", required=True) parser.add_argument('--repo', metavar="<repo-name>", required=True) parser.add_argument('--execute', '-y', action=NTR("store_true")) parser.add_argument('--obliterate', action=NTR("store_true")) args = parser.parse_args() p4gf_util.apply_log_args(args, LOG) LOG.debug("args={}".format(args)) args.change_num = int(args.change_num) return args
def main(): """Parse command line arguments and decide what should be done.""" desc = _("""p4gf_lfs_http_server.py handles LFS requests over HTTP. Typically it is run via a web server and protected by some form of user authentication. The environment variable REMOTE_USER must be set to the name of a valid Perforce user, which is taken to be the user performing a pull or push operation. """) epilog = _("""If the --port argument is given then a simple HTTP server will be started, listening on the specified port. In lieu of REMOTE_USER, the user name is extracted from the URI, which starts with "/~", followed by the user name. To stop the server, send a terminating signal to the process. """) log_l10n() parser = p4gf_util.create_arg_parser(desc, epilog=epilog) parser.add_argument('-p', '--port', type=int, help=_('port on which to listen for LFS reqeuests')) args = parser.parse_args() if args.port: LOG.info("Listening for LFS-HTTP requests on port %s, pid=%s", args.port, os.getpid()) httpd = wsgiref.simple_server.make_server('', args.port, app_wrapper) print(_('Serving on port {port}...').format(port=args.port)) p4gf_http_common.wsgi_install_signal_handler(httpd) p4gf_proc.install_stack_dumper() httpd.serve_forever() else: # Assume we are running inside a web server... p4gf_proc.install_stack_dumper() _handle_cgi()
def main(): ''' Parse the command-line arguments and print a configuration. ''' p4gf_util.has_server_id_or_exit() p4gf_client = p4gf_util.get_object_client_name() p4 = p4gf_create_p4.create_p4(client=p4gf_client) if not p4: sys.exit(1) desc = _("""Display the effective global or repository configuration. All comment lines are elided and formatting is normalized per the default behavior of the configparser Python module. The default configuration options will be produced if either of the configuration files is missing. """) parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument(NTR('repo'), metavar=NTR('R'), nargs='?', default='', help=_('name of the repository, or none to display global.')) args = parser.parse_args() if args.repo: cfg = get_repo(p4, args.repo) else: cfg = get_global(p4) if not cfg: print(_('Unable to read configuration file!')) cfg.write(sys.stdout)
def main(): """Read the log files and report on lock contention.""" desc = _("""Examine lock related log entries and report. How to use: 1) Configure logging to have `p4gf_git_repo_lock` and `p4gf_lock` set to `debug` level. 2) Comment out any `handler` and `filename` (or `file`) entries in logging configuration, such that one XML formatted log file per process will be created. 3) Run the pull or push operations that are of concern. 4) Run this lock_analyze.py script. """) parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument('repo', metavar="REPO", help=_("name of repository to be analyzed")) parser.add_argument('-d', '--logs', metavar="DIR", help=_("path to log files to be processed")) args = parser.parse_args() logging.basicConfig(format="%(levelname)-7s %(message)s", stream=sys.stdout, level=logging.INFO) if args.logs is None: # default args.logs to GFHOME/.git-fusion/logs args.logs = os.path.join(p4gf_const.P4GF_HOME, '.git-fusion', 'logs') log_files = retrieve_log_files(args.logs, args.repo) lexmr = LockExaminer(args.repo) for log_file in log_files: lexmr.examine_log(os.path.join(args.logs, log_file)) lexmr.print_summary()
def main(): """Validate the configuration for one or more repositories.""" # pylint:disable=too-many-branches desc = _("Report on the validity of a repository configuration.") parser = p4gf_util.create_arg_parser(desc) parser.add_argument('-a', '--all', action='store_true', help=_('process all known Git Fusion repositories')) parser.add_argument(NTR('repos'), metavar=NTR('repo'), nargs='*', help=_('name of repository or file to be validated')) args = parser.parse_args() # Check that either --all, or 'repos' was specified, but not both. if not args.all and len(args.repos) == 0: sys.stderr.write(_('Missing repo names; try adding --all option.\n')) sys.exit(2) if args.all and len(args.repos) > 0: sys.stderr.write(_('Ambiguous arguments. Choose --all or a repo name.\n')) sys.exit(2) with p4gf_create_p4.Closer(): p4 = p4gf_create_p4.create_p4_temp_client() if not p4: sys.exit(2) # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() except P4.P4Exception as e: sys.stderr.write(_('P4 exception occurred: {exception}').format(exception=e)) sys.exit(1) p4gf_branch.init_case_handling(p4) if args.all: repos = p4gf_util.repo_config_list(p4) if len(repos) == 0: print(_('No Git Fusion repositories found, nothing to do.')) sys.exit(0) else: repos = args.repos for repo in repos: if os.path.exists(repo): print(_("Processing file {repo_name}...").format(repo_name=repo)) try: config = p4gf_config.RepoConfig.from_local_file(repo, p4, repo) except p4gf_config.ConfigLoadError as e: sys.stderr.write("{}\n", e) except p4gf_config.ConfigParseError as e: sys.stderr.write("{}\n", e) else: repo_name = p4gf_translate.TranslateReponame.git_to_repo(repo) print(_("Processing repository {repo_name}...").format(repo_name=repo_name)) try: config = p4gf_config.RepoConfig.from_depot_file(repo_name, p4) except p4gf_config.ConfigLoadError as err: sys.stderr.write("{}\n", err) if Validator(config, p4).is_valid(): print(_("ok")) print("")
def main(): """Program to check for product updates at updates.perforce.com.""" desc = _( "Report if updates are available by checking at updates.perforce.com.") parser = p4gf_util.create_arg_parser(desc=desc, add_debug_arg=True) parser.add_argument( '--p4port', '-p', metavar='P4PORT', help=_('P4PORT of server - optional - also report P4D version ' 'data to Perforce')) args = parser.parse_args() # get the Git Fusion and P4D product version strings (gf_version, server_version) = get_product_version_strings(args) # Get the local GF version info as dict this_version = p4gf_version_3.as_dict(include_checksum=True) # Munge version strings into url paramters required by updates.perforce.com # add NOARCH to gf version gf_version = gf_version.replace('Git Fusion', 'Git%20Fusion/NOARCH') url = GF_PRODUCT_URL + '?product=' + gf_version if server_version: url = url + '%26product=' + server_version # Ensure all spaces are encoded url = url.replace(' ', '%20') if 'debug' in args: print("debug: url:{}".format(url)) try: webfile = urllib.request.urlopen(url) except (urllib.error.URLError, urllib.error.HTTPError) as e: return URL_ERROR_MSG.format(url=url, error=str(e)) # make the query to the url data = webfile.read() if not data: return ERROR_MSG product_version = json.loads(data.decode()) if 'debug' in args: print("debug: json data:{}".format(product_version)) if 'current' not in product_version: return JSON_KEY_ERROR_MSG # Parse the data and compare c = product_version['current'] current_year_sub = year_sub_to_float(c['major'], c['minor']) this_version_year_sub = year_sub_to_float(this_version['release_year'], this_version['release_sub']) message = NO_UPDATES_EXISTS.format(version=current_year_sub) if this_version_year_sub < current_year_sub: message = UPDATES_EXIST.format(have_version=this_version_year_sub, current_version=current_year_sub) elif this_version_year_sub == current_year_sub and this_version[ 'patchlevel'] < c['build']: message = PATCH_EXISTS.format(version=current_year_sub) return message
def main(): """Parse the command-line arguments and report on locks.""" desc = _(DESCRIPTION) parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument( NTR('--config'), metavar=NTR('config'), help=_('Path to Git Fusion p4gf_config file (required)'), required=True) parser.add_argument('-u', '--p4user', metavar='p4user', help=_('Perforce user')) parser.add_argument('-p', '--p4port', metavar='p4port', help=_('Perforce server')) parser.add_argument('--locale', metavar='locale', default='en_US.UTF-8', help=_('system locale setting')) args = parser.parse_args() need_serverid = False try: p4gf_util.get_server_id() except: # pylint: disable=W0702 need_serverid = True # If connect args not passed, check that the environment is set. if not args.p4port: if 'P4PORT' not in os.environ and 'P4GF_ENV' not in os.environ: print( _("Neither --p4port is an argument nor are P4GF_ENV and P4PORT in the environment." )) sys.exit(0) if 'P4PORT' in os.environ: args.p4port = os.environ['P4PORT'] else: # Set the requested port for Git Fusion's environment os.environ['P4PORT'] = args.p4port if not args.p4user: if 'P4USER' not in os.environ: print( _("Neither --p4user is an argument nor is P4USER in the environment." )) sys.exit(0) else: args.p4user = os.environ['P4USER'] else: # Set the requested user for Git Fusion's environment os.environ['P4USER'] = args.p4user repo_size = RepoSize(args.config, args.p4port, args.p4user, args.locale, need_serverid) repo_size.estimate_size() repo_size.report()
def _parse_argv(): """Parse command line arguments. Only version, help options for now. """ parser = p4gf_util.create_arg_parser(_('Initializes a Git Fusion server.')) Verbosity.add_parse_opts(parser) args = parser.parse_args() Verbosity.parse_level(args)
def _parse_argv(): """Convert command line into a usable dict.""" parser = p4gf_util.create_arg_parser(add_log_args=True, add_debug_arg=True) parser.add_argument('--tag-num', default=0) args = parser.parse_args() p4gf_util.apply_log_args(args, LOG) LOG.debug("args={}".format(args)) args.tag_num = int(args.tag_num) return args
def main(): """ Parse command line arguments and decide what should be done. """ desc = _("""p4gf_http_server.py handles http(s) requests. Typically it is run via a web server and protected by some form of user authentication. The environment variable REMOTE_USER must be set to the name of a valid Perforce user, which is taken to be the user performing a pull or push operation. """) epilog = _("""If the --user argument is given then a simple HTTP server will be started, listening on the port specified by --port. The REMOTE_USER value will be set to the value given to the --user argument. To stop the server, send a terminating signal to the process. """) log_l10n() parser = p4gf_util.create_arg_parser(desc, epilog=epilog) parser.add_argument('-u', '--user', help=_('value for REMOTE_USER variable')) parser.add_argument('-p', '--port', type=int, default=8000, help=_('port on which to listen (default 8000)')) args = parser.parse_args() if args.user: LOG.debug( "Listening for HTTP requests on port {} as user {}, pid={}".format( args.port, args.user, os.getpid())) wrapper = functools.partial(_app_wrapper, args.user) httpd = wsgiref.simple_server.make_server( '', args.port, wrapper, handler_class=GitFusionRequestHandler) print(_('Serving on port {}...').format(args.port)) def _signal_handler(signum, _frame): """ Ensure the web server is shutdown properly. """ LOG.info("received signal {}, pid={}, exiting".format( signum, os.getpid())) httpd.server_close() sys.exit(0) LOG.debug("installing HTTP server signal handler, pid={}".format( os.getpid())) signal.signal(signal.SIGHUP, _signal_handler) signal.signal(signal.SIGINT, _signal_handler) signal.signal(signal.SIGQUIT, _signal_handler) signal.signal(signal.SIGTERM, _signal_handler) signal.signal(signal.SIGTSTP, _signal_handler) p4gf_proc.install_stack_dumper() httpd.serve_forever() else: # Assume we are running inside a web server... _handle_cgi()
def main(): """Process command line arguments and call functions to do the real work of cleaning up the Git mirror and Perforce workspaces. """ # Set up argument parsing. parser = p4gf_util.create_arg_parser( "Deletes Git Fusion repositories and workspaces.") parser.add_argument("-a", "--all", action="store_true", help="remove all known Git mirrors") parser.add_argument("-y", "--delete", action="store_true", help="perform the deletion") parser.add_argument("-v", "--verbose", action="store_true", help="print details of deletion process") parser.add_argument('views', metavar='view', nargs='*', help='name of view to be deleted') args = parser.parse_args() # Check that either --all or 'views' was specified. if not args.all and len(args.views) == 0: sys.stderr.write('Missing view names; try adding the --all option.\n') sys.exit(2) p4 = connect_p4(client=p4gf_util.get_object_client_name()) if not p4: return 2 # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() except P4.P4Exception as e: sys.stderr.write("P4 exception occurred: {}".format(e)) sys.exit(1) if args.all: try: delete_all(args, p4) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) else: # Delete the client(s) for the named view(s). for view in args.views: client_name = p4gf_context.view_to_client_name(view) try: delete_client(args, p4, client_name) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) if not args.delete: print("This was report mode. Use -y to make changes.")
def main(): """Parse the command-line arguments and perform the requested operation.""" desc = """Test wrapper and debugging facility for Git Fusion logging. By default, does not read the global log configuration unless the --default option is given. Set the P4GF_LOG_CONFIG_FILE environment variable to provide the path to a log configuration file. """ parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument('--default', action='store_true', help="allow reading default log configuration") parser.add_argument( '--debug', action='store_true', help="print the effective logging configuration (implies --default)") parser.add_argument('--http', action='store_true', help="audit log as if HTTP request") parser.add_argument('--ssh', action='store_true', help="audit log as if SSH request") parser.add_argument('--level', default='INFO', help="log level name (default is 'INFO')") parser.add_argument('--name', default='test', help="logger name (default is 'test')") parser.add_argument('--msg', default='test message', help="text to write to log") args = parser.parse_args() if not args.default and not args.debug: # Disable loading the default logging configuration since that # makes testing log configurations rather difficult. global _config_filename_default _config_filename_default = '/foo/bar/baz' # Perform usual logging initialization. _lazy_init(args.debug) if args.debug: # We're already done. return elif args.http: record_http({}, os.environ) elif args.ssh: record_argv({'userName': os.environ['REMOTE_USER']}) else: lvl = logging.getLevelName(args.level) if not isinstance(lvl, int): sys.stderr.write("No such logging level: {}\n".format(args.level)) sys.exit(1) log = logging.getLogger(args.name) log.log(lvl, args.msg)
def _argparse(): """Pull args and repo paths out of argv. Return an args object. """ desc = "Compare two Git repos. Identify what differs where." parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument('-v', '--verbose', default=False, action="store_true", help="Report INFO-level progress.") parser.add_argument('--debug', default=False, action="store_true", help="Report DEBUG-level progress.") parser.add_argument('-p', '--p4port', metavar='p4port', help='Perforce server') parser.add_argument('-u', '--p4user', metavar='p4user', help='Admin-privileged Perforce user') parser.add_argument('-n', '--preview', default=False, action="store_true", help="Display a preview of what would be changed," " without actually doing anything.") parser.add_argument('--save', metavar='<save-file>', help="Save a JSON file recording what changed." " Can combine with --preview to save without" " doing anything." " Pass this file to --apply or --revert.") parser.add_argument('--apply', metavar='<save-file>', help="Repair changelist descriptions listed in the" " given JSON file." " Use --save [--preview] to create this file.") parser.add_argument('--revert', metavar='<save-file>', help="Undo repairs to changelist descriptions listed" " in the given JSON file." " Use --save [--preview] to create this file.") parser.add_argument('repo_name', metavar='<repo-name>') args = parser.parse_args() return args
def _parse_argv(): """Convert command line into a usable dict.""" parser = p4gf_util.create_arg_parser( add_log_args=True, add_debug_arg=True, desc="Merge two cProfiler runs into a single spreadsheet.") parser.add_argument('file_a', metavar='file_a') parser.add_argument('file_b', metavar='file_b') args = parser.parse_args() p4gf_util.apply_log_args(args, LOG) LOG.debug("args={}".format(args)) return args
def parse_argv(): """Copy optional port/user args into global P4PORT/P4USER.""" parser = p4gf_util.create_arg_parser( "Creates Git Fusion user, depot, and protect entry.") parser.add_argument('--port', '-p', metavar='P4PORT', nargs=1, help='P4PORT of server') parser.add_argument('--user', '-u', metavar='P4USER', nargs=1, help='P4USER of user with super permissions.') parser.add_argument('--verbose', '-v', metavar='level', nargs='?', default='INFO', help='Reporting verbosity.') parser.add_argument('--quiet', '-q', action='store_true', help='Report only errors. Same as --verbose QUIET') args = parser.parse_args() # Handle verbosity first so that we can honor it when processing args. if args.quiet: args.verbose = QUIET elif not args.verbose: # -v with no arg means "debug" args.verbose = DEBUG # Convert text levels like "INFO" to numeric 2 if (str(args.verbose).upper() in VERBOSE_MAP.keys()): args.verbose = VERBOSE_MAP[str(args.verbose).upper()] elif not args.verbose in VERBOSE_MAP.values(): report( ERROR, "Unknown --verbose value '{val}'. Try {good}".format( val=args.verbose, good=", ".join(VERBOSE_SEQUENCE))) exit(2) global VERBOSE_LEVEL, P4PORT, P4USER VERBOSE_LEVEL = args.verbose report(DEBUG, "args={}".format(args)) # Optional args, None if left unset if args.port: P4PORT = args.port[0] if args.user: P4USER = args.user[0]
def main(): """ Parse command line arguments and decide what should be done. """ desc = _("""p4gf_http_server.py handles http(s) requests. Typically it is run via a web server and protected by some form of user authentication. The environment variable REMOTE_USER must be set to the name of a valid Perforce user, which is taken to be the user performing a pull or push operation. """) epilog = _("""If the --user argument is given then a simple HTTP server will be started, listening on the port specified by --port. The REMOTE_USER value will be set to the value given to the --user argument. To stop the server, send a terminating signal to the process. """) log_l10n() parser = p4gf_util.create_arg_parser(desc, epilog=epilog) parser.add_argument('-u', '--user', help=_('value for REMOTE_USER variable')) parser.add_argument('-p', '--port', type=int, default=8000, help=_('port on which to listen (default 8000)')) args = parser.parse_args() if args.user: LOG.debug("Listening for HTTP requests on port {} as user {}, pid={}".format( args.port, args.user, os.getpid())) wrapper = functools.partial(_app_wrapper, args.user) httpd = wsgiref.simple_server.make_server('', args.port, wrapper, handler_class=GitFusionRequestHandler) print(_('Serving on port {}...').format(args.port)) def _signal_handler(signum, _frame): """ Ensure the web server is shutdown properly. """ LOG.info("received signal {}, pid={}, exiting".format(signum, os.getpid())) httpd.server_close() sys.exit(0) LOG.debug("installing HTTP server signal handler, pid={}".format(os.getpid())) signal.signal(signal.SIGHUP, _signal_handler) signal.signal(signal.SIGINT, _signal_handler) signal.signal(signal.SIGQUIT, _signal_handler) signal.signal(signal.SIGTERM, _signal_handler) signal.signal(signal.SIGTSTP, _signal_handler) p4gf_proc.install_stack_dumper() httpd.serve_forever() else: # Assume we are running inside a web server... _handle_cgi()
def parse_argv(): """Convert command line into a usable dict.""" usage = _(""" Annotate a Git Fusion repo's 'git log' against its Helix changes. gitlog_annotate_with_changenum.py --repo REPO gitlog_annotate_with_changenum.py gitlogs.txt p4files.txt [p4changes.txt] """) desc = _(""" Annotate each git log line with the Helix changelist number (the asterisk marks a "push-state: complete" change): * ace5678 master git commit description ==> * ace5678 @2323232* master git commit description The report file is written to PWD/{}. The first syntax requires execution from the Git Fusion system user's home directory. This is the recommended and simplest method, for in this case all 'git log', 'p4 files' and 'p4 changes' data will be acquired. The second syntax requires no access to the Git Fusion instance by providing all data in files as arguments. The contents of the file data is described below. The optional 'p4changes.txt' is used to identify "push-state: complete" markers. """).format(REPORT_FILE) # pylint: disable=line-too-long parser = p4gf_util.create_arg_parser( desc = desc , usage = usage , formatter_class = RawTextHelpFormatter ) parser.add_argument('--repo', '-r', nargs=1,metavar=NTR('REPO'), help=_("repo name if fetching data from Helix.")) parser.add_argument(NTR('gitlogs'), metavar=NTR('gitlogs'), nargs='?', help=_("output from: 'git log --graph --decorate --oneline --all > gitlogs.txt'")) parser.add_argument(NTR('p4files'), metavar=NTR('p4files'), nargs='?', help=_("output from: 'p4 files //.git-fusion/objects/repos/{repo}/commits/... > p4files.txt'")) parser.add_argument(NTR('p4changes'), metavar=NTR('p4changes'), nargs='?', help=_("output from: 'p4 changes -l //.git-fusion/branches/{repo}/... //depot/xx/... //depot/yy/...'" + \ "\n (list of all branch views)")) parser.add_argument('--stdout', action=NTR("store_true"), help = _("direct report to stdout")) parser.add_argument('--debug', action=NTR("store_true"), help = _("display some debug information")) args = parser.parse_args() LOG.debug("args={}".format(args)) return args
def parse_args(argv): """parser""" parser = p4gf_util.create_arg_parser( _('Translate Git Fusion repo name formats.'), usage=_('p4gf_translate.py --type git|repo|p4 <name>')) parser.add_argument('--type') parser.add_argument(NTR('name'), metavar=NTR('name')) args = parser.parse_args(argv) _type = args.type if not _type in TYPES: print(parser.usage) print( _("Unknown input type '{bad}', must be one of [{good}.]").format( bad=_type, good=", ".join(TYPES))) sys.exit(1) return args
def _get_args(): """Parse command-line args.""" parser = p4gf_util.create_arg_parser( _("Update Git Fusion's internal repo(s) with recent changes from Perforce." )) parser.add_argument('-a', '--all', action=NTR('store_true'), help=_('Update all repos')) parser.add_argument('-v', '--verbose', action=NTR('store_true'), help=_('List each repo updated.')) parser.add_argument(NTR('views'), metavar=NTR('view'), nargs='*', help=_('name of view to update')) return parser.parse_args()
def main(): ''' Invoke p4gf_auth_server as if we're responding to a 'git pull'. ''' # Set up argument parsing. parser = p4gf_util.create_arg_parser( _("Update Git Fusion's internal repo(s) with recent changes from Perforce." )) parser.add_argument('-a', '--all', action=NTR('store_true'), help=_('Update all repos')) parser.add_argument(NTR('views'), metavar=NTR('view'), nargs='*', help=_('name of view to update')) args = parser.parse_args() # Check that either --all, --gc, or 'views' was specified. if not args.all and len(args.views) == 0: sys.stderr.write(_('Missing view names; try adding --all option.\n')) sys.exit(2) view_list = _list_for_server() if not args.all: bad_views = [x for x in args.views if x not in view_list] if bad_views: sys.stderr.write( _('One or more views are not defined on this server:\n\t')) sys.stderr.write('\n\t'.join(bad_views)) sys.stderr.write('\n') sys.stderr.write(_('Defined views:\n\t')) sys.stderr.write('\n\t'.join(view_list)) sys.stderr.write('\n') sys.exit(2) view_list = args.views for view_name in view_list: sys.argv = [ 'p4gf_auth_server.py', '--user={}'.format(p4gf_const.P4GF_USER), 'git-upload-pack', view_name ] p4gf_auth_server.main(poll_only=True)
def main(): """Copy the SSH keys from Perforce to the authorized keys file.""" global LFS_FILE_MAX_SECONDS_TO_KEEP p4gf_util.has_server_id_or_exit() log_l10n() # Set up argument parsing. parser = p4gf_util.create_arg_parser( _("""Removes files from LFS file cache which have not been accessed in some configurable time.""")) group = parser.add_mutually_exclusive_group() group.add_argument( '--hours', nargs=1, help=_('number of hours since last access to keep lfs file')) group.add_argument( '--days', nargs=1, help=_('number of days since last access to keep lfs file')) group.add_argument( '--seconds', nargs=1, help=_('number of seconds since last access to keep lfs file')) parser.add_argument('--gfhome', nargs=1, help=_('set GFHOME')) args = parser.parse_args() if args.gfhome: p4gf_const.P4GF_HOME = args.gfhome[0] try: if args.hours: LFS_FILE_MAX_SECONDS_TO_KEEP = int(args.hours[0]) * 3600 if args.days: LFS_FILE_MAX_SECONDS_TO_KEEP = int(args.days[0]) * 24 * 3600 if args.seconds: LFS_FILE_MAX_SECONDS_TO_KEEP = int(args.seconds[0]) except ValueError: LOG.debug("--hours, --days, --seconds must be integers.") if sys.stdout.isatty(): print("--hours, --days, --seconds must be integers.") sys.exit(1) prune_lfs_file_cache()
def main(): """Parse the command-line arguments and perform the requested operation.""" desc = _("""Search an XML formatted Git Fusion log file for matching records.""") epilog = _("""The --before and --after options take a date/time value with the following format: YYYY-mm-dd HH:MM:SS (e.g. --before '2015-11-17 10:12:49'). The --name argument can take a regular expression, as supported by the `re` module in the Python standard library. 'e.g. (p4gf_git_repo_lock|(?<!p4\\.)cmd.*)'""") parser = p4gf_util.create_arg_parser(desc=desc, epilog=epilog) parser.add_argument('log', metavar="LOG", nargs='+', help=_("name of log file(s) to be processed")) parser.add_argument('-q', '--query', help=_("regular expression to select log records")) parser.add_argument('-l', '--level', type=levelup, help=_("logging level by which to filter (e.g. debug, info, warning)")) parser.add_argument('-n', '--name', type=category_regex, help=_("logging category name (e.g. p4gf_auth_server, p4gf_copy_to_p4)")) parser.add_argument('-B', '--before', type=strptime, help=_("select log entries before the given date/time")) parser.add_argument('-A', '--after', type=strptime, help=_("select log entries after the given date/time")) parser.add_argument('-i', '--ignore-case', action='store_true', help=_("compare in a case-insensitive manner")) parser.add_argument('-p', '--pretty', action='store_true', help=_("present the log records in a pleasing fashion")) parser.add_argument('--no-header', action='store_true', help=_("do not print file name and divider between log files")) args = parser.parse_args() flags = re.IGNORECASE if args.ignore_case else 0 regex = re.compile(args.query, flags) if args.query else None # Suppress the super annoying BrokenPipeError exception when piping our # output to a utility such as `head`. signal.signal(signal.SIGPIPE, signal.SIG_DFL) for log_file in args.log: if not os.path.exists(log_file): sys.stderr.write(_('File does not exist: {logfile}\n').format(logfile=log_file)) sys.exit(2) global HEADER_PRINTED HEADER_PRINTED = False callback = functools.partial(search, regex, args, log_file) with open(log_file, 'rb') as fobj: xml.sax.parse(LogSource(fobj), LogContentHandler(callback))
def main(): """set up repo for a view""" parser = p4gf_util.create_arg_parser( "Initializes Git Fusion Perforce client and Git repository.") parser.add_argument('--start', metavar="", help='Changelist number to start repo history, default=1') parser.add_argument('view', metavar='view', help='name of view to be initialized') args = parser.parse_args() p4gf_version.log_version() view_name = p4gf_util.argv_to_view_name(args.view) p4gf_util.reset_git_enviro() p4 = connect_p4() if not p4: return 2 LOG.debug("connected to P4 at %s", p4.port) try: with p4gf_lock.view_lock(p4, view_name) as view_lock: # ensure we have a sane environment p4gf_init.init(p4) # now initialize the repository print("Initializing {}...".format(view_name)) r = init_repo(p4, view_name) if r > INIT_REPO_OK: return r print("Initialization complete.") if args.start: start = args.start.lstrip('@') print("Copying changes from {}...".format(start)) copy_p2g_with_start(view_name, start, view_lock) print("Copying completed.") except P4.P4Exception as e: sys.stderr.write("Error occurred: {}\n".format(e)) return 0
def _argparse(): """Pull args and repo paths out of argv. Return an args object. """ desc = "Extract Git objects and add to Perforce." parser = p4gf_util.create_arg_parser(desc=desc, add_log_args=True, add_debug_arg=True) parser.add_argument( '-o', '--outfile', help="where to write results, default=git_extract_object.out", default="git_extract_object.out", required=False) parser.add_argument('sha1', help="Full 40-char sha1") args = parser.parse_args() p4gf_util.apply_log_args(args, LOG) # pylint:disable=maybe-no-member LOG.debug2(args) return args
def main(): """Parse the command-line arguments and perform the requested operation.""" desc = _("""Remove older log files.""") parser = p4gf_util.create_arg_parser(desc=desc) parser.add_argument( '--limit', type=int, default=7, help="log files older than LIMIT days are removed (default 7)") parser.add_argument('--yes', action='store_true', help="required if LIMIT is 0 to remove all files") args = parser.parse_args() if args.limit < 0: sys.stderr.write('Limit cannot be negative\n') sys.exit(2) if args.limit == 0 and not args.yes: print( 'Limit of 0 will remove all files, invoke with --yes if you are sure.' ) sys.exit(2) prune_files_older_than(args.limit)
def parse_argv(): """Copy optional port/user args into global P4PORT/P4USER.""" # pylint:disable=line-too-long # Keep tabular code tabular. parser = p4gf_util.create_arg_parser(_("Creates Git Fusion users, depot, and protect entries.")) parser.add_argument('--port', '-p', metavar='P4PORT', nargs=1, help=_('P4PORT of server')) parser.add_argument('--user', '-u', metavar='P4USER', nargs=1, help=_('P4USER of user with super permissions.')) Verbosity.add_parse_opts(parser) parser.add_argument('--id', nargs=1, help=_("Set this Git Fusion server's unique id")) parser.add_argument('--showids', action='store_true', help=_('Display all Git Fusion server ids')) parser.add_argument('--force', action='store_true', help=_("Force set local server-id file when server-id already registered in Git Fusion or change it to a new value if --id option is provided.")) group = parser.add_mutually_exclusive_group() group.add_argument('--passwd', nargs=1, help=_("Do not prompt for password, use PASSWD when creating new service users (ex. 'git-fusion-user' and 'git-fusion-reviews-*')")) group.add_argument('--no-passwd', action='store_true', help=_("Do not prompt for nor set password when creating new service users (ex. 'git-fusion-user' and 'git-fusion-reviews-*')")) parser.add_argument('--unknown-git', action='store_true', help=_("Create the unknown_git user and if --passwd set passwd")) args = parser.parse_args() Verbosity.parse_level(args) # Optional args, None if left unset global P4PORT, P4USER, ID_FROM_ARGV, SHOW_IDS, P4_PASSWD, PROMPT_FOR_PASSWD global OVERRULE_SERVERID_CONFLICT, CREATE_UNKNOWN_GIT if args.port: P4PORT = args.port[0] if args.user: P4USER = args.user[0] if args.id: ID_FROM_ARGV = args.id[0] if args.showids: SHOW_IDS = True if args.passwd: P4_PASSWD = args.passwd[0] PROMPT_FOR_PASSWD = False elif args.no_passwd: PROMPT_FOR_PASSWD = False if args.force: OVERRULE_SERVERID_CONFLICT = True if args.unknown_git: CREATE_UNKNOWN_GIT = True
def parse_argv(): """Copy optional port/user args into global P4PORT/P4USER.""" parser = p4gf_util.create_arg_parser( _("Creates Git Fusion user, depot, and protect entries.")) parser.add_argument('--port', '-p', metavar='P4PORT', nargs=1, help=_('P4PORT of server')) parser.add_argument('--user', '-u', metavar='P4USER', nargs=1, help=_('P4USER of user with super permissions.')) Verbosity.add_parse_opts(parser) parser.add_argument('--id', nargs=1, help=_("Set this Git Fusion server's unique id")) parser.add_argument('--showids', action='store_true', help=_('Display all Git Fusion server ids')) parser.add_argument('--ignore-case', action='store_true', help=_('Do not check for case-handling policy in server.')) parser.add_argument('--force', action='store_true', help=_("Force set local server-id file when server-id already registered in Git Fusion.")) group = parser.add_mutually_exclusive_group() group.add_argument('--passwd', nargs=1, help=_("Password for 'git-fusion-user' and 'git-fusion-reviews-*'")) group.add_argument('--no-passwd', action='store_true', help=_("Do not prompt for nor set password for 'git-fusion-user' and 'git-fusion-reviews-*'")) args = parser.parse_args() Verbosity.parse_level(args) # Optional args, None if left unset global P4PORT, P4USER, ID_FROM_ARGV, SHOW_IDS, P4_PASSWD, PROMPT_FOR_PASSWD global IGNORE_CASE_HANDLING, OVERRULE_SERVERID_CONFLICT if args.port: P4PORT = args.port[0] if args.user: P4USER = args.user[0] if args.id: ID_FROM_ARGV = args.id[0] if args.showids: SHOW_IDS = True if args.passwd: P4_PASSWD = args.passwd[0] PROMPT_FOR_PASSWD = False elif args.no_passwd: PROMPT_FOR_PASSWD = False if args.ignore_case: IGNORE_CASE_HANDLING = True if args.force: OVERRULE_SERVERID_CONFLICT = True
def main(): ''' Invoke p4gf_auth_server as if we're responding to a 'git pull'. ''' # Set up argument parsing. parser = p4gf_util.create_arg_parser( _("Update Git Fusion's internal repo(s) with recent changes from Perforce.")) parser.add_argument('-a', '--all', action=NTR('store_true'), help=_('Update all repos')) parser.add_argument(NTR('views'), metavar=NTR('view'), nargs='*', help=_('name of view to update')) args = parser.parse_args() # Check that either --all, --gc, or 'views' was specified. if not args.all and len(args.views) == 0: sys.stderr.write(_('Missing view names; try adding --all option.\n')) sys.exit(2) view_list = _list_for_server() if not args.all: bad_views = [x for x in args.views if x not in view_list] if bad_views: sys.stderr.write(_('One or more views are not defined on this server:\n\t')) sys.stderr.write('\n\t'.join(bad_views)) sys.stderr.write('\n') sys.stderr.write(_('Defined views:\n\t')) sys.stderr.write('\n\t'.join(view_list)) sys.stderr.write('\n') sys.exit(2) view_list = args.views for view_name in view_list: sys.argv = [ 'p4gf_auth_server.py' , '--user={}'.format(p4gf_const.P4GF_USER) , 'git-upload-pack' , view_name] p4gf_auth_server.main(poll_only=True)
def main(): """Process command line arguments and call functions to do the real work of cleaning up the Git mirror and Perforce workspaces. """ # Set up argument parsing. parser = p4gf_util.create_arg_parser( "Convert 2012.2 Git Fusion configured Perforce Server for use with" " 2013.1 Git Fusion.\nThis is not reversable.") parser.add_argument("-y", "--convert", action="store_true", help="perform the conversion") parser.add_argument("-d", "--delete", action="store_true", help="skip obliterate and show delete command") parser.add_argument('--id', nargs=1, help="Set this Git Fusion server's unique id. Default is hostname.") args = parser.parse_args() # Do not run as root, this is very git account specific user = getpass.getuser() if user == "root": print("This script should be run using the Git dedicated account") return 2 if args.convert: try: global LOG_FILE # pylint:disable=W1501 # "x" is not a valid mode for open. # Yes it is. Pylint 1.0.0 is incorrect here. LOG_FILE = open("p4gf_convert_v12_2.log", "x") # pylint:enable=W1501 print("Logging to p4gf_convert_v12_2.log") except IOError: print("Please remove or rename p4gf_convert_v12_2.log") sys.exit(1) client_name = p4gf_const.P4GF_OBJECT_CLIENT_PREFIX + p4gf_util.get_hostname() try: p4 = p4gf_create_p4.create_p4(client=client_name) except RuntimeError as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not p4: return 2 # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() view = ['//{depot}/... //{client}/...'.format( depot=p4gf_const.P4GF_DEPOT, client=client_name)] spec = {'Host': '', 'Root': os.path.join(os.environ.get("HOME"), p4gf_const.P4GF_DIR), 'View': view} p4gf_util.ensure_spec_values(p4, 'client', client_name, spec) except P4.P4Exception as e: sys.stderr.write("P4 exception occurred: {}".format(e)) sys.exit(1) try: convert(args, p4) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) if not args.convert: print("This was report mode. Use -y to make changes.") else: print("Commands run were logged to p4gf_convert_v12_2.log.") if args.delete: print("You must now run: p4 delete //.git-fusion/objects/...") print(" p4 submit") print(" Use a client which has this location in its view") LOG_FILE.write("Need to run: p4 delete //.git-fusion/objects/...\n") LOG_FILE.write(" p4 submit\n") LOG_FILE.close()
def parse_argv(): """Only version, help options for now""" parser = p4gf_util.create_arg_parser(_('Initializes a Git Fusion server.')) Verbosity.add_parse_opts(parser) args = parser.parse_args() Verbosity.parse_level(args)
def main(): """ Process command line arguments and call functions to do the real work of cleaning up the Git mirror and Perforce workspaces. """ log_l10n() p4gf_util.has_server_id_or_exit() # pylint:disable=C0301 # Line too long? Too bad. Keep tabular code tabular. # Set up argument parsing. parser = p4gf_util.create_arg_parser( _('Deletes Git Fusion repositories and workspaces.')) parser.add_argument('-a', '--all', action='store_true', help=_('remove all known Git mirrors')) parser.add_argument('-y', '--delete', action='store_true', help=_('perform the deletion')) parser.add_argument('-v', '--verbose', action='store_true', help=_('print details of deletion process')) parser.add_argument('-N', '--no-obliterate', action='store_true', help=_('with the --all option, do not obliterate object cache')) parser.add_argument(NTR('views'), metavar=NTR('view'), nargs='*', help=_('name of view to be deleted')) args = parser.parse_args() # pylint:enable=C0301 # Check that either --all, or 'views' was specified. if not args.all and len(args.views) == 0: sys.stderr.write(_('Missing view names; try adding --all option.\n')) sys.exit(2) # Check that --no-obliterate occurs only with --all if not args.all and args.no_obliterate: sys.stderr.write(_('--no-obliterate permitted only with the --all option.\n')) sys.exit(2) with p4gf_create_p4.Closer(): p4 = p4gf_create_p4.create_p4(client=p4gf_util.get_object_client_name()) if not p4: return 2 # Sanity check the connection (e.g. user logged in?) before proceeding. try: p4.fetch_client() except P4.P4Exception as e: sys.stderr.write(_('P4 exception occurred: {}').format(e)) sys.exit(1) metrics = DeletionMetrics() if args.all: try: delete_all(args, p4, metrics) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) sys.exit(1) else: # Delete the client(s) for the named view(s). for git_view in args.views: view_name = p4gf_translate.TranslateReponame.git_to_repo(git_view) client_name = p4gf_util.view_to_client_name(view_name) try: with p4gf_lock.view_lock(p4, view_name, -1): delete_client(args, p4, client_name, metrics) except P4.P4Exception as e: sys.stderr.write("{}\n".format(e)) if not args.delete: print(_('This was report mode. Use -y to make changes.')) else: print(_('Deleted {:d} files, {:d} groups, {:d} clients, and {:d} counters.').format( metrics.files, metrics.groups, metrics.clients, metrics.counters)) if args.all: print(_('Successfully deleted all repos\n')) else: print(_('Successfully deleted repos:\n{}').format("\n".join(args.views)))
def parse_args(argv): """Parse the given arguments into a struct and return it. On error, print error to stdout and return None. If unable to parse, argparse.ArgumentParser.parse_args() will exit, so we add our own exit() calls, too. Otherwise some poor unsuspecting programmer would see all our "return None" calls and think that "None" is the only outcome of a bad argv. """ # pylint:disable=C0301 # line too long? Too bad. Keep tabular code tabular. parser = p4gf_util.create_arg_parser(_("Records requests to audit log, performs only permitted requests."), usage=_("usage: p4gf_auth_server.py [-h] [-V] [--user] [--keyfp] git-upload-pack | git-receive-pack [options] <view>")) parser.add_argument(NTR('--user'), metavar="", help=_('Perforce user account requesting this action')) parser.add_argument(NTR('--keyfp'), metavar="", help=_('ssh key used to authenticate this connection')) parser.add_argument(NTR('command'), metavar=NTR("command"), nargs=1, help=_('git-upload-pack or git-receive-pack, plus options')) parser.add_argument(NTR('options'), metavar="", nargs=argparse.REMAINDER, help=_('options for git-upload-pack or git-receive-pack')) # reverse git's argument modifications # pylint:disable=W1401 # raw strings don't play well with this lambda function. fix_arg = lambda s: s.replace("'\!'", "!").replace("'\\''", "'") argv = [fix_arg(arg) for arg in argv] args = parser.parse_args(argv) if not args.command[0] in p4gf_server_common.COMMAND_TO_PERM: raise p4gf_server_common.CommandError(_("Unknown command '{bad}', must be one of '{good}'.") .format(bad=args.command[0], good = "', '".join(p4gf_server_common.COMMAND_TO_PERM.keys())), usage = parser.usage) if not args.options: raise p4gf_server_common.CommandError(_("Missing directory in '{cmd}' <view>") .format(cmd=args.command[0])) # Carefully remove quotes from any view name, allowing for imbalanced quotes. view_name = args.options[-1] if view_name[0] == '"' and view_name[-1] == '"' or\ view_name[0] == "'" and view_name[-1] == "'": view_name = view_name[1:-1] # Allow for git+ssh URLs where / separates host and repository. if view_name[0] == '/': view_name = view_name[1:] args.options[-1] = view_name # Reject impossible view names/client spec names if not is_special_command(view_name) and not view_name.startswith('@') and not p4gf_util.is_legal_view_name(view_name): raise p4gf_server_common.CommandError(_("Illegal view name '{}'").format(view_name)) for o in args.options[:-1]: if illegal_option(o): raise p4gf_server_common.CommandError(_("Illegal option: '{}'").format(o)) # Require --user if -V did not early return. if not args.user: raise p4gf_server_common.CommandError(_("--user required."), usage=parser.usage) # LOG.warn("running command: {}\n".format(argv)) ### DEBUG REMOVE FOR GA return args