Merge branch 'development_ds' into development_fix_herobin

* development_ds:
  ...
  refactor: improve session action handling in play_core
  refactor: adapt docusaurus to use generic site module
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...

# Conflicts:
#	lib/biz/bizmodel/play.v
#	lib/threefold/grid4/cloudslices/play.v
#	lib/threefold/grid4/farmingsimulator/play.v
#	lib/web/docusaurus/dsite.v
#	lib/web/docusaurus/dsite_add.v
#	lib/web/docusaurus/dsite_configuration.v
#	lib/web/docusaurus/dsite_generate.v
This commit is contained in:
2025-08-03 04:47:53 +02:00
111 changed files with 5160 additions and 4257 deletions

View File

@@ -1,93 +1,69 @@
## How to use Heroscript with Docusaurus
## Docusaurus Module with HeroLib
You can use Heroscript to define and add content to your Docusaurus site. Below is an example:
This module allows you to build and manage Docusaurus websites using a generic configuration layer provided by `lib/web/site`.
### Workflow
1. **Configure Your Site**: Define your site's metadata, navigation, footer, pages, and content sources using `!!site.*` actions in a `.heroscript` file. This creates a generic site definition.
2. **Define Docusaurus Build**: Use `!!docusaurus.define` to specify build paths and other factory-level settings.
3. **Link Site to Docusaurus**: Use `!!docusaurus.add` to link your generic site configuration to the Docusaurus factory. This tells HeroLib to build this specific site using Docusaurus.
4. **Run Actions**: Use actions like `!!docusaurus.dev` or `!!docusaurus.build` to generate and serve your site.
### Example HeroScript
```heroscript
# 1. Define the Docusaurus build environment
!!docusaurus.define
path_build: "/tmp/docusaurus_build"
path_publish: "/tmp/docusaurus_publish"
reset: true
install: true
!!docusaurus.reset
# 2. Configure the site using the generic 'site' module
# This part is handled by lib/web/site
!!site.config
name: "my_site"
title: "My Awesome Docs"
tagline: "The best docs ever"
url: "https://docs.example.com"
base_url: "/"
copyright: "Example Corp"
!!docusaurus.add name:"my_local_docs" path:"./docs"
!!site.menu_item
label: "Homepage"
href: "https://example.com"
position: "right"
!!docusaurus.add name:"tfgrid_docs"
git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/ebooks/tech"
git_reset:true
git_pull:true
# ... add footer, pages, etc. using !!site.* actions ...
# 3. Add the generic site to the Docusaurus factory for building
# The 'path' points to your local source directory with static assets etc.
!!docusaurus.add site:"my_site" path:"./path/to/my/site/source"
# 4. Run the development server
!!docusaurus.dev site:"my_site" open:true watch_changes:true
```
### `docusaurus.define` Arguments
### Heroscript Actions
* `path_build` (string): Path where the Docusaurus site will be built. Default is `os.home_dir()/hero/var/docusaurus/build`.
* `path_publish` (string): Path where the Docusaurus site will be published. Default is `os.home_dir()/hero/var/docusaurus/publish`.
- `!!docusaurus.define`: Configures a Docusaurus factory instance.
- `name` (string): Name of the factory (default: `default`).
- `path_build` (string): Path to build the site.
- `path_publish` (string): Path to publish the final build.
- `reset` (bool): If `true`, clean the build directory before starting.
- `template_update` (bool): If `true`, update the Docusaurus template.
- `install` (bool): If `true`, run `bun install`.
### `docusaurus.reset`
- `!!docusaurus.add`: Links a configured site to the Docusaurus factory.
- `site` (string, required): The name of the site defined in `!!site.config`.
- `path` (string, required): The local filesystem path to the site's source directory (e.g., for `static/` folder).
* resets the full docusaurus build system
- `!!docusaurus.dev`: Runs the Docusaurus development server.
- `site` (string, required): The name of the site to run.
- `host` (string): Host to bind to (default: `localhost`).
- `port` (int): Port to use (default: `3000`).
- `open` (bool): Open the site in a browser.
- `watch_changes` (bool): Watch for source file changes and auto-reload.
### `docusaurus.update`
* updates the docusaurus build system, e.g. pull the templates back in
### `docusaurus.generate` Arguments
* `name` (string): Name of the Docusaurus site. Default is "main".
* `path` (string): Local path to the documentation content. Default is an empty string.
* `git_url` (string): Git URL of the documentation repository. Default is an empty string.
* `git_reset` (boolean): If set to `true`, the Git repository will be reset. Default is `false`.
* `git_pull` (boolean): If set to `true`, the Git repository will be pulled. Default is `false`.
* `git_root` (string): Root directory within the Git repository. Default is an empty string.
* `nameshort` (string): Short name for the Docusaurus site. Default is the value of `name`.
## called through code
### with heroscript in code
```v
import freeflowuniverse.herolib.web.docusaurus
mut ds:=docusaurus.new(heroscript:'
//next is optional
!!docusaurus.define
path_build: "/tmp/docusaurus_build"
path_publish: "/tmp/docusaurus_publish"
!!docusaurus.generate name:"tfgrid_docs"
git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/ebooks/tech"
git_root:"/tmp/code"
')!
mut site:=ds.site_get(name:"tfgrid_docs")!
site.dev()!
```
### directly
```v
import freeflowuniverse.herolib.web.docusaurus
// Create a new docusaurus factory
mut ds := docusaurus.new(
path_build: '/tmp/docusaurus_build'
path_publish: '/tmp/docusaurus_publish'
)!
// mut site:=ds.add(path:"${os.home_dir()}/code/git.threefold.info/tfgrid/docs_tfgrid4/ebooks/tech",name:"atest")!
mut site:=ds.add(git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/ebooks/tech",name:"atest")!
// println(site)
//next generates but doesn't do anything beyond
// site.generate()!
site.dev()!
```
- `!!docusaurus.build`: Builds the static site for production.
- `site` (string, required): The name of the site to build.

