Skip to content

Commit fe67c95

Browse files
authored
refactor: Move from kaptan to ConfigReader (#828)
ConfigReader is typed, doctest'd, 200 lines of code. The maintainer of kaptan gets along well us well but has been unresponsive for years.
2 parents 6b7f9ab + 243a61d commit fe67c95

23 files changed

+543
-371
lines changed

CHANGES

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force
1919

2020
- _Insert changes/features/fixes for next release here_
2121

22+
**Maintenance release, no features or fixes**
23+
24+
### Internal
25+
26+
- Add `ConfigReader`: Our clean, typed parser for raw strings and files (#828)
27+
28+
This is our shiny, new, 200-line, doctested and typed parser that replaces `kaptan`.
29+
30+
### Packaging
31+
32+
- Drop kaptan dependency (#828)
33+
2234
## tmuxp 1.15.3 (2022-10-01)
2335

2436
### Bug fixes

conftest.py

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def socket_name(request) -> str:
6363
def add_doctest_fixtures(
6464
request: pytest.FixtureRequest,
6565
doctest_namespace: t.Dict[str, t.Any],
66+
tmp_path: pathlib.Path,
6667
) -> None:
6768
if isinstance(request._pyfuncitem, DoctestItem) and shutil.which("tmux"):
6869
doctest_namespace["server"] = request.getfixturevalue("server")
@@ -71,3 +72,4 @@ def add_doctest_fixtures(
7172
doctest_namespace["window"] = session.attached_window
7273
doctest_namespace["pane"] = session.attached_pane
7374
doctest_namespace["test_utils"] = test_utils
75+
doctest_namespace["tmp_path"] = tmp_path

docs/about.md

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ from JSON and YAML.
9797
`$ tmuxp -f<config-file>` for config file.
9898

9999
[attempt at 1.7 test]: https://travis-ci.org/tmux-python/tmuxp/jobs/12348263
100-
[kaptan]: https://github.com/emre/kaptan
101100
[mit-licensed]: http://opensource.org/licenses/MIT
102101
[tmuxinator]: https://github.com/aziz/tmuxinator
103102
[teamocil]: https://github.com/remiprev/teamocil

docs/api.md

+6
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ If you need an internal API stabilized please [file an issue](https://github.com
115115
.. automethod:: tmuxp.config.import_tmuxinator
116116
```
117117

118+
## Configuration reader
119+
120+
```{eval-rst}
121+
.. automodule:: tmuxp.config_reader
122+
```
123+
118124
## Workspace Builder
119125

120126
```{eval-rst}

docs/conf.py

+7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@
102102

103103
# sphinx.ext.autodoc
104104
toc_object_entries_show_parents = "hide"
105+
autodoc_default_options = {
106+
"undoc-members": True,
107+
"members": True,
108+
"private-members": True,
109+
"show-inheritance": True,
110+
"member-order": "bysource",
111+
}
105112

106113
# sphinxext.opengraph
107114
ogp_site_url = about["__docs__"]

docs/glossary.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ tmux(1)
1313
The tmux binary. Used internally to distinguish tmuxp is only a
1414
layer on top of tmux.
1515
16-
kaptan
17-
configuration management library, see [kaptan on github](https://github.com/emre/kaptan).
16+
ConfigReader
17+
configuration management class.
1818
1919
Server
2020
Tmux runs in the background of your system as a process.

poetry.lock

+49-47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+7-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ tmuxp = 'tmuxp:cli.cli'
4747
[tool.poetry.dependencies]
4848
python = "^3.7"
4949
click = "~8"
50-
kaptan = ">=0.5.10"
5150
libtmux = "~0.15.7"
5251
colorama = ">=0.3.9"
5352

@@ -90,6 +89,7 @@ flake8-comprehensions = "*"
9089
mypy = "*"
9190
types-colorama = "*"
9291
types-docutils = "*"
92+
types-PyYAML = "*"
9393

9494
[tool.poetry.extras]
9595
docs = [
@@ -118,6 +118,7 @@ lint = [
118118
"mypy",
119119
"types-colorama",
120120
"types-docutils",
121+
"types-PyYAML",
121122
]
122123

123124
[tool.coverage.run]
@@ -142,9 +143,13 @@ exclude_lines = [
142143
"def parse_args",
143144
]
144145

146+
[tool.mypy]
147+
files = [
148+
"src/tmuxp/config_reader.py",
149+
]
150+
145151
[[tool.mypy.overrides]]
146152
module = [
147-
"kaptan",
148153
"aafigure",
149154
"libtmux.*",
150155
"IPython.*",

src/tmuxp/cli/convert.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import os
2+
import pathlib
23

34
import click
4-
import kaptan
5+
6+
from tmuxp.config_reader import ConfigReader
57

68
from .utils import ConfigPath
79

@@ -25,20 +27,18 @@ def command_convert(confirmed, config):
2527
f"Unknown filetype: {ext} (valid: [.json, .yaml, .yml])"
2628
)
2729

28-
configparser = kaptan.Kaptan()
29-
configparser.import_config(config)
30-
newfile = config.replace(ext, ".%s" % to_filetype)
30+
configparser = ConfigReader.from_file(pathlib.Path(config))
31+
newfile = config.replace(ext, f".{to_filetype}")
3132

32-
export_kwargs = {"default_flow_style": False} if to_filetype == "yaml" else {}
33-
newconfig = configparser.export(to_filetype, indent=2, **export_kwargs)
33+
new_config = configparser.dump(format=to_filetype)
3434

3535
if not confirmed:
3636
if click.confirm(f"convert to <{config}> to {to_filetype}?"):
37-
if click.confirm("Save config to %s?" % newfile):
37+
if click.confirm(f"Save config to {newfile}?"):
3838
confirmed = True
3939

4040
if confirmed:
4141
buf = open(newfile, "w")
42-
buf.write(newconfig)
42+
buf.write(new_config)
4343
buf.close()
44-
print("New config saved to <%s>." % newfile)
44+
print(f"New config saved to <{newfile}>.")

src/tmuxp/cli/freeze.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import sys
33

44
import click
5-
import kaptan
65

76
from libtmux.server import Server
7+
from tmuxp.config_reader import ConfigReader
88
from tmuxp.exc import TmuxpException
99

1010
from .. import config, util
@@ -71,9 +71,8 @@ def command_freeze(
7171
return
7272

7373
sconf = freeze(session)
74-
configparser = kaptan.Kaptan()
7574
newconfig = config.inline(sconf)
76-
configparser.import_config(newconfig)
75+
configparser = ConfigReader(newconfig)
7776

7877
if not quiet:
7978
print(
@@ -126,11 +125,11 @@ def command_freeze(
126125
)
127126

128127
if config_format == "yaml":
129-
newconfig = configparser.export(
130-
"yaml", indent=2, default_flow_style=False, safe=True
128+
newconfig = configparser.dump(
129+
format="yaml", indent=2, default_flow_style=False, safe=True
131130
)
132131
elif config_format == "json":
133-
newconfig = configparser.export("json", indent=2)
132+
newconfig = configparser.dump(format="json", indent=2)
134133

135134
if yes or click.confirm("Save to %s?" % dest):
136135
destdir = os.path.dirname(dest)

0 commit comments

Comments
 (0)