diff --git a/CHANGES b/CHANGES index 38fb75befc1..6809f90bb79 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,18 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force - _Insert changes/features/fixes for next release here_ +**Maintenance release, no features or fixes** + +### Internal + +- Add `ConfigReader`: Our clean, typed parser for raw strings and files (#828) + + This is our shiny, new, 200-line, doctested and typed parser that replaces `kaptan`. + +### Packaging + +- Drop kaptan dependency (#828) + ## tmuxp 1.15.3 (2022-10-01) ### Bug fixes diff --git a/conftest.py b/conftest.py index 368f68fdc2b..0d4efe8cc89 100644 --- a/conftest.py +++ b/conftest.py @@ -63,6 +63,7 @@ def socket_name(request) -> str: def add_doctest_fixtures( request: pytest.FixtureRequest, doctest_namespace: t.Dict[str, t.Any], + tmp_path: pathlib.Path, ) -> None: if isinstance(request._pyfuncitem, DoctestItem) and shutil.which("tmux"): doctest_namespace["server"] = request.getfixturevalue("server") @@ -71,3 +72,4 @@ def add_doctest_fixtures( doctest_namespace["window"] = session.attached_window doctest_namespace["pane"] = session.attached_pane doctest_namespace["test_utils"] = test_utils + doctest_namespace["tmp_path"] = tmp_path diff --git a/docs/about.md b/docs/about.md index 74d770e3758..225a862f3a8 100644 --- a/docs/about.md +++ b/docs/about.md @@ -97,7 +97,6 @@ from JSON and YAML. `$ tmuxp -f` for config file. [attempt at 1.7 test]: https://travis-ci.org/tmux-python/tmuxp/jobs/12348263 -[kaptan]: https://github.com/emre/kaptan [mit-licensed]: http://opensource.org/licenses/MIT [tmuxinator]: https://github.com/aziz/tmuxinator [teamocil]: https://github.com/remiprev/teamocil diff --git a/docs/api.md b/docs/api.md index 908fa3b99e0..9341259b79a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -115,6 +115,12 @@ If you need an internal API stabilized please [file an issue](https://github.com .. automethod:: tmuxp.config.import_tmuxinator ``` +## Configuration reader + +```{eval-rst} +.. automodule:: tmuxp.config_reader +``` + ## Workspace Builder ```{eval-rst} diff --git a/docs/conf.py b/docs/conf.py index 7bebbb6c67b..066e67feac5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -102,6 +102,13 @@ # sphinx.ext.autodoc toc_object_entries_show_parents = "hide" +autodoc_default_options = { + "undoc-members": True, + "members": True, + "private-members": True, + "show-inheritance": True, + "member-order": "bysource", +} # sphinxext.opengraph ogp_site_url = about["__docs__"] diff --git a/docs/glossary.md b/docs/glossary.md index 3ce0d22aa37..6cc1a987910 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -13,8 +13,8 @@ tmux(1) The tmux binary. Used internally to distinguish tmuxp is only a layer on top of tmux. -kaptan - configuration management library, see [kaptan on github](https://github.com/emre/kaptan). +ConfigReader + configuration management class. Server Tmux runs in the background of your system as a process. diff --git a/poetry.lock b/poetry.lock index e5bc768653c..d00e1a26580 100644 --- a/poetry.lock +++ b/poetry.lock @@ -286,17 +286,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "kaptan" -version = "0.5.12" -description = "Configuration manager" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -PyYAML = ">=3.13,<6" - [[package]] name = "libtmux" version = "0.15.7" @@ -616,11 +605,11 @@ python-versions = "*" [[package]] name = "PyYAML" -version = "5.4.1" +version = "6.0" description = "YAML parser and emitter for Python" -category = "main" +category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" [[package]] name = "requests" @@ -931,6 +920,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "types-PyYAML" +version = "6.0.12" +description = "Typing stubs for PyYAML" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" version = "4.3.0" @@ -985,7 +982,7 @@ test = [] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "9c6487873c1caebe7d4b6f0e5fa0aaaa077fc00bc6df547b8a67ae66b83b475c" +content-hash = "9e749ca252ed5478f577d45fa242b01032afb605030b84f6c8bd5aea9b11617d" [metadata.files] aafigure = [ @@ -1153,9 +1150,6 @@ Jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] -kaptan = [ - {file = "kaptan-0.5.12.tar.gz", hash = "sha256:1abd1f56731422fce5af1acc28801677a51e56f5d3c3e8636db761ed143c3dd2"}, -] libtmux = [ {file = "libtmux-0.15.7-py3-none-any.whl", hash = "sha256:8ae78d4a3dbc3f5ea3e74f280855ab8129d587cef29db929c1b6e37c8cad5d89"}, {file = "libtmux-0.15.7.tar.gz", hash = "sha256:dee2a138e0eab14256472d140ac816c923c303406b894e27c068cc39f5f8bfb4"}, @@ -1376,35 +1370,39 @@ pytz = [ {file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"}, ] PyYAML = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] requests = [ {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, @@ -1537,6 +1535,10 @@ types-docutils = [ {file = "types-docutils-0.19.1.tar.gz", hash = "sha256:7df133b87105af410fc6a992030a70ee9f5a2c2636c5afe7e0de285eb9fdb015"}, {file = "types_docutils-0.19.1-py3-none-any.whl", hash = "sha256:6b110b17ba4bfbde765b69acca6a6da373094d99a5a3bce1d5a8c9d29b293d89"}, ] +types-PyYAML = [ + {file = "types-PyYAML-6.0.12.tar.gz", hash = "sha256:f6f350418125872f3f0409d96a62a5a5ceb45231af5cc07ee0034ec48a3c82fa"}, + {file = "types_PyYAML-6.0.12-py3-none-any.whl", hash = "sha256:29228db9f82df4f1b7febee06bbfb601677882e98a3da98132e31c6874163e15"}, +] typing-extensions = [ {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, diff --git a/pyproject.toml b/pyproject.toml index a1b03c17b0d..e4d1a711065 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,6 @@ tmuxp = 'tmuxp:cli.cli' [tool.poetry.dependencies] python = "^3.7" click = "~8" -kaptan = ">=0.5.10" libtmux = "~0.15.7" colorama = ">=0.3.9" @@ -90,6 +89,7 @@ flake8-comprehensions = "*" mypy = "*" types-colorama = "*" types-docutils = "*" +types-PyYAML = "*" [tool.poetry.extras] docs = [ @@ -118,6 +118,7 @@ lint = [ "mypy", "types-colorama", "types-docutils", + "types-PyYAML", ] [tool.coverage.run] @@ -142,9 +143,13 @@ exclude_lines = [ "def parse_args", ] +[tool.mypy] +files = [ + "src/tmuxp/config_reader.py", +] + [[tool.mypy.overrides]] module = [ - "kaptan", "aafigure", "libtmux.*", "IPython.*", diff --git a/src/tmuxp/cli/convert.py b/src/tmuxp/cli/convert.py index 6ee78eb2871..2e9d2b09114 100644 --- a/src/tmuxp/cli/convert.py +++ b/src/tmuxp/cli/convert.py @@ -1,7 +1,9 @@ import os +import pathlib import click -import kaptan + +from tmuxp.config_reader import ConfigReader from .utils import ConfigPath @@ -25,20 +27,18 @@ def command_convert(confirmed, config): f"Unknown filetype: {ext} (valid: [.json, .yaml, .yml])" ) - configparser = kaptan.Kaptan() - configparser.import_config(config) - newfile = config.replace(ext, ".%s" % to_filetype) + configparser = ConfigReader.from_file(pathlib.Path(config)) + newfile = config.replace(ext, f".{to_filetype}") - export_kwargs = {"default_flow_style": False} if to_filetype == "yaml" else {} - newconfig = configparser.export(to_filetype, indent=2, **export_kwargs) + new_config = configparser.dump(format=to_filetype) if not confirmed: if click.confirm(f"convert to <{config}> to {to_filetype}?"): - if click.confirm("Save config to %s?" % newfile): + if click.confirm(f"Save config to {newfile}?"): confirmed = True if confirmed: buf = open(newfile, "w") - buf.write(newconfig) + buf.write(new_config) buf.close() - print("New config saved to <%s>." % newfile) + print(f"New config saved to <{newfile}>.") diff --git a/src/tmuxp/cli/freeze.py b/src/tmuxp/cli/freeze.py index 80da186d26f..081afdfa6b1 100644 --- a/src/tmuxp/cli/freeze.py +++ b/src/tmuxp/cli/freeze.py @@ -2,9 +2,9 @@ import sys import click -import kaptan from libtmux.server import Server +from tmuxp.config_reader import ConfigReader from tmuxp.exc import TmuxpException from .. import config, util @@ -71,9 +71,8 @@ def command_freeze( return sconf = freeze(session) - configparser = kaptan.Kaptan() newconfig = config.inline(sconf) - configparser.import_config(newconfig) + configparser = ConfigReader(newconfig) if not quiet: print( @@ -126,11 +125,11 @@ def command_freeze( ) if config_format == "yaml": - newconfig = configparser.export( - "yaml", indent=2, default_flow_style=False, safe=True + newconfig = configparser.dump( + format="yaml", indent=2, default_flow_style=False, safe=True ) elif config_format == "json": - newconfig = configparser.export("json", indent=2) + newconfig = configparser.dump(format="json", indent=2) if yes or click.confirm("Save to %s?" % dest): destdir = os.path.dirname(dest) diff --git a/src/tmuxp/cli/import_config.py b/src/tmuxp/cli/import_config.py index a0a6e6f3272..f88320f7087 100644 --- a/src/tmuxp/cli/import_config.py +++ b/src/tmuxp/cli/import_config.py @@ -1,8 +1,10 @@ import os +import pathlib import sys import click -import kaptan + +from tmuxp.config_reader import ConfigReader from .. import config from .utils import ConfigPath, _validate_choices, get_abs_path, tmuxp_echo @@ -58,25 +60,22 @@ def command_import(): def import_config(configfile, importfunc): - configparser = kaptan.Kaptan(handler="yaml") - - configparser.import_config(configfile) - newconfig = importfunc(configparser.get()) - configparser.import_config(newconfig) + existing_config = ConfigReader._from_file(pathlib.Path(configfile)) + new_config = ConfigReader(importfunc(existing_config)) config_format = click.prompt( "Convert to", value_proc=_validate_choices(["yaml", "json"]), default="yaml" ) if config_format == "yaml": - newconfig = configparser.export("yaml", indent=2, default_flow_style=False) + new_config = new_config.dump("yaml", indent=2, default_flow_style=False) elif config_format == "json": - newconfig = configparser.export("json", indent=2) + new_config = new_config.dump("json", indent=2) else: sys.exit("Unknown config format.") tmuxp_echo( - newconfig + "---------------------------------------------------------------" + new_config + "---------------------------------------------------------------" "\n" "Configuration import does its best to convert files.\n" ) @@ -94,7 +93,7 @@ def import_config(configfile, importfunc): dest = dest_path buf = open(dest, "w") - buf.write(newconfig) + buf.write(new_config) buf.close() tmuxp_echo("Saved to %s." % dest) @@ -138,12 +137,11 @@ def command_convert(confirmed, config): f"Unknown filetype: {ext} (valid: [.json, .yaml, .yml])" ) - configparser = kaptan.Kaptan() - configparser.import_config(config) + configparser = ConfigReader.from_file(config) newfile = config.replace(ext, ".%s" % to_filetype) export_kwargs = {"default_flow_style": False} if to_filetype == "yaml" else {} - newconfig = configparser.export(to_filetype, indent=2, **export_kwargs) + new_config = configparser.dump(format=to_filetype, indent=2, **export_kwargs) if not confirmed: if click.confirm(f"convert to <{config}> to {to_filetype}?"): @@ -152,7 +150,7 @@ def command_convert(confirmed, config): if confirmed: buf = open(newfile, "w") - buf.write(newconfig) + buf.write(new_config) buf.close() print("New config saved to <%s>." % newfile) diff --git a/src/tmuxp/cli/load.py b/src/tmuxp/cli/load.py index ee0ea232c35..04c512cccd7 100644 --- a/src/tmuxp/cli/load.py +++ b/src/tmuxp/cli/load.py @@ -13,10 +13,10 @@ from typing import List import click -import kaptan from libtmux.common import has_gte_version from libtmux.server import Server +from tmuxp import config_reader from .. import config, exc, log, util from ..workspacebuilder import WorkspaceBuilder @@ -266,7 +266,7 @@ def load_workspace( Notes ----- - tmuxp will check and load a configuration file. The file will use kaptan + tmuxp will check and load a configuration file. The file will use ConfigReader to load a JSON/YAML into a :py:obj:`dict`. Then :func:`config.expand` and :func:`config.trickle` will be used to expand any shorthands, template variables, or file paths relative to where the config/script is executed @@ -333,18 +333,18 @@ def load_workspace( Accessed April 8th, 2018. """ # get the canonical path, eliminating any symlinks - config_file = os.path.realpath(config_file) + if isinstance(config_file, str): + config_file = pathlib.Path(config_file) tmuxp_echo( click.style("[Loading] ", fg="green") - + click.style(config_file, fg="blue", bold=True) + + click.style(str(config_file), fg="blue", bold=True) ) - # kaptan allows us to open a yaml or json file as a dict - sconfig = kaptan.Kaptan() - sconfig = sconfig.import_config(config_file).get() + # ConfigReader allows us to open a yaml or json file as a dict + raw_config = config_reader.ConfigReader._from_file(config_file) # shapes configurations relative to config / profile file location - sconfig = config.expand(sconfig, os.path.dirname(config_file)) + sconfig = config.expand(raw_config, cwd=os.path.dirname(config_file)) # Overwrite session name if new_session_name: sconfig["session_name"] = new_session_name diff --git a/src/tmuxp/config.py b/src/tmuxp/config.py index 2cb0391a096..3efe49b138b 100644 --- a/src/tmuxp/config.py +++ b/src/tmuxp/config.py @@ -225,7 +225,7 @@ def expand(session_config, cwd=None, parent=None): 'shell_command': 'htop' - Kaptan will load JSON/YAML files into python dicts for you. + ConfigReader will load JSON/YAML files into python dicts for you. Parameters ---------- diff --git a/src/tmuxp/config_reader.py b/src/tmuxp/config_reader.py new file mode 100644 index 00000000000..32ccbfe26ea --- /dev/null +++ b/src/tmuxp/config_reader.py @@ -0,0 +1,200 @@ +import json +import pathlib +import typing as t + +import yaml + +if t.TYPE_CHECKING: + from typing_extensions import Literal, TypeAlias + + FormatLiteral = Literal["json", "yaml"] + + RawConfigData: TypeAlias = t.Dict[t.Any, t.Any] + + +class ConfigReader: + r"""Parse string data (YAML and JSON) into a dictionary. + + >>> cfg = ConfigReader({ "session_name": "my session" }) + >>> cfg.dump("yaml") + 'session_name: my session\n' + >>> cfg.dump("json") + '{\n "session_name": "my session"\n}' + """ + + def __init__(self, content: "RawConfigData"): + self.content = content + + @staticmethod + def _load(format: "FormatLiteral", content: str): + """Load raw config data and directly return it. + + >>> ConfigReader._load("json", '{ "session_name": "my session" }') + {'session_name': 'my session'} + + >>> ConfigReader._load("yaml", 'session_name: my session') + {'session_name': 'my session'} + """ + if format == "yaml": + return yaml.load( + content, + Loader=yaml.SafeLoader, + ) + elif format == "json": + return json.loads(content) + else: + raise NotImplementedError(f"{format} not supported in configuration") + + @classmethod + def load(cls, format: "FormatLiteral", content: str): + """Load raw config data into a ConfigReader instance (to dump later). + + >>> cfg = ConfigReader.load("json", '{ "session_name": "my session" }') + >>> cfg + + >>> cfg.content + {'session_name': 'my session'} + + >>> cfg = ConfigReader.load("yaml", 'session_name: my session') + >>> cfg + + >>> cfg.content + {'session_name': 'my session'} + """ + return cls( + content=cls._load( + format=format, + content=content, + ), + ) + + @classmethod + def _from_file(cls, path: pathlib.Path): + r"""Load data from file path directly to dictionary. + + **YAML file** + + *For demonstration only,* create a YAML file: + + >>> yaml_file = tmp_path / 'my_config.yaml' + >>> yaml_file.write_text('session_name: my session', encoding='utf-8') + 24 + + *Read YAML file*: + + >>> ConfigReader._from_file(yaml_file) + {'session_name': 'my session'} + + **JSON file** + + *For demonstration only,* create a JSON file: + + >>> json_file = tmp_path / 'my_config.json' + >>> json_file.write_text('{"session_name": "my session"}', encoding='utf-8') + 30 + + *Read JSON file*: + + >>> ConfigReader._from_file(json_file) + {'session_name': 'my session'} + """ + assert isinstance(path, pathlib.Path) + content = open(path).read() + + if path.suffix in [".yaml", ".yml"]: + format: FormatLiteral = "yaml" + elif path.suffix == ".json": + format = "json" + else: + raise NotImplementedError(f"{path.suffix} not supported in {path}") + + return cls._load( + format=format, + content=content, + ) + + @classmethod + def from_file(cls, path: pathlib.Path): + r"""Load data from file path + + **YAML file** + + *For demonstration only,* create a YAML file: + + >>> yaml_file = tmp_path / 'my_config.yaml' + >>> yaml_file.write_text('session_name: my session', encoding='utf-8') + 24 + + *Read YAML file*: + + >>> cfg = ConfigReader.from_file(yaml_file) + >>> cfg + + + >>> cfg.content + {'session_name': 'my session'} + + **JSON file** + + *For demonstration only,* create a JSON file: + + >>> json_file = tmp_path / 'my_config.json' + >>> json_file.write_text('{"session_name": "my session"}', encoding='utf-8') + 30 + + *Read JSON file*: + + >>> cfg = ConfigReader.from_file(json_file) + >>> cfg + + + >>> cfg.content + {'session_name': 'my session'} + """ + return cls(content=cls._from_file(path=path)) + + @staticmethod + def _dump( + format: "FormatLiteral", + content: "RawConfigData", + indent: int = 2, + **kwargs: t.Any, + ) -> str: + r"""Dump directly. + + >>> ConfigReader._dump("yaml", { "session_name": "my session" }) + 'session_name: my session\n' + + >>> ConfigReader._dump("json", { "session_name": "my session" }) + '{\n "session_name": "my session"\n}' + """ + if format == "yaml": + return yaml.dump( + content, + indent=2, + default_flow_style=False, + Dumper=yaml.SafeDumper, + ) + elif format == "json": + return json.dumps( + content, + indent=2, + ) + else: + raise NotImplementedError(f"{format} not supported in config") + + def dump(self, format: "FormatLiteral", indent: int = 2, **kwargs: t.Any) -> str: + r"""Dump via ConfigReader instance. + + >>> cfg = ConfigReader({ "session_name": "my session" }) + >>> cfg.dump("yaml") + 'session_name: my session\n' + >>> cfg.dump("json") + '{\n "session_name": "my session"\n}' + """ + return self._dump( + format=format, + content=self.content, + indent=indent, + **kwargs, + ) diff --git a/src/tmuxp/workspacebuilder.py b/src/tmuxp/workspacebuilder.py index ef0d7549cf2..cdfc4932567 100644 --- a/src/tmuxp/workspacebuilder.py +++ b/src/tmuxp/workspacebuilder.py @@ -96,20 +96,21 @@ class WorkspaceBuilder: The normal phase of loading is: - 1. :term:`kaptan` imports json/yaml/ini. ``.get()`` returns python - :class:`dict`:: + 1. Load JSON / YAML file via via :class:`pathlib.Path`:: - import kaptan - sconf = kaptan.Kaptan(handler='yaml') - sconf = sconfig.import_config(self.yaml_config).get() + from tmuxp import config_reader + sconf = config_reader.ConfigReader._load(raw_yaml) - or from config file with extension:: + The reader automatically detects the file type from :attr:`pathlib.suffix`. - import kaptan - sconf = kaptan.Kaptan() - sconf = sconfig.import_config('path/to/config.yaml').get() + We can also parse raw file:: - kaptan automatically detects the handler from filenames. + import pathlib + from tmuxp import config_reader + + sconf = config_reader.ConfigReader._from_file( + pathlib.Path('path/to/config.yaml') + ) 2. :meth:`config.expand` sconf inline shorthand:: diff --git a/tests/fixtures/config_teamocil/layouts.py b/tests/fixtures/config_teamocil/layouts.py index c61373fd8a1..c6a2f2fd413 100644 --- a/tests/fixtures/config_teamocil/layouts.py +++ b/tests/fixtures/config_teamocil/layouts.py @@ -1,5 +1,6 @@ from .. import utils as test_utils +teamocil_yaml_file = test_utils.get_config_file("config_teamocil/layouts.yaml") teamocil_yaml = test_utils.read_config_file("config_teamocil/layouts.yaml") teamocil_dict = { diff --git a/tests/fixtures/utils.py b/tests/fixtures/utils.py index 5d1ec632306..4c39f67defa 100644 --- a/tests/fixtures/utils.py +++ b/tests/fixtures/utils.py @@ -3,8 +3,12 @@ from ..constants import FIXTURE_PATH +def get_config_file(_file): # return fixture data, relative to __file__ + return FIXTURE_PATH / _file + + def read_config_file(_file): # return fixture data, relative to __file__ - return open(FIXTURE_PATH / _file).read() + return open(get_config_file(_file)).read() def write_config( diff --git a/tests/test_cli.py b/tests/test_cli.py index dbc830cde36..c92e2008c36 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -7,7 +7,6 @@ import pytest import click -import kaptan from click.testing import CliRunner from pytest_mock import MockerFixture @@ -33,6 +32,7 @@ is_pure_name, scan_config, ) +from tmuxp.config_reader import ConfigReader from tmuxp.workspacebuilder import WorkspaceBuilder from .constants import FIXTURE_PATH @@ -973,7 +973,7 @@ def test_freeze(server, cli_args, inputs, tmp_path, monkeypatch): assert yaml_config_path.exists() yaml_config = yaml_config_path.open().read() - frozen_config = kaptan.Kaptan(handler="yaml").import_config(yaml_config).get() + frozen_config = ConfigReader._load(format="yaml", content=yaml_config) assert frozen_config["session_name"] == "myfrozensession" @@ -1116,8 +1116,7 @@ def test_load_plugins(monkeypatch_plugin_test_packages): plugins_config = test_utils.read_config_file("workspacebuilder/plugin_bwb.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(plugins_config).get() + sconfig = ConfigReader._load(format="yaml", content=plugins_config) sconfig = config.expand(sconfig) plugins = load_plugins(sconfig) @@ -1199,8 +1198,7 @@ def test_plugin_system_before_script( def test_reattach_plugins(monkeypatch_plugin_test_packages, server): config_plugins = test_utils.read_config_file("workspacebuilder/plugin_r.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() + sconfig = ConfigReader._load(format="yaml", content=config_plugins) sconfig = config.expand(sconfig) # open it detached @@ -1229,8 +1227,7 @@ def test_load_attached( attach_session_mock.return_value.stderr = None yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1249,8 +1246,7 @@ def test_load_attached_detached( attach_session_mock.return_value.stderr = None yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1269,8 +1265,7 @@ def test_load_attached_within_tmux( switch_client_mock.return_value.stderr = None yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1289,8 +1284,7 @@ def test_load_attached_within_tmux_detached( switch_client_mock.return_value.stderr = None yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1301,8 +1295,7 @@ def test_load_attached_within_tmux_detached( def test_load_append_windows_to_current_session(server, monkeypatch): yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() diff --git a/tests/test_config.py b/tests/test_config.py index 7aee6fc8a28..8ae89298534 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -7,9 +7,8 @@ import pytest -import kaptan - from tmuxp import config, exc +from tmuxp.config_reader import ConfigReader from .constants import EXAMPLE_PATH @@ -37,44 +36,37 @@ def config_fixture(): def load_yaml(path: Union[str, pathlib.Path]) -> str: - return ( - kaptan.Kaptan(handler="yaml") - .import_config(str(path) if isinstance(path, pathlib.Path) else path) - .get() + return ConfigReader._from_file( + pathlib.Path(path) if isinstance(path, str) else path ) def load_config(path: Union[str, pathlib.Path]) -> str: - return ( - kaptan.Kaptan() - .import_config(str(path) if isinstance(path, pathlib.Path) else path) - .get() + return ConfigReader._from_file( + pathlib.Path(path) if isinstance(path, str) else path ) def test_export_json(tmp_path: pathlib.Path, config_fixture: "ConfigTestData"): json_config_file = tmp_path / "config.json" - configparser = kaptan.Kaptan() - configparser.import_config(config_fixture.sampleconfig.sampleconfigdict) + configparser = ConfigReader(config_fixture.sampleconfig.sampleconfigdict) - json_config_data = configparser.export("json", indent=2) + json_config_data = configparser.dump("json", indent=2) json_config_file.write_text(json_config_data, encoding="utf-8") - new_config = kaptan.Kaptan() - new_config_data = new_config.import_config(str(json_config_file)).get() + new_config_data = ConfigReader._from_file(path=json_config_file) assert config_fixture.sampleconfig.sampleconfigdict == new_config_data def test_export_yaml(tmp_path: pathlib.Path, config_fixture: "ConfigTestData"): yaml_config_file = tmp_path / "config.yaml" - configparser = kaptan.Kaptan() sampleconfig = config.inline(config_fixture.sampleconfig.sampleconfigdict) - configparser.import_config(sampleconfig) + configparser = ConfigReader(sampleconfig) - yaml_config_data = configparser.export("yaml", indent=2, default_flow_style=False) + yaml_config_data = configparser.dump("yaml", indent=2, default_flow_style=False) yaml_config_file.write_text(yaml_config_data, encoding="utf-8") @@ -119,8 +111,12 @@ def test_config_expand1(config_fixture: "ConfigTestData"): def test_config_expand2(config_fixture: "ConfigTestData"): """Expand shell commands from string to list.""" - unexpanded_dict = load_yaml(config_fixture.expand2.unexpanded_yaml()) - expanded_dict = load_yaml(config_fixture.expand2.expanded_yaml()) + unexpanded_dict = ConfigReader._load( + format="yaml", content=config_fixture.expand2.unexpanded_yaml() + ) + expanded_dict = ConfigReader._load( + format="yaml", content=config_fixture.expand2.expanded_yaml() + ) assert config.expand(unexpanded_dict) == expanded_dict @@ -248,13 +244,15 @@ def test_shell_command_before(config_fixture: "ConfigTestData"): def test_in_session_scope(config_fixture: "ConfigTestData"): - sconfig = load_yaml(config_fixture.shell_command_before_session.before) + sconfig = ConfigReader._load( + format="yaml", content=config_fixture.shell_command_before_session.before + ) config.validate_schema(sconfig) assert config.expand(sconfig) == sconfig - assert config.expand(config.trickle(sconfig)) == load_yaml( - config_fixture.shell_command_before_session.expected + assert config.expand(config.trickle(sconfig)) == ConfigReader._load( + format="yaml", content=config_fixture.shell_command_before_session.expected ) @@ -273,7 +271,7 @@ def test_trickle_window_with_no_pane_config(): - ls -l - window_name: test_no_panes """ - sconfig = load_yaml(test_yaml) + sconfig = ConfigReader._load(format="yaml", content=test_yaml) config.validate_schema(sconfig) assert config.expand(config.trickle(sconfig))["windows"][1]["panes"][0] == { @@ -327,8 +325,7 @@ def test_no_session_name(): - htop """ - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) with pytest.raises(exc.ConfigError) as excinfo: config.validate_schema(sconfig) @@ -340,8 +337,7 @@ def test_no_windows(): session_name: test session """ - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) with pytest.raises(exc.ConfigError) as excinfo: config.validate_schema(sconfig) @@ -363,8 +359,7 @@ def test_no_window_name(): - htop """ - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) with pytest.raises(exc.ConfigError) as excinfo: config.validate_schema(sconfig) @@ -398,7 +393,7 @@ def test_replaces_env_variables(monkeypatch): TEST_VAR="${%s}" % env_key ) - sconfig = load_yaml(yaml_config) + sconfig = ConfigReader._load(format="yaml", content=yaml_config) monkeypatch.setenv(str(env_key), str(env_val)) sconfig = config.expand(sconfig) @@ -426,8 +421,7 @@ def test_plugins(): start_directory: /var/log """ - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) with pytest.raises(exc.ConfigError) as excinfo: config.validate_schema(sconfig) diff --git a/tests/test_config_teamocil.py b/tests/test_config_teamocil.py index dc040261c38..d7f96a3499f 100644 --- a/tests/test_config_teamocil.py +++ b/tests/test_config_teamocil.py @@ -1,9 +1,7 @@ """Test for tmuxp teamocil configuration.""" import pytest -import kaptan - -from tmuxp import config +from tmuxp import config, config_reader from .fixtures import config_teamocil as fixtures @@ -34,9 +32,9 @@ ], ) def test_config_to_dict(teamocil_yaml, teamocil_dict, tmuxp_dict): - configparser = kaptan.Kaptan(handler="yaml") - test_config = configparser.import_config(teamocil_yaml) - yaml_to_dict = test_config.get() + yaml_to_dict = config_reader.ConfigReader._load( + format="yaml", content=teamocil_yaml + ) assert yaml_to_dict == teamocil_dict assert config.import_teamocil(teamocil_dict) == tmuxp_dict @@ -50,12 +48,11 @@ def multisession_config(): Also prevents re-running assertion the loads the yaml, since ordering of deep list items like panes will be inconsistent.""" - teamocil_yaml = fixtures.layouts.teamocil_yaml - configparser = kaptan.Kaptan(handler="yaml") - test_config = configparser.import_config(teamocil_yaml) + teamocil_yaml_file = fixtures.layouts.teamocil_yaml_file + test_config = config_reader.ConfigReader._from_file(teamocil_yaml_file) teamocil_dict = fixtures.layouts.teamocil_dict - assert test_config.get() == teamocil_dict + assert test_config == teamocil_dict return teamocil_dict diff --git a/tests/test_config_tmuxinator.py b/tests/test_config_tmuxinator.py index ddcf34e68ac..192852aa866 100644 --- a/tests/test_config_tmuxinator.py +++ b/tests/test_config_tmuxinator.py @@ -1,9 +1,8 @@ """Test for tmuxp tmuxinator configuration.""" import pytest -import kaptan - from tmuxp import config +from tmuxp.config_reader import ConfigReader from .fixtures import config_tmuxinator as fixtures @@ -29,9 +28,7 @@ ], ) def test_config_to_dict(tmuxinator_yaml, tmuxinator_dict, tmuxp_dict): - configparser = kaptan.Kaptan(handler="yaml") - test_config = configparser.import_config(tmuxinator_yaml) - yaml_to_dict = test_config.get() + yaml_to_dict = ConfigReader._load(format="yaml", content=tmuxinator_yaml) assert yaml_to_dict == tmuxinator_dict assert config.import_tmuxinator(tmuxinator_dict) == tmuxp_dict diff --git a/tests/test_workspacebuilder.py b/tests/test_workspacebuilder.py index f4e0fcd654b..7a77c689ae0 100644 --- a/tests/test_workspacebuilder.py +++ b/tests/test_workspacebuilder.py @@ -7,14 +7,13 @@ import pytest -import kaptan - import libtmux from libtmux.common import has_gte_version, has_lt_version from libtmux.test import retry_until, temp_session from libtmux.window import Window from tmuxp import config, exc from tmuxp.cli.load import load_plugins +from tmuxp.config_reader import ConfigReader from tmuxp.workspacebuilder import WorkspaceBuilder from .constants import EXAMPLE_PATH, FIXTURE_PATH @@ -25,55 +24,51 @@ def test_split_windows(session): - yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/two_pane.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count - assert len(s._windows) == window_count - for w, wconf in builder.iter_create_windows(s): + assert len(session._windows) == window_count + for w, wconf in builder.iter_create_windows(session): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size p = p - assert len(s._windows) == window_count + assert len(session._windows) == window_count assert isinstance(w, Window) - assert len(s._windows) == window_count + assert len(session._windows) == window_count window_count += 1 def test_split_windows_three_pane(session): - yaml_config = test_utils.read_config_file("workspacebuilder/three_pane.yaml") - - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/three_pane.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig) - window_count = len(s._windows) # current window count - assert len(s._windows) == window_count - for w, wconf in builder.iter_create_windows(s): + window_count = len(session._windows) # current window count + assert len(session._windows) == window_count + for w, wconf in builder.iter_create_windows(session): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size p = p - assert len(s._windows) == window_count + assert len(session._windows) == window_count assert isinstance(w, Window) - assert len(s._windows) == window_count + assert len(session._windows) == window_count window_count += 1 w.set_window_option("main-pane-height", 50) w.select_layout(wconf["layout"]) def test_focus_pane_index(session): - yaml_config = test_utils.read_config_file("workspacebuilder/focus_and_pane.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/focus_and_pane.yaml") + ) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -145,9 +140,9 @@ def f(): """.strip() ) def test_suppress_history(session): - yaml_config = test_utils.read_config_file("workspacebuilder/suppress_history.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/suppress_history.yaml") + ) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -199,31 +194,29 @@ def f(): def test_session_options(session): - yaml_config = test_utils.read_config_file("workspacebuilder/session_options.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/session_options.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) - assert "/bin/sh" in s.show_option("default-shell") - assert "/bin/sh" in s.show_option("default-command") + assert "/bin/sh" in session.show_option("default-shell") + assert "/bin/sh" in session.show_option("default-command") def test_global_options(session): - yaml_config = test_utils.read_config_file("workspacebuilder/global_options.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/global_options.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) - assert "top" in s.show_option("status-position", _global=True) - assert 493 == s.show_option("repeat-time", _global=True) + assert "top" in session.show_option("status-position", _global=True) + assert 493 == session.show_option("repeat-time", _global=True) def test_global_session_env_options(session, monkeypatch): @@ -234,25 +227,25 @@ def test_global_session_env_options(session, monkeypatch): main_pane_height = 8 monkeypatch.setenv("MAIN_PANE_HEIGHT", str(main_pane_height)) - yaml_config = test_utils.read_config_file("workspacebuilder/env_var_options.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/env_var_options.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) - assert visual_silence in s.show_option("visual-silence", _global=True) - assert repeat_time == s.show_option("repeat-time") - assert main_pane_height == s.attached_window.show_window_option("main-pane-height") + assert visual_silence in session.show_option("visual-silence", _global=True) + assert repeat_time == session.show_option("repeat-time") + assert main_pane_height == session.attached_window.show_window_option( + "main-pane-height" + ) def test_window_options(session): - yaml_config = test_utils.read_config_file("workspacebuilder/window_options.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/window_options.yaml") + ) sconfig = config.expand(sconfig) if has_gte_version("2.3"): @@ -261,29 +254,27 @@ def test_window_options(session): builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count - assert len(s._windows) == window_count - for w, wconf in builder.iter_create_windows(s): + assert len(session._windows) == window_count + for w, wconf in builder.iter_create_windows(session): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size p = p - assert len(s._windows) == window_count + assert len(session._windows) == window_count assert isinstance(w, Window) assert w.show_window_option("main-pane-height") == 5 if has_gte_version("2.3"): assert w.show_window_option("pane-border-format") == " #P " - assert len(s._windows) == window_count + assert len(session._windows) == window_count window_count += 1 w.select_layout(wconf["layout"]) @pytest.mark.flaky(reruns=5) def test_window_options_after(session): - yaml_config = test_utils.read_config_file( - "workspacebuilder/window_options_after.yaml" + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/window_options_after.yaml") ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) @@ -319,15 +310,14 @@ def f(): def test_window_shell(session): - yaml_config = test_utils.read_config_file("workspacebuilder/window_shell.yaml") - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/window_shell.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) - for w, wconf in builder.iter_create_windows(s): + for w, wconf in builder.iter_create_windows(session): if "window_shell" in wconf: assert wconf["window_shell"] == "top" @@ -341,9 +331,9 @@ def f(): def test_environment_variables(session): - yaml_config = test_utils.read_config_file("workspacebuilder/environment_vars.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/environment_vars.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) @@ -355,12 +345,9 @@ def test_environment_variables(session): def test_automatic_rename_option(session): """With option automatic-rename: on.""" - yaml_config = test_utils.read_config_file( - "workspacebuilder/window_automatic_rename.yaml" + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/window_automatic_rename.yaml") ) - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() # This should be a command guaranteed to be terminal name across systems portable_command = sconfig["windows"][0]["panes"][0]["shell_command"][0]["cmd"] @@ -371,23 +358,23 @@ def test_automatic_rename_option(session): builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count - assert len(s._windows) == window_count - for w, wconf in builder.iter_create_windows(s): + assert len(session._windows) == window_count + for w, wconf in builder.iter_create_windows(session): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size p = p - assert len(s._windows), window_count + assert len(session._windows), window_count assert isinstance(w, Window) assert w.show_window_option("automatic-rename") == "on" - assert len(s._windows) == window_count + assert len(session._windows) == window_count window_count += 1 w.select_layout(wconf["layout"]) - assert s.name != "tmuxp" - w = s.windows[0] + assert session.name != "tmuxp" + w = session.windows[0] def check_window_name_mismatch() -> bool: session.server._update_windows() @@ -414,7 +401,8 @@ def check_window_name_match() -> bool: def test_blank_pane_count(session): """:todo: Verify blank panes of various types build into workspaces.""" yaml_config_file = EXAMPLE_PATH / "blank-panes.yaml" - test_config = kaptan.Kaptan().import_config(str(yaml_config_file)).get() + test_config = ConfigReader._from_file(yaml_config_file) + test_config = config.expand(test_config) builder = WorkspaceBuilder(sconf=test_config) builder.build(session=session) @@ -435,13 +423,13 @@ def test_blank_pane_count(session): def test_start_directory(session, tmp_path: pathlib.Path): - yaml_config = test_utils.read_config_file("workspacebuilder/start_directory.yaml") test_dir = tmp_path / "foo bar" test_dir.mkdir() + + yaml_config = test_utils.read_config_file("workspacebuilder/start_directory.yaml") test_config = yaml_config.format(TEST_DIR=test_dir) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(test_config).get() + sconfig = ConfigReader._load(format="yaml", content=test_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -483,10 +471,9 @@ def test_start_directory_relative(session, tmp_path: pathlib.Path): test_dir.mkdir() config_dir = tmp_path / "testRelConfigDir" config_dir.mkdir() - test_config = yaml_config.format(TEST_DIR=test_dir) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(test_config).get() + test_config = yaml_config.format(TEST_DIR=test_dir) + sconfig = ConfigReader._load(format="yaml", content=test_config) # the second argument of os.getcwd() mimics the behavior # the CLI loader will do, but it passes in the config file's location. sconfig = config.expand(sconfig, config_dir) @@ -518,11 +505,9 @@ def f(): has_lt_version("3.2a"), reason="needs format introduced in tmux >= 3.2a" ) def test_start_directory_sets_session_path(server): - yaml_config = test_utils.read_config_file( - "workspacebuilder/start_directory_session_path.yaml" + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/start_directory_session_path.yaml") ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -540,9 +525,7 @@ def test_pane_order(session): """Pane ordering based on position in config and ``pane_index``. Regression test for https://github.com/tmux-python/tmuxp/issues/15. - """ - yaml_config = test_utils.read_config_file( "workspacebuilder/pane_ordering.yaml" ).format(HOME=os.path.realpath(os.path.expanduser("~"))) @@ -555,25 +538,23 @@ def test_pane_order(session): os.path.realpath(os.path.expanduser("~")), ] - s = session - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count - assert len(s._windows) == window_count + assert len(session._windows) == window_count - for w, wconf in builder.iter_create_windows(s): + for w, wconf in builder.iter_create_windows(session): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size - assert len(s._windows) == window_count + assert len(session._windows) == window_count assert isinstance(w, Window) - assert len(s._windows) == window_count + assert len(session._windows) == window_count window_count += 1 for w in session.windows: @@ -593,13 +574,13 @@ def f(): def test_window_index(session): - yaml_config = test_utils.read_config_file("workspacebuilder/window_index.yaml") proc = session.cmd("show-option", "-gv", "base-index") base_index = int(proc.stdout[0]) name_index_map = {"zero": 0 + base_index, "one": 1 + base_index, "five": 5} - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + test_utils.get_config_file("workspacebuilder/window_index.yaml") + ) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -614,12 +595,11 @@ def test_before_load_throw_error_if_retcode_error(server): config_script_fails = test_utils.read_config_file( "workspacebuilder/config_script_fails.yaml" ) - sconfig = kaptan.Kaptan(handler="yaml") - yaml = config_script_fails.format( + yaml_config = config_script_fails.format( script_failed=FIXTURE_PATH / "script_failed.sh", ) - sconfig = sconfig.import_config(yaml).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -639,22 +619,21 @@ def test_before_load_throw_error_if_file_not_exists(server): config_script_not_exists = test_utils.read_config_file( "workspacebuilder/config_script_not_exists.yaml" ) - sconfig = kaptan.Kaptan(handler="yaml") - yaml = config_script_not_exists.format( + yaml_config = config_script_not_exists.format( script_not_exists=FIXTURE_PATH / "script_not_exists.sh", ) - sconfig = sconfig.import_config(yaml).get() + sconfig = ConfigReader._load(format="yaml", content=yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) - with temp_session(server) as sess: - session_name = sess.name - temp_session_exists = server.has_session(sess.name) + with temp_session(server) as session: + session_name = session.name + temp_session_exists = server.has_session(session.name) assert temp_session_exists with pytest.raises((exc.BeforeLoadScriptNotExists, OSError)) as excinfo: - builder.build(session=sess) + builder.build(session=session) excinfo.match(r"No such file or directory") result = server.has_session(session_name) assert not result, "Kills session if before_script doesn't exist" @@ -666,12 +645,9 @@ def test_before_load_true_if_test_passes(server): ) script_complete_sh = FIXTURE_PATH / "script_complete.sh" assert script_complete_sh.exists() - sconfig = kaptan.Kaptan(handler="yaml") - yaml = config_script_completes.format( - script_complete=script_complete_sh, - ) - sconfig = sconfig.import_config(yaml).get() + yaml_config = config_script_completes.format(script_complete=script_complete_sh) + sconfig = ConfigReader._load(format="yaml", content=yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -687,10 +663,10 @@ def test_before_load_true_if_test_passes_with_args(server): ) script_complete_sh = FIXTURE_PATH / "script_complete.sh" assert script_complete_sh.exists() - sconfig = kaptan.Kaptan(handler="yaml") - yaml = config_script_completes.format(script_complete=script_complete_sh) - sconfig = sconfig.import_config(yaml).get() + yaml_config = config_script_completes.format(script_complete=script_complete_sh) + + sconfig = ConfigReader._load(format="yaml", content=yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -703,10 +679,9 @@ def test_before_load_true_if_test_passes_with_args(server): def test_plugin_system_before_workspace_builder( monkeypatch_plugin_test_packages, session ): - config_plugins = test_utils.read_config_file("workspacebuilder/plugin_bwb.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/plugin_bwb.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -719,10 +694,9 @@ def test_plugin_system_before_workspace_builder( def test_plugin_system_on_window_create(monkeypatch_plugin_test_packages, session): - config_plugins = test_utils.read_config_file("workspacebuilder/plugin_owc.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/plugin_owc.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -735,10 +709,9 @@ def test_plugin_system_on_window_create(monkeypatch_plugin_test_packages, sessio def test_plugin_system_after_window_finished(monkeypatch_plugin_test_packages, session): - config_plugins = test_utils.read_config_file("workspacebuilder/plugin_awf.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/plugin_awf.yaml") + ) sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -751,12 +724,11 @@ def test_plugin_system_after_window_finished(monkeypatch_plugin_test_packages, s def test_plugin_system_on_window_create_multiple_windows(session): - config_plugins = test_utils.read_config_file( - "workspacebuilder/plugin_owc_multiple_windows.yaml" + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file( + "workspacebuilder/plugin_owc_multiple_windows.yaml" + ) ) - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -772,12 +744,11 @@ def test_plugin_system_on_window_create_multiple_windows(session): def test_plugin_system_after_window_finished_multiple_windows( monkeypatch_plugin_test_packages, session ): - config_plugins = test_utils.read_config_file( - "workspacebuilder/plugin_awf_multiple_windows.yaml" + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file( + "workspacebuilder/plugin_awf_multiple_windows.yaml" + ) ) - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -791,12 +762,9 @@ def test_plugin_system_after_window_finished_multiple_windows( def test_plugin_system_multiple_plugins(monkeypatch_plugin_test_packages, session): - config_plugins = test_utils.read_config_file( - "workspacebuilder/plugin_multiple_plugins.yaml" + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/plugin_multiple_plugins.yaml") ) - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(config_plugins).get() sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig, plugins=load_plugins(sconfig)) @@ -816,9 +784,9 @@ def test_plugin_system_multiple_plugins(monkeypatch_plugin_test_packages, sessio def test_load_configs_same_session(server): - yaml_config = test_utils.read_config_file("workspacebuilder/three_windows.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/three_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() @@ -826,20 +794,18 @@ def test_load_configs_same_session(server): assert len(server.sessions) == 1 assert len(server.sessions[0]._windows) == 3 - yaml_config = test_utils.read_config_file("workspacebuilder/two_windows.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/two_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() assert len(server.sessions) == 2 assert len(server.sessions[1]._windows) == 2 - yaml_config = test_utils.read_config_file("workspacebuilder/two_windows.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/two_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build(server.sessions[1], True) @@ -849,9 +815,9 @@ def test_load_configs_same_session(server): def test_load_configs_separate_sessions(server): - yaml_config = test_utils.read_config_file("workspacebuilder/three_windows.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/three_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() @@ -859,10 +825,9 @@ def test_load_configs_separate_sessions(server): assert len(server.sessions) == 1 assert len(server.sessions[0]._windows) == 3 - yaml_config = test_utils.read_config_file("workspacebuilder/two_windows.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/two_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() @@ -873,17 +838,16 @@ def test_load_configs_separate_sessions(server): def test_find_current_active_pane(server, monkeypatch): - yaml_config = test_utils.read_config_file("workspacebuilder/three_windows.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/three_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() - yaml_config = test_utils.read_config_file("workspacebuilder/two_windows.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + sconfig = ConfigReader._from_file( + path=test_utils.get_config_file("workspacebuilder/two_windows.yaml") + ) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() @@ -1032,12 +996,8 @@ def test_load_workspace_enter( should_see, ): yaml_config = tmp_path / "simple.yaml" - yaml_config.write_text( - yaml, - encoding="utf-8", - ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(str(yaml_config)).get() + yaml_config.write_text(yaml, encoding="utf-8") + sconfig = ConfigReader._from_file(yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1156,12 +1116,8 @@ def test_load_workspace_sleep( output, ): yaml_config = tmp_path / "simple.yaml" - yaml_config.write_text( - yaml, - encoding="utf-8", - ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(str(yaml_config)).get() + yaml_config.write_text(yaml, encoding="utf-8") + sconfig = ConfigReader._from_file(yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig, server=server) @@ -1183,12 +1139,11 @@ def test_load_workspace_sleep( def test_first_pane_start_directory(session, tmp_path: pathlib.Path): - yaml_config = test_utils.read_config_file( + yaml_config = test_utils.get_config_file( "workspacebuilder/first_pane_start_directory.yaml" ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(str(yaml_config)).get() + sconfig = ConfigReader._from_file(yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) @@ -1215,10 +1170,8 @@ def f(): has_lt_version("2.9"), reason="needs option introduced in tmux >= 2.9" ) def test_layout_main_horizontal(session): - yaml_config = test_utils.read_config_file("workspacebuilder/three_pane.yaml") - - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + yaml_config = test_utils.get_config_file("workspacebuilder/three_pane.yaml") + sconfig = ConfigReader._from_file(path=yaml_config) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) @@ -1303,11 +1256,11 @@ def test_issue_800_default_size_many_windows( See also: https://github.com/tmux-python/tmuxp/issues/800 """ - yaml_config = test_utils.read_config_file( + yaml_config = test_utils.get_config_file( "regressions/issue_800_default_size_many_windows.yaml" ) - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + + sconfig = ConfigReader._from_file(yaml_config) sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) diff --git a/tests/test_workspacefreezer.py b/tests/test_workspacefreezer.py index 659295ae849..a3103ccca34 100644 --- a/tests/test_workspacefreezer.py +++ b/tests/test_workspacefreezer.py @@ -1,33 +1,35 @@ -"""Test for tmuxp workspacefreezer.""" +"""Tests for freezing tmux sessions with tmuxp.""" import time -import kaptan - from tmuxp import config +from tmuxp.config_reader import ConfigReader from tmuxp.workspacebuilder import WorkspaceBuilder, freeze from .fixtures import utils as test_utils def test_freeze_config(session): - yaml_config = test_utils.read_config_file("workspacefreezer/sampleconfig.yaml") - sconfig = kaptan.Kaptan(handler="yaml") - sconfig = sconfig.import_config(yaml_config).get() + session_config = ConfigReader._from_file( + test_utils.get_config_file("workspacefreezer/sampleconfig.yaml") + ) - builder = WorkspaceBuilder(sconf=sconfig) + builder = WorkspaceBuilder(sconf=session_config) builder.build(session=session) assert session == builder.session time.sleep(0.50) session = session - sconf = freeze(session) + new_config = freeze(session) + + config.validate_schema(new_config) - config.validate_schema(sconf) + # These should dump without an error + ConfigReader._dump(format="json", content=new_config) + ConfigReader._dump(format="yaml", content=new_config) - sconf = config.inline(sconf) + # Inline configs should also dump without an error + compact_config = config.inline(new_config) - kaptanconf = kaptan.Kaptan() - kaptanconf = kaptanconf.import_config(sconf) - kaptanconf.export("json", indent=2) - kaptanconf.export("yaml", indent=2, default_flow_style=False, safe=True) + ConfigReader._dump(format="json", content=compact_config) + ConfigReader._dump(format="yaml", content=compact_config)