View File

@@ -3,53 +3,119 @@ module docusaurus
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
@[heap]
pub struct DocusaurusFactory {
pub mut:
sites map[string]&DocSite @[skip; str: skip]
path_build pathlib.Path
path_publish pathlib.Path
args DocusaurusArgs
config Configuration // Stores configuration from HeroScript if provided
__global (
docusaurus_sites map[string]&DocSite
)
@[params]
pub struct AddArgs {
pub:
site &site.Site
path_src string
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 DocusaurusArgs {
pub mut:
path_publish string
path_build string
install bool //install required modules
reset bool //reset the full system
template_update bool //update docusaurus template
heroscript string
heroscript_path string
struct TemplateInstallArgs {
mut:
install bool
reset bool
template_update bool
}
pub fn new(args_ DocusaurusArgs) !&DocusaurusFactory {
// copy template in build location
pub fn install(path_build_path string, args_ TemplateInstallArgs) ! {
mut gs := gittools.new()!
mut args := args_
if args.path_build == '' {
args.path_build = '${os.home_dir()}/hero/var/docusaurus/build'
}
if args.path_publish == '' {
args.path_publish = '${os.home_dir()}/hero/var/docusaurus/publish'
if args.reset {
osal.rm(path_build_path)!
osal.dir_ensure(path_build_path)!
}
// Create the factory instance
mut f := &DocusaurusFactory{
args: args_
path_build: pathlib.get_dir(path: args.path_build, create: true)!
path_publish: pathlib.get_dir(path: args_.path_publish, create: true)!
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: path_build_path, delete: args.reset)! // Changed args.delete to args.reset
if !os.exists('${path_build_path}/node_modules') {
args.install = true
}
f.install(install: args.install, template_update: args.template_update, reset: args.reset)!
return f
}
// get site from the docusaurus factory
pub fn (mut self DocusaurusFactory) site_get(name string) !&DocSite { // Changed return type to !&DocSite
name_:=texttools.name_fix(name) // Removed !
return self.sites[name_] or {return error('site not found: ${name} in docusaurus factory.') } // Removed ! from error()
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
'
)!
}
}

50
lib/web/docusaurus/play.v Normal file
View File

@@ -0,0 +1,50 @@
module docusaurus
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.web.site
pub fn play(mut plbook PlayBook) ! {
// 1. Process generic site configuration first.
// This populates the global `site.websites` map.
site.play(mut plbook)!
// 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 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')
template_update: p.get_default_false('template_update')
install: p.get_default_false('install')
)!
}
// 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 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 dsite := get(site_name)!
dsite.build()!
}
}