fix: single load in remove, use dataclasses.replace in config_cmd, add remove-running test
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import click
|
import click
|
||||||
|
from dataclasses import replace
|
||||||
from autossh_mgr.config import (
|
from autossh_mgr.config import (
|
||||||
TunnelConfig, get_config_dir, ensure_dirs,
|
TunnelConfig, get_config_dir, ensure_dirs,
|
||||||
load_tunnels, save_tunnels, get_tunnel,
|
load_tunnels, save_tunnels, get_tunnel,
|
||||||
@@ -98,14 +99,15 @@ def add(
|
|||||||
def remove(ctx, name):
|
def remove(ctx, name):
|
||||||
"""Remove a tunnel configuration."""
|
"""Remove a tunnel configuration."""
|
||||||
config_dir = ctx.obj["config_dir"]
|
config_dir = ctx.obj["config_dir"]
|
||||||
get_tunnel(config_dir, name) # raises if not found
|
tunnels = load_tunnels(config_dir)
|
||||||
|
if not any(t.name == name for t in tunnels):
|
||||||
|
raise click.ClickException(f"No tunnel named '{name}'")
|
||||||
status = get_status(config_dir, name)
|
status = get_status(config_dir, name)
|
||||||
if status.state == "running":
|
if status.state == "running":
|
||||||
raise click.ClickException(f"Stop '{name}' before removing it")
|
raise click.ClickException(f"Stop '{name}' before removing it")
|
||||||
if not click.confirm(f"Remove tunnel '{name}'?"):
|
if not click.confirm(f"Remove tunnel '{name}'?"):
|
||||||
return
|
return
|
||||||
tunnels = [t for t in load_tunnels(config_dir) if t.name != name]
|
save_tunnels(config_dir, [t for t in tunnels if t.name != name])
|
||||||
save_tunnels(config_dir, tunnels)
|
|
||||||
click.echo(f"Removed tunnel '{name}'")
|
click.echo(f"Removed tunnel '{name}'")
|
||||||
|
|
||||||
|
|
||||||
@@ -149,13 +151,8 @@ def config_cmd(ctx, name, key, value):
|
|||||||
f"Invalid value for '{key}': expected {_FIELD_TYPES[key].__name__}"
|
f"Invalid value for '{key}': expected {_FIELD_TYPES[key].__name__}"
|
||||||
)
|
)
|
||||||
tunnels = load_tunnels(config_dir)
|
tunnels = load_tunnels(config_dir)
|
||||||
found = False
|
if not any(t.name == name for t in tunnels):
|
||||||
for t in tunnels:
|
|
||||||
if t.name == name:
|
|
||||||
setattr(t, key, typed_value)
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
if not found:
|
|
||||||
raise click.ClickException(f"No tunnel named '{name}'")
|
raise click.ClickException(f"No tunnel named '{name}'")
|
||||||
|
tunnels = [replace(t, **{key: typed_value}) if t.name == name else t for t in tunnels]
|
||||||
save_tunnels(config_dir, tunnels)
|
save_tunnels(config_dir, tunnels)
|
||||||
click.echo(f"Updated {name}.{key} = {typed_value}")
|
click.echo(f"Updated {name}.{key} = {typed_value}")
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
from datetime import datetime, timezone
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
from autossh_mgr.cli import cli
|
from autossh_mgr.cli import cli
|
||||||
from autossh_mgr.config import load_tunnels, save_tunnels
|
from autossh_mgr.config import load_tunnels, save_tunnels
|
||||||
|
from autossh_mgr.process import write_pid_file
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
@@ -126,3 +129,12 @@ def test_config_invalid_type(runner, config_dir, sample_tunnel):
|
|||||||
save_tunnels(config_dir, [sample_tunnel])
|
save_tunnels(config_dir, [sample_tunnel])
|
||||||
result = runner.invoke(cli, ["config", "web-service", "port", "notanumber"])
|
result = runner.invoke(cli, ["config", "web-service", "port", "notanumber"])
|
||||||
assert result.exit_code != 0
|
assert result.exit_code != 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_running_tunnel_fails(runner, config_dir, sample_tunnel):
|
||||||
|
save_tunnels(config_dir, [sample_tunnel])
|
||||||
|
write_pid_file(config_dir, "web-service", os.getpid(), datetime.now(timezone.utc))
|
||||||
|
result = runner.invoke(cli, ["remove", "web-service"], input="y\n")
|
||||||
|
assert result.exit_code != 0
|
||||||
|
assert "Stop" in result.output
|
||||||
|
assert len(load_tunnels(config_dir)) == 1
|
||||||
|
|||||||
Reference in New Issue
Block a user