Skip to content

Commit 8194e49

Browse files
Add --status flag to list (#91)
1 parent e48668a commit 8194e49

3 files changed

Lines changed: 59 additions & 13 deletions

File tree

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.2.4
2+
3+
* Add the `--status` option to `kup list` showing the lag behind the default branch for each dependency
4+
15
# 0.2.3
26

37
* Cleanup help and docs, removing mentions to the update/remove keywords

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "kup"
7-
version = "0.2.3"
7+
version = "0.2.4"
88
description = "kup is a tool for managing installations of the K framework along with the different available semantics"
99
authors = [
1010
"Runtime Verification, Inc. <contact@runtimeverification.com>",

src/kup/__main__.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import giturlparse
1111
import requests
1212
import rich
13+
from rich.align import Align
14+
from rich.columns import Columns
1315
from rich.console import Console
1416
from rich.markdown import Markdown
1517
from rich.theme import Theme
@@ -113,7 +115,9 @@ def walk_path_nix_meta(nodes: dict, current_node_id: str, path: list[str]) -> st
113115

114116

115117
# walk all the inputs recursively and collect only the ones pointing to runtimeverification repos
116-
def parse_package_metadata(nodes: dict, current_node_id: str, root_level: bool = False) -> Union[PackageMetadata, None]:
118+
def parse_package_metadata(
119+
nodes: dict, current_node_id: str, root_level: bool = False, repo: str = ''
120+
) -> Union[PackageMetadata, None]:
117121
if not (
118122
'original' in nodes[current_node_id]
119123
and 'owner' in nodes[current_node_id]['original']
@@ -122,7 +126,6 @@ def parse_package_metadata(nodes: dict, current_node_id: str, root_level: bool =
122126
if not root_level:
123127
return None
124128
else:
125-
repo = ''
126129
rev = ''
127130
org = 'runtimeverification'
128131
else:
@@ -161,7 +164,7 @@ def get_package_metadata(package: GithubPackage) -> PackageMetadata:
161164
meta = json.loads(result)
162165
root_id = meta['locks']['root']
163166

164-
res = parse_package_metadata(meta['locks']['nodes'], root_id, True)
167+
res = parse_package_metadata(meta['locks']['nodes'], root_id, True, package.repo)
165168
if not res:
166169
rich.print('❗ [red]Could not parse package metadata!')
167170
sys.exit(1)
@@ -170,16 +173,38 @@ def get_package_metadata(package: GithubPackage) -> PackageMetadata:
170173

171174

172175
# build a rich.Tree of inputs for the given package metadata
173-
def package_metadata_tree(p: Union[PackageMetadata, Follows], lbl: Union[str, None] = None) -> Tree:
176+
def package_metadata_tree(
177+
p: Union[PackageMetadata, Follows], lbl: Union[str, None] = None, show_status: bool = False
178+
) -> Tree:
174179
if lbl is None:
175180
tree = Tree('Inputs:')
176181
else:
177182
rev = f' - github:{p.org}/{p.repo}' if type(p) == PackageMetadata else ''
178183
follows = (' - follows [green]' + '/'.join(p.follows)) if type(p) == Follows else ''
179-
tree = Tree(f'{lbl}{rev}{follows}')
184+
status = ''
185+
if show_status and type(p) == PackageMetadata:
186+
auth = {'Authorization': f'Bearer {os.getenv("GH_TOKEN")}'} if os.getenv('GH_TOKEN') else {}
187+
commits = requests.get(f'https://api.github.com/repos/{p.org}/{p.repo}/commits', headers=auth)
188+
if commits.ok:
189+
commits_list = [c['sha'] for c in commits.json()]
190+
if p.rev in commits_list:
191+
idx = commits_list.index(p.rev)
192+
if idx == 0:
193+
status = ' 🟢 up to date '
194+
elif idx == 1:
195+
status = f' 🟠 {idx} version behind master '
196+
elif idx < 10:
197+
status = f' 🟠 {idx} versions behind master '
198+
else:
199+
status = f' 🔴 {idx} versions behind master'
200+
201+
if status != '':
202+
tree = Tree(Columns([Align(f'{lbl}{rev}{follows}'), Align(status, align='right')], expand=True))
203+
else:
204+
tree = Tree(f'{lbl}{rev}{follows}')
180205
if type(p) == PackageMetadata:
181206
for k in p.inputs.keys():
182-
tree.add(package_metadata_tree(p.inputs[k], k))
207+
tree.add(package_metadata_tree(p.inputs[k], k, show_status))
183208
return tree
184209

185210

@@ -275,7 +300,7 @@ def highlight_row(condition: bool, xs: List[str]) -> List[str]:
275300
return xs
276301

277302

278-
def list_package(package_name: str, show_inputs: bool) -> None:
303+
def list_package(package_name: str, show_inputs: bool, show_status: bool) -> None:
279304
reload_packages()
280305
if package_name != 'all':
281306
if package_name not in packages.keys():
@@ -286,11 +311,17 @@ def list_package(package_name: str, show_inputs: bool) -> None:
286311
return
287312
listed_package = packages[package_name]
288313

289-
if show_inputs:
314+
if show_inputs or show_status:
290315
inputs = get_package_metadata(listed_package)
291-
rich.print(package_metadata_tree(inputs))
316+
rich.print(package_metadata_tree(inputs, show_status=show_status))
292317
else:
293-
auth = {'Authorization': f'Bearer {listed_package.access_token}'} if listed_package.access_token else {}
318+
auth = (
319+
{'Authorization': f'Bearer {listed_package.access_token}'}
320+
if listed_package.access_token
321+
else {'Authorization': f'Bearer {os.getenv("GH_TOKEN")}'}
322+
if os.getenv('GH_TOKEN')
323+
else {}
324+
)
294325
tags = requests.get(
295326
f'https://api.github.com/repos/{listed_package.org}/{listed_package.repo}/tags', headers=auth
296327
)
@@ -533,7 +564,13 @@ def ping_nix_store(url: str, access_token: Optional[str] = None) -> Tuple[bool,
533564

534565

535566
def check_github_api_accessible(org: str, repo: str, access_token: Optional[str]) -> bool:
536-
auth = {'Authorization': f'Bearer {access_token}'} if access_token else {}
567+
auth = (
568+
{'Authorization': f'Bearer {access_token}'}
569+
if access_token
570+
else {'Authorization': f'Bearer {os.getenv("GH_TOKEN")}'}
571+
if os.getenv('GH_TOKEN')
572+
else {}
573+
)
537574
commits = requests.get(f'https://api.github.com/repos/{org}/{repo}/commits', headers=auth)
538575
return commits.ok
539576

@@ -817,6 +854,11 @@ def main() -> None:
817854
list = subparser.add_parser('list', help='show the active and installed K semantics', add_help=False)
818855
list.add_argument('package', nargs='?', default='all', type=str)
819856
list.add_argument('--inputs', action='store_true', help='show the input dependencies of the selected package')
857+
list.add_argument(
858+
'--status',
859+
action='store_true',
860+
help='show the input dependencies of the selected package and how stale they are compared to the default branch',
861+
)
820862
list.add_argument('-h', '--help', action=_HelpListAction)
821863

822864
install = subparser.add_parser(
@@ -879,7 +921,7 @@ def main() -> None:
879921
package_name = PackageName.parse(args.package)
880922

881923
if args.command == 'list':
882-
list_package(package_name.base, args.inputs)
924+
list_package(package_name.base, args.inputs, args.status)
883925

884926
elif args.command == 'install':
885927
install_package(package_name, args.version, args.override, args.verbose, args.refresh)

0 commit comments

Comments
 (0)