Skip to content

Commit 6eb2fd1

Browse files
authored
Move toward subcommands (#7)
1 parent 3c3a667 commit 6eb2fd1

3 files changed

Lines changed: 119 additions & 36 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
## [0.0.3] - 2023-11-07
11+
12+
### Changed
13+
14+
- Listing repositories of a given flavor is now the `list` subcommand
15+
16+
### Added
17+
18+
- List flavors of a given repository using the `flavors` subcommand
19+
- Configure a repository for a flavor using the `add` subcommand
20+
1021
## [0.0.2] - 2023-11-07
1122

1223
### Fixed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = repo-man
3-
version = 0.0.2
3+
version = 0.0.3
44
description = Manage repositories of different flavors.
55
long_description = file: README.md
66
long_description_content_type = text/markdown

src/repoman/cli.py

Lines changed: 107 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#!/usr/bin/env python
2-
31
import argparse
42
import configparser
53
import sys
@@ -20,20 +18,49 @@ def check_if_allowed(path: Path) -> Union[bool, NoReturn]:
2018
return True
2119

2220

23-
def configure_arguments(parser: argparse.ArgumentParser) -> None:
24-
parser.add_argument(
25-
"-l",
26-
"--list",
27-
action="store_true",
28-
help="List repositories of the specified type",
29-
)
21+
def configure_arguments(parser: argparse.ArgumentParser, repo_types: dict[str, set[str]]) -> None:
22+
subparsers = parser.add_subparsers(description="Subcommands for managing repositories", dest="subcommand")
3023

31-
parser.add_argument(
24+
# List repos
25+
list_parser = subparsers.add_parser("list", help="List matching repositories")
26+
27+
list_parser.add_argument(
3228
"-t",
3329
"--type",
30+
required=True,
31+
choices=sorted(set(repo_types.keys()) - {"ignore", "all"}),
32+
metavar="TYPE",
3433
help="The type of repository to manage",
3534
)
3635

36+
# Add a new repo
37+
add_parser = subparsers.add_parser("add", help="Add a new repository")
38+
39+
add_parser.add_argument(
40+
"repository",
41+
choices=[str(directory) for directory in Path(".").iterdir() if directory.is_dir()],
42+
metavar="REPOSITORY",
43+
help="The name of the repository",
44+
)
45+
46+
add_parser.add_argument(
47+
"-t",
48+
"--type",
49+
required=True,
50+
help="The type of the repository",
51+
)
52+
53+
# Check a repo
54+
flavor_parser = subparsers.add_parser("flavors", help="List the configured types for a repository")
55+
56+
flavor_parser.add_argument(
57+
"repository",
58+
choices=[str(directory) for directory in Path(".").iterdir() if directory.is_dir()],
59+
metavar="REPOSITORY",
60+
help="The name of the repository",
61+
)
62+
63+
# Inspect repos
3764
parser.add_argument(
3865
"-k",
3966
"--known",
@@ -63,8 +90,7 @@ def configure_arguments(parser: argparse.ArgumentParser) -> None:
6390
)
6491

6592

66-
def parse_repo_types() -> dict[str, set[str]]:
67-
config = configparser.ConfigParser()
93+
def parse_repo_types(config: configparser.ConfigParser) -> dict[str, set[str]]:
6894
config.read(REPO_TYPES_CFG)
6995

7096
repo_types: dict[str, set[str]] = {"all": set()}
@@ -77,7 +103,7 @@ def parse_repo_types() -> dict[str, set[str]]:
77103
return repo_types
78104

79105

80-
def check_missing_repos(path: Path, repo_types: dict[str, set[str]]) -> Union[None, NoReturn]:
106+
def check_missing_repos(path: Path, repo_types: dict[str, set[str]]) -> None:
81107
missing = set()
82108
directories = {str(directory) for directory in path.iterdir()}
83109

@@ -94,35 +120,59 @@ def check_missing_repos(path: Path, repo_types: dict[str, set[str]]) -> Union[No
94120
return None
95121

96122

97-
def main():
98-
path = Path(".")
123+
def handle_list(
124+
path: Path, config: configparser.ConfigParser, args, repo_types: dict[str, set[str]]
125+
) -> Union[None, NoReturn]:
126+
if args.type not in repo_types:
127+
print(f"\n{FAIL}Unknown type {args.type}. Valid types are:{ENDC}")
128+
for repo_type in repo_types:
129+
if repo_type != "all" and repo_type != "ignore":
130+
print(f"\t{repo_type}")
131+
sys.exit(1)
99132

100-
check_if_allowed(path)
133+
for repo in repo_types[args.type]:
134+
print(repo)
101135

102-
parser = argparse.ArgumentParser(
103-
prog="repoman",
104-
description="Manage repositories of different types",
105-
)
136+
return None
106137

107-
configure_arguments(parser)
108-
args = parser.parse_args()
109-
repo_types = parse_repo_types()
110-
check_missing_repos(path, repo_types)
111138

139+
def handle_add(path: Path, config: configparser.ConfigParser, args, repo_types: dict[str, set[str]]) -> None:
140+
if args.type in config:
141+
original_config = config[args.type]["known"]
142+
else:
143+
original_config = ""
144+
config.add_section(args.type)
145+
146+
if "known" not in config[args.type] or args.repository not in config[args.type]["known"].split("\n"):
147+
config.set(args.type, "known", f"{original_config}\n{args.repository}")
148+
149+
with open(REPO_TYPES_CFG, "w") as config_file:
150+
config.write(config_file)
151+
152+
return None
153+
154+
155+
def handle_flavors(path: Path, config: configparser.ConfigParser, args, repo_types: dict[str, set[str]]) -> None:
156+
found = set()
157+
for section in config.sections():
158+
if section == "ignore":
159+
continue
160+
if args.repository in config[section]["known"].split("\n"):
161+
found.add(section)
162+
for repository in sorted(found):
163+
print(repository)
164+
165+
return None
166+
167+
168+
def handle_meta(path: Path, config: configparser.ConfigParser, args, repo_types: dict[str, set[str]]) -> None:
112169
if args.known:
113170
known_repo_types = sorted(
114171
[repo_type for repo_type in repo_types if repo_type != "all" and repo_type != "ignore"]
115172
)
116173
for repo_type in known_repo_types:
117174
print(repo_type)
118175

119-
if args.type and args.type not in repo_types:
120-
print(f"\n{FAIL}Unknown type {args.type}. Valid types are:{ENDC}")
121-
for repo_type in repo_types:
122-
if repo_type != "all":
123-
print(f"\t{repo_type}")
124-
sys.exit(1)
125-
126176
if args.unconfigured:
127177
for directory in sorted(path.iterdir()):
128178
if (
@@ -132,10 +182,6 @@ def main():
132182
):
133183
print(directory)
134184

135-
if args.list:
136-
for repo in repo_types[args.type]:
137-
print(repo)
138-
139185
if args.duplicates:
140186
seen = set()
141187
for repo_type in repo_types:
@@ -144,3 +190,29 @@ def main():
144190
if repo in seen:
145191
print(repo)
146192
seen.add(repo)
193+
194+
195+
def main():
196+
path = Path(".")
197+
198+
check_if_allowed(path)
199+
200+
parser = argparse.ArgumentParser(
201+
prog="repoman",
202+
description="Manage repositories of different types",
203+
)
204+
205+
config = configparser.ConfigParser()
206+
repo_types = parse_repo_types(config)
207+
configure_arguments(parser, repo_types)
208+
args = parser.parse_args()
209+
check_missing_repos(path, repo_types)
210+
211+
if args.subcommand == "list":
212+
handle_list(path, config, args, repo_types)
213+
elif args.subcommand == "add":
214+
handle_add(path, config, args, repo_types)
215+
elif args.subcommand == "flavors":
216+
handle_flavors(path, config, args, repo_types)
217+
else:
218+
handle_meta(path, config, args, repo_types)

0 commit comments

Comments
 (0)