revert
This commit is contained in:
@@ -1,63 +1,6 @@
|
||||
# Redisclient
|
||||
|
||||
Getting started:
|
||||
|
||||
```v
|
||||
// Connect to Redis (recommended way)
|
||||
import freeflowuniverse.herolib.core.base
|
||||
mut context := base.context()!
|
||||
mut redis := context.redis()!
|
||||
|
||||
// String commands
|
||||
redis.set('mykey', 'hello')!
|
||||
println(redis.get('mykey')!) // Output: hello
|
||||
redis.del('mykey')!
|
||||
|
||||
// Hash commands
|
||||
redis.hset('myhash', 'field1', 'value1')!
|
||||
println(redis.hget('myhash', 'field1')!) // Output: value1
|
||||
println(redis.hgetall('myhash')!) // Output: {'field1': 'value1', 'field2': 'value2'}
|
||||
redis.hdel('myhash', 'field1')!
|
||||
|
||||
// List commands
|
||||
redis.lpush('mylist', 'item1')!
|
||||
redis.rpush('mylist', 'item2')!
|
||||
println(redis.lrange('mylist', 0, -1)!) // Output: ['item1', 'item2']
|
||||
println(redis.lpop('mylist')!) // Output: item1
|
||||
println(redis.rpop('mylist')!) // Output: item2
|
||||
|
||||
// Set commands
|
||||
redis.sadd('myset', ['member1', 'member2', 'member3'])!
|
||||
println(redis.smismember('myset', ['member1', 'member4'])!) // Output: [1, 0]
|
||||
|
||||
// Key commands
|
||||
redis.set('key1', 'value1')!
|
||||
redis.set('key2', 'value2')!
|
||||
println(redis.keys('*')!) // Output: ['key1', 'key2'] (order may vary)
|
||||
redis.expire('key1', 10)! // Set expiry to 10 seconds
|
||||
|
||||
// Increment/Decrement commands
|
||||
redis.set('counter', '10')!
|
||||
println(redis.incr('counter')!) // Output: 11
|
||||
println(redis.decrby('counter', 5)!) // Output: 6
|
||||
|
||||
// Append command
|
||||
redis.set('mytext', 'hello')!
|
||||
println(redis.append('mytext', ' world')!) // Output: 11 (length of new string)
|
||||
println(redis.get('mytext')!) // Output: hello world
|
||||
|
||||
// Type command
|
||||
println(redis.type_of('mykey')!) // Output: string (or none if key doesn't exist)
|
||||
|
||||
// Flush commands (use with caution!)
|
||||
// redis.flushdb()! // Flushes the current database
|
||||
// redis.flushall()! // Flushes all databases
|
||||
|
||||
```
|
||||
|
||||
## archive
|
||||
|
||||
### non recommended example to connect to local redis on 127.0.0.1:6379
|
||||
## basic example to connect to local redis on 127.0.0.1:6379
|
||||
|
||||
```v
|
||||
|
||||
@@ -73,3 +16,4 @@ if r != 'some data' {
|
||||
```
|
||||
|
||||
> redis commands can be found on https://redis.io/commands/
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
The TextTools module provides a comprehensive set of utilities for text manipulation and processing in V. It includes functions for cleaning, parsing, formatting, and transforming text in various ways.
|
||||
|
||||
## Features
|
||||
|
||||
### Array Operations
|
||||
- `to_array(r string) []string` - Converts a comma or newline separated list to an array of strings
|
||||
@@ -36,12 +37,6 @@ The TextTools module provides a comprehensive set of utilities for text manipula
|
||||
- Handles comments, code blocks, and preserves formatting
|
||||
|
||||
### Name/Path Processing
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
texttools.name_fix(sometext)
|
||||
```
|
||||
|
||||
- `name_fix(name string) string` - Normalizes filenames and paths
|
||||
- `name_fix_keepspace(name string) !string` - Like name_fix but preserves spaces
|
||||
- `name_fix_no_ext(name_ string) string` - Removes file extension
|
||||
@@ -126,3 +121,26 @@ ver := texttools.version("v1.4.36")
|
||||
// Result: 1004036
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Many functions in the module return a Result type (indicated by `!` in the function signature). These functions can return errors that should be handled appropriately:
|
||||
|
||||
```v
|
||||
// Example of error handling
|
||||
name := texttools.name_fix_keepspace("some@name") or {
|
||||
println("Error: ${err}")
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. Always use appropriate error handling for functions that return Results
|
||||
2. Consider using `dedent()` before processing multiline text to ensure consistent formatting
|
||||
3. When working with filenames, use the appropriate name_fix variant based on your needs
|
||||
4. For command line parsing, be aware of quote handling and escaping rules
|
||||
5. When using tokenization, consider the context and whether smart splitting is needed
|
||||
|
||||
## Contributing
|
||||
|
||||
The TextTools module is part of the heroLib project. Contributions are welcome through pull requests.
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
module docusaurus
|
||||
|
||||
import os
|
||||
import strings
|
||||
|
||||
pub fn (mut site DocSite) clean(args ErrorArgs) ! {
|
||||
toclean := '
|
||||
/node_modules
|
||||
|
||||
babel.config.js
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
bun.lockb
|
||||
bun.lock
|
||||
|
||||
yarn.lock
|
||||
|
||||
build.sh
|
||||
build_dev.sh
|
||||
build-dev.sh
|
||||
develop.sh
|
||||
install.sh
|
||||
|
||||
package.json
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
|
||||
sidebars.ts
|
||||
|
||||
tsconfig.json
|
||||
'
|
||||
|
||||
mut sb := strings.new_builder(200)
|
||||
for line in toclean.split_into_lines() {
|
||||
clean_line := line.trim_space()
|
||||
if clean_line == '' || clean_line.starts_with('#') {
|
||||
continue
|
||||
}
|
||||
|
||||
// Remove leading slash if present to make path relative
|
||||
path_to_clean := if clean_line.starts_with('/') {
|
||||
clean_line[1..]
|
||||
} else {
|
||||
clean_line
|
||||
}
|
||||
|
||||
full_path := os.join_path(site.path_src.path, path_to_clean)
|
||||
|
||||
// Handle glob patterns (files ending with *)
|
||||
if path_to_clean.ends_with('*') {
|
||||
base_pattern := path_to_clean#[..-1] // Remove the * at the end
|
||||
base_dir := os.dir(full_path)
|
||||
if os.exists(base_dir) {
|
||||
files := os.ls(base_dir) or {
|
||||
sb.writeln('Failed to list directory ${base_dir}: ${err}')
|
||||
continue
|
||||
}
|
||||
for file in files {
|
||||
if file.starts_with(base_pattern) {
|
||||
file_path := os.join_path(base_dir, file)
|
||||
os.rm(file_path) or { sb.writeln('Failed to remove ${file_path}: ${err}') }
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle regular files and directories
|
||||
if os.exists(full_path) {
|
||||
if os.is_dir(full_path) {
|
||||
os.rmdir_all(full_path) or {
|
||||
sb.writeln('Failed to remove directory ${full_path}: ${err}')
|
||||
}
|
||||
} else {
|
||||
os.rm(full_path) or { sb.writeln('Failed to remove file ${full_path}: ${err}') }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
module docusaurus
|
||||
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import json
|
||||
import os
|
||||
|
||||
// THE FOLLOWING STRUCTS CAN BE SERIALIZED IN
|
||||
// main.json
|
||||
// Main
|
||||
// {
|
||||
// "title": "Internet Geek",
|
||||
// "tagline": "Internet Geek",
|
||||
// "favicon": "img/favicon.png",
|
||||
// "url": "https://friends.threefold.info",
|
||||
// "url_home": "docs/",
|
||||
// "baseUrl": "/kristof/",
|
||||
// "image": "img/tf_graph.png",
|
||||
// "metadata": {
|
||||
// "description": "ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.",
|
||||
// "image": "https://threefold.info/kristof/img/tf_graph.png",
|
||||
// "title": "ThreeFold Technology Vision"
|
||||
// },
|
||||
// "buildDest":"root@info.ourworld.tf:/root/hero/www/info",
|
||||
// "buildDestDev":"root@info.ourworld.tf:/root/hero/www/infodev"
|
||||
// }
|
||||
//
|
||||
// navbar.json
|
||||
// Navbar:
|
||||
// {
|
||||
// "title": "Kristof = Chief Executive Geek",
|
||||
// "items": [
|
||||
// {
|
||||
// "href": "https://threefold.info/kristof/",
|
||||
// "label": "ThreeFold Technology",
|
||||
// "position": "right"
|
||||
// },
|
||||
// {
|
||||
// "href": "https://threefold.io",
|
||||
// "label": "ThreeFold.io",
|
||||
// "position": "right"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// footer.json
|
||||
// Footer:
|
||||
// {
|
||||
// "style": "dark",
|
||||
// "links": [
|
||||
// {
|
||||
// "title": "Docs",
|
||||
// "items": [
|
||||
// {
|
||||
// "label": "Introduction",
|
||||
// "to": "/docs"
|
||||
// },
|
||||
// {
|
||||
// "label": "TFGrid V4 Docs",
|
||||
// "href": "https://docs.threefold.io/"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// "title": "Community",
|
||||
// "items": [
|
||||
// {
|
||||
// "label": "Telegram",
|
||||
// "href": "https://t.me/threefold"
|
||||
// },
|
||||
// {
|
||||
// "label": "X",
|
||||
// "href": "https://x.com/threefold_io"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// "title": "Links",
|
||||
// "items": [
|
||||
// {
|
||||
// "label": "ThreeFold.io",
|
||||
// "href": "https://threefold.io"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
// Combined config structure
|
||||
pub struct Config {
|
||||
pub mut:
|
||||
footer Footer
|
||||
main Main
|
||||
navbar Navbar
|
||||
build_destinations []BuildDest
|
||||
import_sources []ImportSource
|
||||
ssh_connections []SSHConnection
|
||||
}
|
||||
|
||||
// THE SUBELEMENTS
|
||||
|
||||
pub struct Main {
|
||||
pub mut:
|
||||
name string
|
||||
title string = 'Docusaurus'
|
||||
tagline string
|
||||
favicon string = 'img/favicon.png'
|
||||
url string = 'http://localhost'
|
||||
url_home string
|
||||
base_url string = '/' @[json: 'baseUrl']
|
||||
image string = 'img/tf_graph.png' @[required]
|
||||
metadata MainMetadata
|
||||
build_dest []string @[json: 'buildDest']
|
||||
build_dest_dev []string @[json: 'buildDestDev']
|
||||
copyright string = 'someone'
|
||||
to_import []MyImport @[json: 'import']
|
||||
}
|
||||
|
||||
// Footer config structures
|
||||
pub struct FooterItem {
|
||||
pub mut:
|
||||
label string
|
||||
to string
|
||||
href string
|
||||
}
|
||||
|
||||
pub struct FooterLink {
|
||||
pub mut:
|
||||
title string
|
||||
items []FooterItem
|
||||
}
|
||||
|
||||
pub struct Footer {
|
||||
pub mut:
|
||||
style string = 'dark'
|
||||
links []FooterLink
|
||||
}
|
||||
|
||||
// Main config structure
|
||||
pub struct MainMetadata {
|
||||
pub mut:
|
||||
description string = 'Docusaurus'
|
||||
image string = 'Docusaurus'
|
||||
title string = 'Docusaurus'
|
||||
}
|
||||
|
||||
pub struct MyImport {
|
||||
pub mut:
|
||||
url string
|
||||
dest string
|
||||
visible bool
|
||||
replace map[string]string
|
||||
}
|
||||
|
||||
// Navbar config structures
|
||||
pub struct NavbarItem {
|
||||
pub mut:
|
||||
href string
|
||||
label string
|
||||
position string
|
||||
}
|
||||
|
||||
pub struct Navbar {
|
||||
pub mut:
|
||||
title string
|
||||
items []NavbarItem
|
||||
}
|
||||
|
||||
pub struct SSHConnection {
|
||||
pub mut:
|
||||
name string = 'main'
|
||||
login string = 'root' // e.g. 'root'
|
||||
host string // e.g. info.ourworld.tf
|
||||
port int = 21 // default is std ssh port
|
||||
key string
|
||||
key_path string // location of the key (private ssh key to be able to connect over ssh)
|
||||
}
|
||||
|
||||
pub struct BuildDest {
|
||||
pub mut:
|
||||
ssh_name string = 'main'
|
||||
path string // can be on the ssh root or direct path e.g. /root/hero/www/info
|
||||
}
|
||||
|
||||
pub struct ImportSource {
|
||||
pub mut:
|
||||
url string // http git url can be to specific path
|
||||
path string
|
||||
dest string // location in the docs folder of the place where we will build docusaurus
|
||||
replace map[string]string // will replace ${NAME} in the imported content
|
||||
}
|
||||
|
||||
// Export config as JSON files (main.json, navbar.json, footer.json)
|
||||
pub fn (config Config) export_json(path string) ! {
|
||||
// Ensure directory exists
|
||||
os.mkdir_all(path)!
|
||||
|
||||
// Export main.json
|
||||
os.write_file('${path}/main.json', json.encode_pretty(config.main))!
|
||||
|
||||
// Export navbar.json
|
||||
os.write_file('${path}/navbar.json', json.encode_pretty(config.navbar))!
|
||||
|
||||
// Export footer.json
|
||||
os.write_file('${path}/footer.json', json.encode_pretty(config.footer))!
|
||||
}
|
||||
|
||||
pub fn (c Config) write(path string) ! {
|
||||
mut footer_file := pathlib.get_file(path: '${path}/footer.json', create: true)!
|
||||
footer_file.write(json.encode(c.footer))!
|
||||
mut main_file := pathlib.get_file(path: '${path}/main.json', create: true)!
|
||||
main_file.write(json.encode(c.main))!
|
||||
mut navbar_file := pathlib.get_file(path: '${path}/navbar.json', create: true)!
|
||||
navbar_file.write(json.encode(c.navbar))!
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
module docusaurus
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
// load_config loads all configuration from the specified directory
|
||||
pub fn load_config(cfg_dir string) !Config {
|
||||
// Ensure the config directory exists
|
||||
if !os.exists(cfg_dir) {
|
||||
return error('Config directory ${cfg_dir} does not exist')
|
||||
}
|
||||
|
||||
// Load and parse footer config
|
||||
footer_content := os.read_file(os.join_path(cfg_dir, 'footer.json'))!
|
||||
footer := json.decode(Footer, footer_content)!
|
||||
|
||||
// Load and parse main config
|
||||
main_config_path := os.join_path(cfg_dir, 'main.json')
|
||||
main_content := os.read_file(main_config_path)!
|
||||
main := json.decode(Main, main_content) or {
|
||||
eprintln('${main_config_path} is not in the right format please fix.')
|
||||
println('
|
||||
|
||||
## EXAMPLE OF A GOOD ONE:
|
||||
|
||||
- note the list for buildDest and buildDestDev
|
||||
- note its the full path where the html is pushed too
|
||||
|
||||
{
|
||||
"title": "ThreeFold Web4",
|
||||
"tagline": "ThreeFold Web4",
|
||||
"favicon": "img/favicon.png",
|
||||
"url": "https://docs.threefold.io",
|
||||
"url_home": "docs/introduction",
|
||||
"baseUrl": "/",
|
||||
"image": "img/tf_graph.png",
|
||||
"metadata": {
|
||||
"description": "ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.",
|
||||
"image": "https://threefold.info/kristof/img/tf_graph.png",
|
||||
"title": "ThreeFold Docs"
|
||||
},
|
||||
"buildDest":["root@info.ourworld.tf:/root/hero/www/info/tfgrid4"],
|
||||
"buildDestDev":["root@info.ourworld.tf:/root/hero/www/infodev/tfgrid4"]
|
||||
|
||||
}
|
||||
')
|
||||
exit(99)
|
||||
}
|
||||
|
||||
// Load and parse navbar config
|
||||
navbar_content := os.read_file(os.join_path(cfg_dir, 'navbar.json'))!
|
||||
navbar := json.decode(Navbar, navbar_content)!
|
||||
|
||||
return Config{
|
||||
footer: footer
|
||||
main: main
|
||||
navbar: navbar
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ pub mut:
|
||||
// path_publish pathlib.Path
|
||||
args DSiteGetArgs
|
||||
errors []SiteError
|
||||
config Config
|
||||
config Configuration
|
||||
factory &DocusaurusFactory @[skip; str: skip] // Reference to the parent
|
||||
}
|
||||
|
||||
@@ -58,8 +58,14 @@ 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')!
|
||||
}
|
||||
|
||||
|
||||
pub fn (mut s DocSite) dev() ! {
|
||||
s.clean()!
|
||||
s.generate()!
|
||||
|
||||
// Create screen session for docusaurus development server
|
||||
@@ -76,8 +82,9 @@ 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('bash develop.sh')!
|
||||
scr.cmd_send('bun start')!
|
||||
|
||||
// Print instructions for user
|
||||
console.print_header(' Docusaurus Development Server')
|
||||
@@ -98,6 +105,10 @@ pub fn (mut s DocSite) dev() ! {
|
||||
// tf.wait()!
|
||||
println('\n')
|
||||
|
||||
if s.args.open {
|
||||
s.open()!
|
||||
}
|
||||
|
||||
if s.args.watch_changes {
|
||||
docs_path := '${s.path_src.path}/docs'
|
||||
watch_docs(docs_path, s.path_src.path, s.path_build.path)!
|
||||
@@ -139,76 +150,10 @@ fn (mut site DocSite) check() ! {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut site DocSite) generate() ! {
|
||||
console.print_header(' site generate: ${site.name} on ${site.path_build.path}')
|
||||
console.print_header(' site source on ${site.path_src.path}')
|
||||
site.check()!
|
||||
site.template_install()!
|
||||
|
||||
// Now copy all directories that exist in src to build
|
||||
for item in ['src', 'static', 'cfg'] {
|
||||
if os.exists('${site.path_src.path}/${item}') {
|
||||
mut aa := site.path_src.dir_get(item)!
|
||||
aa.copy(dest: '${site.path_build.path}/${item}')!
|
||||
}
|
||||
}
|
||||
for item in ['docs'] {
|
||||
if os.exists('${site.path_src.path}/${item}') {
|
||||
mut aa := site.path_src.dir_get(item)!
|
||||
aa.copy(dest: '${site.path_build.path}/${item}', delete: true)!
|
||||
}
|
||||
}
|
||||
|
||||
mut gs := gittools.new()!
|
||||
|
||||
for item in site.config.main.to_import {
|
||||
mypath := gs.get_path(
|
||||
pull: false
|
||||
reset: false
|
||||
url: item.url
|
||||
)!
|
||||
mut mypatho := pathlib.get(mypath)
|
||||
site.process_md(mut mypatho, item)!
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut site DocSite) process_md(mut path pathlib.Path, args MyImport) ! {
|
||||
if path.is_dir() {
|
||||
mut pathlist_images := path.list(
|
||||
regex: [r'.*\.png$', r'.*\.jpg$', r'.*\.svg$', r'.*\.jpeg$']
|
||||
recursive: true
|
||||
)!
|
||||
for mut mypatho_img in pathlist_images.paths {
|
||||
// now copy the image to the dest
|
||||
dest := '${site.path_build.path}/docs/${args.dest}/img/${texttools.name_fix(mypatho_img.name())}'
|
||||
// println("image copy: ${dest}")
|
||||
mypatho_img.copy(dest: dest, rsync: false)!
|
||||
}
|
||||
|
||||
mut pathlist := path.list(regex: [r'.*\.md$'], recursive: true)!
|
||||
for mut mypatho2 in pathlist.paths {
|
||||
site.process_md(mut mypatho2, args)!
|
||||
}
|
||||
return
|
||||
}
|
||||
mydest := '${site.path_build.path}/docs/${args.dest}/${texttools.name_fix(path.name())}'
|
||||
mut mydesto := pathlib.get_file(path: mydest, create: true)!
|
||||
|
||||
mut mymd := markdownparser.new(path: path.path)!
|
||||
mut myfm := mymd.frontmatter2()!
|
||||
if !args.visible {
|
||||
myfm.args['draft'] = 'true'
|
||||
}
|
||||
println(myfm)
|
||||
println(mymd.markdown()!)
|
||||
mydesto.write(mymd.markdown()!)!
|
||||
exit(0)
|
||||
}
|
||||
|
||||
fn (mut site DocSite) template_install() ! {
|
||||
mut gs := gittools.new()!
|
||||
|
||||
site.factory.template_install(template_update: false, install: false, delete: false)!
|
||||
site.factory.template_install(template_update: false, install: true, delete: false)!
|
||||
|
||||
cfg := site.config
|
||||
|
||||
@@ -225,7 +170,7 @@ fn (mut site DocSite) template_install() ! {
|
||||
|
||||
develop := $tmpl('templates/develop.sh')
|
||||
build := $tmpl('templates/build.sh')
|
||||
build_dev_publish := $tmpl('templates/build_dev_publish.sh')
|
||||
// build_dev_publish := $tmpl('templates/build_dev_publish.sh')
|
||||
build_publish := $tmpl('templates/build_publish.sh')
|
||||
|
||||
mut develop_ := site.path_build.file_get_new('develop.sh')!
|
||||
@@ -240,9 +185,10 @@ fn (mut site DocSite) template_install() ! {
|
||||
build_publish_.template_write(build_publish, true)!
|
||||
build_publish_.chmod(0o700)!
|
||||
|
||||
mut build_dev_publish_ := site.path_build.file_get_new('build_dev_publish.sh')!
|
||||
build_dev_publish_.template_write(build_dev_publish, true)!
|
||||
build_dev_publish_.chmod(0o700)!
|
||||
// TODO: implement
|
||||
// mut build_dev_publish_ := site.path_build.file_get_new('build_dev_publish.sh')!
|
||||
// build_dev_publish_.template_write(build_dev_publish, true)!
|
||||
// build_dev_publish_.chmod(0o700)!
|
||||
|
||||
develop_templ := $tmpl('templates/develop_src.sh')
|
||||
mut develop2_ := site.path_src.file_get_new('develop.sh')!
|
||||
|
||||
@@ -18,9 +18,10 @@ pub mut:
|
||||
production bool
|
||||
watch_changes bool = true
|
||||
update bool
|
||||
open bool
|
||||
init bool // means create new one if needed
|
||||
deploykey string
|
||||
config ?Config
|
||||
config ?Configuration
|
||||
}
|
||||
|
||||
pub fn (mut f DocusaurusFactory) get(args_ DSiteGetArgs) !&DocSite {
|
||||
@@ -50,9 +51,13 @@ pub fn (mut f DocusaurusFactory) get(args_ DSiteGetArgs) !&DocSite {
|
||||
)!
|
||||
mut template_path := r.patho()!
|
||||
|
||||
// First, check if the new site args provides a configuration that can be written instead of template cfg dir
|
||||
// First, check if the new site args provides a configuration
|
||||
if cfg := args.config {
|
||||
cfg.write('${args.path}/cfg')!
|
||||
// Use the provided config
|
||||
generate_configuration(args.path, cfg)!
|
||||
} else if f.config.main.title != '' {
|
||||
// Use the factory's config from heroscript if available
|
||||
generate_configuration(args.path, f.config)!
|
||||
} else {
|
||||
// Then ensure cfg directory exists in src,
|
||||
if !os.exists('${args.path}/cfg') {
|
||||
@@ -65,17 +70,31 @@ pub fn (mut f DocusaurusFactory) get(args_ DSiteGetArgs) !&DocSite {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !os.exists('${args.path}/docs') {
|
||||
if args.init {
|
||||
mut template_cfg := template_path.dir_get('docs')!
|
||||
template_cfg.copy(dest: '${args.path}/docs')!
|
||||
// Create docs directory if it doesn't exist in template or site
|
||||
os.mkdir_all('${args.path}/docs')!
|
||||
|
||||
// Create a default docs/intro.md file
|
||||
intro_content := '---
|
||||
title: Introduction
|
||||
slug: /
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Welcome to the documentation site.
|
||||
|
||||
This is a default page created by the Docusaurus site generator.
|
||||
'
|
||||
os.write_file('${args.path}/docs/intro.md', intro_content)!
|
||||
} else {
|
||||
return error("Can't find docs dir in chosen docusaurus location: ${args.path}")
|
||||
}
|
||||
}
|
||||
|
||||
mut myconfig := load_config('${args.path}/cfg')!
|
||||
mut myconfig := load_configuration('${args.path}/cfg')!
|
||||
|
||||
if myconfig.main.name.len == 0 {
|
||||
myconfig.main.name = myconfig.main.base_url.trim_space().trim('/').trim_space()
|
||||
|
||||
@@ -5,7 +5,8 @@ import os
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
// import freeflowuniverse.herolib.ui.console
|
||||
// import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.develop.gittools
|
||||
// import freeflowuniverse.herolib.develop.gittools
|
||||
// import freeflowuniverse.herolib.ui.console
|
||||
|
||||
@[heap]
|
||||
pub struct DocusaurusFactory {
|
||||
@@ -13,16 +14,19 @@ pub mut:
|
||||
sites []&DocSite @[skip; str: skip]
|
||||
path_build pathlib.Path
|
||||
// path_publish pathlib.Path
|
||||
args DocusaurusArgs
|
||||
args DocusaurusArgs
|
||||
config Configuration // Stores configuration from HeroScript if provided
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct DocusaurusArgs {
|
||||
pub mut:
|
||||
// publish_path string
|
||||
build_path string
|
||||
production bool
|
||||
update bool
|
||||
build_path string
|
||||
production bool
|
||||
update bool
|
||||
heroscript string
|
||||
heroscript_path string
|
||||
}
|
||||
|
||||
pub fn new(args_ DocusaurusArgs) !&DocusaurusFactory {
|
||||
@@ -32,7 +36,9 @@ pub fn new(args_ DocusaurusArgs) !&DocusaurusFactory {
|
||||
}
|
||||
// if args.publish_path == ""{
|
||||
// args.publish_path = "${os.home_dir()}/hero/var/docusaurus/publish"
|
||||
// }
|
||||
// }
|
||||
|
||||
// Create the factory instance
|
||||
mut ds := &DocusaurusFactory{
|
||||
args: args_
|
||||
path_build: pathlib.get_dir(path: args.build_path, create: true)!
|
||||
|
||||
229
lib/web/docusaurus/generate.v
Normal file
229
lib/web/docusaurus/generate.v
Normal file
@@ -0,0 +1,229 @@
|
||||
module docusaurus
|
||||
|
||||
import freeflowuniverse.herolib.develop.gittools
|
||||
import freeflowuniverse.herolib.osal
|
||||
import freeflowuniverse.herolib.installers.web.bun
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import json
|
||||
import os
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
@[params]
|
||||
struct TemplateInstallArgs {
|
||||
template_update bool = true
|
||||
install bool = true
|
||||
delete bool = true
|
||||
}
|
||||
|
||||
pub fn (mut site DocSite) generate() ! {
|
||||
console.print_header(' site generate: ${site.name} on ${site.path_build.path}')
|
||||
console.print_header(' site source on ${site.path_src.path}')
|
||||
site.check()!
|
||||
site.template_install()!
|
||||
|
||||
site.config = fix_configuration(site.config)!
|
||||
generate_configuration(site.path_build.path, site.config)!
|
||||
generate_docusaurus_config_ts(site.path_build.path, site.config)!
|
||||
|
||||
// Now copy all directories that exist in src to build
|
||||
for item in ['src', 'static', 'cfg'] {
|
||||
if os.exists('${site.path_src.path}/${item}') {
|
||||
mut aa := site.path_src.dir_get(item)!
|
||||
aa.copy(dest: '${site.path_build.path}/${item}')!
|
||||
}
|
||||
}
|
||||
for item in ['docs'] {
|
||||
if os.exists('${site.path_src.path}/${item}') {
|
||||
mut aa := site.path_src.dir_get(item)!
|
||||
aa.copy(dest: '${site.path_build.path}/${item}', delete: true)!
|
||||
}
|
||||
}
|
||||
|
||||
mut gs := gittools.new()!
|
||||
|
||||
// for item in site.config.import_sources {
|
||||
// mypath := gs.get_path(
|
||||
// pull: false
|
||||
// reset: false
|
||||
// url: item.url
|
||||
// )!
|
||||
// mut mypatho := pathlib.get(mypath)
|
||||
// site.process_md(mut mypatho, item)!
|
||||
// }
|
||||
}
|
||||
|
||||
fn generate_configuration(path string, config Configuration) ! {
|
||||
cfg_path := os.join_path(path, 'cfg')
|
||||
|
||||
mut main_file := pathlib.get_file(path: '${cfg_path}/main.json', create: true)!
|
||||
main_file.write(json.encode(config.main))!
|
||||
|
||||
mut navbar_file := pathlib.get_file(path: '${cfg_path}/navbar.json', create: true)!
|
||||
navbar_file.write(json.encode(config.navbar))!
|
||||
|
||||
mut footer_file := pathlib.get_file(path: '${cfg_path}/footer.json', create: true)!
|
||||
footer_file.write(json.encode(config.footer))!
|
||||
}
|
||||
|
||||
fn generate_docusaurus_config_ts(path string, config Configuration) ! {
|
||||
mut config_file := pathlib.get_file(
|
||||
path: os.join_path(path, 'docusaurus.config.ts')
|
||||
create: true
|
||||
)!
|
||||
content := $tmpl('templates/docusaurus.config.ts')
|
||||
config_file.write(content)!
|
||||
}
|
||||
|
||||
fn (mut self DocusaurusFactory) template_install(args TemplateInstallArgs) ! {
|
||||
mut gs := gittools.new()!
|
||||
|
||||
mut r := gs.get_repo(
|
||||
url: 'https://github.com/freeflowuniverse/docusaurus_template.git'
|
||||
pull: args.template_update
|
||||
)!
|
||||
mut template_path := r.patho()!
|
||||
|
||||
// always start from template first for static assets and source files
|
||||
for item in ['src', 'static'] {
|
||||
mut aa := template_path.dir_get(item)!
|
||||
aa.copy(dest: '${self.path_build.path}/${item}', delete: args.delete)!
|
||||
}
|
||||
|
||||
// Generate config files dynamically from config
|
||||
self.generate_package_json()!
|
||||
self.generate_tsconfig_json()!
|
||||
self.generate_sidebars_ts()!
|
||||
self.generate_gitignore()!
|
||||
|
||||
if args.install {
|
||||
// install bun
|
||||
mut installer := bun.get()!
|
||||
installer.install()!
|
||||
|
||||
osal.exec(
|
||||
cmd: '
|
||||
${osal.profile_path_source_and()!}
|
||||
export PATH=/tmp/docusaurus_build/node_modules/.bin:${os.home_dir()}/.bun/bin/:??PATH
|
||||
cd ${self.path_build.path}
|
||||
bun install
|
||||
'
|
||||
)!
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut self DocusaurusFactory) generate_gitignore() ! {
|
||||
mut gitignore := pathlib.get_file(
|
||||
path: os.join_path(self.path_build.path, '.gitignore')
|
||||
create: true
|
||||
)!
|
||||
content := $tmpl('templates/.gitignore')
|
||||
gitignore.write(content)!
|
||||
}
|
||||
|
||||
// Generate package.json based on the configuration
|
||||
fn (mut self DocusaurusFactory) generate_package_json() ! {
|
||||
// Build package.json content as a structured JSON string
|
||||
mut name := 'docusaurus-site'
|
||||
if self.config.main.name != '' {
|
||||
name = self.config.main.name
|
||||
} else if self.config.navbar.title != '' {
|
||||
name = self.config.navbar.title.to_lower().replace(' ', '-')
|
||||
}
|
||||
|
||||
// Load package.json from template
|
||||
// The 'name' variable is defined in this function's scope and will be used by $tmpl.
|
||||
content := $tmpl('templates/package.json')
|
||||
mut package_file := pathlib.get_file(
|
||||
path: os.join_path(self.path_build.path, 'package.json')
|
||||
create: true
|
||||
)!
|
||||
package_file.write(content)!
|
||||
}
|
||||
|
||||
// Generate tsconfig.json based on the configuration
|
||||
fn (mut self DocusaurusFactory) generate_tsconfig_json() ! {
|
||||
// Load tsconfig.json from template
|
||||
content := $tmpl('templates/tsconfig.json')
|
||||
mut tsconfig_file := pathlib.get_file(
|
||||
path: os.join_path(self.path_build.path, 'tsconfig.json')
|
||||
create: true
|
||||
)!
|
||||
tsconfig_file.write(content)!
|
||||
}
|
||||
|
||||
// Generate sidebars.ts based on the configuration
|
||||
fn (mut self DocusaurusFactory) generate_sidebars_ts() ! {
|
||||
// Load sidebars.ts from template
|
||||
content := $tmpl('templates/sidebars.ts')
|
||||
mut sidebars_file := pathlib.get_file(
|
||||
path: os.join_path(self.path_build.path, 'sidebars.ts')
|
||||
create: true
|
||||
)!
|
||||
sidebars_file.write(content)!
|
||||
}
|
||||
|
||||
// // Generate docusaurus.config.ts based on the configuration
|
||||
// fn (mut self DocusaurusFactory) generate_docusaurus_config_ts() ! {
|
||||
// // Use config values with fallbacks
|
||||
// title := if self.config.main.title != '' { self.config.main.title } else { 'Docusaurus Site' }
|
||||
|
||||
// // Format navbar items from config
|
||||
// mut navbar_items_list_temp := []string{}
|
||||
// for item in self.config.navbar.items {
|
||||
// navbar_items_list_temp << "{
|
||||
// label: '${item.label}',
|
||||
// href: '${item.href}',
|
||||
// position: '${item.position}'
|
||||
// }"
|
||||
// }
|
||||
|
||||
// // Generate footer links if available
|
||||
// mut footer_links_list_temp := []string{}
|
||||
// for link in self.config.footer.links {
|
||||
// mut items_temp := []string{}
|
||||
// for item in link.items {
|
||||
// mut item_str := '{'
|
||||
// if item.label != '' {
|
||||
// item_str += "label: '${item.label}', "
|
||||
// }
|
||||
// if item.href != '' {
|
||||
// item_str += "href: '${item.href}'"
|
||||
// } else if item.to != '' {
|
||||
// item_str += "to: '${item.to}'"
|
||||
// } else {
|
||||
// item_str += "to: '/docs'" // Default link
|
||||
// }
|
||||
// item_str += '}'
|
||||
// items_temp << item_str
|
||||
// }
|
||||
// footer_links_list_temp << "{
|
||||
// title: '${link.title}',
|
||||
// items: [
|
||||
// ${items_temp.join(',\n ')}
|
||||
// ]
|
||||
// }"
|
||||
// }
|
||||
|
||||
// // Year for copyright
|
||||
// year := time.now().year.str()
|
||||
|
||||
// // Copyright string (variable `copyright` must be in scope for the template)
|
||||
// // `title` is defined at line 181, `year` is defined above.
|
||||
// copyright := if self.config.main.copyright != '' {
|
||||
// self.config.main.copyright
|
||||
// } else {
|
||||
// 'Copyright © ${year} ${title}'
|
||||
// }
|
||||
|
||||
// // Load docusaurus.config.ts from template
|
||||
// // All required variables (title, tagline, favicon, url, base_url,
|
||||
// // projectName, navbarTitle, navbarItems, footerLinks, copyright)
|
||||
// // are in scope for $tmpl.
|
||||
// content := $tmpl('templates/docusaurus.config.ts')
|
||||
|
||||
// mut config_file := pathlib.get_file(
|
||||
// path: os.join_path(self.path_build.path, 'docusaurus.config.ts')
|
||||
// create: true
|
||||
// )!
|
||||
// config_file.write(content)!
|
||||
// }
|
||||
101
lib/web/docusaurus/model_configuration.v
Normal file
101
lib/web/docusaurus/model_configuration.v
Normal file
@@ -0,0 +1,101 @@
|
||||
module docusaurus
|
||||
|
||||
import os
|
||||
import json
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
pub struct Configuration {
|
||||
pub mut:
|
||||
main Main
|
||||
navbar Navbar
|
||||
footer Footer
|
||||
}
|
||||
|
||||
pub struct Main {
|
||||
pub mut:
|
||||
title string
|
||||
tagline string
|
||||
favicon string
|
||||
url string
|
||||
base_url string @[json: 'baseUrl']
|
||||
url_home string
|
||||
image string
|
||||
metadata Metadata
|
||||
build_dest []string @[json: 'buildDest']
|
||||
build_dest_dev []string @[json: 'buildDestDev']
|
||||
copyright string
|
||||
name string
|
||||
}
|
||||
|
||||
pub struct Metadata {
|
||||
pub mut:
|
||||
description string
|
||||
image string
|
||||
title string
|
||||
}
|
||||
|
||||
pub struct Navbar {
|
||||
pub mut:
|
||||
title string
|
||||
logo Logo
|
||||
items []NavbarItem
|
||||
}
|
||||
|
||||
pub struct Logo {
|
||||
pub mut:
|
||||
alt string
|
||||
src string
|
||||
src_dark string @[json: 'srcDark']
|
||||
}
|
||||
|
||||
pub struct NavbarItem {
|
||||
pub mut:
|
||||
label string
|
||||
href string
|
||||
position string
|
||||
to string
|
||||
}
|
||||
|
||||
pub struct Footer {
|
||||
pub mut:
|
||||
style string
|
||||
links []FooterLink
|
||||
}
|
||||
|
||||
pub struct FooterLink {
|
||||
pub mut:
|
||||
title string
|
||||
items []FooterItem
|
||||
}
|
||||
|
||||
pub struct FooterItem {
|
||||
pub mut:
|
||||
label string
|
||||
href string
|
||||
to string
|
||||
}
|
||||
|
||||
pub fn load_configuration(cfg_path string) !Configuration {
|
||||
mut main_json := pathlib.get_file(path: os.join_path(cfg_path, 'main.json'))!
|
||||
mut navbar_json := pathlib.get_file(path: os.join_path(cfg_path, 'navbar.json'))!
|
||||
mut footer_json := pathlib.get_file(path: os.join_path(cfg_path, 'footer.json'))!
|
||||
mut cfg := Configuration{
|
||||
main: json.decode(Main, main_json.read()!)!,
|
||||
navbar: json.decode(Navbar, navbar_json.read()!)!,
|
||||
footer: json.decode(Footer, footer_json.read()!)!
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
pub fn fix_configuration(config Configuration) !Configuration {
|
||||
return Configuration {
|
||||
...config,
|
||||
main: Main {
|
||||
...config.main,
|
||||
title: if config.main.title == "" { "Docusaurus" } else { config.main.title },
|
||||
favicon: if config.main.favicon == "" { "img/favicon.ico" } else { config.main.favicon },
|
||||
url: if config.main.url == "" { "https://example.com" } else { config.main.url },
|
||||
base_url: if config.main.base_url == "" { "/" } else { config.main.base_url },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
module docusaurus
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
|
||||
@[params]
|
||||
pub struct PlayArgs {
|
||||
pub mut:
|
||||
heroscript string // if filled in then playbook will be made out of it
|
||||
plbook ?PlayBook
|
||||
reset bool
|
||||
}
|
||||
|
||||
// Process the heroscript and return a filled Config object
|
||||
pub fn play(args_ PlayArgs) ! {
|
||||
mut plbook := playbook.new(text: args_.heroscript)!
|
||||
mut config := Config{}
|
||||
|
||||
play_config(mut plbook, mut config)!
|
||||
play_config_meta(mut plbook, mut config)!
|
||||
play_ssh_connection(mut plbook, mut config)!
|
||||
play_import_source(mut plbook, mut config)!
|
||||
play_build_dest(mut plbook, mut config)!
|
||||
play_navbar(mut plbook, mut config)!
|
||||
play_footer(mut plbook, mut config)!
|
||||
}
|
||||
|
||||
fn play_config(mut plbook PlayBook, mut config Config) ! {
|
||||
config_actions := plbook.find(filter: 'docusaurus.config')!
|
||||
for action in config_actions {
|
||||
mut p := action.params
|
||||
config.main = Main{
|
||||
title: p.get_default('title', 'Internet Geek')!
|
||||
tagline: p.get_default('tagline', 'Internet Geek')!
|
||||
favicon: p.get_default('favicon', 'img/favicon.png')!
|
||||
url: p.get_default('url', 'https://friends.threefold.info')!
|
||||
url_home: p.get_default('url_home', 'docs/')!
|
||||
base_url: p.get_default('base_url', '/testsite/')!
|
||||
image: p.get_default('image', 'img/tf_graph.png')!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn play_config_meta(mut plbook PlayBook, mut config Config) ! {
|
||||
meta_actions := plbook.find(filter: 'docusaurus.config_meta')!
|
||||
for action in meta_actions {
|
||||
mut p := action.params
|
||||
config.main.metadata = MainMetadata{
|
||||
description: p.get_default('description', 'ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.')!
|
||||
image: p.get_default('image', 'https://threefold.info/something/img/tf_graph.png')!
|
||||
title: p.get_default('title', 'ThreeFold Technology Vision')!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn play_ssh_connection(mut plbook PlayBook, mut config Config) ! {
|
||||
ssh_actions := plbook.find(filter: 'docusaurus.ssh_connection')!
|
||||
for action in ssh_actions {
|
||||
mut p := action.params
|
||||
mut ssh := SSHConnection{
|
||||
name: p.get_default('name', 'main')!
|
||||
host: p.get_default('host', 'info.ourworld.tf')!
|
||||
port: p.get_int_default('port', 21)!
|
||||
login: p.get_default('login', 'root')!
|
||||
key_path: p.get_default('key_path', '')!
|
||||
key: p.get_default('key', '')!
|
||||
}
|
||||
config.ssh_connections << ssh
|
||||
}
|
||||
}
|
||||
|
||||
fn play_import_source(mut plbook PlayBook, mut config Config) ! {
|
||||
import_actions := plbook.find(filter: 'docusaurus.import_source')!
|
||||
for action in import_actions {
|
||||
mut p := action.params
|
||||
mut replace_map := map[string]string{}
|
||||
if replace_str := p.get_default('replace', '') {
|
||||
parts := replace_str.split(',')
|
||||
for part in parts {
|
||||
kv := part.split(':')
|
||||
if kv.len == 2 {
|
||||
replace_map[kv[0].trim_space()] = kv[1].trim_space()
|
||||
}
|
||||
}
|
||||
}
|
||||
mut import_ := ImportSource{
|
||||
url: p.get('url')!
|
||||
path: p.get_default('path', '')!
|
||||
dest: p.get_default('dest', '')!
|
||||
replace: replace_map
|
||||
}
|
||||
config.import_sources << import_
|
||||
}
|
||||
}
|
||||
|
||||
fn play_build_dest(mut plbook PlayBook, mut config Config) ! {
|
||||
build_actions := plbook.find(filter: 'docusaurus.build_dest')!
|
||||
for action in build_actions {
|
||||
mut p := action.params
|
||||
mut build := BuildDest{
|
||||
ssh_name: p.get_default('ssh_name', 'main')!
|
||||
path: p.get_default('path', '')!
|
||||
}
|
||||
config.build_destinations << build
|
||||
}
|
||||
}
|
||||
|
||||
fn play_navbar(mut plbook PlayBook, mut config Config) ! {
|
||||
navbar_actions := plbook.find(filter: 'docusaurus.navbar')!
|
||||
for action in navbar_actions {
|
||||
mut p := action.params
|
||||
config.navbar.title = p.get_default('title', 'Chief Executive Geek')!
|
||||
}
|
||||
|
||||
navbar_item_actions := plbook.find(filter: 'docusaurus.navbar_item')!
|
||||
for action in navbar_item_actions {
|
||||
mut p := action.params
|
||||
mut item := NavbarItem{
|
||||
label: p.get_default('label', 'ThreeFold Technology')!
|
||||
href: p.get_default('href', 'https://threefold.info/tech')!
|
||||
position: p.get_default('position', 'right')!
|
||||
}
|
||||
config.navbar.items << item
|
||||
}
|
||||
}
|
||||
|
||||
fn play_footer(mut plbook PlayBook, mut config Config) ! {
|
||||
footer_actions := plbook.find(filter: 'docusaurus.footer')!
|
||||
for action in footer_actions {
|
||||
mut p := action.params
|
||||
config.footer.style = p.get_default('style', 'dark')!
|
||||
}
|
||||
|
||||
footer_item_actions := plbook.find(filter: 'docusaurus.footer_item')!
|
||||
mut links_map := map[string][]FooterItem{}
|
||||
|
||||
for action in footer_item_actions {
|
||||
mut p := action.params
|
||||
title := p.get_default('title', 'Docs')!
|
||||
mut item := FooterItem{
|
||||
label: p.get_default('label', 'Introduction')!
|
||||
to: p.get_default('to', '/docs')!
|
||||
href: p.get_default('href', '')!
|
||||
}
|
||||
|
||||
if title !in links_map {
|
||||
links_map[title] = []FooterItem{}
|
||||
}
|
||||
links_map[title] << item
|
||||
}
|
||||
|
||||
// Convert map to footer links array
|
||||
for title, items in links_map {
|
||||
config.footer.links << FooterLink{
|
||||
title: title
|
||||
items: items
|
||||
}
|
||||
}
|
||||
}
|
||||
35
lib/web/docusaurus/process.v
Normal file
35
lib/web/docusaurus/process.v
Normal file
@@ -0,0 +1,35 @@
|
||||
module docusaurus
|
||||
|
||||
|
||||
// fn (mut site DocSite) process_md(mut path pathlib.Path, args ImportSource) ! {
|
||||
// if path.is_dir() {
|
||||
// mut pathlist_images := path.list(
|
||||
// regex: [r'.*\.png$', r'.*\.jpg$', r'.*\.svg$', r'.*\.jpeg$']
|
||||
// recursive: true
|
||||
// )!
|
||||
// for mut mypatho_img in pathlist_images.paths {
|
||||
// // now copy the image to the dest
|
||||
// dest := '${site.path_build.path}/docs/${args.dest}/img/${texttools.name_fix(mypatho_img.name())}'
|
||||
// // println("image copy: ${dest}")
|
||||
// mypatho_img.copy(dest: dest, rsync: false)!
|
||||
// }
|
||||
|
||||
// mut pathlist := path.list(regex: [r'.*\.md$'], recursive: true)!
|
||||
// for mut mypatho2 in pathlist.paths {
|
||||
// site.process_md(mut mypatho2, args)!
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
// mydest := '${site.path_build.path}/docs/${args.dest}/${texttools.name_fix(path.name())}'
|
||||
// mut mydesto := pathlib.get_file(path: mydest, create: true)!
|
||||
|
||||
// mut mymd := markdownparser.new(path: path.path)!
|
||||
// mut myfm := mymd.frontmatter2()!
|
||||
// if !args.visible {
|
||||
// myfm.args['draft'] = 'true'
|
||||
// }
|
||||
// // println(myfm)
|
||||
// // println(mymd.markdown()!)
|
||||
// mydesto.write(mymd.markdown()!)!
|
||||
// // Note: exit(0) was removed to prevent unexpected program termination
|
||||
// }
|
||||
@@ -1,60 +0,0 @@
|
||||
module docusaurus
|
||||
|
||||
import freeflowuniverse.herolib.develop.gittools
|
||||
import freeflowuniverse.herolib.osal
|
||||
import freeflowuniverse.herolib.installers.web.bun
|
||||
import os
|
||||
|
||||
@[params]
|
||||
struct TemplateInstallArgs {
|
||||
template_update bool = true
|
||||
install bool
|
||||
delete bool = true
|
||||
}
|
||||
|
||||
fn (mut self DocusaurusFactory) template_install(args TemplateInstallArgs) ! {
|
||||
mut gs := gittools.new()!
|
||||
|
||||
mut r := gs.get_repo(
|
||||
url: 'https://github.com/freeflowuniverse/docusaurus_template.git'
|
||||
pull: args.template_update
|
||||
)!
|
||||
mut template_path := r.patho()!
|
||||
|
||||
for item in ['package.json', 'sidebars.ts', 'tsconfig.json'] {
|
||||
mut aa := template_path.file_get(item)!
|
||||
aa.copy(dest: '${self.path_build.path}/${item}')!
|
||||
}
|
||||
|
||||
// always start from template first
|
||||
for item in ['src', 'static'] {
|
||||
mut aa := template_path.dir_get(item)!
|
||||
aa.copy(dest: '${self.path_build.path}/${item}', delete: args.delete)!
|
||||
}
|
||||
|
||||
for item in ['package.json', 'sidebars.ts', 'tsconfig.json', 'docusaurus.config.ts'] {
|
||||
src_path := os.join_path(template_path.path, item)
|
||||
dest_path := os.join_path(self.path_build.path, item)
|
||||
os.cp(src_path, dest_path) or {
|
||||
return error('Failed to copy ${item} to build path: ${err}')
|
||||
}
|
||||
}
|
||||
|
||||
if args.install {
|
||||
// install bun
|
||||
mut installer := bun.get()!
|
||||
installer.install()!
|
||||
|
||||
osal.exec(
|
||||
cmd: '
|
||||
${osal.profile_path_source_and()!}
|
||||
export PATH=/tmp/docusaurus_build/node_modules/.bin:${os.home_dir()}/.bun/bin/:??PATH
|
||||
cd ${self.path_build.path}
|
||||
bun install
|
||||
'
|
||||
)!
|
||||
}
|
||||
|
||||
mut aa := template_path.dir_get('docs') or { return }
|
||||
aa.delete()!
|
||||
}
|
||||
21
lib/web/docusaurus/templates/.gitignore
vendored
Normal file
21
lib/web/docusaurus/templates/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# build output
|
||||
build
|
||||
.docusaurus
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
script_dir="???cd "???dirname "??{BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "??{script_dir}"
|
||||
|
||||
|
||||
echo "Docs directory: ??script_dir"
|
||||
|
||||
cd "${mydir}"
|
||||
|
||||
export PATH=/tmp/docusaurus_build/node_modules/.bin:??{HOME}/.bun/bin/:??PATH
|
||||
|
||||
rm -rf ${site.path_build.path}/build/
|
||||
|
||||
${profile_include}
|
||||
|
||||
bun docusaurus build
|
||||
|
||||
@for dest in cfg.main.build_dest_dev
|
||||
rsync -rv --delete ${site.path_build.path}/build/ ${dest.trim_right("/")}/
|
||||
@end
|
||||
94
lib/web/docusaurus/templates/docusaurus.config.ts
Normal file
94
lib/web/docusaurus/templates/docusaurus.config.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import {themes as prismThemes} from 'prism-react-renderer';
|
||||
import type {Configuration} from '@@docusaurus/types';
|
||||
import type * as Preset from '@@docusaurus/preset-classic';
|
||||
|
||||
const config: Configuration = {
|
||||
title: '@{config.main.title}',
|
||||
tagline: '@{config.main.tagline}',
|
||||
favicon: '@{config.main.favicon}',
|
||||
|
||||
// Set the production url of your site here
|
||||
url: '@{config.main.url}',
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: '@{config.main.base_url}',
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: 'freeflowuniverse', // Usually your GitHub org/user name.
|
||||
projectName: '@{config.main.name}', // Usually your repo name.
|
||||
|
||||
onBrokenLinks: 'warn',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
// Enable for i18n
|
||||
// i18n: {
|
||||
// defaultLocale: 'en',
|
||||
// locales: ['en'],
|
||||
// },
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
{
|
||||
docs: {
|
||||
sidebarPath: './sidebars.ts',
|
||||
},
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
},
|
||||
} satisfies Preset.Options,
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig: {
|
||||
// Replace with your project's social card
|
||||
image: 'img/docusaurus-social-card.jpg',
|
||||
colorMode: {
|
||||
defaultMode: 'dark',
|
||||
},
|
||||
navbar: {
|
||||
title: '@{config.navbar.title}',
|
||||
items: [
|
||||
@for item in config.navbar.items
|
||||
{
|
||||
label: '@{item.label}',
|
||||
href: '@{item.href}',
|
||||
position: '@{item.position}'
|
||||
},
|
||||
@end
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: '@{config.footer.style}',
|
||||
links: [
|
||||
@for link_group in config.footer.links
|
||||
{
|
||||
title: '@{link_group.title}',
|
||||
items: [
|
||||
@for item in link_group.items
|
||||
{
|
||||
label: '@{item.label}',
|
||||
@if item.href != ''
|
||||
href: '@{item.href}'
|
||||
@else if item.to != ''
|
||||
to: '@{item.to}'
|
||||
@else
|
||||
to: '/docs'
|
||||
@end
|
||||
},
|
||||
@end
|
||||
]
|
||||
},
|
||||
@end
|
||||
],
|
||||
copyright: '@{config.main.copyright}',
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
},
|
||||
} satisfies Preset.ThemeConfig,
|
||||
};
|
||||
|
||||
export default config;
|
||||
39
lib/web/docusaurus/templates/package.json
Normal file
39
lib/web/docusaurus/templates/package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@{name}",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@@docusaurus/core": "^3.1.0",
|
||||
"@@docusaurus/preset-classic": "^3.1.0",
|
||||
"@@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@@docusaurus/module-type-aliases": "^3.1.0",
|
||||
"@@docusaurus/tsconfig": "^3.1.0",
|
||||
"@@docusaurus/types": "^3.1.0",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [">0.5%", "not dead", "not op_mini all"],
|
||||
"development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
}
|
||||
18
lib/web/docusaurus/templates/sidebars.ts
Normal file
18
lib/web/docusaurus/templates/sidebars.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type {SidebarsConfig} from '@@docusaurus/plugin-content-docs';
|
||||
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
const sidebars: SidebarsConfig = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
8
lib/web/docusaurus/templates/tsconfig.json
Normal file
8
lib/web/docusaurus/templates/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@@docusaurus/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*", "docusaurus.config.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user