diff --git a/workspaces.py b/workspaces.py index a9bb772..b9ce726 100755 --- a/workspaces.py +++ b/workspaces.py @@ -868,6 +868,7 @@ def choose_files_for_wip(repo_path: Path, changes: List[Tuple[str, str]]) -> Lis return selected_files + @app.command("wip") def wip_workspace( ctx: typer.Context, @@ -894,48 +895,9 @@ def wip_workspace( if not ws_dir.exists(): console.print(f"[red]Workspace '{ws_dir.name}' does not exist at {ws_dir}[/red]") raise typer.Exit(1) + title, _desc = read_workspace_readme(ws_dir) commit_message = f"wip: {title or ws_dir.name}" - commit_workspace(ctx, workspace, message=commit_message) - -@app.command("commit") -def commit_workspace( - ctx: typer.Context, - workspace: Optional[str] = typer.Option( - None, - "--workspace", - "-w", - help=( - "Workspace directory name to WIP-commit. " - "If omitted, uses the workspace containing the current directory." - ), - ), - message: Optional[str] = typer.Option( - None, - "--message", - "-m", - help="Commit message to use.", - ), -): - """ - For each repo in the workspace: - - - Show list of changed files. - - Ask whether to stage all, none, or pick some files. - - Stage chosen files. - """ - if not message: - console.print( - "[red]No commit message provided. Exiting.[/red]", - file=sys.stderr, - ) - raise typer.Exit(1) - _settings, _repos_dir, workspaces_dir = get_ctx_paths(ctx) - ws_dir = find_workspace_dir(workspaces_dir, workspace) - if not ws_dir.exists(): - console.print(f"[red]Workspace '{ws_dir.name}' does not exist at {ws_dir}[/red]") - raise typer.Exit(1) - title, _desc = read_workspace_readme(ws_dir) worktrees: List[Path] = [] for child in sorted(p for p in ws_dir.iterdir() if p.is_dir()): @@ -976,14 +938,14 @@ def commit_workspace( continue # Commit - code, _out, err = run_cmd(["git", "commit", "-m", message], cwd=wt) + code, _out, err = run_cmd(["git", "commit", "-m", commit_message], cwd=wt) if code != 0: console.print( f"[red]Failed to commit in {wt.name}:[/red]\n{err}" ) else: console.print( - f" [green]Created commit in {wt.name}:[/green] '{message}'" + f" [green]Created WIP commit in {wt.name}:[/green] '{commit_message}'" ) @@ -1091,12 +1053,8 @@ def status_workspace( title, desc = read_workspace_readme(ws_dir) - # if desc: - # console.print(Panel(desc, title=title)) - table = Table( - title=f"Status for workspace:'{title}'\n(dir: {ws_dir.name})\n\n{desc}", - title_justify="left", + title=f"Status for workspace '{title}' (dir: {ws_dir.name})", show_lines=False, ) table.add_column("Repo (dir)", style="bold") @@ -1104,11 +1062,6 @@ def status_workspace( table.add_column("Ahead/Behind/Dirty") table.add_column("Changed Files", justify="right") - files_table = Table(show_lines=False) - files_table.add_column("Repo (dir)", style="bold") - files_table.add_column("File", justify="left") - files_table.add_column("Status", justify="right") - worktrees: List[Path] = [] for child in sorted(p for p in ws_dir.iterdir() if p.is_dir()): if child.name.lower() == "readme.md": @@ -1132,96 +1085,10 @@ def status_workspace( str(len(changes)), ) - if changes: - for f, s in changes: - files_table.add_row(wt.name, f, s) - console.print(table) - console.print("\nFiles with changes:") - if files_table.rows: - console.print(files_table) - -@app.command("diff") -def diff_workspace( - ctx: typer.Context, - workspace: Optional[str] = typer.Option( - None, - "--workspace", - "-w", - help=( - "Workspace directory name to diff. " - "If omitted, uses the workspace containing the current directory." - ), - ), - staged: bool = typer.Option( - False, - "--staged", - "-s", - help="Show only staged changes (git diff --cached).", - ), -): - """ - Show git diff for all repos in the workspace. - - - If --staged: uses `git diff --cached` (only staged changes). - - Otherwise: uses `git diff` (staged + unstaged). - """ - _settings, _repos_dir, workspaces_dir = get_ctx_paths(ctx) - ws_dir = find_workspace_dir(workspaces_dir, workspace) - if not ws_dir.exists(): - console.print(f"[red]Workspace '{ws_dir.name}' does not exist at {ws_dir}[/red]") - raise typer.Exit(1) - - title, _desc = read_workspace_readme(ws_dir) - console.print( - f"Showing diffs for workspace [bold]{title or ws_dir.name}[/bold] (dir: {ws_dir.name})" - ) - - # Collect worktrees (repos) in this workspace - worktrees: List[Path] = [] - for child in sorted(p for p in ws_dir.iterdir() if p.is_dir()): - if child.name.lower() == "readme.md": - continue - if not ensure_git_repo(child): - continue - worktrees.append(child) - - if not worktrees: - console.print(f"[yellow]No repos in workspace {ws_dir.name}[/yellow]") - raise typer.Exit(0) - - any_diffs = False - - for wt in worktrees: - # Quick check: skip repos with no changes at all - changes = git_status_porcelain(wt) - if not changes: - continue - - any_diffs = True - console.rule(f"[bold]{wt.name}[/bold]") - - cmd = ["git", "diff"] - if staged: - cmd.append("--cached") - - code, out, err = run_cmd(cmd, cwd=wt) - if code != 0: - console.print( - f"[red]Failed to get diff for {wt.name}:[/red]\n{err}" - ) - continue - - if not out.strip(): - console.print("[dim]No diff output.[/dim]") - else: - # Use markup=False so diff characters like [ ] don't get eaten by Rich - console.print(out, markup=False) - - if not any_diffs: - console.print("[green]No changes to diff in any repo.[/green]") - + if desc: + console.print(Panel(desc, title="Workspace description")) def not_in_tmux() -> bool: """Return True if not inside tmux or zellij.""" @@ -1423,5 +1290,62 @@ def attach( app.add_typer(tmux_app) +# @app.command() +# def main( +# dir: Optional[Path] = typer.Argument( +# None, +# help="Base directory containing projects. If omitted, auto-attach or --start behavior.", +# ), +# start: bool = typer.Option( +# False, +# "--start", +# help="Start a new session based on the current directory.", +# ), +# ): +# # Replicate initial "DIR=$1" and attach-or-start logic +# # If no args and no --start +# if dir is None and not start: +# if not_in_tmux(): +# # Try to attach to an existing session +# attach_proc = run_tmux(["attach"]) +# if attach_proc.returncode == 0: +# # Successfully attached; exit like the bash script +# raise typer.Exit(1) +# # If attach failed, fall through to start mode +# start = True +# else: +# # In tmux and no dir/start: nothing to do +# raise typer.Exit(1) +# +# # Figure out session_name and path_name +# if start: +# path_name = Path.cwd() +# session_name = path_name.name.replace(".", "_") +# else: +# if dir is None: +# typer.echo("[ta] DIR argument is required unless --start is used.", err=True) +# raise typer.Exit(1) +# +# dir = dir.expanduser().resolve() +# project = pick_project(dir) +# if not project: +# # cancelled or error +# raise typer.Exit(1) +# +# session_name = project.replace(".", "_") +# path_name = (dir / project).resolve() +# +# typer.echo(f'session name is "{session_name}"') +# typer.echo(f"path name is {path_name}") +# +# if not session_name: +# raise typer.Exit(1) +# +# # Try main attach/create flow; on failure, fall back +# ok = create_if_needed_and_attach(session_name, path_name, start_mode=start) +# if not ok: +# attach_to_first_session() +# + if __name__ == "__main__": app()