amap-cli 0.1.1__tar.gz → 0.1.2__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.
- {amap_cli-0.1.1 → amap_cli-0.1.2}/PKG-INFO +1 -1
- {amap_cli-0.1.1 → amap_cli-0.1.2}/pyproject.toml +1 -1
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/config.py +69 -11
- {amap_cli-0.1.1 → amap_cli-0.1.2}/uv.lock +1 -1
- {amap_cli-0.1.1 → amap_cli-0.1.2}/.gitignore +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/.trae/specs/build-amap-cli/checklist.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/.trae/specs/build-amap-cli/spec.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/.trae/specs/build-amap-cli/tasks.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/README.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/amap-gui-reference.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/docs/manual-verification.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/skills/amap-cli/SKILL.md +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/__init__.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/__main__.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/api.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/cli.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/distance.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/errors.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/geocode.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/output.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/params.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/route.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/search_poi.py +0 -0
- {amap_cli-0.1.1 → amap_cli-0.1.2}/src/amap_cli/skill.py +0 -0
|
@@ -81,27 +81,67 @@ def get_config_path() -> Path:
|
|
|
81
81
|
return get_config_dir() / CONFIG_FILE_NAME
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
def _merge_error_details(
|
|
85
|
+
current: Any | None,
|
|
86
|
+
*,
|
|
87
|
+
path: Path,
|
|
88
|
+
operation: str | None = None,
|
|
89
|
+
exc: BaseException | None = None,
|
|
90
|
+
) -> dict[str, Any]:
|
|
91
|
+
"""Attach config file context to an error payload."""
|
|
92
|
+
details = current.copy() if isinstance(current, dict) else {}
|
|
93
|
+
details["path"] = str(path)
|
|
94
|
+
if operation is not None:
|
|
95
|
+
details["operation"] = operation
|
|
96
|
+
if exc is not None:
|
|
97
|
+
details["type"] = type(exc).__name__
|
|
98
|
+
details["reason"] = str(exc)
|
|
99
|
+
return details
|
|
100
|
+
|
|
101
|
+
|
|
84
102
|
def load_config(*, required: bool = False) -> AmapConfig | None:
|
|
85
103
|
"""Load config from disk, optionally requiring it to exist."""
|
|
86
104
|
path = get_config_path()
|
|
87
|
-
|
|
105
|
+
try:
|
|
106
|
+
exists = path.exists()
|
|
107
|
+
except OSError as exc:
|
|
108
|
+
raise ConfigError(
|
|
109
|
+
"检查配置文件状态失败。",
|
|
110
|
+
details=_merge_error_details(None, path=path, operation="stat", exc=exc),
|
|
111
|
+
) from exc
|
|
112
|
+
|
|
113
|
+
if not exists:
|
|
88
114
|
if required:
|
|
89
115
|
raise MissingConfigError(
|
|
90
|
-
"未找到高德 API 配置,请先执行 `amap-cli config set --api-key <KEY>`。"
|
|
116
|
+
"未找到高德 API 配置,请先执行 `amap-cli config set --api-key <KEY>`。",
|
|
117
|
+
details=_merge_error_details(None, path=path),
|
|
91
118
|
)
|
|
92
119
|
return None
|
|
93
120
|
|
|
94
121
|
try:
|
|
95
122
|
raw = json.loads(path.read_text(encoding="utf-8"))
|
|
96
123
|
except json.JSONDecodeError as exc:
|
|
97
|
-
raise ConfigError(
|
|
124
|
+
raise ConfigError(
|
|
125
|
+
"配置文件不是合法的 JSON。",
|
|
126
|
+
details=_merge_error_details(None, path=path, operation="read", exc=exc),
|
|
127
|
+
) from exc
|
|
98
128
|
except OSError as exc:
|
|
99
|
-
raise ConfigError(
|
|
129
|
+
raise ConfigError(
|
|
130
|
+
"读取配置文件失败。",
|
|
131
|
+
details=_merge_error_details(None, path=path, operation="read", exc=exc),
|
|
132
|
+
) from exc
|
|
100
133
|
|
|
101
134
|
if not isinstance(raw, dict):
|
|
102
|
-
raise ConfigError(
|
|
135
|
+
raise ConfigError(
|
|
136
|
+
"配置文件内容格式无效。",
|
|
137
|
+
details=_merge_error_details(None, path=path),
|
|
138
|
+
)
|
|
103
139
|
|
|
104
|
-
|
|
140
|
+
try:
|
|
141
|
+
return AmapConfig.from_dict(raw)
|
|
142
|
+
except ConfigError as exc:
|
|
143
|
+
exc.details = _merge_error_details(exc.details, path=path)
|
|
144
|
+
raise
|
|
105
145
|
|
|
106
146
|
|
|
107
147
|
def save_config(
|
|
@@ -131,11 +171,29 @@ def save_config(
|
|
|
131
171
|
config.timeout_seconds = float(timeout_seconds)
|
|
132
172
|
|
|
133
173
|
path = get_config_path()
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
174
|
+
try:
|
|
175
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
176
|
+
except OSError as exc:
|
|
177
|
+
raise ConfigError(
|
|
178
|
+
"创建配置目录失败。",
|
|
179
|
+
details=_merge_error_details(
|
|
180
|
+
None,
|
|
181
|
+
path=path.parent,
|
|
182
|
+
operation="create_dir",
|
|
183
|
+
exc=exc,
|
|
184
|
+
),
|
|
185
|
+
) from exc
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
path.write_text(
|
|
189
|
+
json.dumps(config.to_dict(), ensure_ascii=False, indent=2) + "\n",
|
|
190
|
+
encoding="utf-8",
|
|
191
|
+
)
|
|
192
|
+
except OSError as exc:
|
|
193
|
+
raise ConfigError(
|
|
194
|
+
"写入配置文件失败。",
|
|
195
|
+
details=_merge_error_details(None, path=path, operation="write", exc=exc),
|
|
196
|
+
) from exc
|
|
139
197
|
|
|
140
198
|
if os.name != "nt":
|
|
141
199
|
try:
|
|
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
|