1414import requests
1515from requests .exceptions import RequestException
1616
17- import argparse
18- import re
19- import os
20-
2117def valid_hostname (hostname ):
2218 """Validate hostname format"""
2319 if len (hostname ) > 253 :
@@ -41,7 +37,9 @@ def non_empty_string(value):
4137 epilog = "Environment variables required (unless --dry): PYPI_CLEANUP_PASSWORD, PYPI_CLEANUP_OTP"
4238)
4339parser .add_argument ("--dry" , action = "store_true" , help = "Show what would be deleted but don't actually do it" )
44- parser .add_argument ("-i" , "--index-hostname" , type = valid_hostname , required = True , help = "Index hostname (required)" )
40+ host_group = parser .add_mutually_exclusive_group (required = True )
41+ host_group .add_argument ("--prod" , action = "store_true" , help = "Use production PyPI (pypi.org)" )
42+ host_group .add_argument ("--test" , action = "store_true" , help = "Use test PyPI (test.pypi.org)" )
4543parser .add_argument ("-m" , "--max-nightlies" , type = int , default = 2 , help = "Max number of nightlies of unreleased versions (default=2)" )
4644parser .add_argument ("-u" , "--username" , type = non_empty_string , help = "Username (required unless --dry)" )
4745args = parser .parse_args ()
@@ -62,21 +60,25 @@ def non_empty_string(value):
6260 if not otp :
6361 parser .error ("PYPI_CLEANUP_OTP environment variable is required when not in dry-run mode" )
6462
65- print (f"Dry run: { args .dry } " )
66- print (f"Max nightlies: { args .max_nightlies } " )
63+ dry_run = args .dry
64+ pypi_username = args .username
65+ max_dev_releases = args .max_nightlies
66+ host = None
67+ if args .prod :
68+ host = 'pypi.org'
69+ elif args .test :
70+ host = 'test.pypi.org'
71+ pypi_url = 'https://{}/' .format (host )
72+ pypi_password = password
73+ pypi_otp = otp
74+
75+ print (f"Dry run: { dry_run } " )
76+ print (f"Max nightlies: { max_dev_releases } " )
6777if not args .dry :
68- print (f"Hostname : { args . index_hostname } " )
69- print (f"Username: { args . username } " )
78+ print (f"URL : { pypi_url } " )
79+ print (f"Username: { pypi_username } " )
7080 print ("Password and OTP loaded from environment variables" )
7181
72- # deletes old dev wheels from pypi. evil hack.
73- actually_delete = not args .dry
74- pypi_username = args .username or "user"
75- max_dev_releases = args .max_nightlies
76- host = 'https://{}/' .format (args .index_hostname )
77- pypi_password = password or "password"
78- pypi_otp = otp or "otp"
79-
8082patterns = [re .compile (r".*\.dev\d+$" )]
8183###### NOTE: This code is taken from the pypi-cleanup package (https://github.com/arcivanov/pypi-cleanup/tree/master)
8284class CsfrParser (HTMLParser ):
@@ -300,4 +302,4 @@ def run(self):
300302 logging .info (f"Would be deleting { self .package } version { pkg_ver } , but not doing it!" )
301303
302304
303- PypiCleanup (host , pypi_username , 'duckdb' , pypi_password , pypi_otp , patterns , actually_delete , max_dev_releases ).run ()
305+ PypiCleanup (pypi_url , pypi_username , 'duckdb' , pypi_password , pypi_otp , patterns , not dry_run , max_dev_releases ).run ()
0 commit comments