@@ -236,6 +236,16 @@ def setup_instparser(instparser):
236
236
"releaseargs" , nargs = argparse .REMAINDER , help = extraargs_help ("pytest" )
237
237
)
238
238
239
+ patchreleaseparser = subparsers .add_parser (
240
+ "update_patch_versions" ,
241
+ help = "Updates version numbers during patch release, used by maintainers and CI" ,
242
+ )
243
+ patchreleaseparser .set_defaults (func = patch_release_args )
244
+ patchreleaseparser .add_argument ("--stable_version" , required = True )
245
+ patchreleaseparser .add_argument ("--unstable_version" , required = True )
246
+ patchreleaseparser .add_argument ("--stable_version_prev" , required = True )
247
+ patchreleaseparser .add_argument ("--unstable_version_prev" , required = True )
248
+
239
249
fmtparser = subparsers .add_parser (
240
250
"format" ,
241
251
help = "Formats all source code with black and isort." ,
@@ -599,6 +609,24 @@ def update_dependencies(targets, version, packages):
599
609
)
600
610
601
611
612
+ def update_patch_dependencies (targets , version , prev_version , packages ):
613
+ print ("updating patch dependencies" )
614
+ # PEP 508 allowed specifier operators
615
+ operators = ["==" , "!=" , "<=" , ">=" , "<" , ">" , "===" , "~=" , "=" ]
616
+ operators_pattern = "|" .join (re .escape (op ) for op in operators )
617
+
618
+ for pkg in packages :
619
+ search = rf"({ basename (pkg )} [^,]*?)(\s?({ operators_pattern } )\s?)(.*{ prev_version } )"
620
+ replace = r"\g<1>\g<2>" + version
621
+ print (f"{ search = } \t { replace = } \t { pkg = } " )
622
+ update_files (
623
+ targets ,
624
+ "pyproject.toml" ,
625
+ search ,
626
+ replace ,
627
+ )
628
+
629
+
602
630
def update_files (targets , filename , search , replace ):
603
631
errors = False
604
632
for target in targets :
@@ -640,6 +668,32 @@ def release_args(args):
640
668
update_version_files (targets , version , packages )
641
669
642
670
671
+ def patch_release_args (args ):
672
+ print ("preparing patch release" )
673
+
674
+ rootpath = find_projectroot ()
675
+ targets = list (find_targets_unordered (rootpath ))
676
+ cfg = ConfigParser ()
677
+ cfg .read (str (find_projectroot () / "eachdist.ini" ))
678
+ # stable
679
+ mcfg = cfg ["stable" ]
680
+ packages = mcfg ["packages" ].split ()
681
+ print (f"update stable packages to { args .stable_version } " )
682
+ update_patch_dependencies (
683
+ targets , args .stable_version , args .stable_version_prev , packages
684
+ )
685
+ update_version_files (targets , args .stable_version , packages )
686
+
687
+ # prerelease
688
+ mcfg = cfg ["prerelease" ]
689
+ packages = mcfg ["packages" ].split ()
690
+ print (f"update prerelease packages to { args .unstable_version } " )
691
+ update_patch_dependencies (
692
+ targets , args .unstable_version , args .unstable_version_prev , packages
693
+ )
694
+ update_version_files (targets , args .unstable_version , packages )
695
+
696
+
643
697
def test_args (args ):
644
698
clean_remainder_args (args .pytestargs )
645
699
execute_args (
0 commit comments