blob: 3c579c34d6bac890e9a9a86133ef7d27c0cabf22 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Command line interface for the Bitbucket bridge."""
from __future__ import annotations
import argparse
import json
from collections.abc import Sequence
from typing import Any
from magpie_bitbucket import cloud, datacenter, normalize
from magpie_bitbucket.client import BitbucketConfig, load_config
def main(argv: Sequence[str] | None = None) -> int:
"""Run the magpie-bitbucket command line interface."""
parser = _build_parser()
args = parser.parse_args(argv)
config = load_config()
result = _dispatch(args, config)
_print_json(result)
return 0
def _build_parser() -> argparse.ArgumentParser:
"""Build the CLI parser."""
parser = argparse.ArgumentParser(
prog="magpie-bitbucket",
description="Bitbucket Cloud and Data Center bridge for Apache Magpie.",
)
subparsers = parser.add_subparsers(dest="subcommand", required=True)
subparsers.add_parser("auth-check", help="Verify configured Bitbucket repository access.")
repo_parser = subparsers.add_parser("repo", help="Interact with Bitbucket repositories.")
repo_subparsers = repo_parser.add_subparsers(dest="repo_action", required=True)
repo_subparsers.add_parser("get", help="Fetch repository metadata.")
pr_parser = subparsers.add_parser("pr", help="Interact with Bitbucket pull requests.")
pr_subparsers = pr_parser.add_subparsers(dest="pr_action", required=True)
pr_subparsers.add_parser("list-open", help="List open pull requests.")
pr_get = pr_subparsers.add_parser("get", help="Fetch one pull request.")
pr_get.add_argument("pull_request_id", help="Pull request ID to fetch.")
pr_commits = pr_subparsers.add_parser("commits", help="Fetch pull request commits.")
pr_commits.add_argument("pull_request_id", help="Pull request ID to fetch commits for.")
pr_diff = pr_subparsers.add_parser("diff", help="Fetch pull request diff.")
pr_diff.add_argument("pull_request_id", help="Pull request ID to fetch diff for.")
pr_discussion = pr_subparsers.add_parser("discussion", help="Fetch pull request discussion.")
pr_discussion.add_argument("pull_request_id", help="Pull request ID to fetch discussion for.")
pr_reviews = pr_subparsers.add_parser("reviews", help="Fetch pull request review-state activity.")
pr_reviews.add_argument("pull_request_id", help="Pull request ID to fetch review state for.")
pr_merge_checks = pr_subparsers.add_parser("merge-checks", help="Fetch pull request merge-check context.")
pr_merge_checks.add_argument("pull_request_id", help="Pull request ID to fetch merge-check context for.")
pr_status = pr_subparsers.add_parser("status", help="Fetch pull request build/status checks.")
pr_status.add_argument("pull_request_id", help="Pull request ID to fetch status checks for.")
return parser
def _dispatch(args: argparse.Namespace, config: BitbucketConfig) -> dict[str, Any]:
"""Dispatch parsed CLI arguments to the selected backend."""
backend = _backend(config)
if args.subcommand == "auth-check":
raw = backend.get_repository(config)
return {
"ok": True,
"backend": "bitbucket-cloud" if config.kind == "cloud" else "bitbucket-datacenter",
"repository": normalize.repository(config.kind, raw),
}
if args.subcommand == "repo" and args.repo_action == "get":
raw = backend.get_repository(config)
return normalize.repository(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "list-open":
raw = backend.list_open_pull_requests(config)
return normalize.pull_request_list(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "get":
raw = backend.get_pull_request(config, args.pull_request_id)
return normalize.pull_request(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "commits":
raw = backend.get_pull_request_commits(config, args.pull_request_id)
return normalize.pull_request_commits(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "diff":
raw = backend.get_pull_request_diff(config, args.pull_request_id)
return normalize.pull_request_diff(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "discussion":
raw = backend.get_pull_request_discussion(config, args.pull_request_id)
return normalize.pull_request_discussion(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "reviews":
raw = backend.get_pull_request_reviews(config, args.pull_request_id)
return normalize.pull_request_reviews(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "merge-checks":
raw = backend.get_pull_request_merge_checks(config, args.pull_request_id)
return normalize.pull_request_merge_checks(config.kind, raw)
if args.subcommand == "pr" and args.pr_action == "status":
raw = backend.get_pull_request_status(config, args.pull_request_id)
return normalize.pull_request_status(config.kind, raw)
msg = "Unsupported command"
raise ValueError(msg)
def _backend(config: BitbucketConfig) -> Any:
"""Return the module implementing the configured Bitbucket backend."""
if config.kind == "cloud":
return cloud
return datacenter
def _print_json(data: dict[str, Any]) -> None:
"""Print JSON output to stdout."""
print(json.dumps(data, indent=2, sort_keys=True))