commit 29faa2ce60140cf199d65e8b73994509972e83be
parent 901a0bdeaf60fcd2a584046163b77a6b30951c89
Author: Erik Loualiche <eloualiche@users.noreply.github.com>
Date: Sun, 4 May 2025 09:58:07 -0500
Merge pull request #1 from eloualiche/feature/2fa-authentication
Feature/2fa authentication
Diffstat:
3 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/esync/cli.py b/esync/cli.py
@@ -190,15 +190,22 @@ def sync(
if not local or not remote:
console.print("[red]Both local and remote paths are required with --quick option[/]")
raise typer.Exit(1)
+
+ local_path = Path(local).expanduser().resolve()
+ local_path.mkdir(parents=True, exist_ok=True)
+ remote_path = Path(remote).expanduser().resolve()
# Create quick configuration
- config = create_config_for_paths(local, remote, watcher.value if watcher else None)
+ config = create_config_for_paths(local_path, remote_path, watcher.value if watcher else None)
if not quiet:
console.print("[bold blue]Using quick sync configuration[/]")
-
# Display effective configuration
console.print("\n[bold]Quick Sync Configuration:[/]")
display_config(config)
+
+
+
+ # else we branch to configuration where we use the configuration toml file
else:
# Find and load config file (original flow)
config_path = config_file or find_config_file()
@@ -213,7 +220,7 @@ def sync(
console.print(f"[bold blue]Loading configuration from:[/] {config_path.resolve()}")
try:
- config = load_config(config_path)
+ config = load_config(config_path) # config is the toml parsed
except Exception as e:
console.print(f"[red]Failed to load config: {e}[/]")
raise typer.Exit(1)
@@ -221,17 +228,33 @@ def sync(
sync_data = config.model_dump().get('sync', {})
# Validate required sections
- if 'local' not in sync_data or 'remote' not in sync_data:
- console.print("[red]Invalid configuration: 'sync.local' and 'sync.remote' sections required[/]")
+ if ('local' not in sync_data) and (not local):
+ console.print(f"[red]Invalid configuration: specifications for local required ('sync.local' in {config_path} or -l option)[/]")
+ raise typer.Exit(1)
+ if local:
+ local_path = local # if local is provided via CLI, use it and override the config
+ else:
+ local_path = sync_data['local']['path']
+
+ local_path = Path(local_path).expanduser().resolve()
+ local_path.mkdir(parents=True, exist_ok=True)
+
+
+ if ('remote' not in sync_data) and (not remote):
+ console.print(f"[red]Invalid configuration: specifications for remote required ('sync.remote' in {config_path} or -r option)[/]")
raise typer.Exit(1)
-
- # Override config with CLI options
- if local:
- sync_data['local']['path'] = local
if remote:
- sync_data['remote']['path'] = remote
+ remote_path = remote
+ else:
+ remote_path = sync_data['remote']['path']
+ remote_path = Path(remote_path).expanduser().resolve()
+
if watcher:
config.settings.esync.watcher = watcher.value
+
+ # update the config based on potential overrides above
+ config.sync['local']['path'] = str(local_path)
+ config.sync['remote']['path'] = str(remote_path)
# Display effective configuration
if not quiet:
@@ -241,9 +264,8 @@ def sync(
# Get sync data from config
sync_data = config.model_dump().get('sync', {})
- # Prepare paths
- local_path = Path(sync_data['local']['path']).expanduser().resolve()
- local_path.mkdir(parents=True, exist_ok=True)
+ # remote_path.mkdir(parents=True, exist_ok=True)
+
# Create sync configuration
remote_config = sync_data['remote']
@@ -251,7 +273,7 @@ def sync(
if "ssh" in remote_config:
sync_config = SyncConfig(
- target=remote_config["path"],
+ target=remote_config['path'],
ssh=SSHConfig(**remote_config["ssh"]),
ignores=rsync_settings.ignore + config.settings.esync.ignore,
backup_enabled=rsync_settings.backup_enabled,
@@ -260,10 +282,8 @@ def sync(
human_readable=rsync_settings.human_readable
)
else:
- remote_path = Path(remote_config["path"]).expanduser().resolve()
- remote_path.mkdir(parents=True, exist_ok=True)
sync_config = SyncConfig(
- target=remote_path,
+ target=remote_config.path,
ignores=rsync_settings.ignore + config.settings.esync.ignore,
backup_enabled=rsync_settings.backup_enabled,
backup_dir=rsync_settings.backup_dir,
diff --git a/esync/config.py b/esync/config.py
@@ -11,6 +11,9 @@ class SSHConfig(BaseModel):
host: str
user: Optional[str] = None
port: int = 22
+ allow_password_auth: bool = True
+ identity_file: Optional[str] = None
+ interactive_auth: bool = True # Enable interactive authentication prompts
class SyncConfig(BaseModel):
target: Union[Path, str]
diff --git a/readme.md b/readme.md
@@ -0,0 +1,6 @@
+Usage
+
+quick sync from one folder to a remote ...
+```bash
+esync sync -q -l ./local -r user@host:/path
+```+
\ No newline at end of file