diff --git a/binder b/binder index 8a9637c25..f905de020 100755 --- a/binder +++ b/binder @@ -1092,15 +1092,25 @@ class BookBinder: console.print(f"[blue]ℹ️ Current branch: {current_branch}[/blue]") console.print("[blue]ℹ️ Publishing requires being on main branch with latest dev changes[/blue]") console.print() - console.print("[yellow]Move to main branch and pull in dev changes? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Switch to main and merge dev changes (recommended)") + console.print("[red] n/no[/red] - Cancel publishing (default)") + console.print("[yellow]Move to main branch and pull in dev changes? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: # Step 1: Handle uncommitted changes if changes_count > 0: console.print("[yellow]⚠️ You have uncommitted changes on current branch[/yellow]") - console.print("[yellow]Commit current changes before switching? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Commit changes before switching") + console.print("[red] n/no[/red] - Cancel (cannot switch with uncommitted changes) [default]") + console.print("[yellow]Commit current changes before switching? [y/N] [default: N]: [/yellow]", end="") commit_choice = input().strip().lower() + if not commit_choice: + commit_choice = 'n' if commit_choice in ['y', 'yes']: console.print("[white]Commit message [fix: update before switching to main]: [/white]", end="") commit_msg = input().strip() or "fix: update before switching to main" @@ -1143,8 +1153,13 @@ class BookBinder: return False elif changes_count > 0: console.print("[yellow]⚠️ You have uncommitted changes[/yellow]") - console.print("[yellow]Commit changes before continuing? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Commit and push changes before publishing") + console.print("[red] n/no[/red] - Cancel publishing (cannot continue with uncommitted changes) [default]") + console.print("[yellow]Commit changes before continuing? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: console.print("[white]Commit message [fix: update before publishing]: [/white]", end="") commit_msg = input().strip() or "fix: update before publishing" @@ -1183,8 +1198,10 @@ class BookBinder: console.print() console.print("[white]What type of changes are you publishing?[/white]") - console.print("[white]Select option [1-4] [2 for minor]: [/white]", end="") - choice = input().strip() or "2" + console.print("[white]Select option [1-4] [default: 2 for minor]: [/white]", end="") + choice = input().strip() + if not choice: + choice = "2" release_types = ["patch", "minor", "major", "custom"] try: @@ -1217,8 +1234,13 @@ class BookBinder: console.print("[dim] This will delete the existing tag from both local and remote repositories[/dim]") console.print("[dim] and recreate it with the new release[/dim]") console.print() - console.print("[yellow]Delete existing tag and recreate? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Delete existing tag and recreate with new release") + console.print("[red] n/no[/red] - Cancel publishing (keep existing tag) [default]") + console.print("[yellow]Delete existing tag and recreate? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: console.print("[purple]🔄 Deleting existing tag...[/purple]") self._delete_version(new_version) @@ -1232,8 +1254,10 @@ class BookBinder: console.print() console.print("[bold white]📝 Release Description:[/bold white]") console.print("[dim] This will appear in the GitHub release and help users understand what changed[/dim]") - console.print("[white]Enter description [Content updates and improvements]: [/white]", end="") - description = input().strip() or "Content updates and improvements" + console.print("[white]Enter description [default: Content updates and improvements]: [/white]", end="") + description = input().strip() + if not description: + description = "Content updates and improvements" return { 'version': new_version, @@ -1269,8 +1293,13 @@ class BookBinder: console.print("[green] • Create GitHub release with PDF (optional)[/green]") console.print() - console.print("[yellow]Proceed with publishing? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Proceed with publishing to production") + console.print("[red] n/no[/red] - Cancel publishing [default]") + console.print("[yellow]Proceed with publishing? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: return True @@ -1300,8 +1329,13 @@ class BookBinder: console.print() console.print("[white]Reuse existing builds? This will skip the build phase and save time.[/white]") - console.print("[yellow]Reuse existing builds? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Use existing builds (faster)") + console.print("[blue] n/no[/blue] - Rebuild from scratch (slower, fresher) [default]") + console.print("[yellow]Reuse existing builds? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: console.print("[blue]✅ Using existing builds[/blue]") @@ -1315,8 +1349,13 @@ class BookBinder: console.print("[dim] Uses Ghostscript with /ebook settings to reduce file size[/dim]") console.print("[dim] Good balance between size and quality for web distribution[/dim]") console.print(f"[blue] Current PDF size: {size_mb:.1f} MB[/blue]") - console.print("[yellow]Compress PDF? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Compress PDF for smaller file size (recommended)") + console.print("[blue] n/no[/blue] - Keep original PDF without compression [default]") + console.print("[yellow]Compress PDF? [y/N] [default: N]: [/yellow]", end="") compress_choice = input().strip().lower() + if not compress_choice: + compress_choice = 'n' if compress_choice in ['y', 'yes']: console.print("[purple]🔄 Compressing PDF...[/purple]") if not self._compress_pdf(): @@ -1598,8 +1637,13 @@ class BookBinder: console.print() console.print("[bold white]🌐 GitHub Pages Deployment:[/bold white]") console.print("[dim] Deploy the website to your public GitHub Pages (recommended)[/dim]") - console.print("[yellow]Deploy to GitHub Pages? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Deploy website to GitHub Pages (recommended)") + console.print("[blue] n/no[/blue] - Skip GitHub Pages deployment [default]") + console.print("[yellow]Deploy to GitHub Pages? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: console.print("[purple]🔄 Deploying to GitHub Pages...[/purple]") if self._deploy_to_github_pages(): @@ -1613,8 +1657,13 @@ class BookBinder: console.print() console.print("[bold white]📦 GitHub Release Creation:[/bold white]") console.print("[dim] Create a public release with downloadable PDF and AI-generated release notes[/dim]") - console.print("[yellow]Create GitHub release? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Create public release with downloadable PDF (recommended)") + console.print("[blue] n/no[/blue] - Skip GitHub release creation [default]") + console.print("[yellow]Create GitHub release? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' release_created = False if choice in ['y', 'yes']: pdf_path = self.build_dir / "pdf" / "Machine-Learning-Systems.pdf" @@ -1632,8 +1681,13 @@ class BookBinder: console.print() console.print("[bold white]🌐 GitHub Pages PDF Update:[/bold white]") console.print("[dim] Update the PDF in mlsysbook.ai/assets/ to match the release[/dim]") - console.print("[yellow]Update GitHub Pages PDF? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Update PDF on website (mlsysbook.ai/assets/)") + console.print("[blue] n/no[/blue] - Keep existing PDF on website [default]") + console.print("[yellow]Update GitHub Pages PDF? [y/N] [default: N]: [/yellow]", end="") choice = input().strip().lower() + if not choice: + choice = 'n' if choice in ['y', 'yes']: console.print("[purple]🔄 Updating GitHub Pages PDF...[/purple]") if self._update_github_pages_pdf(pdf_path): @@ -1711,12 +1765,30 @@ class BookBinder: console.print(f"[green]✅ Release notes generated and saved to: {release_notes_file}[/green]") console.print() - console.print("[bold white]📝 Review and Edit Release Notes:[/bold white]") - console.print(f"[blue] File: {release_notes_file}[/blue]") - console.print("[dim] You can now review and edit the release notes in your favorite editor[/dim]") + + # Show a preview of the generated release notes + console.print("[bold white]📝 Generated Release Notes Preview:[/bold white]") + preview_lines = release_notes.split('\n')[:15] # Show first 15 lines + preview_panel = Panel( + '\n'.join(preview_lines) + ('\n...' if len(release_notes.split('\n')) > 15 else ''), + title="Release Notes Preview", + border_style="blue", + padding=(1, 2) + ) + console.print(preview_panel) + + console.print("[bold white]📝 Review and Edit Options:[/bold white]") + console.print(f"[blue] 📄 File location: {release_notes_file}[/blue]") + console.print("[dim] You can review and edit the release notes before publishing[/dim]") console.print() - console.print("[yellow]Open file in default editor? [y/N]: [/yellow]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Open file in default editor for review/editing") + console.print("[blue] n/no[/blue] - Use release notes as-is [default]") + console.print("[cyan] s/show[/cyan] - Show full release notes content in terminal") + console.print("[yellow]Open file in default editor? [y/n/s] [default: n]: [/yellow]", end="") open_choice = input().strip().lower() + if not open_choice: + open_choice = 'n' if open_choice in ['y', 'yes']: try: import subprocess @@ -1732,10 +1804,54 @@ class BookBinder: except Exception as e: console.print(f"[yellow]⚠️ Could not open file automatically: {e}[/yellow]") console.print(f"[blue]💡 Please open manually: {release_notes_file}[/blue]") - - console.print() - console.print("[yellow]Press Enter to continue after reviewing/editing the release notes...[/yellow]", end="") - input() + + console.print() + console.print("[yellow]Press Enter to continue after reviewing/editing the release notes...[/yellow]", end="") + input() + + elif open_choice in ['s', 'show']: + # Show full release notes in terminal + console.print() + full_notes_panel = Panel( + release_notes, + title="Full Release Notes Content", + border_style="cyan", + padding=(1, 2) + ) + console.print(full_notes_panel) + + console.print() + console.print("[bold white]Options:[/bold white]") + console.print("[green] e/edit[/green] - Open in editor for modifications") + console.print("[blue] c/continue[/blue] - Use as-is and continue [default]") + console.print("[yellow]What would you like to do? [e/c] [default: c]: [/yellow]", end="") + action = input().strip().lower() + if not action: + action = 'c' + + if action in ['e', 'edit']: + try: + import subprocess + import platform + system = platform.system().lower() + if system == "darwin": # macOS + subprocess.run(['open', str(release_notes_file)]) + elif system == "linux": + subprocess.run(['xdg-open', str(release_notes_file)]) + elif system == "windows": + subprocess.run(['start', str(release_notes_file)], shell=True) + console.print("[green]✅ File opened in default editor[/green]") + console.print() + console.print("[yellow]Press Enter to continue after editing...[/yellow]", end="") + input() + except Exception as e: + console.print(f"[yellow]⚠️ Could not open file automatically: {e}[/yellow]") + console.print(f"[blue]💡 Please open manually: {release_notes_file}[/blue]") + else: + console.print("[blue]✅ Using release notes as-is[/blue]") + + else: + console.print("[blue]✅ Using generated release notes as-is[/blue]") # Read the potentially edited release notes try: @@ -2724,7 +2840,10 @@ Please format as: console.print(f" Email: {current_email}") console.print("\n[blue]Would you like to update your Git configuration?[/blue]") - console.print("[bold]Update Git config? (y/N) [N]: [/bold]", end="") + console.print("[bold white]Options:[/bold white]") + console.print("[green] y/yes[/green] - Update Git configuration") + console.print("[blue] n/no[/blue] - Keep current configuration [default]") + console.print("[bold]Update Git config? [y/N] [default: N]: [/bold]", end="") update_choice = input().strip().lower() if not update_choice: update_choice = 'n'