Skip to content

Commit cc06b4c

Browse files
authored
Merge pull request #23 from mittel-labs/feat/improve-cli
Improving CLI
2 parents b5593bf + e389bc3 commit cc06b4c

File tree

12 files changed

+169
-47
lines changed

12 files changed

+169
-47
lines changed

README.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
11
# bibleit
22

3-
Interactive bible reading
3+
Interactive Bible reading.
44

55
## How to run
66

77
```sh
8-
python -m bibleit
8+
$ python -m bibleit
9+
10+
usage: bibleit [-h] [--version] [--repl] [--linesep value] [--bible value] [--debug] [--screen] [--textwrap] [--bold] [--label] [args ...]
11+
12+
positional arguments:
13+
args Arguments to be evaluated
14+
15+
options:
16+
-h, --help show this help message and exit
17+
--version show program's version number and exit
18+
--repl Opens bibleit REPL
19+
--linesep value Configure line separator
20+
--bible value Use one or more Bible translations
21+
--debug Enable debug flag
22+
--screen Enable screen flag
23+
--textwrap Enable textwrap flag
24+
--bold Enable bold flag
25+
--label Enable label flag
926
```
1027
28+
## REPL
29+
30+
Bibleit has an interactive interpreter in order to interact with the Bible.
31+
32+
You can use `--repl` argument:
33+
1134
```sh
12-
python -m bibleit help
35+
python -m bibleit --repl
1336
```
1437
38+
Or run directly from `bibleit.repl` module:
39+
1540
```sh
16-
python -m bibleit ref Joao 11
17-
```
41+
python -m bibleit.repl
42+
```
43+
44+
After that you're going to see a console, so that you can start typing commands:
45+
46+
![](repl.gif)

repl.gif

190 KB
Loading

src/bibleit/__main__.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
1-
import sys
1+
from bibleit.command import args as bargs
2+
from bibleit import repl
23

3-
args = sys.argv[1:]
4+
_FLAG_PREFIX = "flag_"
45

5-
if args:
6-
from bibleit import command, context
6+
args = bargs.parser.parse_args()
7+
8+
9+
def get_active_flags(ctx):
10+
for flag in (
11+
flag.removeprefix(_FLAG_PREFIX)
12+
for flag in dir(ctx)
13+
if flag.startswith(_FLAG_PREFIX)
14+
):
15+
if getattr(args, f"{_FLAG_PREFIX}{flag}"):
16+
yield flag
717

8-
if result := command.eval(context.Context(), *args):
9-
print(result)
10-
else:
11-
from bibleit import repl
1218

19+
if args.repl:
1320
repl.run()
21+
else:
22+
if args.args:
23+
from bibleit import context, config
24+
from bibleit.command import set
25+
26+
for flag in get_active_flags(args):
27+
config.set_flag(flag, True)
28+
29+
ctx = context.Context()
30+
31+
if args.bible:
32+
set.bible(ctx, ",".join(args.bible))
33+
34+
if args.linesep is not None:
35+
set.linesep(ctx, str(args.linesep))
36+
37+
repl.eval(ctx, " ".join(args.args))
38+
else:
39+
bargs.parser.print_help()

src/bibleit/bible.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ def __eq__(self, other):
6060
return self.__class__ == other.__class__ and self.version == other.version
6161

6262
def labeled(self, value):
63-
return f"✝ {self.version}{_config.context_ps1}\t{value}" if _config.label else value
63+
return (
64+
f"✝ {self.version}{_config.context_ps1}\t{value}"
65+
if _config.flags.label
66+
else value
67+
)
6468

6569
def bolded(self, value):
66-
if _config.bold:
70+
if _config.flags.bold:
6771
if ref_idx := re.search(r" \d+:\d+", value):
6872
ref_idx = ref_idx.end()
6973
return f"{BOLD}{value[:ref_idx]}{END} {value[ref_idx + 1:]}"

src/bibleit/command/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def eval_module(name):
2626
return import_module(target)
2727
return sys.modules[target]
2828
except ModuleNotFoundError as e:
29-
if config.debug:
29+
if config.flags.debug:
3030
print(e)
3131
return eval_module(_default_module)
3232

@@ -59,7 +59,7 @@ def eval(ctx, *line, module=None):
5959
except AssertionError as e:
6060
print(f"Error: {e}")
6161
except Exception as e:
62-
if config.debug:
62+
if config.flags.debug:
6363
print(f"*** {e}\n")
6464
print(traceback.format_exc())
6565
if module != _default_module:

src/bibleit/command/args.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import argparse
2+
3+
from bibleit import config, bible
4+
5+
parser = argparse.ArgumentParser(
6+
prog=config.application,
7+
description=f"{config.application} v{config.version}",
8+
allow_abbrev=False,
9+
)
10+
11+
parser.add_argument(
12+
"--version", action="version", version=f"{config.application} v{config.version}"
13+
)
14+
parser.add_argument("--repl", action="store_true", help="Opens bibleit REPL")
15+
parser.add_argument(
16+
"--linesep",
17+
type=int,
18+
choices=range(0, 11),
19+
metavar="value",
20+
help="Configure line separator",
21+
)
22+
parser.add_argument(
23+
"--bible",
24+
choices=bible.get_available_bibles(),
25+
action="append",
26+
metavar="value",
27+
help="Use one or more Bible translations",
28+
)
29+
parser.add_argument("args", nargs="*", help="Arguments to be evaluated")
30+
31+
for flag in config.flag_names:
32+
parser.add_argument(
33+
f"--{flag}",
34+
action="store_true",
35+
dest=f"flag_{flag}",
36+
help=f"Enable {flag} flag",
37+
)

src/bibleit/command/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212

1313
def _format_lines(lines):
14-
linesep = ("\n" * (_config.linesep + 1))
15-
if _config.textwrap:
14+
linesep = "\n" * (_config.linesep + 1)
15+
if _config.flags.textwrap:
1616
lines = map(
1717
lambda x: linesep.join(x),
1818
map(lambda x: _tw.wrap(x, width=120, fix_sentence_endings=True), lines),

src/bibleit/command/set.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
_FLAGS_OFF = ["false", "off"]
1010
_FLAGS_TOGGLE = _FLAGS_ON + _FLAGS_OFF
1111

12-
_FLAGS = {"debug", "label", "screen", "textwrap", "bold"}
13-
1412

1513
def _flag(value):
1614
if value := value.lower():
@@ -21,11 +19,11 @@ def _flag(value):
2119
return False
2220

2321

24-
for _flag_name in _FLAGS:
22+
for _flag_name in _config.flag_names:
2523

2624
def _flag_method(name):
2725
def fn(ctx, value):
28-
setattr(_config, name, _flag(value))
26+
_config.set_flag(name, _flag(value))
2927

3028
fn.__doc__ = f"Configure {_flag_name} config\n\n set {_flag_name} <{'|'.join(_FLAGS_TOGGLE)}>"
3129
return fn
@@ -40,13 +38,13 @@ def bible(ctx, *args):
4038
4139
Examples:
4240
set bible kjv
43-
set bible acf, nvi/pt"""
41+
set bible acf, nvi"""
4442
translations = [value for arg in args for value in arg.split(",") if value]
4543
ctx.bible = sorted(
4644
{_Bible(translation.lower()) for translation in translations},
4745
key=_attrgetter("version"),
4846
)
49-
_config.label = len(translations) > 1
47+
_config.flags.label = len(translations) > 1
5048

5149

5250
def linesep(ctx, *args):
@@ -60,7 +58,7 @@ def linesep(ctx, *args):
6058
value = "".join(args)
6159
if value.isdigit():
6260
value = int(value)
63-
assert 0 <= value < 10, "value must be a int between 0 and 10"
61+
assert 0 <= value <= 10, "line separation value must be a int between 0 and 10"
6462
_config.linesep = value
6563
else:
66-
raise AssertionError("value should be an int")
64+
raise AssertionError("line separation value should be an int")

src/bibleit/config.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import sys
2+
3+
from types import SimpleNamespace
4+
5+
__this = sys.modules[__name__]
6+
17
# General
2-
debug = False
3-
label = False
4-
screen = False
5-
textwrap = False
6-
bold = False
78
application = "bibleit"
89
version = "0.0.17"
910
help = 'Type "help" for more information.'
@@ -16,7 +17,17 @@
1617
# Bible
1718
default_bible = "nvi"
1819

20+
# Config
21+
flags = SimpleNamespace(
22+
debug=False, label=False, screen=False, textwrap=False, bold=False
23+
)
24+
flag_names = set(flags.__dict__)
25+
linesep = 1
26+
1927
# Repl
2028
history_length = 1000
2129
context_ps1 = ">"
22-
linesep = 1
30+
31+
32+
def set_flag(name: str, value: bool):
33+
setattr(flags, name, value)

src/bibleit/context.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
from bibleit import config
23
from bibleit.bible import Bible, BibleNotFound, BOLD, END
34

@@ -6,6 +7,7 @@ class Context:
67
def __init__(self):
78
self._notes = set()
89
self.screen = None
10+
self.__main__ = None
911
try:
1012
self.bible = [Bible(config.default_bible)]
1113
except BibleNotFound as e:
@@ -14,7 +16,7 @@ def __init__(self):
1416

1517
def __repr__(self):
1618
line = f"{','.join(map(str,self.bible))}{config.context_ps1}"
17-
if config.bold:
19+
if config.flags.bold:
1820
line = f"{BOLD}{line}{END}"
1921
return f"✝ {line} "
2022

@@ -24,3 +26,7 @@ def notes(self):
2426

2527
def add_note(self, value):
2628
self._notes.add(value)
29+
30+
def exit_non_main(self):
31+
if self.__main__ != "__main__":
32+
sys.exit(0)

0 commit comments

Comments
 (0)