-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
args.py
148 lines (124 loc) · 4.24 KB
/
args.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import argparse
from pathlib import Path
from typing import List, Optional, cast
from attrs import define, field, Attribute
# Must be ignored to pass Mypy as this has
# an expression of Any, likely due to how
# attrs works
@define # type: ignore
class Args:
"""
All arguments defined, converted into their intended
types to make developer's lives less of a headache.
Attributes
----------
path: Path
Path to build configuration; by default set to bpy-build.yaml in
the current directory.
-c/--config can replace this path, should the user decide to do so.
versions: List[float]
Specific versions the user wants to install too
actions: List[str]
The actions that the user wants to execute
debug_mode: bool
Enable debug logging
supress_messages: bool
Supress BpyBuild output
"""
path: Path = field(default=Path("bpy-build.yaml"))
versions: List[float] = field(default=[])
actions: List[str] = field(default=["default"])
debug_mode: bool = field(default=False)
supress_messages: bool = field(default=False)
@path.validator
def path_validate(self, _: Attribute, value: Path) -> None:
# Assume the user did not pass
# a path in
if value is None:
return
if not value.exists():
raise FileNotFoundError("File does not exist!")
if value.is_dir():
raise IsADirectoryError("Expected a file, got a direcory!")
@versions.validator
def version_validate(self, _: Attribute, value: List[float]) -> None:
if value is None:
self.versions = []
else:
for ver in value:
if not isinstance(ver, float):
raise ValueError("Expected List of floating point values!")
@actions.validator
def actions_validate(self, _: Attribute, value: List[str]) -> None:
if value is None:
self.actions = ["default"]
else:
for act in value:
if not isinstance(act, str):
raise ValueError("Expect List of strings!")
def parse_args() -> Args:
"""
Parses arguments passed in the CLI.
This uses argparse and creates an Args object
based on the arguments passed
This can throw an exception in the following cases:
- File related
- The passed config does not exist
- The passed config is a directory
- Version related
- -v/--versions wasn't passed with a list
- The list passed doesn't contain all floating
point values
Returns:
Args
"""
from argparse import ArgumentParser, Namespace
parser = ArgumentParser()
parser.add_argument("-c", "--config", help="Defines the config file to use")
parser.add_argument(
"-v",
"--versions",
help="Limits which versions to install to",
nargs="+",
type=float,
)
parser.add_argument(
"-b",
"--build-actions",
help="Defines what actions to execute",
nargs="+",
type=str,
)
parser.add_argument(
"-dbg",
"--debug-mode",
help="Activates debug mode to understand what's going on",
default=False,
action="store_true",
)
parser.add_argument(
"-s",
"--supress-output",
help="Supress all BpyBuild output except for build actions. This does not apply to debug logs",
default=False,
action="store_true",
)
args: Namespace = parser.parse_args()
config: str = "bpy-build.yaml"
actions: List[str] = ["default"]
# The config path can be None
if cast(Optional[str], args.config) is not None:
config = args.config
# This allows the default action to always
# be executed
if cast(List[str], args.build_actions) is not None:
actions += cast(List[str], args.build_actions)
# We use cast here to prevent Mypy from complaining, the
# validators should handle the types anyway, if argparse doesn't
return Args(
Path(cast(str, config)),
cast(List[float], args.versions),
cast(List[str], actions),
cast(bool, args.debug_mode),
cast(bool, args.supress_output),
)