pystand 2.23__tar.gz → 2.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pystand-2.23/pystand.egg-info → pystand-2.25}/PKG-INFO +1 -1
- {pystand-2.23 → pystand-2.25/pystand.egg-info}/PKG-INFO +1 -1
- {pystand-2.23 → pystand-2.25}/pystand.py +73 -57
- {pystand-2.23 → pystand-2.25}/.gitignore +0 -0
- {pystand-2.23 → pystand-2.25}/README.md +0 -0
- {pystand-2.23 → pystand-2.25}/justfile +0 -0
- {pystand-2.23 → pystand-2.25}/pyproject.toml +0 -0
- {pystand-2.23 → pystand-2.25}/pystand.egg-info/SOURCES.txt +0 -0
- {pystand-2.23 → pystand-2.25}/pystand.egg-info/dependency_links.txt +0 -0
- {pystand-2.23 → pystand-2.25}/pystand.egg-info/entry_points.txt +0 -0
- {pystand-2.23 → pystand-2.25}/pystand.egg-info/requires.txt +0 -0
- {pystand-2.23 → pystand-2.25}/pystand.egg-info/top_level.txt +0 -0
- {pystand-2.23 → pystand-2.25}/setup.cfg +0 -0
|
@@ -18,7 +18,6 @@ import sys
|
|
|
18
18
|
import time
|
|
19
19
|
from collections import defaultdict
|
|
20
20
|
from collections.abc import Iterable, Iterator
|
|
21
|
-
from dataclasses import dataclass, field
|
|
22
21
|
from datetime import date, datetime
|
|
23
22
|
from pathlib import Path
|
|
24
23
|
from typing import Any
|
|
@@ -71,14 +70,45 @@ COLORS = [
|
|
|
71
70
|
]
|
|
72
71
|
|
|
73
72
|
|
|
74
|
-
@dataclass
|
|
75
73
|
class ColorTable:
|
|
76
|
-
|
|
77
|
-
table: dict[str, str] = field(default_factory=dict)
|
|
74
|
+
"Base class for color tables"
|
|
78
75
|
|
|
76
|
+
def __init__(self, initval: str, no_color: bool) -> None:
|
|
77
|
+
self.table = None if no_color else {self.parse_key(initval): COLORS[0]}
|
|
78
|
+
self.next = itertools.cycle(COLORS[1:-1])
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
def get_color(self, text: str) -> str:
|
|
81
|
+
"Assign a new color by cycling through the available colors"
|
|
82
|
+
if not self.table:
|
|
83
|
+
return text
|
|
84
|
+
|
|
85
|
+
if not (color := self.table.get(key := self.parse_key(text))):
|
|
86
|
+
self.table[key] = color = next(self.next)
|
|
87
|
+
|
|
88
|
+
return f'{color}{text}{COLORS[-1]}'
|
|
89
|
+
|
|
90
|
+
def parse_key(self, text: str) -> str:
|
|
91
|
+
"Parse text for color table key, default is full text"
|
|
92
|
+
return text
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ColorRel(ColorTable):
|
|
96
|
+
"Return colored release version string"
|
|
97
|
+
|
|
98
|
+
def format(self, version: str, release: str) -> str:
|
|
99
|
+
"Return a formatted release version string"
|
|
100
|
+
return f'{version} @ {self.get_color(release)}'
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ColorDist(ColorTable):
|
|
104
|
+
"Return colored distribution string"
|
|
105
|
+
|
|
106
|
+
def format(self, dist: str) -> str:
|
|
107
|
+
return f'distribution="{self.get_color(dist)}"'
|
|
108
|
+
|
|
109
|
+
def parse_key(self, text: str) -> str:
|
|
110
|
+
"Extract key for distribution color"
|
|
111
|
+
return text.split('-', 1)[0]
|
|
82
112
|
|
|
83
113
|
|
|
84
114
|
def is_admin() -> bool:
|
|
@@ -103,36 +133,6 @@ def get_version() -> str:
|
|
|
103
133
|
return ver
|
|
104
134
|
|
|
105
135
|
|
|
106
|
-
def fmtrel(version: str, release: str, args: Namespace) -> str:
|
|
107
|
-
"Return a formatted release version string"
|
|
108
|
-
if not args.no_color:
|
|
109
|
-
if release == args._release:
|
|
110
|
-
color = COLORS[0]
|
|
111
|
-
elif not (color := colors_rel.table.get(release)):
|
|
112
|
-
# Assign a new color for this release by cycling through the
|
|
113
|
-
# available colors.
|
|
114
|
-
colors_rel.table[release] = color = next(colors_rel.next)
|
|
115
|
-
|
|
116
|
-
release = f'{color}{release}{COLORS[-1]}'
|
|
117
|
-
|
|
118
|
-
return f'{version} @ {release}'
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def fmtdist(dist: str, args: Namespace) -> str:
|
|
122
|
-
"Return a formatted distribution string"
|
|
123
|
-
if not args.no_color:
|
|
124
|
-
if dist == args._distribution:
|
|
125
|
-
color = COLORS[0]
|
|
126
|
-
elif not (color := colors_dist.table.get(dist)):
|
|
127
|
-
# Assign a new color for this distribution by cycling through the
|
|
128
|
-
# available colors.
|
|
129
|
-
colors_dist.table[dist] = color = next(colors_dist.next)
|
|
130
|
-
|
|
131
|
-
dist = f'{color}{dist}{COLORS[-1]}'
|
|
132
|
-
|
|
133
|
-
return f'distribution="{dist}"'
|
|
134
|
-
|
|
135
|
-
|
|
136
136
|
def get_json(file: Path) -> dict[str, Any]:
|
|
137
137
|
from json import load
|
|
138
138
|
|
|
@@ -398,7 +398,11 @@ def fetch_tag_latest(args: Namespace) -> str:
|
|
|
398
398
|
|
|
399
399
|
def get_release_tag(args: Namespace) -> str:
|
|
400
400
|
"Return the release tag, or latest if not specified"
|
|
401
|
-
if
|
|
401
|
+
if (
|
|
402
|
+
hasattr(args, 'release')
|
|
403
|
+
and (release := args.release)
|
|
404
|
+
and isinstance(release, str)
|
|
405
|
+
):
|
|
402
406
|
if err := check_release_tag(release):
|
|
403
407
|
sys.exit(err)
|
|
404
408
|
|
|
@@ -691,7 +695,9 @@ def show_cache_size(path: Path, args: Namespace) -> None:
|
|
|
691
695
|
)
|
|
692
696
|
total += size
|
|
693
697
|
size_str = f'{size}B' if args.no_human_readable else to_human(size)
|
|
694
|
-
name =
|
|
698
|
+
name = (
|
|
699
|
+
str(spath) if spath.is_dir() else f'{spath.parent.name}{os.sep}{spath.name}'
|
|
700
|
+
)
|
|
695
701
|
print(f'{size_str}\t{name}')
|
|
696
702
|
|
|
697
703
|
if not args.no_total:
|
|
@@ -838,6 +844,7 @@ def main() -> str | None:
|
|
|
838
844
|
|
|
839
845
|
args._implementation = 'cpython' # at the moment, only support CPython
|
|
840
846
|
args._distribution = distribution
|
|
847
|
+
args._fmtdist = ColorDist(distribution, args.no_color).format
|
|
841
848
|
args._data = f'{PROG}.json'
|
|
842
849
|
|
|
843
850
|
args._versions = prefix_dir
|
|
@@ -855,6 +862,7 @@ def main() -> str | None:
|
|
|
855
862
|
try:
|
|
856
863
|
with locks[0].acquire(blocking=False), locks[1].acquire(blocking=False):
|
|
857
864
|
args._release = get_release_tag(args)
|
|
865
|
+
args._fmtrel = ColorRel(args._release, args.no_color).format
|
|
858
866
|
result = args.func(args)
|
|
859
867
|
purge_unused_releases(args)
|
|
860
868
|
update_version_symlinks(args)
|
|
@@ -944,7 +952,7 @@ class install_:
|
|
|
944
952
|
for version in args.version:
|
|
945
953
|
full_version = matcher.match(version)
|
|
946
954
|
if not full_version:
|
|
947
|
-
return f'Version {
|
|
955
|
+
return f'Version {args._fmtrel(version, release)} not found.'
|
|
948
956
|
|
|
949
957
|
version = full_version
|
|
950
958
|
vdir = args._versions / version
|
|
@@ -956,7 +964,7 @@ class install_:
|
|
|
956
964
|
if error := install(args, vdir, release, args._distribution, files):
|
|
957
965
|
return error
|
|
958
966
|
|
|
959
|
-
print(f'Version {
|
|
967
|
+
print(f'Version {args._fmtrel(version, release)} installed.')
|
|
960
968
|
|
|
961
969
|
|
|
962
970
|
# COMMAND
|
|
@@ -1018,9 +1026,9 @@ class update_:
|
|
|
1018
1026
|
|
|
1019
1027
|
if nextver == version and args.keep and release:
|
|
1020
1028
|
print(
|
|
1021
|
-
f'Error: {
|
|
1022
|
-
f'if update to {
|
|
1023
|
-
f'{
|
|
1029
|
+
f'Error: {args._fmtrel(version, release)} would not be kept '
|
|
1030
|
+
f'if update to {args._fmtrel(nextver, release_target)} '
|
|
1031
|
+
f'{args._fmtdist(distribution)}',
|
|
1024
1032
|
file=sys.stderr,
|
|
1025
1033
|
)
|
|
1026
1034
|
continue
|
|
@@ -1030,9 +1038,9 @@ class update_:
|
|
|
1030
1038
|
continue
|
|
1031
1039
|
|
|
1032
1040
|
print(
|
|
1033
|
-
f'{
|
|
1034
|
-
f'{
|
|
1035
|
-
f'{
|
|
1041
|
+
f'{args._fmtrel(version, release)} updating to '
|
|
1042
|
+
f'{args._fmtrel(nextver, release_target)} '
|
|
1043
|
+
f'{args._fmtdist(distribution)} ..'
|
|
1036
1044
|
)
|
|
1037
1045
|
|
|
1038
1046
|
# If the source was originally included, then include it in
|
|
@@ -1084,7 +1092,7 @@ class remove_:
|
|
|
1084
1092
|
release = get_json(dfile).get('release') or '?'
|
|
1085
1093
|
if not release_del or release == release_del:
|
|
1086
1094
|
remove(args, version)
|
|
1087
|
-
print(f'Version {
|
|
1095
|
+
print(f'Version {args._fmtrel(version, release)} removed.')
|
|
1088
1096
|
|
|
1089
1097
|
|
|
1090
1098
|
# COMMAND
|
|
@@ -1147,7 +1155,7 @@ class list_:
|
|
|
1147
1155
|
)
|
|
1148
1156
|
app = (
|
|
1149
1157
|
f' not eligible for '
|
|
1150
|
-
f'update because {
|
|
1158
|
+
f'update because {args._fmtrel(nextver, nrelease)} '
|
|
1151
1159
|
'is already installed.'
|
|
1152
1160
|
)
|
|
1153
1161
|
else:
|
|
@@ -1155,19 +1163,19 @@ class list_:
|
|
|
1155
1163
|
# this same distribution anymore
|
|
1156
1164
|
if nextver and distribution in files.get(nextver, {}):
|
|
1157
1165
|
upd = (
|
|
1158
|
-
f' updatable to {
|
|
1166
|
+
f' updatable to {args._fmtrel(nextver, release_target)}'
|
|
1159
1167
|
)
|
|
1160
1168
|
elif args.verbose:
|
|
1161
1169
|
app = (
|
|
1162
1170
|
' not eligible for update because '
|
|
1163
|
-
f'{
|
|
1164
|
-
f'not provide {
|
|
1171
|
+
f'{args._fmtrel(nextver, release_target)} does '
|
|
1172
|
+
f'not provide {args._fmtdist(distribution)}.'
|
|
1165
1173
|
)
|
|
1166
1174
|
|
|
1167
1175
|
if release:
|
|
1168
1176
|
print(
|
|
1169
|
-
f'{
|
|
1170
|
-
f'{
|
|
1177
|
+
f'{args._fmtrel(version, release)}{upd} '
|
|
1178
|
+
f'{args._fmtdist(distribution)}{app}'
|
|
1171
1179
|
)
|
|
1172
1180
|
|
|
1173
1181
|
|
|
@@ -1239,12 +1247,12 @@ class show_:
|
|
|
1239
1247
|
args.re_match, f'{version}+{distribution}'
|
|
1240
1248
|
):
|
|
1241
1249
|
print(
|
|
1242
|
-
f'{
|
|
1243
|
-
f'{
|
|
1250
|
+
f'{args._fmtrel(version, release)} '
|
|
1251
|
+
f'{args._fmtdist(distribution)}{app}'
|
|
1244
1252
|
)
|
|
1245
1253
|
if not installable:
|
|
1246
1254
|
print(
|
|
1247
|
-
f'Warning: no {
|
|
1255
|
+
f'Warning: no {args._fmtdist(args._distribution)} '
|
|
1248
1256
|
f'versions found in release "{release}".'
|
|
1249
1257
|
)
|
|
1250
1258
|
|
|
@@ -1338,7 +1346,15 @@ class cache_:
|
|
|
1338
1346
|
|
|
1339
1347
|
elif args.release:
|
|
1340
1348
|
for release in args.release:
|
|
1341
|
-
|
|
1349
|
+
# Allow user to include cache path in release name
|
|
1350
|
+
path = (args._downloads / release).expanduser()
|
|
1351
|
+
if err := check_release_tag(path.name):
|
|
1352
|
+
return err
|
|
1353
|
+
|
|
1354
|
+
if not path.exists():
|
|
1355
|
+
return f'No cache for release {release}.'
|
|
1356
|
+
|
|
1357
|
+
show_cache_size(path, args)
|
|
1342
1358
|
else:
|
|
1343
1359
|
show_cache_size(args._downloads, args)
|
|
1344
1360
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|