|
27 | 27 | # Ideas stolen from Mailman's release script, Lib/tokens.py and welease |
28 | 28 |
|
29 | 29 |
|
| 30 | +class Tag: |
| 31 | + def __init__(self, tag_name): |
| 32 | + # if tag is ".", use current directory name as tag |
| 33 | + # e.g. if current directory name is "3.4.6", |
| 34 | + # "release.py --bump 3.4.6" and "release.py --bump ." are the same |
| 35 | + if tag_name == ".": |
| 36 | + tag_name = os.path.basename(os.getcwd()) |
| 37 | + result = tag_cre.match(tag_name) |
| 38 | + if result is None: |
| 39 | + error(f"tag {tag_name} is not valid") |
| 40 | + data = list(result.groups()) |
| 41 | + if data[3] is None: |
| 42 | + # A final release. |
| 43 | + self.is_final = True |
| 44 | + data[3] = "f" |
| 45 | + else: |
| 46 | + self.is_final = False |
| 47 | + # For everything else, None means 0. |
| 48 | + for i, thing in enumerate(data): |
| 49 | + if thing is None: |
| 50 | + data[i] = 0 |
| 51 | + self.major = int(data[0]) |
| 52 | + self.minor = int(data[1]) |
| 53 | + self.patch = int(data[2]) |
| 54 | + self.level = data[3] |
| 55 | + self.serial = int(data[4]) |
| 56 | + # This has the effect of normalizing the version. |
| 57 | + self.text = self.normalized() |
| 58 | + if self.level != "f": |
| 59 | + self.text += self.level + str(self.serial) |
| 60 | + self.basic_version = f"{self.major}.{self.minor}" |
| 61 | + |
| 62 | + def __str__(self): |
| 63 | + return self.text |
| 64 | + |
| 65 | + def normalized(self): |
| 66 | + return f"{self.major}.{self.minor}.{self.patch}" |
| 67 | + |
| 68 | + @property |
| 69 | + def branch(self): |
| 70 | + return "main" if self.is_alpha_release else f"{self.major}.{self.minor}" |
| 71 | + |
| 72 | + @property |
| 73 | + def is_alpha_release(self): |
| 74 | + return self.level == "a" |
| 75 | + |
| 76 | + @property |
| 77 | + def is_release_candidate(self): |
| 78 | + return self.level == "rc" |
| 79 | + |
| 80 | + @property |
| 81 | + def is_feature_freeze_release(self): |
| 82 | + return self.level == "b" and self.serial == 1 |
| 83 | + |
| 84 | + @property |
| 85 | + def nickname(self): |
| 86 | + return self.text.replace(".", "") |
| 87 | + |
| 88 | + @property |
| 89 | + def gitname(self): |
| 90 | + return "v" + self.text |
| 91 | + |
| 92 | + def next_minor_release(self): |
| 93 | + return self.__class__(f"{self.major}.{int(self.minor)+1}.0a0") |
| 94 | + |
| 95 | + def as_tuple(self): |
| 96 | + return (self.major, self.minor, self.patch, self.level, self.serial) |
| 97 | + |
| 98 | + @property |
| 99 | + def committed_at(self): |
| 100 | + # Fetch the epoch of the tagged commit for build reproducibility. |
| 101 | + proc = subprocess.run( |
| 102 | + ["git", "log", self.gitname, "-1", "--pretty=%ct"], stdout=subprocess.PIPE |
| 103 | + ) |
| 104 | + if proc.returncode != 0: |
| 105 | + error(f"Couldn't fetch the epoch of tag {self.gitname}") |
| 106 | + return datetime.datetime.fromtimestamp( |
| 107 | + int(proc.stdout.decode().strip()), tz=datetime.timezone.utc |
| 108 | + ) |
| 109 | + |
| 110 | + |
30 | 111 | def error(*msgs): |
31 | 112 | print("**ERROR**", file=sys.stderr) |
32 | 113 | for msg in msgs: |
@@ -485,88 +566,6 @@ def scp(from_loc, to_loc): |
485 | 566 | ) |
486 | 567 |
|
487 | 568 |
|
488 | | -class Tag: |
489 | | - |
490 | | - def __init__(self, tag_name): |
491 | | - # if tag is ".", use current directory name as tag |
492 | | - # e.g. if current directory name is "3.4.6", |
493 | | - # "release.py --bump 3.4.6" and "release.py --bump ." are the same |
494 | | - if tag_name == ".": |
495 | | - tag_name = os.path.basename(os.getcwd()) |
496 | | - result = tag_cre.match(tag_name) |
497 | | - if result is None: |
498 | | - error(f"tag {tag_name} is not valid") |
499 | | - data = list(result.groups()) |
500 | | - if data[3] is None: |
501 | | - # A final release. |
502 | | - self.is_final = True |
503 | | - data[3] = "f" |
504 | | - else: |
505 | | - self.is_final = False |
506 | | - # For everything else, None means 0. |
507 | | - for i, thing in enumerate(data): |
508 | | - if thing is None: |
509 | | - data[i] = 0 |
510 | | - self.major = int(data[0]) |
511 | | - self.minor = int(data[1]) |
512 | | - self.patch = int(data[2]) |
513 | | - self.level = data[3] |
514 | | - self.serial = int(data[4]) |
515 | | - # This has the effect of normalizing the version. |
516 | | - self.text = self.normalized() |
517 | | - if self.level != "f": |
518 | | - self.text += self.level + str(self.serial) |
519 | | - self.basic_version = f"{self.major}.{self.minor}" |
520 | | - |
521 | | - def __str__(self): |
522 | | - return self.text |
523 | | - |
524 | | - def normalized(self): |
525 | | - return f"{self.major}.{self.minor}.{self.patch}" |
526 | | - |
527 | | - @property |
528 | | - def branch(self): |
529 | | - return "main" if self.is_alpha_release else f"{self.major}.{self.minor}" |
530 | | - |
531 | | - @property |
532 | | - def is_alpha_release(self): |
533 | | - return self.level == "a" |
534 | | - |
535 | | - @property |
536 | | - def is_release_candidate(self): |
537 | | - return self.level == "rc" |
538 | | - |
539 | | - @property |
540 | | - def is_feature_freeze_release(self): |
541 | | - return self.level == "b" and self.serial == 1 |
542 | | - |
543 | | - @property |
544 | | - def nickname(self): |
545 | | - return self.text.replace(".", "") |
546 | | - |
547 | | - @property |
548 | | - def gitname(self): |
549 | | - return "v" + self.text |
550 | | - |
551 | | - def next_minor_release(self): |
552 | | - return self.__class__(f"{self.major}.{int(self.minor)+1}.0a0") |
553 | | - |
554 | | - def as_tuple(self): |
555 | | - return (self.major, self.minor, self.patch, self.level, self.serial) |
556 | | - |
557 | | - @property |
558 | | - def committed_at(self): |
559 | | - # Fetch the epoch of the tagged commit for build reproducibility. |
560 | | - proc = subprocess.run( |
561 | | - ["git", "log", self.gitname, "-1", "--pretty=%ct"], stdout=subprocess.PIPE |
562 | | - ) |
563 | | - if proc.returncode != 0: |
564 | | - error(f"Couldn't fetch the epoch of tag {self.gitname}") |
565 | | - return datetime.datetime.fromtimestamp( |
566 | | - int(proc.stdout.decode().strip()), tz=datetime.timezone.utc |
567 | | - ) |
568 | | - |
569 | | - |
570 | 569 | def make_tag(tag): |
571 | 570 | # make sure we've run blurb export |
572 | 571 | good_files = glob.glob("Misc/NEWS.d/" + str(tag) + ".rst") |
|
0 commit comments