Skip to content

Commit f33f928

Browse files
committed
Add color to error message
1 parent 3d2ed21 commit f33f928

File tree

3 files changed

+38
-28
lines changed

3 files changed

+38
-28
lines changed

auto_editor/__main__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22

33
import sys
4+
from os import environ
45

56
import auto_editor
67
from auto_editor.edit import edit_media
@@ -281,9 +282,14 @@ def main() -> None:
281282
obj.main(sys.argv[2:])
282283
return
283284

285+
ff_color = "AV_LOG_FORCE_NOCOLOR"
286+
no_color = bool(environ.get("NO_COLOR")) or bool(environ.get(ff_color))
287+
log = Log(no_color=no_color)
288+
284289
args = main_options(ArgumentParser("Auto-Editor")).parse_args(
285290
Args,
286291
sys.argv[1:],
292+
log,
287293
macros=[
288294
({"--frame-margin"}, ["--margin"]),
289295
({"--export-to-premiere", "-exp"}, ["--export", "premiere"]),
@@ -311,12 +317,11 @@ def main() -> None:
311317
print(f"Auto-Editor Version: {auto_editor.version}")
312318
return
313319

314-
log = Log(args.debug, args.quiet)
315320
if not args.input:
316321
log.error("You need to give auto-editor an input file.")
317322

318323
temp = setup_tempdir(args.temp_dir, log)
319-
log = Log(args.debug, args.quiet, temp, args.progress == "machine")
324+
log = Log(args.debug, args.quiet, temp, args.progress == "machine", no_color)
320325
log.debug(f"Temp Directory: {temp}")
321326

322327
ffmpeg = FFmpeg(

auto_editor/utils/log.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@
88

99

1010
class Log:
11-
__slots__ = ("is_debug", "quiet", "temp", "machine", "start_time")
11+
__slots__ = ("is_debug", "quiet", "temp", "machine", "start_time", "no_color")
1212

1313
def __init__(
1414
self,
1515
is_debug: bool = False,
1616
quiet: bool = False,
1717
temp: str | None = None,
1818
machine: bool = False,
19+
no_color: bool = True,
1920
):
2021
self.is_debug = is_debug
2122
self.quiet = quiet
2223
self.temp = temp
2324
self.machine = machine
25+
self.no_color = no_color
2426
self.start_time = 0 if self.quiet or self.machine else perf_counter()
2527

2628
def debug(self, message: object) -> None:
@@ -74,7 +76,11 @@ def error(self, message: str | Exception) -> NoReturn:
7476
raise message
7577

7678
self.conwrite("")
77-
sys.stderr.write(f"Error! {message}\n")
79+
if self.no_color:
80+
sys.stderr.write(f"Error! {message}\n")
81+
else:
82+
sys.stderr.write(f"\033[31;40mError! {message}\033[0m\n")
83+
7884
self.cleanup()
7985
from platform import system
8086

auto_editor/vanparse.py

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -160,25 +160,6 @@ def get_option(name: str, options: list[Options]) -> Options | None:
160160
return None
161161

162162

163-
def parse_value(option: Options | Required, val: str | None) -> Any:
164-
if val is None and option.nargs == 1:
165-
Log().error(f"{option.names[0]} needs argument.")
166-
167-
try:
168-
value = option.type(val)
169-
except CoerceError as e:
170-
Log().error(e)
171-
172-
if option.choices is not None and value not in option.choices:
173-
choices = ", ".join(option.choices)
174-
175-
Log().error(
176-
f"{value} is not a choice for {option.names[0]}\nchoices are:\n {choices}"
177-
)
178-
179-
return value
180-
181-
182163
class ArgumentParser:
183164
def __init__(self, program_name: str | None):
184165
self.program_name = program_name
@@ -201,6 +182,7 @@ def parse_args(
201182
self,
202183
ns_obj: type[T],
203184
sys_args: list[str],
185+
log_: Log | None = None,
204186
macros: list[tuple[set[str], list[str]]] | None = None,
205187
) -> T:
206188
if not sys_args and self.program_name is not None:
@@ -219,9 +201,26 @@ def parse_args(
219201
del _macros
220202
del macros
221203

204+
log = Log() if log_ is None else log_
222205
ns = ns_obj()
223206
option_names: list[str] = []
224207

208+
def parse_value(option: Options | Required, val: str | None) -> Any:
209+
if val is None and option.nargs == 1:
210+
log.error(f"{option.names[0]} needs argument.")
211+
212+
try:
213+
value = option.type(val)
214+
except CoerceError as e:
215+
log.error(e)
216+
217+
if option.choices is not None and value not in option.choices:
218+
log.error(
219+
f"{value} is not a choice for {option.names[0]}\n"
220+
f"choices are:\n {', '.join(option.choices)}"
221+
)
222+
return value
223+
225224
program_name = self.program_name
226225
requireds = self.requireds
227226
options = self.options
@@ -256,7 +255,7 @@ def parse_args(
256255
val = oplist_coerce(arg)
257256
ns.__setattr__(oplist_name, getattr(ns, oplist_name) + [val])
258257
except (CoerceError, ValueError) as e:
259-
Log().error(e)
258+
log.error(e)
260259
elif requireds and not arg.startswith("--"):
261260
if requireds[0].nargs == 1:
262261
ns.__setattr__(req_list_name, parse_value(requireds[0], arg))
@@ -268,19 +267,19 @@ def parse_args(
268267

269268
# 'Did you mean' message might appear that options need a comma.
270269
if arg.replace(",", "") in option_names:
271-
Log().error(f"Option '{arg}' has an unnecessary comma.")
270+
log.error(f"Option '{arg}' has an unnecessary comma.")
272271

273272
close_matches = difflib.get_close_matches(arg, option_names)
274273
if close_matches:
275-
Log().error(
274+
log.error(
276275
f"Unknown {label}: {arg}\n\n Did you mean:\n "
277276
+ ", ".join(close_matches)
278277
)
279-
Log().error(f"Unknown {label}: {arg}")
278+
log.error(f"Unknown {label}: {arg}")
280279
else:
281280
if option.nargs != "*":
282281
if option in used_options:
283-
Log().error(
282+
log.error(
284283
f"Option {option.names[0]} may not be used more than once."
285284
)
286285
used_options.append(option)

0 commit comments

Comments
 (0)