qwik-envr 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ .venv-*/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .opencode/
12
+ .env
13
+ .env.*
14
+ .pypirc
15
+ *.log
16
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Himakar Reddy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,215 @@
1
+ Metadata-Version: 2.5
2
+ Name: qwik-envr
3
+ Version: 0.5.0
4
+ Summary: A local browser editor for Unix shell environment variables.
5
+ Project-URL: Homepage, https://github.com/Qwik-Tools/envr
6
+ Project-URL: Repository, https://github.com/Qwik-Tools/envr
7
+ Project-URL: Issues, https://github.com/Qwik-Tools/envr/issues
8
+ Author: Himakar Reddy
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,environment,secrets,shell,unix
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX
16
+ Classifier: Operating System :: POSIX :: BSD
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Topic :: System :: Systems Administration
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+
24
+ # envr
25
+
26
+ Edit shell environment variables in your browser. Run `envr`, and it opens a local
27
+ table for the `export NAME=value` entries in a marked section of your startup file.
28
+ Add, edit, save, or delete entries without dumping the rest of your shell config.
29
+
30
+ **Package:** `qwik-envr` on PyPI · **Command:** `envr` · **Python:** 3.9+
31
+
32
+ ## Install
33
+
34
+ ```sh
35
+ pipx install qwik-envr
36
+ # or use a virtual environment
37
+ python3 -m venv .venv
38
+ . .venv/bin/activate
39
+ python -m pip install qwik-envr
40
+ ```
41
+
42
+ The unrelated PyPI package named `envr` is **not** this project. Do not install both
43
+ in the same environment: they may share the `envr` import/command name.
44
+
45
+ ## Quick start
46
+
47
+ Put two **identical** marker lines in your shell config:
48
+
49
+ ```sh
50
+ ##</env secrets>
51
+ export API_KEY='your-value'
52
+ export DATABASE_URL='postgres://localhost/example'
53
+ ##</env secrets>
54
+ ```
55
+
56
+ Then run:
57
+
58
+ ```console
59
+ $ envr
60
+ envr: macOS 26.3 (arm64) -- OK
61
+ envr: 2 exports from ~/.zshrc at http://127.0.0.1:49152/<random-token>/
62
+ envr: Ctrl-C to stop
63
+ ```
64
+
65
+ The port and access token are randomly assigned each run. Your default browser
66
+ opens automatically; the server stays running until **Ctrl-C**. Each row has
67
+ **Save** and **Delete** buttons; use **Add** for new variables. Changes save
68
+ immediately. Refresh the page to reload changes made in another editor.
69
+
70
+ If the startup file is missing, an interactive run asks before creating an empty,
71
+ owner-only file (`0600`, subject to umask). Add the markers yourself afterward.
72
+ Noninteractive runs never prompt or create a file. Missing markers are reported,
73
+ not inserted automatically. Existing files are never overwritten just to create
74
+ a new block.
75
+
76
+ ## Platform and shell support
77
+
78
+ The platform gate accepts desktop/server Unix-like systems, including macOS,
79
+ Linux, the BSDs, Solaris, and AIX. Local verification is on macOS, including
80
+ sh/bash integration. Other Unix platforms are not independently verified.
81
+ Windows, mobile Python, and browser/WASI runtimes are not supported.
82
+
83
+ `$SHELL` selects the default **file to edit**:
84
+
85
+ | Shell | Default file |
86
+ | --- | --- |
87
+ | zsh | `$ZDOTDIR/.zshrc` if set, otherwise `~/.zshrc` |
88
+ | bash | `~/.bashrc` |
89
+ | ksh | `~/.kshrc` |
90
+ | sh, dash, ash | `~/.profile` |
91
+
92
+ If `$SHELL` is unset or unsupported, envr chooses the first existing file among
93
+ `~/.zshrc`, `~/.bashrc`, and `~/.profile`, falling back to `~/.profile`.
94
+ `--file PATH` overrides this selection. Known filenames select their matching
95
+ validation shell; custom filenames use the supported `$SHELL`, or `sh`.
96
+ The selected shell must be installed to save changes.
97
+
98
+ These are editing defaults, not a guarantee of what every shell startup mode
99
+ loads. Bash login shells may use `.bash_profile`; ksh may require `ENV` to point
100
+ to `.kshrc`. Use `--file` for your setup. Fish/csh syntax is not supported.
101
+
102
+ ## Commands
103
+
104
+ | Command | Behavior |
105
+ | --- | --- |
106
+ | `envr` | Open the local editor in your default browser |
107
+ | `envr --file ~/.bash_profile` | Edit a specific file |
108
+ | `envr --no-browser` | Print the URL without opening a browser |
109
+ | `envr --timeout 120` | Stop after 120 seconds; default `0` means until Ctrl-C |
110
+ | `envr --json` | Print one JSON document with platform/config metadata and variable names, **not values**; no prompts/server |
111
+ | `envr -q` | Unix platform gate only; silent, no config file access |
112
+ | `envr --mac -q` | macOS-only gate; silent, no config file access |
113
+ | `envr --version` | Print the version |
114
+ | `python -m envr` | Same command when using the installed interpreter |
115
+
116
+ Exit codes: `0` = supported platform, `1` = unsupported platform (or server startup
117
+ failure), `2` = invalid usage, `130` = interrupted. Config/marker problems are
118
+ reported but do not change the platform verdict. `--mac` exits `1` off macOS.
119
+
120
+ ## Editing rules and safe saves
121
+
122
+ - The **first two** marker lines delimit the block. Put them at top level, not
123
+ inside quoted strings, functions, conditionals, or here-documents.
124
+ - Editable entries are single-line literal `export NAME=value` statements.
125
+ Plain, single-quoted, double-quoted, and escaped literal values are supported.
126
+ - Names use `[A-Za-z_][A-Za-z0-9_]*` (at most 128 characters); values are at most
127
+ 4096 characters, without newline, NUL, or invalid Unicode. Duplicate names are
128
+ rejected when adding or editing.
129
+ - Comments and blank lines are preserved. If a block contains shell expressions
130
+ such as `$HOME`, command substitution, multiline values, or other statements,
131
+ the **whole block is read-only**. Edit those blocks manually. Nothing is evaluated
132
+ merely to display the table.
133
+ - Edited values are treated as **literal strings**, safely shell-quoted. Untouched
134
+ entries, inline comments, line endings, and content outside the block stay intact.
135
+ - Existing symlinks are followed; the target is updated without replacing the link.
136
+ The target's Unix permission bits are retained. Atomic replacement changes the
137
+ inode; hard-link relationships, ACLs, and extended attributes are not preserved.
138
+ - External changes are detected before replacement and rejected. Refresh before
139
+ retrying. Use one editor tab/session per file; this is not a multiuser editor.
140
+
141
+ On save, envr writes a private temporary candidate in the same directory, runs
142
+ `<shell> -n` against it, and replaces the live file **only if validation succeeds**.
143
+ If validation fails or the shell is unavailable, the original file is unchanged.
144
+ Temporary files are removed afterward.
145
+
146
+ ### Sourcing: important limitation
147
+
148
+ After saving, envr executes `. <file>` in a **child shell** with a 15-second timeout.
149
+ Raw shell output is discarded so secrets cannot leak into HTTP errors or terminal
150
+ logs; the page reports whether sourcing completed successfully.
151
+
152
+ **This executes your entire startup file, including commands outside the block.**
153
+ Use envr only with configurations you trust. Syntax validation is not a sandbox.
154
+ Startup guards may skip parts of a file in a noninteractive child shell.
155
+
156
+ A child process cannot change an already-open terminal's environment. To apply
157
+ changes there, run the appropriate command yourself:
158
+
159
+ ```sh
160
+ source ~/.zshrc # zsh
161
+ source ~/.bashrc # bash
162
+ . ~/.profile # POSIX sh
163
+ ```
164
+
165
+ ## Security
166
+
167
+ The server binds **127.0.0.1 only**, uses an OS-assigned port and a random 192-bit
168
+ token in the URL, and rejects foreign Host/Origin headers. It has no external
169
+ assets, analytics, CORS permissions, or runtime package dependencies. Responses
170
+ use `no-store`, `no-referrer`, `nosniff`, frame denial, and a nonce-based script CSP.
171
+ JSON writes are bounded and validated; displayed values are not inserted as HTML.
172
+
173
+ The local URL grants **read/write access** and sourcing permission: do not share
174
+ it. It can remain in browser history and terminal scrollback. This is a local
175
+ convenience tool, not encrypted secret storage or a sandbox against other processes
176
+ running as your user. Close the server when finished. See [SECURITY.md](SECURITY.md).
177
+
178
+ ## Development
179
+
180
+ ```sh
181
+ git clone https://github.com/Qwik-Tools/envr.git
182
+ cd envr
183
+ python3 -m venv .venv
184
+ . .venv/bin/activate
185
+ python -m pip install --upgrade pip
186
+ python -m pip install -e . --group dev
187
+ python -m pytest
188
+ ruff check src tests
189
+ ruff format --check src tests
190
+ mypy src/envr
191
+ python -m build
192
+ python -m twine check dist/*
193
+ ```
194
+
195
+ Tests use temporary config files; they do not edit or source your real startup file.
196
+ Each test has a timeout to prevent accidental indefinite server runs.
197
+
198
+ ```text
199
+ src/envr/system.py platform detection
200
+ src/envr/shellrc.py config selection, read/create prompt
201
+ src/envr/secretblock.py marker extraction helper
202
+ src/envr/secretfile.py literal parsing, CRUD, validated writes, child sourcing
203
+ src/envr/webview.py loopback HTTP API and browser table
204
+ src/envr/cli.py command-line entry point
205
+ ```
206
+
207
+ The distribution is `qwik-envr`; Python imports remain under `envr`. The main
208
+ library interface is `SecretStore.load(path, shell=...)`, then `items()`,
209
+ `add()`, `update()`, `delete()`, `save()`, and `reload()`. `StoreError.code` is
210
+ stable; error details never include values. Store access must be serialized by
211
+ the caller (the HTTP server does this). Maintained by Qwik-Tools / Himakar Reddy.
212
+
213
+ ## License
214
+
215
+ [MIT](LICENSE).
@@ -0,0 +1,192 @@
1
+ # envr
2
+
3
+ Edit shell environment variables in your browser. Run `envr`, and it opens a local
4
+ table for the `export NAME=value` entries in a marked section of your startup file.
5
+ Add, edit, save, or delete entries without dumping the rest of your shell config.
6
+
7
+ **Package:** `qwik-envr` on PyPI · **Command:** `envr` · **Python:** 3.9+
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ pipx install qwik-envr
13
+ # or use a virtual environment
14
+ python3 -m venv .venv
15
+ . .venv/bin/activate
16
+ python -m pip install qwik-envr
17
+ ```
18
+
19
+ The unrelated PyPI package named `envr` is **not** this project. Do not install both
20
+ in the same environment: they may share the `envr` import/command name.
21
+
22
+ ## Quick start
23
+
24
+ Put two **identical** marker lines in your shell config:
25
+
26
+ ```sh
27
+ ##</env secrets>
28
+ export API_KEY='your-value'
29
+ export DATABASE_URL='postgres://localhost/example'
30
+ ##</env secrets>
31
+ ```
32
+
33
+ Then run:
34
+
35
+ ```console
36
+ $ envr
37
+ envr: macOS 26.3 (arm64) -- OK
38
+ envr: 2 exports from ~/.zshrc at http://127.0.0.1:49152/<random-token>/
39
+ envr: Ctrl-C to stop
40
+ ```
41
+
42
+ The port and access token are randomly assigned each run. Your default browser
43
+ opens automatically; the server stays running until **Ctrl-C**. Each row has
44
+ **Save** and **Delete** buttons; use **Add** for new variables. Changes save
45
+ immediately. Refresh the page to reload changes made in another editor.
46
+
47
+ If the startup file is missing, an interactive run asks before creating an empty,
48
+ owner-only file (`0600`, subject to umask). Add the markers yourself afterward.
49
+ Noninteractive runs never prompt or create a file. Missing markers are reported,
50
+ not inserted automatically. Existing files are never overwritten just to create
51
+ a new block.
52
+
53
+ ## Platform and shell support
54
+
55
+ The platform gate accepts desktop/server Unix-like systems, including macOS,
56
+ Linux, the BSDs, Solaris, and AIX. Local verification is on macOS, including
57
+ sh/bash integration. Other Unix platforms are not independently verified.
58
+ Windows, mobile Python, and browser/WASI runtimes are not supported.
59
+
60
+ `$SHELL` selects the default **file to edit**:
61
+
62
+ | Shell | Default file |
63
+ | --- | --- |
64
+ | zsh | `$ZDOTDIR/.zshrc` if set, otherwise `~/.zshrc` |
65
+ | bash | `~/.bashrc` |
66
+ | ksh | `~/.kshrc` |
67
+ | sh, dash, ash | `~/.profile` |
68
+
69
+ If `$SHELL` is unset or unsupported, envr chooses the first existing file among
70
+ `~/.zshrc`, `~/.bashrc`, and `~/.profile`, falling back to `~/.profile`.
71
+ `--file PATH` overrides this selection. Known filenames select their matching
72
+ validation shell; custom filenames use the supported `$SHELL`, or `sh`.
73
+ The selected shell must be installed to save changes.
74
+
75
+ These are editing defaults, not a guarantee of what every shell startup mode
76
+ loads. Bash login shells may use `.bash_profile`; ksh may require `ENV` to point
77
+ to `.kshrc`. Use `--file` for your setup. Fish/csh syntax is not supported.
78
+
79
+ ## Commands
80
+
81
+ | Command | Behavior |
82
+ | --- | --- |
83
+ | `envr` | Open the local editor in your default browser |
84
+ | `envr --file ~/.bash_profile` | Edit a specific file |
85
+ | `envr --no-browser` | Print the URL without opening a browser |
86
+ | `envr --timeout 120` | Stop after 120 seconds; default `0` means until Ctrl-C |
87
+ | `envr --json` | Print one JSON document with platform/config metadata and variable names, **not values**; no prompts/server |
88
+ | `envr -q` | Unix platform gate only; silent, no config file access |
89
+ | `envr --mac -q` | macOS-only gate; silent, no config file access |
90
+ | `envr --version` | Print the version |
91
+ | `python -m envr` | Same command when using the installed interpreter |
92
+
93
+ Exit codes: `0` = supported platform, `1` = unsupported platform (or server startup
94
+ failure), `2` = invalid usage, `130` = interrupted. Config/marker problems are
95
+ reported but do not change the platform verdict. `--mac` exits `1` off macOS.
96
+
97
+ ## Editing rules and safe saves
98
+
99
+ - The **first two** marker lines delimit the block. Put them at top level, not
100
+ inside quoted strings, functions, conditionals, or here-documents.
101
+ - Editable entries are single-line literal `export NAME=value` statements.
102
+ Plain, single-quoted, double-quoted, and escaped literal values are supported.
103
+ - Names use `[A-Za-z_][A-Za-z0-9_]*` (at most 128 characters); values are at most
104
+ 4096 characters, without newline, NUL, or invalid Unicode. Duplicate names are
105
+ rejected when adding or editing.
106
+ - Comments and blank lines are preserved. If a block contains shell expressions
107
+ such as `$HOME`, command substitution, multiline values, or other statements,
108
+ the **whole block is read-only**. Edit those blocks manually. Nothing is evaluated
109
+ merely to display the table.
110
+ - Edited values are treated as **literal strings**, safely shell-quoted. Untouched
111
+ entries, inline comments, line endings, and content outside the block stay intact.
112
+ - Existing symlinks are followed; the target is updated without replacing the link.
113
+ The target's Unix permission bits are retained. Atomic replacement changes the
114
+ inode; hard-link relationships, ACLs, and extended attributes are not preserved.
115
+ - External changes are detected before replacement and rejected. Refresh before
116
+ retrying. Use one editor tab/session per file; this is not a multiuser editor.
117
+
118
+ On save, envr writes a private temporary candidate in the same directory, runs
119
+ `<shell> -n` against it, and replaces the live file **only if validation succeeds**.
120
+ If validation fails or the shell is unavailable, the original file is unchanged.
121
+ Temporary files are removed afterward.
122
+
123
+ ### Sourcing: important limitation
124
+
125
+ After saving, envr executes `. <file>` in a **child shell** with a 15-second timeout.
126
+ Raw shell output is discarded so secrets cannot leak into HTTP errors or terminal
127
+ logs; the page reports whether sourcing completed successfully.
128
+
129
+ **This executes your entire startup file, including commands outside the block.**
130
+ Use envr only with configurations you trust. Syntax validation is not a sandbox.
131
+ Startup guards may skip parts of a file in a noninteractive child shell.
132
+
133
+ A child process cannot change an already-open terminal's environment. To apply
134
+ changes there, run the appropriate command yourself:
135
+
136
+ ```sh
137
+ source ~/.zshrc # zsh
138
+ source ~/.bashrc # bash
139
+ . ~/.profile # POSIX sh
140
+ ```
141
+
142
+ ## Security
143
+
144
+ The server binds **127.0.0.1 only**, uses an OS-assigned port and a random 192-bit
145
+ token in the URL, and rejects foreign Host/Origin headers. It has no external
146
+ assets, analytics, CORS permissions, or runtime package dependencies. Responses
147
+ use `no-store`, `no-referrer`, `nosniff`, frame denial, and a nonce-based script CSP.
148
+ JSON writes are bounded and validated; displayed values are not inserted as HTML.
149
+
150
+ The local URL grants **read/write access** and sourcing permission: do not share
151
+ it. It can remain in browser history and terminal scrollback. This is a local
152
+ convenience tool, not encrypted secret storage or a sandbox against other processes
153
+ running as your user. Close the server when finished. See [SECURITY.md](SECURITY.md).
154
+
155
+ ## Development
156
+
157
+ ```sh
158
+ git clone https://github.com/Qwik-Tools/envr.git
159
+ cd envr
160
+ python3 -m venv .venv
161
+ . .venv/bin/activate
162
+ python -m pip install --upgrade pip
163
+ python -m pip install -e . --group dev
164
+ python -m pytest
165
+ ruff check src tests
166
+ ruff format --check src tests
167
+ mypy src/envr
168
+ python -m build
169
+ python -m twine check dist/*
170
+ ```
171
+
172
+ Tests use temporary config files; they do not edit or source your real startup file.
173
+ Each test has a timeout to prevent accidental indefinite server runs.
174
+
175
+ ```text
176
+ src/envr/system.py platform detection
177
+ src/envr/shellrc.py config selection, read/create prompt
178
+ src/envr/secretblock.py marker extraction helper
179
+ src/envr/secretfile.py literal parsing, CRUD, validated writes, child sourcing
180
+ src/envr/webview.py loopback HTTP API and browser table
181
+ src/envr/cli.py command-line entry point
182
+ ```
183
+
184
+ The distribution is `qwik-envr`; Python imports remain under `envr`. The main
185
+ library interface is `SecretStore.load(path, shell=...)`, then `items()`,
186
+ `add()`, `update()`, `delete()`, `save()`, and `reload()`. `StoreError.code` is
187
+ stable; error details never include values. Store access must be serialized by
188
+ the caller (the HTTP server does this). Maintained by Qwik-Tools / Himakar Reddy.
189
+
190
+ ## License
191
+
192
+ [MIT](LICENSE).
@@ -0,0 +1,36 @@
1
+ # Security policy
2
+
3
+ Report vulnerabilities privately through GitHub's private vulnerability reporting
4
+ for `Qwik-Tools/envr`. If reporting is unavailable, contact a maintainer without
5
+ including real tokens, config files, or tokenized local URLs in a public issue.
6
+
7
+ ## Threat model
8
+
9
+ Assets are plaintext environment values, the user's startup file, and commands
10
+ executed when that file is sourced. Trust boundaries are the browser-to-loopback
11
+ HTTP connection, JSON edits, and the filesystem/shell boundary.
12
+
13
+ Foreign websites are denied by a random 192-bit URL capability, Host/Origin
14
+ checks, absence of CORS, JSON-only bounded writes, and CSP/frame restrictions.
15
+ Values are handled as literal strings when edited, not interpolated shell code.
16
+ Syntax checks happen before atomic replacement. Snapshot checks reject external
17
+ changes observed before replacement; this is not a filesystem locking service.
18
+
19
+ ## Residual risks
20
+
21
+ - Anyone with the complete URL can read/write exports and trigger sourcing.
22
+ - URLs can remain in browser history or terminal scrollback.
23
+ - The HTTP transport is plaintext over IPv4 loopback; do not proxy or expose it.
24
+ - Other programs running as the same user can read config files, inspect process
25
+ memory, or race filesystem changes. envr does not defend against that actor.
26
+ - Sourcing intentionally executes the entire trusted config with your privileges.
27
+ The timeout is not a sandbox; spawned processes or existing shell commands can
28
+ have side effects. Do not open an untrusted configuration with this tool.
29
+ - Unix permission bits are retained, but atomic replacement does not retain ACLs,
30
+ extended attributes, or hard-link relationships. Use ordinary user-owned UTF-8
31
+ shell config files, not shared or specially permissioned system files.
32
+ - Use one browser tab and envr process per file. Concurrent browser edits are not
33
+ a supported collaboration mode.
34
+
35
+ Only the latest published release is supported. No real secrets should ever be
36
+ included in fixtures, screenshots, bug reports, source archives, or logs.
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "qwik-envr"
7
+ version = "0.5.0"
8
+ description = "A local browser editor for Unix shell environment variables."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Himakar Reddy" }]
14
+ keywords = ["unix", "shell", "environment", "cli", "secrets"]
15
+ classifiers = [
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: MacOS",
19
+ "Operating System :: POSIX",
20
+ "Operating System :: POSIX :: BSD",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3 :: Only",
24
+ "Topic :: System :: Systems Administration",
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://github.com/Qwik-Tools/envr"
29
+ Repository = "https://github.com/Qwik-Tools/envr"
30
+ Issues = "https://github.com/Qwik-Tools/envr/issues"
31
+
32
+ [project.scripts]
33
+ envr = "envr.cli:main"
34
+
35
+ [dependency-groups]
36
+ dev = ["pytest>=8.0", "pytest-timeout>=2.3", "ruff>=0.14", "mypy>=1.15,<1.20", "build>=1.2", "twine>=6"]
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/envr"]
40
+
41
+ [tool.hatch.build.targets.sdist]
42
+ include = ["src/", "tests/", "pyproject.toml", "README.md", "LICENSE", "SECURITY.md"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
46
+ addopts = "-q"
47
+ timeout = 15
48
+
49
+ [tool.ruff]
50
+ target-version = "py39"
51
+
52
+ [tool.ruff.lint]
53
+ select = ["E4", "E7", "E9", "F", "I", "UP", "B"]
54
+
55
+ [tool.mypy]
56
+ python_version = "3.9"
57
+ check_untyped_defs = true
@@ -0,0 +1,62 @@
1
+ """envr -- a Unix check, plus a browser editor for your shell secrets block.
2
+
3
+ Public surface:
4
+
5
+ is_unix() -> bool
6
+ is_mac() -> bool
7
+ os_label() -> str
8
+ os_version() -> str
9
+ platform_info() -> dict
10
+ shell_config_path() -> Path
11
+ inspect_shell_config()-> ShellReport
12
+ extract_block() -> str
13
+ SecretStore -- parse/edit/save the export block
14
+ serve_store() -> ServeResult
15
+
16
+ The ``envr`` console script is the only intended entry point; ``python -m envr``
17
+ runs the same command.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from .secretblock import SecretsBlockError, extract_block
23
+ from .secretfile import SecretStore, StoreError, quote_value, unquote_value
24
+ from .shellrc import (
25
+ POSIX_SHELLS,
26
+ ShellReport,
27
+ ShellState,
28
+ config_path_for,
29
+ detect_shell,
30
+ inspect_shell_config,
31
+ shell_config_path,
32
+ shell_name,
33
+ )
34
+ from .system import is_mac, is_unix, os_label, os_version, platform_info
35
+ from .webview import ServeResult, serve_store
36
+
37
+ __version__ = "0.5.0"
38
+
39
+ __all__ = [
40
+ "POSIX_SHELLS",
41
+ "SecretStore",
42
+ "SecretsBlockError",
43
+ "ServeResult",
44
+ "ShellReport",
45
+ "ShellState",
46
+ "StoreError",
47
+ "__version__",
48
+ "config_path_for",
49
+ "detect_shell",
50
+ "extract_block",
51
+ "inspect_shell_config",
52
+ "is_mac",
53
+ "is_unix",
54
+ "os_label",
55
+ "os_version",
56
+ "platform_info",
57
+ "quote_value",
58
+ "serve_store",
59
+ "shell_config_path",
60
+ "shell_name",
61
+ "unquote_value",
62
+ ]
@@ -0,0 +1,10 @@
1
+ """Allow ``python -m envr`` to behave exactly like the ``envr`` script."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+
7
+ from .cli import main
8
+
9
+ if __name__ == "__main__":
10
+ sys.exit(main())