| 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import argparse, os, re, sys, requests |
| 4 | |
| 5 | USERNAME = os.environ["BINTRAY_USERNAME"] |
| 6 | API_KEY = os.environ["BINTRAY_API_KEY"] |
| 7 | API_BASE = os.environ.get("BINTRAY_URL", "https://api.bintray.com/content") |
| 8 | ORGANIZATION = os.environ.get("BINTRAY_ORGANIZATION") |
| 9 | ALLOWED_ARCH = ["all", "arm", "i686", "aarch64", "x86_64"] |
| 10 | |
| 11 | VERSION_RE = re.compile("^\d+(\.\d+)+([^\-]+)?\-([\da-z]+)$") |
| 12 | VERIFY_FORMAT = """ |
| 13 | Does this look correct? |
| 14 | - Name: {a.name} |
| 15 | - Version: {a.version} |
| 16 | - Architecture: {a.architecture} |
| 17 | - Distribution: {a.distribution} |
| 18 | - Component: {a.component} |
| 19 | - BinTray Repo: {a.org}/{a.repo} |
| 20 | |
| 21 | (Please enter y/n): """ |
| 22 | |
| 23 | |
| 24 | def main(): |
| 25 | parser = argparse.ArgumentParser(description="Upload BinTray package.") |
| 26 | parser.add_argument("package") |
| 27 | parser.add_argument("--name", "-n") |
| 28 | parser.add_argument("--no-confirm", action='store_true', default=False) |
| 29 | parser.add_argument("--repo", "-r", default="main") |
| 30 | parser.add_argument("--org", "-o", default=ORGANIZATION) |
| 31 | parser.add_argument("--component", "-c", default="main") |
| 32 | parser.add_argument("--distribution", "-d", default="stable") |
| 33 | |
| 34 | args = parser.parse_args() |
| 35 | basename = os.path.basename(args.package) |
| 36 | |
| 37 | if not os.path.isfile(args.package): |
| 38 | raise ValueError("File {0} is not valid / does not exist.".format(args.package)) |
| 39 | |
| 40 | if not args.org: |
| 41 | raise ValueError("Organization is missing.") |
| 42 | |
| 43 | # Determine name, version and architecture from file name: |
| 44 | base, _ = os.path.splitext(basename) |
| 45 | name, version, arch = base.split("_") |
| 46 | if arch not in ALLOWED_ARCH: raise ValueError("Architecture {0} not discoverable".format(arch)) |
| 47 | if not VERSION_RE.match(version): raise ValueError("Version not discoverable ({0})".format(version)) |
| 48 | |
| 49 | args.architecture = arch |
| 50 | args.version = version |
| 51 | args.name = args.name or name |
| 52 | |
| 53 | url = "{url}/{a.org}/{a.repo}/{a.name}/{a.version}/pool/{a.component}" \ |
| 54 | "/{a.name[0]}/{basename}?publish=1".format( |
| 55 | url=API_BASE, a=args, basename=basename) |
| 56 | |
| 57 | if not args.no_confirm: |
| 58 | sys.stdout.write(VERIFY_FORMAT.format(a=args)) |
| 59 | if not sys.stdin.readline().rstrip() == "y": |
| 60 | print("\nNot submitting package.") |
| 61 | return |
| 62 | |
| 63 | print("Submitting package...") |
| 64 | |
| 65 | parameters = {"publish": "1"} |
| 66 | headers = { |
| 67 | "X-Bintray-Debian-Distribution": args.distribution, |
| 68 | "X-Bintray-Debian-Architecture": args.architecture, |
| 69 | "X-Bintray-Debian-Component": args.component |
| 70 | } |
| 71 | |
| 72 | with open(args.package, "rb") as package_fp: |
| 73 | response = requests.put(url, auth=(USERNAME, API_KEY), params=parameters, headers=headers, data=package_fp) |
| 74 | |
| 75 | if response.status_code != 201: |
| 76 | raise Exception("Failed to submit package: {0}\n{1}".format(response.status_code, response.text)) |
| 77 | |
| 78 | print("Submitted successfully.") |
| 79 | |
| 80 | if __name__ == "__main__": |
| 81 | main() |