refactor: overhaul Docusaurus command and generation

- Rework `hero docusaurus` command to use local `cfg` files
- Scan and export doctree collections during site generation
- Fix `baseUrl` redirect path handling in `index.tsx`
- Add cycle detection for `play.include` in playbooks
- Improve site config processing to prevent duplicate items
This commit is contained in:
Mahmoud-Emad
2025-08-07 10:46:57 +03:00
parent 2667856633
commit 82a46e8149
15 changed files with 291 additions and 140 deletions

View File

@@ -1,9 +1,11 @@
module herocmds
import freeflowuniverse.herolib.web.docusaurus
import freeflowuniverse.herolib.web.site
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.playcmds
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.web.site
import freeflowuniverse.herolib.web.docusaurus
import os
import cli { Command, Flag }
@@ -119,23 +121,20 @@ pub fn cmd_docusaurus(mut cmdroot Command) Command {
}
fn cmd_docusaurus_execute(cmd Command) ! {
mut update := cmd.flags.get_bool('update') or { false }
mut init := cmd.flags.get_bool('new') or { false }
mut open := cmd.flags.get_bool('open') or { false }
mut url := cmd.flags.get_string('url') or { '' }
mut publish_path := cmd.flags.get_string('publish') or { '' }
mut buildpublish := cmd.flags.get_bool('buildpublish') or { false }
mut builddevpublish := cmd.flags.get_bool('builddevpublish') or { false }
mut dev := cmd.flags.get_bool('dev') or { false }
// --- Build Path Logic ---
mut build_path := cmd.flags.get_string('buildpath') or { '' }
if build_path == '' {
// Default build path if not provided (e.g., use CWD or a specific temp dir)
// Using CWD for now based on previous edits, adjust if needed
build_path = '${os.home_dir()}/hero/var/docusaurus'
}
// --- Start: Heroscript Path Logic ---
// --- Path Logic ---
mut provided_path := cmd.flags.get_string('path') or { '' }
mut heroscript_config_dir := ''
mut source_path := ''
if provided_path != '' {
if !os.exists(provided_path) || !os.is_dir(provided_path) {
@@ -145,10 +144,14 @@ fn cmd_docusaurus_execute(cmd Command) ! {
// Check if the provided path contains a cfg subdirectory (ebook directory structure)
cfg_subdir := os.join_path(provided_path, 'cfg')
if os.exists(cfg_subdir) && os.is_dir(cfg_subdir) {
heroscript_config_dir = cfg_subdir
source_path = provided_path
} else {
// Assume the provided path is already the cfg directory
heroscript_config_dir = provided_path
if provided_path.ends_with('cfg') {
// If path ends with cfg, use parent directory as source
source_path = os.dir(provided_path)
} else {
return error('Provided path "${provided_path}" does not contain a "cfg" subdirectory.')
}
}
} else {
mut cwd := os.getwd()
@@ -156,54 +159,72 @@ fn cmd_docusaurus_execute(cmd Command) ! {
if !os.exists(cfg_dir) || !os.is_dir(cfg_dir) {
return error('Flag -path not provided and directory "./cfg" not found in the current working directory.')
}
heroscript_config_dir = cfg_dir
source_path = cwd
}
mut buildpublish := cmd.flags.get_bool('buildpublish') or { false }
mut builddevpublish := cmd.flags.get_bool('builddevpublish') or { false }
mut dev := cmd.flags.get_bool('dev') or { false }
console.print_header('Running Docusaurus for: ${source_path}')
// Process the site configuration first (excluding global includes)
mut combined_heroscript := ''
cfg_path := os.join_path(source_path, 'cfg')
if os.exists(cfg_path) {
files := os.ls(cfg_path) or { []string{} }
for file in files {
if file.ends_with('.heroscript') {
file_path := os.join_path(cfg_path, file)
content := os.read_file(file_path) or { continue }
// // Get the site configuration that was processed from the heroscript files
// // The site.play() function processes the heroscript and creates sites in the global websites map
// // We need to get the site by name from the processed configuration
// config_actions := plbook.find(filter: 'site.config')!
// if config_actions.len == 0 {
// return error('No site.config found in heroscript files. Make sure config.heroscript contains !!site.config.')
// }
// Skip files that contain play.include to avoid global processing
if content.contains('!!play.include') {
continue
}
// // Get the site name from the first site.config action
// site_name := config_actions[0].params.get('name') or {
// return error('site.config must specify a name parameter')
// }
combined_heroscript += content + '\n\n'
}
}
}
// // Get the processed site configuration
// mut generic_site := site.get(name: site_name)!
if combined_heroscript.len == 0 {
return error('No valid heroscript files found (all contained global includes)')
}
// // Add docusaurus site
// mut dsite := docusaurus.dsite_add(
// site: generic_site
// path_src: url // Use URL as source path for now
// path_build: build_path
// path_publish: publish_path
// reset: false
// template_update: update
// install: init
// )!
// Process the site configuration to get the site name
mut plbook := playbook.new(text: combined_heroscript)!
site.play(mut plbook)!
// // Conditional site actions based on flags
// if buildpublish {
// dsite.build_publish()!
// } else if builddevpublish {
// dsite.build_dev_publish()!
// } else if dev {
// dsite.dev(host: 'localhost', port: 3000, open: open)!
// } else if open {
// dsite.open('localhost', 3000)!
// } else {
// // If no specific action (build/dev/open) is requested, just generate the site
// dsite.generate()!
// }
// Get the site name from the processed site configuration
available_sites := site.list()
if available_sites.len == 0 {
return error('No sites were created from the configuration')
}
site_name := available_sites[0] // Use the first (and likely only) site
panic("implement")
// Set up the docusaurus factory
docusaurus.factory_set(
path_build: build_path
reset: true
install: true
template_update: true
)!
// Add the docusaurus site
mut dsite := docusaurus.dsite_add(
sitename: site_name
path: source_path
play: false // Site already processed
)!
// Execute the requested action directly
if buildpublish {
dsite.build_publish()!
} else if builddevpublish {
dsite.build()!
} else if dev {
dsite.dev(
open: open
watch_changes: true
)!
} else {
dsite.build()!
}
}