def test_splitPrUrl_failure_badTrailing(self): """Failure test of split_pr_url: bad trailing stuff in the URL""" (repo, pr_number ) = split_pr_url('https://github.com/ESMCI/github-tools/pull/1357a') self.assertSplitPrUrlFailure(repo, pr_number)
def _commandline_args(): """Parse and return command-line arguments Note: even if the positional pr_url is given, the returned args will always have args.repo and args.pr_number set. """ description = """ Tool for querying GitHub pull requests To show all of the outstanding todo items in all comments in a pull request (i.e., all unchecked checkboxes): gh-pr-query -r REPO -p PR_NUMBER -t or: gh-pr-query https://github.com/ORG/REPO/pull/PR_NUMBER -t To show all of the completed todo items in all comments in a pull request (i.e., all checked checkboxes): gh-pr-query -r REPO -p PR_NUMBER -c or: gh-pr-query https://github.com/ORG/REPO/pull/PR_NUMBER -c To show all comments in a pull request: gh-pr-query -r REPO -p PR_NUMBER -s or: gh-pr-query https://github.com/ORG/REPO/pull/PR_NUMBER -s Output is sorted by date; for todos, all required todos are listed before optional todos. (Optional todos are denoted by starting a todo item with '[optional]', '(optional)', or 'optional:', lowercase or uppercase.) If the environment variable GITHUB_TOKEN is set, it will be used as a personal access token for authentication. Otherwise, no authentication will be used. For details, see <https://github.com/ESMCI/github-tools#providing-a-personal-access-token>. Examples: gh-pr-query -r ESMCI/github-tools -p 1 -t gh-pr-query https://github.com/ESMCI/github-tools/pull/1 -t """ parser = argparse.ArgumentParser( description=description, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('pr_url', nargs='?', default=None, help='Full URL to the pull request.\n' 'You must specify EITHER this argument OR both\n' '--repo and --pr-number.') parser.add_argument('-r', '--repo', help='GitHub repository, in the form ORG/REPO.\n' 'Must be combined with --pr-number; cannot be combined\n' 'with the pr_url positional argument.') parser.add_argument('-p', '--pr-number', type=int, help='Pull request number.\n' 'Must be combined with --repo; cannot be combined\n' 'with the pr_url positional argument.') mode = parser.add_mutually_exclusive_group(required=True) mode.add_argument('-t', '--todo', action='store_true', help='Print all outstanding todo items in this PR') mode.add_argument('-c', '--completed', action='store_true', help='Print all completed todo items in this PR') mode.add_argument('-s', '--show', action='store_true', help='Print all comments from this PR') parser.add_argument('-u', '--filter-username', help='Only show comments made by the given user') parser.add_argument('--created-since', help='Only show comments created since the given date/time.\n' '(Format can be YYYY-MM-DD or other ISO-formatted date/time strings.\n' 'Unless timezone is explicitly specified, date/time is assumed to be UTC.\n' 'Requires python 3.7 or later.)') parser.add_argument('--updated-since', help='Only show comments updated since the given date/time.\n' 'Note that updated time is not available for the top-level PR comment\n' 'and for top-level review comments. So we show these if anything in the\n' 'PR has been updated since the given time.\n' 'Also: based on experimentation, it seems like GitHub may update the\n' 'last-updated time of comments more often than expected, so this option\n' 'may show more than expected.\n' '(Format can be YYYY-MM-DD or other ISO-formatted date/time strings.\n' 'Unless timezone is explicitly specified, date/time is assumed to be UTC.\n' 'Requires python 3.7 or later.)') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') args = parser.parse_args() if args.pr_url: if args.repo or args.pr_number: parser.error("Cannot combine --repo or --pr-number with a positional pr_url") (args.repo, args.pr_number) = split_pr_url(args.pr_url) if args.repo is None or args.pr_number is None: parser.error("Malformed pr_url") else: if not args.repo or not args.pr_number: parser.error("Without a positional pr_url, must provide both --repo and --pr-number") return args
def test_splitPrUrl_failure_noOrg(self): """Failure test of split_pr_url: no org in the URL""" (repo, pr_number) = split_pr_url('https://github.com/github-tools/pull/1357') self.assertSplitPrUrlFailure(repo, pr_number)
def test_splitPrUrl_failure_extraComponent(self): """Failure test of split_pr_url: extra component in the URL""" (repo, pr_number) = split_pr_url( 'https://github.com/ESMCI/github-tools/foo/pull/1357') self.assertSplitPrUrlFailure(repo, pr_number)
def test_splitPrUrl_failure_noPull(self): """Failure test of split_pr_url: no 'pull' in the URL""" (repo, pr_number ) = split_pr_url('https://github.com/ESMCI/github-tools/1357') self.assertSplitPrUrlFailure(repo, pr_number)
def test_splitPrUrl_success_trailingPound(self): """A success test of split_pr_url with a trailing pound sign in the URL""" (repo, pr_number) = split_pr_url( 'https://github.com/ESMCI/github-tools/pull/1357#issuecomment-123') self.assertEqual(repo, 'ESMCI/github-tools') self.assertEqual(pr_number, 1357)
def test_splitPrUrl_success_extraTrailing(self): """A success test of split_pr_url with acceptable trailing stuff in the URL""" (repo, pr_number) = split_pr_url( 'https://github.com/ESMCI/github-tools/pull/1357/files') self.assertEqual(repo, 'ESMCI/github-tools') self.assertEqual(pr_number, 1357)
def test_splitPrUrl_success_basic_extraSlash(self): """A success test of split_pr_url with a trailing slash""" (repo, pr_number ) = split_pr_url('https://github.com/ESMCI/github-tools/pull/1357/') self.assertEqual(repo, 'ESMCI/github-tools') self.assertEqual(pr_number, 1357)
def test_splitPrUrl_success_basic(self): """A basic success test of split_pr_url""" (repo, pr_number ) = split_pr_url('https://github.com/ESMCI/github-tools/pull/1357') self.assertEqual(repo, 'ESMCI/github-tools') self.assertEqual(pr_number, 1357)