proxyctl 0.1.1__tar.gz → 0.1.3__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.
@@ -1,9 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxyctl
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Proxy configuration lifecycle management for macOS and Linux
5
5
  Project-URL: Homepage, https://github.com/crhan/proxyctl
6
6
  Project-URL: Issues, https://github.com/crhan/proxyctl/issues
7
+ Project-URL: Changelog, https://github.com/crhan/proxyctl/blob/main/CHANGELOG.md
8
+ Project-URL: Repository, https://github.com/crhan/proxyctl
7
9
  Author-email: crhan <crhan123@gmail.com>
8
10
  License: MIT
9
11
  License-File: LICENSE
@@ -225,6 +227,10 @@ python3 bin/proxyctl status
225
227
  export PROXYCTL_DEBUG=1
226
228
  ```
227
229
 
230
+ ## Changelog
231
+
232
+ 版本变更记录见 [CHANGELOG.md](https://github.com/crhan/proxyctl/blob/main/CHANGELOG.md)。
233
+
228
234
  ## License
229
235
 
230
236
  MIT
@@ -198,6 +198,10 @@ python3 bin/proxyctl status
198
198
  export PROXYCTL_DEBUG=1
199
199
  ```
200
200
 
201
+ ## Changelog
202
+
203
+ 版本变更记录见 [CHANGELOG.md](https://github.com/crhan/proxyctl/blob/main/CHANGELOG.md)。
204
+
201
205
  ## License
202
206
 
203
207
  MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "proxyctl"
3
- version = "0.1.1"
3
+ version = "0.1.3"
4
4
  description = "Proxy configuration lifecycle management for macOS and Linux"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -27,6 +27,8 @@ dependencies = ["pyyaml>=6.0"]
27
27
  [project.urls]
28
28
  Homepage = "https://github.com/crhan/proxyctl"
29
29
  Issues = "https://github.com/crhan/proxyctl/issues"
30
+ Changelog = "https://github.com/crhan/proxyctl/blob/main/CHANGELOG.md"
31
+ Repository = "https://github.com/crhan/proxyctl"
30
32
 
31
33
  [project.scripts]
32
34
  proxyctl = "proxyctl.cli:main"
@@ -1,3 +1,3 @@
1
1
  """proxyctl — Proxy configuration lifecycle management."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.2"
@@ -518,9 +518,33 @@ def _wait_ready(backend: Backend):
518
518
  time.sleep(3)
519
519
 
520
520
 
521
+ # ── 路由钩子调度 ──────────────────────────────────────────────────────────────
522
+
523
+ def _apply_route_hooks(registry, ctx: dict, action: str) -> None:
524
+ """调度所有插件的 RouteHook。action ∈ {'activate', 'deactivate'}。
525
+
526
+ 单个 hook 失败只打 warning,不中断主流程——路由注入是辅助优化,
527
+ 不能让某个插件挂了拖死 start/stop。
528
+ """
529
+ if registry is None:
530
+ return
531
+ hooks = registry.collect("route_hooks")
532
+ for h in hooks:
533
+ fn = getattr(h, action, None)
534
+ if fn is None:
535
+ continue
536
+ try:
537
+ fn(ctx)
538
+ except Exception as e:
539
+ sys.stderr.write(
540
+ f"[route_hook warning] {h.name}.{action} failed: "
541
+ f"{type(e).__name__}: {e}\n"
542
+ )
543
+
544
+
521
545
  # ── 命令:start ───────────────────────────────────────────────────────────────
522
546
 
523
- def cmd_start(backend: Backend, config: dict):
547
+ def cmd_start(backend: Backend, config: dict, registry=None):
524
548
  r = service_start(backend, config)
525
549
  if r.returncode != 0:
526
550
  print(f"{RED}✗{NC} {backend.name} 启动失败")
@@ -538,10 +562,18 @@ def cmd_start(backend: Backend, config: dict):
538
562
  proxy_activate()
539
563
  print("系统代理 → 127.0.0.1:7890 (已激活)")
540
564
 
565
+ _apply_route_hooks(registry,
566
+ {"engine": backend.name, "config": config, "phase": "start"},
567
+ "activate")
568
+
541
569
 
542
570
  # ── 命令:stop ────────────────────────────────────────────────────────────────
543
571
 
544
- def cmd_stop(backend: Backend, config: dict):
572
+ def cmd_stop(backend: Backend, config: dict, registry=None):
573
+ _apply_route_hooks(registry,
574
+ {"engine": backend.name, "config": config, "phase": "stop"},
575
+ "deactivate")
576
+
545
577
  if IS_MACOS:
546
578
  dns_lock_stop(config)
547
579
  dns_deactivate(config)
@@ -554,7 +586,7 @@ def cmd_stop(backend: Backend, config: dict):
554
586
 
555
587
  # ── 命令:restart ─────────────────────────────────────────────────────────────
556
588
 
557
- def cmd_restart(backend: Backend, config: dict, *, clean: bool = False):
589
+ def cmd_restart(backend: Backend, config: dict, *, clean: bool = False, registry=None):
558
590
  if clean and os.path.isfile(backend.cache_file):
559
591
  os.remove(backend.cache_file)
560
592
  # 人工介入后清掉 watchdog 的失败状态,避免误判为"还在触顶窗口内"
@@ -578,10 +610,14 @@ def cmd_restart(backend: Backend, config: dict, *, clean: bool = False):
578
610
  else:
579
611
  proxy_deactivate()
580
612
 
613
+ _apply_route_hooks(registry,
614
+ {"engine": backend.name, "config": config, "phase": "restart"},
615
+ "activate")
616
+
581
617
 
582
618
  # ── 命令:fix ─────────────────────────────────────────────────────────────────
583
619
 
584
- def cmd_fix(backend: Backend, config: dict):
620
+ def cmd_fix(backend: Backend, config: dict, registry=None):
585
621
  """修复引擎状态:运行中则重注入 DNS/代理,已停止则还原系统配置。"""
586
622
  api_base = config.get("api_base", DEFAULTS["api_base"])
587
623
  api_secret = config.get("api_secret", "")
@@ -602,6 +638,11 @@ def cmd_fix(backend: Backend, config: dict):
602
638
  if get_mode(backend) == "proxy":
603
639
  proxy_activate()
604
640
  print(f" {GREEN}✓{NC} 系统代理 → 127.0.0.1:7890")
641
+
642
+ _apply_route_hooks(registry,
643
+ {"engine": backend.name, "config": config,
644
+ "phase": "fix"},
645
+ "activate")
605
646
  else:
606
647
  print(f"{BOLD}[引擎运行中] 尝试热重载配置{NC}")
607
648
 
@@ -1176,7 +1217,7 @@ def cmd_env(config: dict, unset: bool = False):
1176
1217
 
1177
1218
  # ── 帮助 ──────────────────────────────────────────────────────────────────────
1178
1219
 
1179
- VERSION = "0.1.1"
1220
+ VERSION = "0.1.3"
1180
1221
 
1181
1222
  def cmd_help(verbose: bool = False):
1182
1223
  """打印帮助信息
@@ -1280,13 +1321,13 @@ def main():
1280
1321
  cmd = sys.argv[1] if len(sys.argv) > 1 else "status"
1281
1322
 
1282
1323
  if cmd == "start":
1283
- cmd_start(backend, config)
1324
+ cmd_start(backend, config, registry=registry)
1284
1325
  elif cmd == "stop":
1285
- cmd_stop(backend, config)
1326
+ cmd_stop(backend, config, registry=registry)
1286
1327
  elif cmd == "restart":
1287
- cmd_restart(backend, config)
1328
+ cmd_restart(backend, config, registry=registry)
1288
1329
  elif cmd == "restart-clean":
1289
- cmd_restart(backend, config, clean=True)
1330
+ cmd_restart(backend, config, clean=True, registry=registry)
1290
1331
  elif cmd == "status":
1291
1332
  from proxyctl.status import cmd_status
1292
1333
  mode_str = get_mode(backend)
@@ -1303,7 +1344,7 @@ def main():
1303
1344
  default_groups = registry.collect("check_groups") if registry else None
1304
1345
  cmd_bench(api_base, api_secret, bench_groups, default_groups=default_groups)
1305
1346
  elif cmd == "fix":
1306
- cmd_fix(backend, config)
1347
+ cmd_fix(backend, config, registry=registry)
1307
1348
  elif cmd == "recover":
1308
1349
  cmd_recover(backend, config)
1309
1350
  elif cmd == "dns-lock":
File without changes
File without changes
File without changes
File without changes
File without changes