From dbf18c7a341c135b4fd05c912144644daf020557 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Sun, 22 Jun 2025 15:34:03 +0300 Subject: [PATCH 1/2] feat: Allow specifying host and port for dev servers - Updated `dev()` methods in Docusaurus and Starlight to accept host and port arguments, defaulting to `localhost:3000`. - This allows more flexibility in development server setup. - Updated example scripts to use the new parameters. --- examples/web/docusaurus_example_complete.vsh | 2 +- examples/web/starllight_example.vsh | 2 +- lib/core/herocmds/docusaurus.v | 2 +- lib/core/herocmds/starlight.v | 2 +- lib/web/docusaurus/dsite.v | 22 +++++++++++++------- lib/web/starlight/factory.v | 1 - lib/web/starlight/site.v | 18 +++++++++------- 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/examples/web/docusaurus_example_complete.vsh b/examples/web/docusaurus_example_complete.vsh index 122a2309..81ccc3f6 100755 --- a/examples/web/docusaurus_example_complete.vsh +++ b/examples/web/docusaurus_example_complete.vsh @@ -211,7 +211,7 @@ console.log(result); // Option 1: Run in development mode // This will start a development server in a screen session println('Starting development server...') - site.dev() or { + site.dev(host: 'localhost', port: 3000) or { eprintln('Error starting development server: ${err}') exit(1) } diff --git a/examples/web/starllight_example.vsh b/examples/web/starllight_example.vsh index d5195dde..b680cb01 100755 --- a/examples/web/starllight_example.vsh +++ b/examples/web/starllight_example.vsh @@ -14,4 +14,4 @@ mut site := docs.get( init: true // init means we put config files if not there )! -site.dev()! +site.dev(host: 'localhost', port: 3000)! diff --git a/lib/core/herocmds/docusaurus.v b/lib/core/herocmds/docusaurus.v index e989d93f..50b227d8 100644 --- a/lib/core/herocmds/docusaurus.v +++ b/lib/core/herocmds/docusaurus.v @@ -206,7 +206,7 @@ fn cmd_docusaurus_execute(cmd Command) ! { } if dev { - site.dev()! + site.dev(host: 'localhost', port: 3000)! } if open { diff --git a/lib/core/herocmds/starlight.v b/lib/core/herocmds/starlight.v index 9e69693d..ec6b01bf 100644 --- a/lib/core/herocmds/starlight.v +++ b/lib/core/herocmds/starlight.v @@ -138,6 +138,6 @@ fn cmd_starlight_execute(cmd Command) ! { } if dev { - site.dev()! + site.dev(host: 'localhost', port: 3000)! } } diff --git a/lib/web/docusaurus/dsite.v b/lib/web/docusaurus/dsite.v index cd60c172..421295cb 100644 --- a/lib/web/docusaurus/dsite.v +++ b/lib/web/docusaurus/dsite.v @@ -3,9 +3,7 @@ module docusaurus import freeflowuniverse.herolib.osal.screen import os import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.core.texttools // import freeflowuniverse.herolib.core.base -import freeflowuniverse.herolib.data.markdownparser import freeflowuniverse.herolib.develop.gittools // import json import freeflowuniverse.herolib.osal @@ -58,13 +56,20 @@ pub fn (mut s DocSite) build_publish() ! { )! } -pub fn (mut s DocSite) open() ! { - // Print instructions for user - console.print_item('open browser: ${s.url}') - osal.exec(cmd: 'open https://localhost:3000')! +@[params] +pub struct DevArgs { +pub mut: + host string = 'localhost' + port int = 3000 } -pub fn (mut s DocSite) dev() ! { +pub fn (mut s DocSite) open(args DevArgs) ! { + // Print instructions for user + console.print_item('open browser: https://${args.host}:${args.port}') + osal.exec(cmd: 'open https://${args.host}:${args.port}')! +} + +pub fn (mut s DocSite) dev(args DevArgs) ! { s.generate()! // Create screen session for docusaurus development server @@ -83,11 +88,12 @@ pub fn (mut s DocSite) dev() ! { // Send commands to the screen session console.print_item('To view the server output:: cd ${s.path_build.path}') scr.cmd_send('cd ${s.path_build.path}')! - scr.cmd_send('bun start')! + scr.cmd_send('bun start -p ${args.port} -h ${args.host}')! // Print instructions for user console.print_header(' Docusaurus Development Server') console.print_item('Development server is running in a screen session.') + console.print_item('Server is running on: https://${args.host}:${args.port}') console.print_item('To view the server output:') console.print_item(' 1. Attach to screen: screen -r ${screen_name}') console.print_item(' 2. To detach from screen: Press Ctrl+A then D') diff --git a/lib/web/starlight/factory.v b/lib/web/starlight/factory.v index fe526d61..18940fc7 100644 --- a/lib/web/starlight/factory.v +++ b/lib/web/starlight/factory.v @@ -2,7 +2,6 @@ module starlight import os import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.develop.gittools @[heap] pub struct StarlightFactory { diff --git a/lib/web/starlight/site.v b/lib/web/starlight/site.v index 58bd939a..25a44abc 100644 --- a/lib/web/starlight/site.v +++ b/lib/web/starlight/site.v @@ -3,10 +3,6 @@ module starlight import freeflowuniverse.herolib.osal.screen import os import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.core.texttools -import freeflowuniverse.herolib.core.base -import freeflowuniverse.herolib.develop.gittools -import json import freeflowuniverse.herolib.osal import freeflowuniverse.herolib.ui.console @@ -57,7 +53,14 @@ pub fn (mut s DocSite) build_publish() ! { )! } -pub fn (mut s DocSite) dev() ! { +@[params] +pub struct DevArgs { +pub mut: + host string = 'localhost' + port int = 3000 +} + +pub fn (mut s DocSite) dev(args DevArgs) ! { s.clean()! s.generate()! @@ -76,11 +79,12 @@ pub fn (mut s DocSite) dev() ! { // Send commands to the screen session scr.cmd_send('cd ${s.path_build.path}')! - scr.cmd_send('bash develop.sh')! + scr.cmd_send('bun start -p ${args.port} -h ${args.host}')! // Print instructions for user console.print_header(' Starlight Development Server') console.print_item('Development server is running in a screen session.') + console.print_item('Server is running on: https://${args.host}:${args.port}') console.print_item('To view the server output:') console.print_item(' 1. Attach to screen: screen -r ${screen_name}') console.print_item(' 2. To detach from screen: Press Ctrl+A then D') @@ -160,8 +164,6 @@ pub fn (mut site DocSite) generate() ! { } fn (mut site DocSite) template_install() ! { - mut gs := gittools.new()! - site.factory.template_install(template_update: false, install: false, delete: false)! cfg := site.config From e2aa9e7c461273b46671a20ea33f44f81869b937 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Sun, 22 Jun 2025 19:20:43 +0300 Subject: [PATCH 2/2] feat: Improve Docusaurus dev server experience - Stream server logs to the terminal for better monitoring. - Run the server in a background screen session for persistence. - Provide clearer instructions for managing the server. - Improve error handling and fallback mechanisms. --- lib/web/docusaurus/dsite.v | 76 +++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/lib/web/docusaurus/dsite.v b/lib/web/docusaurus/dsite.v index 421295cb..bc9e9ab3 100644 --- a/lib/web/docusaurus/dsite.v +++ b/lib/web/docusaurus/dsite.v @@ -8,6 +8,7 @@ import freeflowuniverse.herolib.develop.gittools // import json import freeflowuniverse.herolib.osal import freeflowuniverse.herolib.ui.console +import time @[heap] pub struct DocSite { @@ -88,22 +89,36 @@ pub fn (mut s DocSite) dev(args DevArgs) ! { // Send commands to the screen session console.print_item('To view the server output:: cd ${s.path_build.path}') scr.cmd_send('cd ${s.path_build.path}')! - scr.cmd_send('bun start -p ${args.port} -h ${args.host}')! - // Print instructions for user + // Start script recording in the screen session for log streaming + log_file := '/tmp/docusaurus_${screen_name}.log' + script_cmd := 'script -f ${log_file}' + scr.cmd_send(script_cmd)! + + // Small delay to ensure script is ready + time.sleep(500 * time.millisecond) + + // Start bun in the scripted session + bun_cmd := 'bun start -p ${args.port} -h ${args.host}' + scr.cmd_send(bun_cmd)! + + // Stream the log output to current terminal console.print_header(' Docusaurus Development Server') - console.print_item('Development server is running in a screen session.') - console.print_item('Server is running on: https://${args.host}:${args.port}') - console.print_item('To view the server output:') - console.print_item(' 1. Attach to screen: screen -r ${screen_name}') - console.print_item(' 2. To detach from screen: Press Ctrl+A then D') - console.print_item(' 3. To list all screens: screen -ls') - console.print_item('The site content is on::') - console.print_item(' 1. location of documents: ${s.path_src.path}/docs') - // if osal.cmd_exists('code') { - // console.print_item(' 2. We opened above dir in vscode.') - // osal.exec(cmd: 'code ${s.path_src.path}/docs')! - // } + console.print_item('Streaming server output... Press Ctrl+C to detach and leave server running') + console.print_item('Server will be available at: http://${args.host}:${args.port}') + console.print_item('To reattach later: screen -r ${screen_name}') + println('') + + // Stream logs until user interrupts + s.stream_logs(log_file, screen_name)! + + // After user interrupts, show final instructions + console.print_header(' Server Running in Background') + console.print_item('✓ Development server is running in background') + console.print_item('Server URL: http://${args.host}:${args.port}') + console.print_item('To reattach: screen -r ${screen_name}') + console.print_item('To stop server: screen -S ${screen_name} -X kill') + console.print_item('The site content is on: ${s.path_src.path}/docs') // Start the watcher in a separate thread // mut tf:=spawn watch_docs(docs_path, s.path_src.path, s.path_build.path) @@ -120,6 +135,39 @@ pub fn (mut s DocSite) dev(args DevArgs) ! { } } +// Stream logs from script file to current terminal until user interrupts +fn (mut s DocSite) stream_logs(log_file string, screen_name string) ! { + // Wait a moment for the log file to be created + mut attempts := 0 + for !os.exists(log_file) && attempts < 10 { + time.sleep(200 * time.millisecond) + attempts++ + } + + if !os.exists(log_file) { + console.print_stderr('Warning: Log file not created, falling back to screen attach') + console.print_item('Attaching to screen session... Press Ctrl+A then D to detach') + // Fallback to direct screen attach + osal.execute_interactive('screen -r ${screen_name}')! + return + } + + // Use tail -f to stream the log file + // The -f flag follows the file as it grows + tail_cmd := 'tail -f ${log_file}' + + // Execute tail in interactive mode - this will stream until Ctrl+C + osal.execute_interactive(tail_cmd) or { + // If tail fails, try alternative approach + console.print_stderr('Log streaming failed, attaching to screen session...') + osal.execute_interactive('screen -r ${screen_name}')! + return + } + + // Clean up the log file after streaming + os.rm(log_file) or {} +} + @[params] pub struct ErrorArgs { pub mut: