This commit is contained in:
2025-07-30 20:06:27 +02:00
parent b99f5ae6e9
commit 59386bb1c2
7 changed files with 130 additions and 213 deletions

View File

@@ -15,10 +15,11 @@ pub mut:
name string
path_src pathlib.Path
path_publish pathlib.Path
path_build pathlib.Path // <<< ADD THIS FIELD
errors []SiteError
config Configuration // Docusaurus-specific config, transformed from site.SiteConfig
site &site.Site @[skip; str: skip]
factory &DocusaurusFactory @[skip; str: skip] // Reference to the parent
// factory &DocusaurusFactory @[skip; str: skip] // <<< REMOVE THIS FIELD
// OPEN & WATCH ARGS are now passed directly to dev_watch
}
@@ -27,7 +28,7 @@ pub fn (mut s DocSite) build() ! {
s.generate()!
osal.exec(
cmd: '
cd ${s.factory.path_build.path}
cd ${s.path_build.path}
bun run build
',
retry: 0
@@ -38,7 +39,7 @@ pub fn (mut s DocSite) build_dev_publish() ! {
s.generate()!
osal.exec(
cmd: '
cd ${s.factory.path_build.path}
cd ${s.path_build.path}
exit 1
',
retry: 0
@@ -49,7 +50,7 @@ pub fn (mut s DocSite) build_publish() ! {
s.generate()!
osal.exec(
cmd: '
cd ${s.factory.path_build.path}
cd ${s.path_build.path}
exit 1
',
retry: 0
@@ -82,7 +83,7 @@ pub fn (mut s DocSite) dev(args DevArgs) ! {
}
osal.exec(
cmd: '
cd ${s.factory.path_build.path}
cd ${s.path_build.path}
bun run start -p ${args.port} -h ${args.host}
',
retry: 0
@@ -107,8 +108,8 @@ pub fn (mut s DocSite) dev_watch(args DevArgs) ! {
)!
// Send commands to the screen session
console.print_item('To view the server output:: cd ${s.factory.path_build.path}')
scr.cmd_send('cd ${s.factory.path_build.path}')!
console.print_item('To view the server output:: cd ${s.path_build.path}')
scr.cmd_send('cd ${s.path_build.path}')!
// Start script recording in the screen session for log streaming
log_file := '/tmp/docusaurus_${screen_name}.log'
@@ -141,7 +142,7 @@ pub fn (mut s DocSite) dev_watch(args DevArgs) ! {
console.print_item('The site content is on: ${s.path_src.path}/docs')
// Start the watcher in a separate thread
spawn watch_docs(s, s.path_src.path, s.factory.path_build.path)
spawn watch_docs(os.join_path(s.path_src.path, 'docs'), s.path_src.path, s.path_build.path)
println('')
if args.open {
@@ -197,6 +198,6 @@ pub fn (mut doc_site DocSite) error(args ErrorArgs) {
msg: args.msg
cat: args.cat
}
site.errors << e
doc_site.errors << e
console.print_stderr(args.msg)
}

View File

@@ -1,47 +0,0 @@
module docusaurus
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.web.site
import freeflowuniverse.herolib.ui.console
@[params]
pub struct AddArgs {
pub:
site &site.Site
path string // Source path for additional assets (static/, local docs/)
}
pub fn (mut f DocusaurusFactory) add(args AddArgs) !&DocSite {
name := args.site.siteconfig.name
console.print_header('Docusaurus: add site: ${name}')
if name in f.sites {
return f.sites[name]
}
// The `path` arg points to the source repo/directory for this site,
// containing things like `static/` or a base `docs/` folder.
src_path := pathlib.get_dir(path: args.path, create: false) or {
return error("Source path '${args.path}' for site '${name}' not found or not a directory.")
}
// Transform the generic site config to a docusaurus-specific one
docusaurus_config := config_from_site(args.site.siteconfig)!
// The path to publish this specific site to
mut path_publish := pathlib.get_dir(path: '${f.path_publish.path}/${name}', create: true)!
mut ds := &DocSite{
name: name
path_src: src_path
path_publish: path_publish
site: args.site
config: docusaurus_config
factory: f
}
ds.check()!
f.sites[name] = ds
return ds
}

View File

@@ -76,7 +76,7 @@ pub mut:
// ... (struct definitions remain the same) ...
// This function is now a pure transformer: site.SiteConfig -> docusaurus.Configuration
fn config_from_site(site_cfg site.SiteConfig) !Configuration {
pub fn new_configuration(site_cfg site.SiteConfig) !Configuration {
// Transform site.SiteConfig to docusaurus.Configuration
mut nav_items := []NavbarItem{}
for item in site_cfg.menu.items {

View File

@@ -10,11 +10,11 @@ import freeflowuniverse.herolib.core.texttools.regext
import freeflowuniverse.herolib.web.site
pub fn (mut self DocSite) generate() ! {
console.print_header(' site generate: ${self.name} on ${self.factory.path_build.path}')
console.print_header(' site generate: ${self.name} on ${self.path_build.path}')
console.print_header(' site source on ${self.path_src.path}')
// lets make sure we remove the cfg dir so we rebuild
cfg_path := os.join_path(self.factory.path_build.path, 'cfg')
cfg_path := os.join_path(self.path_build.path, 'cfg')
osal.rm(cfg_path)!
mut gs := gittools.new()!
@@ -27,12 +27,12 @@ pub fn (mut self DocSite) generate() ! {
for item in ['src', 'static'] {
mut template_src_path := pathlib.get_dir(path: '${template_path}/${item}', create: true)!
template_src_path.copy(dest: '${self.factory.path_build.path}/${item}', delete: true)!
template_src_path.copy(dest: '${self.path_build.path}/${item}', delete: true)!
// now copy the info which can be overruled from source in relation to the template
src_item_path := os.join_path(self.path_src.path, item)
if os.exists(src_item_path) {
mut src_path := pathlib.get_dir(path: src_item_path, create: false)!
src_path.copy(dest: '${self.factory.path_build.path}/${item}', delete: false)!
src_path.copy(dest: '${self.path_build.path}/${item}', delete: false)!
}
}
@@ -45,7 +45,7 @@ pub fn (mut self DocSite) generate() ! {
mut footer_file := pathlib.get_file(path: '${cfg_path}/footer.json', create: true)!
footer_file.write(json.encode_pretty(self.config.footer))!
docs_dest := os.join_path(self.factory.path_build.path, 'docs')
docs_dest := os.join_path(self.path_build.path, 'docs')
osal.rm(docs_dest)!
osal.dir_ensure(docs_dest)!
@@ -69,7 +69,7 @@ pub fn (mut self DocSite) process_imports() ! {
)!
mut mypatho := pathlib.get(mypath)
dest_path := '${self.factory.path_build.path}/docs/${item.dest}'
dest_path := '${self.path_build.path}/docs/${item.dest}'
mypatho.copy(dest: dest_path, delete: true)!
mut ri := regext.regex_instructions_new()

View File

@@ -4,89 +4,119 @@ import os
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.web.site
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.installers.web.bun
__global (
docusaurus_factories map[string]&DocusaurusFactory
docusaurus_sites map[string]&DocSite
)
@[heap]
pub struct DocusaurusFactory {
pub mut:
name string
sites map[string]&DocSite @[skip; str: skip]
path_build pathlib.Path
path_publish pathlib.Path
@[params]
pub struct AddArgs {
pub:
site &site.Site
path_src string
// Parameters that were previously on the factory
path_build string
path_publish string
install bool
reset bool
template_update bool
}
pub fn add(args AddArgs) !&DocSite {
site_name := texttools.name_fix(args.site.siteconfig.name)
if site_name in docusaurus_sites {
console.print_debug('Docusaurus site ${site_name} already exists, returning existing.')
return docusaurus_sites[site_name]
}
console.print_debug('Adding docusaurus site ${site_name}')
mut path_build_ := args.path_build
if path_build_ == '' {
path_build_ = '${os.home_dir()}/hero/var/docusaurus/build/${site_name}'
}
mut path_publish_ := args.path_publish
if path_publish_ == '' {
path_publish_ = '${os.home_dir()}/hero/var/docusaurus/publish/${site_name}'
}
// Install template if required
install(path_build_, TemplateInstallArgs{
install: args.install
reset: args.reset
template_update: args.template_update
})!
// Create the DocSite instance
mut dsite := &DocSite{
name: site_name
path_src: pathlib.get_dir(path: args.path_src, create: false)!
path_publish: pathlib.get_dir(path: path_publish_, create: true)!
path_build: pathlib.get_dir(path: path_build_, create: true)!
config: new_configuration(args.site.siteconfig)!
site: args.site
}
docusaurus_sites[site_name] = dsite
return dsite
}
pub fn get(name_ string) !&DocSite {
name := texttools.name_fix(name_)
return docusaurus_sites[name] or {
return error('docusaurus site with name "${name}" does not exist')
}
}
@[params]
pub struct FactoryArgs {
pub mut:
name string = 'default'
path_publish string
path_build string
install bool // install required modules
reset bool // reset the full system
template_update bool // update docusaurus template
struct TemplateInstallArgs {
mut:
install bool
reset bool
template_update bool
}
pub fn new(args FactoryArgs) !&DocusaurusFactory {
name := texttools.name_fix(args.name)
if name in docusaurus_factories {
console.print_debug('Docusaurus factory ${name} already exists, returning existing.')
return docusaurus_factories[name]
// copy template in build location
pub fn install(path_build_path string, args_ TemplateInstallArgs) ! {
mut gs := gittools.new()!
mut args := args_
if args.reset {
osal.rm(path_build_path)!
osal.dir_ensure(path_build_path)!
}
console.print_debug('Create docusaurus factory ${name}')
mut path_build_ := args.path_build
if path_build_ == '' {
path_build_ = '${os.home_dir()}/hero/var/docusaurus/build'
}
mut path_publish_ := args.path_publish
if path_publish_ == '' {
path_publish_ = '${os.home_dir()}/hero/var/docusaurus/publish'
}
// Create the factory instance
mut f := &DocusaurusFactory{
name: name
path_build: pathlib.get_dir(path: path_build_, create: true)!
path_publish: pathlib.get_dir(path: path_publish_, create: true)!
}
f.install(
install: args.install
template_update: args.template_update
reset: args.reset
template_path := gs.get_path(
pull: args.template_update
reset: args.reset // Changed args.delete to args.reset
url: 'https://github.com/freeflowuniverse/docusaurus_template/src/branch/main/template'
)!
docusaurus_factories[name] = f
return f
}
mut template_path0 := pathlib.get_dir(path: template_path, create: false)!
pub fn get(name_ string) !&DocusaurusFactory {
name := texttools.name_fix(name_)
return docusaurus_factories[name] or {
return error('docusaurus factory with name "${name}" does not exist')
}
}
template_path0.copy(dest: path_build_path, delete: args.reset)! // Changed args.delete to args.reset
pub fn default() !&DocusaurusFactory {
if docusaurus_factories.len == 0 {
return new(FactoryArgs{})!
if !os.exists('${path_build_path}/node_modules') {
args.install = true
}
if 'default' in docusaurus_factories {
return get('default')!
}
// return the first one if default is not there
for _, factory in docusaurus_factories {
return factory
}
return error('no docusaurus factories found')
}
// get site from the docusaurus factory
pub fn (mut self DocusaurusFactory) site_get(name string) !&DocSite {
name_ := texttools.name_fix(name)
return self.sites[name_] or { return error('site not found: ${name} in docusaurus factory.') }
if args.install {
// install bun
mut installer := bun.get()!
installer.install()!
osal.exec(
// always stay in the context of the build directory
cmd: '
${osal.profile_path_source_and()!}
export PATH=${path_build_path}/node_modules/.bin::${os.home_dir()}/.bun/bin/:\$PATH
cd ${path_build_path}
bun install
'
)!
}
}

View File

@@ -1,55 +0,0 @@
module docusaurus
import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.osal.core as osal
import freeflowuniverse.herolib.installers.web.bun
import freeflowuniverse.herolib.core.pathlib
import os
@[params]
struct TemplateInstallArgs {
mut:
install bool
reset bool
template_update bool
}
// copy template in build location
fn (mut self DocusaurusFactory) install(args_ TemplateInstallArgs) ! {
mut gs := gittools.new()!
mut args := args_
if args.reset {
osal.rm('${self.path_build.path}')!
osal.dir_ensure('${self.path_build.path}')!
}
template_path := gs.get_path(
pull: args.template_update
reset: args.reset // Changed args.delete to args.reset
url: 'https://github.com/freeflowuniverse/docusaurus_template/src/branch/main/template'
)!
mut template_path0 := pathlib.get_dir(path: template_path, create: false)!
template_path0.copy(dest: '${self.path_build.path}', delete: args.reset)! // Changed args.delete to args.reset
if !os.exists('${self.path_build.path}/node_modules') {
args.install = true
}
if args.install {
// install bun
mut installer := bun.get()!
installer.install()!
osal.exec(
// always stay in the context of the build directory
cmd: '
${osal.profile_path_source_and()!}
export PATH=${self.path_build.path}/node_modules/.bin::${os.home_dir()}/.bun/bin/:\$PATH
cd ${self.path_build.path}
bun install
'
)!
}
}

View File

@@ -8,12 +8,18 @@ pub fn play(mut plbook PlayBook) ! {
// This populates the global `site.websites` map.
site.play(mut plbook)!
// 2. Process docusaurus factory definition.
if plbook.exists_once(filter: 'docusaurus.define') {
mut action := plbook.get(filter: 'docusaurus.define')!
// 3. Process `docusaurus.add` actions to create sites.
for action in plbook.find(filter: 'docusaurus.add')! {
mut p := action.params
new(
name: p.get_default('name', 'default')!
site_name := p.get('site') or { return error('In docusaurus.add, param "site" is required.') }
path := p.get('path') or { return error('In docusaurus.add, param "path" to the site source code is required.') }
mut generic_site := site.get(name: site_name)!
add(
site: generic_site
path_src: path
path_build: p.get_default('path_build', '')!
path_publish: p.get_default('path_publish', '')!
reset: p.get_default_false('reset')
@@ -22,41 +28,23 @@ pub fn play(mut plbook PlayBook) ! {
)!
}
// 3. Process `docusaurus.add` actions to create sites.
for action in plbook.find(filter: 'docusaurus.add')! {
mut p := action.params
site_name := p.get('site') or { return error('In docusaurus.add, param "site" is required.') }
path := p.get('path') or { return error('In docusaurus.add, param "path" to the site source code is required.') }
mut factory := default()!
// Get the configured site from the site module
mut generic_site := site.get(name: site_name)!
// Add the site to the docusaurus factory
factory.add(
site: generic_site
path: path
)!
}
// 4. Process actions like 'dev', 'build', etc.
for action in plbook.find(filter: 'docusaurus.dev')! {
mut p := action.params
site_name := p.get('site')!
mut factory := default()!
mut dsite := factory.site_get(site_name)!
mut dsite := get(site_name)!
dsite.dev(
host: p.get_default('host', 'localhost')!
port: p.get_int_default('port', 3000)!
open: p.get_default_false('open')
watch_changes: p.get_default_false('watch_changes')
)!
}
for action in plbook.find(filter: 'docusaurus.build')! {
mut p := action.params
site_name := p.get('site')!
mut factory := default()!
mut dsite := factory.site_get(site_name)!
mut dsite := get(site_name)!
dsite.build()!
}
}