-
Notifications
You must be signed in to change notification settings - Fork 23
/
list_cmd.py
109 lines (89 loc) · 3.96 KB
/
list_cmd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Copyright (C) 2022 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
"""This module lists the libraries that were installed with hekit"""
from pathlib import Path
from itertools import chain
from kit.utils.files import list_dirs, load_toml
from kit.utils.config import config_required
from kit.utils.typing import PathType
# Number of separation spaces for columns
_SEP_SPACES = 2
_HEADER_COL_1 = "COMPONENT"
_HEADER_COL_2 = "INSTANCE"
class RepoProperties:
"""Contains a dictionary with the structure of the repo
and widths of the widest component and instance"""
def __init__(self, repo_location: str, separation_spaces: int = _SEP_SPACES):
# Get the components and instances
self._repo_structure = RepoProperties._repo_struct(repo_location)
# Get the width of the widest component
all_components = [*self._repo_structure.keys(), _HEADER_COL_1]
self.width_comp = self.max_len(all_components)
# Get the width of the widest instance
all_instances = [*self._repo_structure.values(), [_HEADER_COL_2]]
self.width_inst = self.max_len(chain.from_iterable(all_instances))
# Include column separation
self.width_comp += separation_spaces
self.width_inst += separation_spaces
self.width_status = 10
self.separation_spaces = separation_spaces
@staticmethod
def max_len(iterable):
"""Return the width of the widest string"""
return max(map(len, iterable), default=0)
@property
def structure(self) -> dict[str, list[str]]:
"""Return a dictionary with the structure of the repo"""
return self._repo_structure
@staticmethod
def _repo_struct(path: PathType) -> dict[str, list[str]]:
"""Return a dictionary with sorted keys as components and values as
sorted list of instances"""
path = Path(path)
return {component: list_dirs(path / component) for component in list_dirs(path)}
@config_required
def list_components(args):
"""List to stdout info on components."""
repo_location = Path(args.config.repo_location)
repo_properties = RepoProperties(repo_location)
# Aliases
width_status = repo_properties.width_status
width_comp = repo_properties.width_comp
width_inst = repo_properties.width_inst
# Header
print(
f"{_HEADER_COL_1:{width_comp}} {_HEADER_COL_2:{width_inst}} {'FETCH':{width_status}} {'BUILD':{width_status}} {'INSTALL':{width_status}}"
)
for comp_name, inst_list in repo_properties.structure.items():
for comp_inst in inst_list:
try:
info_filepath = repo_location / comp_name / comp_inst / "hekit.info"
info_file = load_toml(info_filepath)
print(
f"{comp_name:{width_comp}} {comp_inst:{width_inst}}",
f"{info_file['status']['fetch']:{width_status}}",
f"{info_file['status']['build']:{width_status}}",
f"{info_file['status']['install']:{width_status}}",
)
except FileNotFoundError:
print(
f"{comp_name:{width_comp}} {comp_inst:{width_inst}}",
f"{'unknown':{width_status}}",
f"{'unknown':{width_status}}",
f"{'unknown':{width_status}}",
f"file '{info_filepath}' not found",
)
except KeyError as emsg:
print(
f"{comp_name:{width_comp}} {comp_inst:{width_inst}}",
f"{'unknown':{width_status}}",
f"{'unknown':{width_status}}",
f"{'unknown':{width_status}}",
f"key {emsg} not found",
)
def set_list_subparser(subparsers):
"""create the parser for the 'list' command"""
parser_list = subparsers.add_parser(
"list", description="lists installed components"
)
parser_list.set_defaults(fn=list_components)