keepassxc-cli 1.2.0__tar.gz → 1.3.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.
Potentially problematic release.
This version of keepassxc-cli might be problematic. Click here for more details.
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/PKG-INFO +29 -2
- keepassxc_cli-1.2.0/keepassxc_cli.egg-info/PKG-INFO → keepassxc_cli-1.3.0/README.md +27 -15
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/__main__.py +3 -1
- keepassxc_cli-1.3.0/keepassxc_cli/commands/group_uuid.py +58 -0
- keepassxc_cli-1.3.0/keepassxc_cli/commands/version.py +31 -0
- keepassxc_cli-1.2.0/README.md → keepassxc_cli-1.3.0/keepassxc_cli.egg-info/PKG-INFO +42 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli.egg-info/SOURCES.txt +2 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli.egg-info/requires.txt +1 -1
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/pyproject.toml +1 -1
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/tests/conftest.py +1 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/tests/test_commands.py +85 -1
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/.github/workflows/auto-merge-dependabot.yml +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/.github/workflows/auto-release.yml +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/.github/workflows/lint_and_test.yml +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/.github/workflows/pypi.yml +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/.gitignore +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/CLAUDE.md +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/LICENSE +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/__init__.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/__init__.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/add.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/clip.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/edit.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/lock.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/mkdir.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/rm.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/setup.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/show.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/status.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/commands/totp.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/config.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli/output.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli.egg-info/dependency_links.txt +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli.egg-info/entry_points.txt +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/keepassxc_cli.egg-info/top_level.txt +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/setup.cfg +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/tests/test_config.py +0 -0
- {keepassxc_cli-1.2.0 → keepassxc_cli-1.3.0}/tests/test_output.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: keepassxc-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: CLI for KeePassXC using the browser extension protocol with biometric unlock
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
-
Requires-Dist: keepassxc-browser-api==1.
|
|
9
|
+
Requires-Dist: keepassxc-browser-api==1.2.0
|
|
10
10
|
Requires-Dist: pyperclip==1.8.0
|
|
11
11
|
Provides-Extra: dev
|
|
12
12
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
@@ -163,6 +163,33 @@ keepassxc-cli mkdir "Work/Projects" # create Projects inside Work
|
|
|
163
163
|
|
|
164
164
|
Use `/`-separated paths to create nested groups. KeePassXC creates any missing path segments automatically.
|
|
165
165
|
|
|
166
|
+
#### `group-uuid` — Look up a group's UUID by path
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
keepassxc-cli group-uuid "Work"
|
|
170
|
+
keepassxc-cli group-uuid "Work/Projects"
|
|
171
|
+
keepassxc-cli group-uuid "Work/Projects" -j
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Returns the UUID for the group at the given path (relative to the database root). Useful for scripting — pipe the UUID into `add --group-uuid`.
|
|
175
|
+
|
|
176
|
+
JSON output (`-j`):
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"path": "Work/Projects",
|
|
180
|
+
"name": "Projects",
|
|
181
|
+
"uuid": "<uuid>"
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### `version` — Show the CLI version
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
keepassxc-cli version
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Does not require a running KeePassXC instance.
|
|
192
|
+
|
|
166
193
|
## Configuration
|
|
167
194
|
|
|
168
195
|
### CLI config (`~/.keepassxc/cli.json`)
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: keepassxc-cli
|
|
3
|
-
Version: 1.2.0
|
|
4
|
-
Summary: CLI for KeePassXC using the browser extension protocol with biometric unlock
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Dist: keepassxc-browser-api==1.1.0
|
|
10
|
-
Requires-Dist: pyperclip==1.8.0
|
|
11
|
-
Provides-Extra: dev
|
|
12
|
-
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
13
|
-
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
14
|
-
Dynamic: license-file
|
|
15
|
-
|
|
16
1
|
# keepassxc-cli
|
|
17
2
|
|
|
18
3
|
A command-line interface for [KeePassXC](https://keepassxc.org/) that communicates via the browser extension protocol, supporting biometric (TouchID/fingerprint) unlock on supported platforms.
|
|
@@ -163,6 +148,33 @@ keepassxc-cli mkdir "Work/Projects" # create Projects inside Work
|
|
|
163
148
|
|
|
164
149
|
Use `/`-separated paths to create nested groups. KeePassXC creates any missing path segments automatically.
|
|
165
150
|
|
|
151
|
+
#### `group-uuid` — Look up a group's UUID by path
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
keepassxc-cli group-uuid "Work"
|
|
155
|
+
keepassxc-cli group-uuid "Work/Projects"
|
|
156
|
+
keepassxc-cli group-uuid "Work/Projects" -j
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Returns the UUID for the group at the given path (relative to the database root). Useful for scripting — pipe the UUID into `add --group-uuid`.
|
|
160
|
+
|
|
161
|
+
JSON output (`-j`):
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"path": "Work/Projects",
|
|
165
|
+
"name": "Projects",
|
|
166
|
+
"uuid": "<uuid>"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### `version` — Show the CLI version
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
keepassxc-cli version
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Does not require a running KeePassXC instance.
|
|
177
|
+
|
|
166
178
|
## Configuration
|
|
167
179
|
|
|
168
180
|
### CLI config (`~/.keepassxc/cli.json`)
|
|
@@ -11,7 +11,7 @@ from keepassxc_browser_api import BrowserClient, BrowserConfig
|
|
|
11
11
|
from keepassxc_browser_api.exceptions import KeePassXCError, ConnectionError
|
|
12
12
|
|
|
13
13
|
from .config import CliConfig, DEFAULT_CLI_CONFIG_PATH
|
|
14
|
-
from .commands import setup, status, show, add, edit, rm, totp, clip, lock, mkdir
|
|
14
|
+
from .commands import setup, status, show, add, edit, rm, totp, clip, lock, mkdir, group_uuid, version
|
|
15
15
|
|
|
16
16
|
# Shared parent parser that injects -j/--json into each subparser that supports it.
|
|
17
17
|
# Defined at module level so command modules can import it if needed.
|
|
@@ -55,6 +55,8 @@ def main() -> None:
|
|
|
55
55
|
clip.add_parser(subparsers)
|
|
56
56
|
lock.add_parser(subparsers)
|
|
57
57
|
mkdir.add_parser(subparsers)
|
|
58
|
+
group_uuid.add_parser(subparsers, fmt_parent)
|
|
59
|
+
version.add_parser(subparsers)
|
|
58
60
|
|
|
59
61
|
args = parser.parse_args()
|
|
60
62
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from keepassxc_browser_api import BrowserClient, BrowserConfig
|
|
9
|
+
|
|
10
|
+
from keepassxc_cli.config import CliConfig
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def add_parser(subparsers: argparse._SubParsersAction, fmt_parent: argparse.ArgumentParser | None = None) -> None:
|
|
14
|
+
parents = [fmt_parent] if fmt_parent else []
|
|
15
|
+
p = subparsers.add_parser(
|
|
16
|
+
"group-uuid",
|
|
17
|
+
parents=parents,
|
|
18
|
+
help="Look up the UUID of a group by its path",
|
|
19
|
+
)
|
|
20
|
+
p.add_argument(
|
|
21
|
+
"path",
|
|
22
|
+
help="Group path relative to the database root (e.g. 'Work/Projects')",
|
|
23
|
+
)
|
|
24
|
+
p.set_defaults(func=run)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def run(
|
|
28
|
+
client: BrowserClient,
|
|
29
|
+
args: argparse.Namespace,
|
|
30
|
+
cli_config: CliConfig,
|
|
31
|
+
browser_config: BrowserConfig,
|
|
32
|
+
browser_config_path: Path,
|
|
33
|
+
*,
|
|
34
|
+
fmt: str = "table",
|
|
35
|
+
) -> int:
|
|
36
|
+
groups = client.get_database_groups()
|
|
37
|
+
if not groups:
|
|
38
|
+
print("Failed to retrieve group tree.", file=sys.stderr)
|
|
39
|
+
return 1
|
|
40
|
+
|
|
41
|
+
root = groups[0]
|
|
42
|
+
parts = args.path.split("/")
|
|
43
|
+
|
|
44
|
+
# Paths are root-relative: traverse root.children, not the root itself.
|
|
45
|
+
current = root.children
|
|
46
|
+
matched = None
|
|
47
|
+
for part in parts:
|
|
48
|
+
matched = next((g for g in current if g.name == part), None)
|
|
49
|
+
if matched is None:
|
|
50
|
+
print(f"Group not found: {args.path!r}", file=sys.stderr)
|
|
51
|
+
return 1
|
|
52
|
+
current = matched.children
|
|
53
|
+
|
|
54
|
+
if fmt == "json":
|
|
55
|
+
print(json.dumps({"path": args.path, "name": matched.name, "uuid": matched.uuid}, indent=2))
|
|
56
|
+
else:
|
|
57
|
+
print(f"{args.path} [{matched.uuid}]")
|
|
58
|
+
return 0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from keepassxc_browser_api import BrowserClient, BrowserConfig
|
|
8
|
+
|
|
9
|
+
from keepassxc_cli.config import CliConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def add_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
13
|
+
p = subparsers.add_parser("version", help="Show the keepassxc-cli version")
|
|
14
|
+
p.set_defaults(func=run)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def run(
|
|
18
|
+
client: BrowserClient,
|
|
19
|
+
args: argparse.Namespace,
|
|
20
|
+
cli_config: CliConfig,
|
|
21
|
+
browser_config: BrowserConfig,
|
|
22
|
+
browser_config_path: Path,
|
|
23
|
+
*,
|
|
24
|
+
fmt: str = "table",
|
|
25
|
+
) -> int:
|
|
26
|
+
try:
|
|
27
|
+
ver = version("keepassxc-cli")
|
|
28
|
+
except PackageNotFoundError:
|
|
29
|
+
ver = "unknown"
|
|
30
|
+
print(f"keepassxc-cli {ver}")
|
|
31
|
+
return 0
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keepassxc-cli
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: CLI for KeePassXC using the browser extension protocol with biometric unlock
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: keepassxc-browser-api==1.2.0
|
|
10
|
+
Requires-Dist: pyperclip==1.8.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
13
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
1
16
|
# keepassxc-cli
|
|
2
17
|
|
|
3
18
|
A command-line interface for [KeePassXC](https://keepassxc.org/) that communicates via the browser extension protocol, supporting biometric (TouchID/fingerprint) unlock on supported platforms.
|
|
@@ -148,6 +163,33 @@ keepassxc-cli mkdir "Work/Projects" # create Projects inside Work
|
|
|
148
163
|
|
|
149
164
|
Use `/`-separated paths to create nested groups. KeePassXC creates any missing path segments automatically.
|
|
150
165
|
|
|
166
|
+
#### `group-uuid` — Look up a group's UUID by path
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
keepassxc-cli group-uuid "Work"
|
|
170
|
+
keepassxc-cli group-uuid "Work/Projects"
|
|
171
|
+
keepassxc-cli group-uuid "Work/Projects" -j
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Returns the UUID for the group at the given path (relative to the database root). Useful for scripting — pipe the UUID into `add --group-uuid`.
|
|
175
|
+
|
|
176
|
+
JSON output (`-j`):
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"path": "Work/Projects",
|
|
180
|
+
"name": "Projects",
|
|
181
|
+
"uuid": "<uuid>"
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### `version` — Show the CLI version
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
keepassxc-cli version
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Does not require a running KeePassXC instance.
|
|
192
|
+
|
|
151
193
|
## Configuration
|
|
152
194
|
|
|
153
195
|
### CLI config (`~/.keepassxc/cli.json`)
|
|
@@ -21,6 +21,7 @@ keepassxc_cli/commands/__init__.py
|
|
|
21
21
|
keepassxc_cli/commands/add.py
|
|
22
22
|
keepassxc_cli/commands/clip.py
|
|
23
23
|
keepassxc_cli/commands/edit.py
|
|
24
|
+
keepassxc_cli/commands/group_uuid.py
|
|
24
25
|
keepassxc_cli/commands/lock.py
|
|
25
26
|
keepassxc_cli/commands/mkdir.py
|
|
26
27
|
keepassxc_cli/commands/rm.py
|
|
@@ -28,6 +29,7 @@ keepassxc_cli/commands/setup.py
|
|
|
28
29
|
keepassxc_cli/commands/show.py
|
|
29
30
|
keepassxc_cli/commands/status.py
|
|
30
31
|
keepassxc_cli/commands/totp.py
|
|
32
|
+
keepassxc_cli/commands/version.py
|
|
31
33
|
tests/conftest.py
|
|
32
34
|
tests/test_commands.py
|
|
33
35
|
tests/test_config.py
|
|
@@ -71,6 +71,7 @@ def mock_client():
|
|
|
71
71
|
client.get_logins.return_value = [make_entry()]
|
|
72
72
|
client.set_login.return_value = True
|
|
73
73
|
client.create_group.return_value = make_group(uuid="new-uuid", name="NewGroup")
|
|
74
|
+
client.get_database_groups.return_value = [make_group()]
|
|
74
75
|
client.get_totp.return_value = "123456"
|
|
75
76
|
client.delete_entry.return_value = True
|
|
76
77
|
client.lock_database.return_value = True
|
|
@@ -10,7 +10,7 @@ import pytest
|
|
|
10
10
|
from keepassxc_browser_api import Entry, BrowserConfig, Association
|
|
11
11
|
from keepassxc_cli.config import CliConfig
|
|
12
12
|
from keepassxc_cli.commands import (
|
|
13
|
-
setup, status, show, add, edit, rm, totp, clip, lock, mkdir,
|
|
13
|
+
setup, status, show, add, edit, rm, totp, clip, lock, mkdir, group_uuid, version,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
|
|
@@ -41,6 +41,7 @@ def make_args(**kwargs) -> argparse.Namespace:
|
|
|
41
41
|
"group_uuid": "",
|
|
42
42
|
"uuid": "abcdef12-0000-0000-0000-000000000000",
|
|
43
43
|
"name": "NewGroup",
|
|
44
|
+
"path": "Work",
|
|
44
45
|
}
|
|
45
46
|
defaults.update(kwargs)
|
|
46
47
|
return argparse.Namespace(**defaults)
|
|
@@ -287,3 +288,86 @@ class TestMkdirCommand:
|
|
|
287
288
|
args = make_args(name="MyGroup")
|
|
288
289
|
rc = mkdir.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
289
290
|
assert rc == 1
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
# --- group-uuid ---
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class TestGroupUuidCommand:
|
|
297
|
+
def _make_tree(self, mock_group):
|
|
298
|
+
from keepassxc_browser_api import Group
|
|
299
|
+
projects = mock_group(uuid="projects-uuid", name="Projects")
|
|
300
|
+
work = mock_group(uuid="work-uuid", name="Work", children=[projects])
|
|
301
|
+
root = mock_group(uuid="root-uuid", name="Root", children=[work])
|
|
302
|
+
return [root]
|
|
303
|
+
|
|
304
|
+
def test_found_top_level(self, mock_client, cli_config, browser_config, browser_config_path, capsys, mock_group):
|
|
305
|
+
mock_client.get_database_groups.return_value = self._make_tree(mock_group)
|
|
306
|
+
args = make_args(path="Work")
|
|
307
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
308
|
+
assert rc == 0
|
|
309
|
+
out = capsys.readouterr().out
|
|
310
|
+
assert "work-uuid" in out
|
|
311
|
+
assert "Work" in out
|
|
312
|
+
|
|
313
|
+
def test_found_nested_path(self, mock_client, cli_config, browser_config, browser_config_path, capsys, mock_group):
|
|
314
|
+
mock_client.get_database_groups.return_value = self._make_tree(mock_group)
|
|
315
|
+
args = make_args(path="Work/Projects")
|
|
316
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
317
|
+
assert rc == 0
|
|
318
|
+
out = capsys.readouterr().out
|
|
319
|
+
assert "projects-uuid" in out
|
|
320
|
+
|
|
321
|
+
def test_not_found(self, mock_client, cli_config, browser_config, browser_config_path, capsys, mock_group):
|
|
322
|
+
mock_client.get_database_groups.return_value = self._make_tree(mock_group)
|
|
323
|
+
args = make_args(path="Nonexistent")
|
|
324
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
325
|
+
assert rc == 1
|
|
326
|
+
err = capsys.readouterr().err
|
|
327
|
+
assert "not found" in err.lower()
|
|
328
|
+
|
|
329
|
+
def test_not_found_mid_path(self, mock_client, cli_config, browser_config, browser_config_path, capsys, mock_group):
|
|
330
|
+
mock_client.get_database_groups.return_value = self._make_tree(mock_group)
|
|
331
|
+
args = make_args(path="Work/Nope/Projects")
|
|
332
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
333
|
+
assert rc == 1
|
|
334
|
+
|
|
335
|
+
def test_json_output(self, mock_client, cli_config, browser_config, browser_config_path, capsys, mock_group):
|
|
336
|
+
import json
|
|
337
|
+
mock_client.get_database_groups.return_value = self._make_tree(mock_group)
|
|
338
|
+
args = make_args(path="Work/Projects")
|
|
339
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path, fmt="json")
|
|
340
|
+
assert rc == 0
|
|
341
|
+
data = json.loads(capsys.readouterr().out)
|
|
342
|
+
assert data["path"] == "Work/Projects"
|
|
343
|
+
assert data["name"] == "Projects"
|
|
344
|
+
assert data["uuid"] == "projects-uuid"
|
|
345
|
+
|
|
346
|
+
def test_get_database_groups_failure(self, mock_client, cli_config, browser_config, browser_config_path, capsys):
|
|
347
|
+
mock_client.get_database_groups.return_value = []
|
|
348
|
+
args = make_args(path="Work")
|
|
349
|
+
rc = group_uuid.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
350
|
+
assert rc == 1
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
# --- version ---
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class TestVersionCommand:
|
|
357
|
+
def test_prints_version(self, mock_client, cli_config, browser_config, browser_config_path, capsys):
|
|
358
|
+
with patch("keepassxc_cli.commands.version.version", return_value="1.3.0"):
|
|
359
|
+
args = make_args()
|
|
360
|
+
rc = version.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
361
|
+
assert rc == 0
|
|
362
|
+
out = capsys.readouterr().out
|
|
363
|
+
assert "keepassxc-cli" in out
|
|
364
|
+
assert "1.3.0" in out
|
|
365
|
+
|
|
366
|
+
def test_package_not_found(self, mock_client, cli_config, browser_config, browser_config_path, capsys):
|
|
367
|
+
from importlib.metadata import PackageNotFoundError
|
|
368
|
+
with patch("keepassxc_cli.commands.version.version", side_effect=PackageNotFoundError):
|
|
369
|
+
args = make_args()
|
|
370
|
+
rc = version.run(mock_client, args, cli_config, browser_config, browser_config_path)
|
|
371
|
+
assert rc == 0
|
|
372
|
+
out = capsys.readouterr().out
|
|
373
|
+
assert "unknown" in out
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|