...
This commit is contained in:
@@ -13,12 +13,12 @@ prod_mode := fp.bool('prod', `p`, false, 'Build production version (optimized)')
|
||||
help_requested := fp.bool('help', `h`, false, 'Show help message')
|
||||
|
||||
if help_requested {
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
}
|
||||
|
||||
additional_args := fp.finalize() or {
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env -S v -n -cg -w -parallel-cc -enable-globals run
|
||||
// #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
// #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
import os
|
||||
import flag
|
||||
|
||||
@@ -14,20 +14,20 @@ prod_mode := fp.bool('prod', `p`, false, 'Build production version (optimized)')
|
||||
help_requested := fp.bool('help', `h`, false, 'Show help message')
|
||||
|
||||
if help_requested {
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
}
|
||||
|
||||
additional_args := fp.finalize() or {
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if additional_args.len > 0 {
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Change to the hero directory
|
||||
@@ -37,35 +37,37 @@ os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}
|
||||
// Set HEROPATH based on OS
|
||||
mut heropath := '/usr/local/bin/hero'
|
||||
if os.user_os() == 'macos' {
|
||||
heropath = os.join_path(os.home_dir(), 'hero/bin/hero')
|
||||
heropath = os.join_path(os.home_dir(), 'hero/bin/hero')
|
||||
}
|
||||
|
||||
// Set compilation command based on OS and mode
|
||||
compile_cmd := if os.user_os() == 'macos' {
|
||||
if prod_mode {
|
||||
'v -enable-globals -w -n -prod hero.v'
|
||||
} else {
|
||||
'v -w -cg -gc none -cc tcc -d use_openssl -enable-globals hero.v'
|
||||
}
|
||||
if prod_mode {
|
||||
'v -enable-globals -w -n -prod hero.v'
|
||||
} else {
|
||||
'v -w -cg -gc none -cc tcc -d use_openssl -enable-globals hero.v'
|
||||
}
|
||||
} else {
|
||||
if prod_mode {
|
||||
'v -cg -enable-globals -parallel-cc -w -n hero.v'
|
||||
} else {
|
||||
'v -cg -enable-globals -w -n hero.v'
|
||||
}
|
||||
if prod_mode {
|
||||
'v -cg -enable-globals -parallel-cc -w -n hero.v'
|
||||
} else {
|
||||
'v -cg -enable-globals -w -n hero.v'
|
||||
}
|
||||
}
|
||||
|
||||
println('Building in ${if prod_mode { 'production' } else { 'debug' }} mode...')
|
||||
|
||||
if os.system(compile_cmd) != 0 {
|
||||
panic('Failed to compile hero.v with command: ${compile_cmd}')
|
||||
panic('Failed to compile hero.v with command: ${compile_cmd}')
|
||||
}
|
||||
|
||||
// Make executable
|
||||
os.chmod('hero', 0o755) or { panic('Failed to make hero binary executable: ${err}') }
|
||||
|
||||
// Ensure destination directory exists
|
||||
os.mkdir_all(os.dir(heropath)) or { panic('Failed to create directory ${os.dir(heropath)}: ${err}') }
|
||||
os.mkdir_all(os.dir(heropath)) or {
|
||||
panic('Failed to create directory ${os.dir(heropath)}: ${err}')
|
||||
}
|
||||
println(heropath)
|
||||
// Copy to destination paths
|
||||
os.cp('hero', heropath) or { panic('Failed to copy hero binary to ${heropath}: ${err}') }
|
||||
|
||||
@@ -64,7 +64,9 @@ account = ${s3keyid}
|
||||
key = ${s3appid}
|
||||
hard_delete = true'
|
||||
|
||||
os.write_file(rclone_conf, config_content) or { return error('Failed to write rclone config: ${err}') }
|
||||
os.write_file(rclone_conf, config_content) or {
|
||||
return error('Failed to write rclone config: ${err}')
|
||||
}
|
||||
|
||||
println('made S3 config on: ${rclone_conf}')
|
||||
content := os.read_file(rclone_conf) or { return error('Failed to read rclone config: ${err}') }
|
||||
@@ -72,8 +74,10 @@ hard_delete = true'
|
||||
}
|
||||
|
||||
fn hero_upload() ! {
|
||||
hero_path := os.find_abs_path_of_executable('hero') or { return error("Error: 'hero' command not found in PATH") }
|
||||
|
||||
hero_path := os.find_abs_path_of_executable('hero') or {
|
||||
return error("Error: 'hero' command not found in PATH")
|
||||
}
|
||||
|
||||
s3_configure()!
|
||||
|
||||
platform_id := get_platform_id()
|
||||
@@ -83,15 +87,18 @@ fn hero_upload() ! {
|
||||
|
||||
// List contents
|
||||
os.execute_or_panic('rclone --config="${rclone_conf}" lsl b2:threefold/${platform_id}/')
|
||||
|
||||
|
||||
// Copy hero binary
|
||||
os.execute_or_panic('rclone --config="${rclone_conf}" copy "${hero_path}" b2:threefold/${platform_id}/')
|
||||
}
|
||||
|
||||
fn main() {
|
||||
//os.execute_or_panic('${os.home_dir()}/code/github/freeflowuniverse/herolib/cli/compile.vsh -p')
|
||||
println("compile hero can take 60 sec+ on osx.")
|
||||
// os.execute_or_panic('${os.home_dir()}/code/github/freeflowuniverse/herolib/cli/compile.vsh -p')
|
||||
println('compile hero can take 60 sec+ on osx.')
|
||||
os.execute_or_panic('${os.home_dir()}/code/github/freeflowuniverse/herolib/cli/compile.vsh -p')
|
||||
println( "upload:")
|
||||
hero_upload() or { eprintln(err) exit(1) }
|
||||
println('upload:')
|
||||
hero_upload() or {
|
||||
eprintln(err)
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env -S v -n -cg -w -parallel-cc -enable-globals run
|
||||
// #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
// #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
import os
|
||||
import flag
|
||||
|
||||
@@ -14,20 +14,20 @@ prod_mode := fp.bool('prod', `p`, false, 'Build production version (optimized)')
|
||||
help_requested := fp.bool('help', `h`, false, 'Show help message')
|
||||
|
||||
if help_requested {
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
}
|
||||
|
||||
additional_args := fp.finalize() or {
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if additional_args.len > 0 {
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Change to the vdo directory
|
||||
@@ -37,35 +37,37 @@ os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}
|
||||
// Set HEROPATH based on OS
|
||||
mut heropath := '/usr/local/bin/vdo'
|
||||
if os.user_os() == 'macos' {
|
||||
heropath = os.join_path(os.home_dir(), 'hero/bin/vdo')
|
||||
heropath = os.join_path(os.home_dir(), 'hero/bin/vdo')
|
||||
}
|
||||
|
||||
// Set compilation command based on OS and mode
|
||||
compile_cmd := if os.user_os() == 'macos' {
|
||||
if prod_mode {
|
||||
'v -enable-globals -w -n -prod vdo.v'
|
||||
} else {
|
||||
'v -w -cg -gc none -cc tcc -d use_openssl -enable-globals vdo.v'
|
||||
}
|
||||
if prod_mode {
|
||||
'v -enable-globals -w -n -prod vdo.v'
|
||||
} else {
|
||||
'v -w -cg -gc none -cc tcc -d use_openssl -enable-globals vdo.v'
|
||||
}
|
||||
} else {
|
||||
if prod_mode {
|
||||
'v -cg -enable-globals -parallel-cc -w -n vdo.v'
|
||||
} else {
|
||||
'v -cg -enable-globals -w -n vdo.v'
|
||||
}
|
||||
if prod_mode {
|
||||
'v -cg -enable-globals -parallel-cc -w -n vdo.v'
|
||||
} else {
|
||||
'v -cg -enable-globals -w -n vdo.v'
|
||||
}
|
||||
}
|
||||
|
||||
println('Building in ${if prod_mode { 'production' } else { 'debug' }} mode...')
|
||||
|
||||
if os.system(compile_cmd) != 0 {
|
||||
panic('Failed to compile vdo.v with command: ${compile_cmd}')
|
||||
panic('Failed to compile vdo.v with command: ${compile_cmd}')
|
||||
}
|
||||
|
||||
// Make executable
|
||||
os.chmod('vdo', 0o755) or { panic('Failed to make vdo binary executable: ${err}') }
|
||||
|
||||
// Ensure destination directory exists
|
||||
os.mkdir_all(os.dir(heropath)) or { panic('Failed to create directory ${os.dir(heropath)}: ${err}') }
|
||||
os.mkdir_all(os.dir(heropath)) or {
|
||||
panic('Failed to create directory ${os.dir(heropath)}: ${err}')
|
||||
}
|
||||
println(heropath)
|
||||
// Copy to destination paths
|
||||
os.cp('vdo', heropath) or { panic('Failed to copy vdo binary to ${heropath}: ${err}') }
|
||||
|
||||
@@ -15,7 +15,7 @@ import freeflowuniverse.herolib.core.playcmds
|
||||
|
||||
fn playcmds_do(path string) ! {
|
||||
mut plbook := playbook.new(path: path)!
|
||||
playcmds.run(plbook:plbook)!
|
||||
playcmds.run(plbook: plbook)!
|
||||
}
|
||||
|
||||
fn do() ! {
|
||||
@@ -114,4 +114,4 @@ fn main() {
|
||||
|
||||
fn pre_func(cmd Command) ! {
|
||||
herocmds.plbook_run(cmd)!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ fn main() {
|
||||
// Create and start the MCP server
|
||||
mut server := v_do.new_server()
|
||||
server.start() or {
|
||||
eprintln('Error starting server: $err')
|
||||
eprintln('Error starting server: ${err}')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
35
doc.vsh
35
doc.vsh
@@ -7,13 +7,13 @@ abs_dir_of_script := dir(@FILE)
|
||||
// Format code
|
||||
println('Formatting code...')
|
||||
if os.system('v fmt -w ${abs_dir_of_script}/examples') != 0 {
|
||||
eprintln('Warning: Failed to format examples')
|
||||
exit(1)
|
||||
eprintln('Warning: Failed to format examples')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if os.system('v fmt -w ${abs_dir_of_script}/lib') != 0 {
|
||||
eprintln('Warning: Failed to format herolib')
|
||||
exit(1)
|
||||
eprintln('Warning: Failed to format herolib')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Clean existing docs
|
||||
@@ -24,9 +24,7 @@ os.rmdir_all('docs') or {}
|
||||
os.rmdir_all('vdocs') or {}
|
||||
|
||||
herolib_path := os.join_path(abs_dir_of_script, 'lib')
|
||||
os.chdir(herolib_path) or {
|
||||
panic('Failed to change directory to herolib: ${err}')
|
||||
}
|
||||
os.chdir(herolib_path) or { panic('Failed to change directory to herolib: ${err}') }
|
||||
|
||||
os.mkdir_all('_docs') or {}
|
||||
os.mkdir_all('docs') or {}
|
||||
@@ -35,17 +33,14 @@ os.mkdir_all('vdocs') or {}
|
||||
// Generate HTML documentation
|
||||
println('Generating HTML documentation...')
|
||||
if os.system('v doc -m -f html . -readme -comments -no-timestamp -o ../docs') != 0 {
|
||||
panic('Failed to generate HTML documentation')
|
||||
panic('Failed to generate HTML documentation')
|
||||
}
|
||||
|
||||
if os.system('v doc -m -f md . -no-color -o ../vdocs/') != 0 {
|
||||
panic('Failed to generate Hero markdown documentation')
|
||||
panic('Failed to generate Hero markdown documentation')
|
||||
}
|
||||
|
||||
|
||||
os.chdir(abs_dir_of_script) or {
|
||||
panic('Failed to change directory to abs_dir_of_script: ${err}')
|
||||
}
|
||||
os.chdir(abs_dir_of_script) or { panic('Failed to change directory to abs_dir_of_script: ${err}') }
|
||||
|
||||
// Generate Markdown documentation
|
||||
println('Generating Markdown documentation...')
|
||||
@@ -60,12 +55,10 @@ println('Generating Markdown documentation...')
|
||||
|
||||
// Open documentation in browser on non-Linux systems
|
||||
$if !linux {
|
||||
os.chdir(abs_dir_of_script) or {
|
||||
panic('Failed to change directory: ${err}')
|
||||
}
|
||||
if os.system('open docs/index.html') != 0 {
|
||||
eprintln('Warning: Failed to open documentation in browser')
|
||||
}
|
||||
os.chdir(abs_dir_of_script) or { panic('Failed to change directory: ${err}') }
|
||||
if os.system('open docs/index.html') != 0 {
|
||||
eprintln('Warning: Failed to open documentation in browser')
|
||||
}
|
||||
}
|
||||
|
||||
// Create Jekyll required files
|
||||
@@ -75,7 +68,7 @@ os.mkdir_all('docs/assets/css') or {}
|
||||
// Create style.scss
|
||||
style_content := '---\n---\n\n@import "{{ site.theme }}";'
|
||||
os.write_file('docs/assets/css/style.scss', style_content) or {
|
||||
panic('Failed to create style.scss: ${err}')
|
||||
panic('Failed to create style.scss: ${err}')
|
||||
}
|
||||
|
||||
// Create _config.yml
|
||||
@@ -94,7 +87,7 @@ exclude:
|
||||
- vendor/ruby/'
|
||||
|
||||
os.write_file('docs/_config.yml', config_content) or {
|
||||
panic('Failed to create _config.yml: ${err}')
|
||||
panic('Failed to create _config.yml: ${err}')
|
||||
}
|
||||
|
||||
println('Documentation generation completed successfully!')
|
||||
|
||||
@@ -4,46 +4,45 @@ import os
|
||||
import flag
|
||||
|
||||
fn addtoscript(tofind string, toadd string) ! {
|
||||
home_dir := os.home_dir()
|
||||
mut rc_file := '${home_dir}/.zshrc'
|
||||
if !os.exists(rc_file) {
|
||||
rc_file = '${home_dir}/.bashrc'
|
||||
if !os.exists(rc_file) {
|
||||
return error('No .zshrc or .bashrc found in home directory')
|
||||
}
|
||||
}
|
||||
home_dir := os.home_dir()
|
||||
mut rc_file := '${home_dir}/.zshrc'
|
||||
if !os.exists(rc_file) {
|
||||
rc_file = '${home_dir}/.bashrc'
|
||||
if !os.exists(rc_file) {
|
||||
return error('No .zshrc or .bashrc found in home directory')
|
||||
}
|
||||
}
|
||||
|
||||
// Read current content
|
||||
mut content := os.read_file(rc_file)!
|
||||
|
||||
// Remove existing alias if present
|
||||
lines := content.split('\n')
|
||||
mut new_lines := []string{}
|
||||
mut prev_is_emtpy := false
|
||||
for line in lines {
|
||||
if prev_is_emtpy {
|
||||
if line.trim_space() == ""{
|
||||
continue
|
||||
}else{
|
||||
prev_is_emtpy = false
|
||||
}
|
||||
}
|
||||
if line.trim_space() == ""{
|
||||
prev_is_emtpy = true
|
||||
}
|
||||
// Read current content
|
||||
mut content := os.read_file(rc_file)!
|
||||
|
||||
if !line.contains(tofind) {
|
||||
new_lines << line
|
||||
}
|
||||
}
|
||||
new_lines << toadd
|
||||
new_lines << ""
|
||||
// Write back to file
|
||||
new_content := new_lines.join('\n')
|
||||
os.write_file(rc_file, new_content)!
|
||||
// Remove existing alias if present
|
||||
lines := content.split('\n')
|
||||
mut new_lines := []string{}
|
||||
mut prev_is_emtpy := false
|
||||
for line in lines {
|
||||
if prev_is_emtpy {
|
||||
if line.trim_space() == '' {
|
||||
continue
|
||||
} else {
|
||||
prev_is_emtpy = false
|
||||
}
|
||||
}
|
||||
if line.trim_space() == '' {
|
||||
prev_is_emtpy = true
|
||||
}
|
||||
|
||||
if !line.contains(tofind) {
|
||||
new_lines << line
|
||||
}
|
||||
}
|
||||
new_lines << toadd
|
||||
new_lines << ''
|
||||
// Write back to file
|
||||
new_content := new_lines.join('\n')
|
||||
os.write_file(rc_file, new_content)!
|
||||
}
|
||||
|
||||
|
||||
vroot := @VROOT
|
||||
abs_dir_of_script := dir(@FILE)
|
||||
|
||||
@@ -52,20 +51,20 @@ println('Resetting all symlinks...')
|
||||
os.rm('${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {}
|
||||
|
||||
// Create necessary directories
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
||||
}
|
||||
|
||||
// Create new symlinks
|
||||
os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {
|
||||
panic('Failed to create herolib symlink: ${err}')
|
||||
panic('Failed to create herolib symlink: ${err}')
|
||||
}
|
||||
|
||||
println('Herolib installation completed successfully!')
|
||||
|
||||
// Add vtest alias
|
||||
addtoscript('alias vtest=', 'alias vtest=\'v -stats -enable-globals -n -w -cg -gc none -cc tcc test\' ') or {
|
||||
eprintln('Failed to add vtest alias: ${err}')
|
||||
addtoscript('alias vtest=', "alias vtest='v -stats -enable-globals -n -w -cg -gc none -cc tcc test' ") or {
|
||||
eprintln('Failed to add vtest alias: ${err}')
|
||||
}
|
||||
|
||||
println('Added vtest alias to shell configuration')
|
||||
|
||||
@@ -5,9 +5,9 @@ import freeflowuniverse.herolib.web.ui
|
||||
fn main() {
|
||||
println('Starting UI test server on port 8080...')
|
||||
println('Visit http://localhost:8080 to see the admin interface')
|
||||
|
||||
|
||||
ui.start(
|
||||
title: 'Test Admin Panel'
|
||||
port: 8080
|
||||
port: 8080
|
||||
)!
|
||||
}
|
||||
}
|
||||
|
||||
30
generate.vsh
30
generate.vsh
@@ -10,41 +10,39 @@ fp.version('v0.1.0')
|
||||
fp.description('Generate code')
|
||||
fp.skip_executable()
|
||||
|
||||
mut path := fp.string('path', `p`, "", 'Path where to generate a module, if not mentioned will scan over all installers & clients.\nif . then will be path we are on.')
|
||||
mut path := fp.string('path', `p`, '', 'Path where to generate a module, if not mentioned will scan over all installers & clients.\nif . then will be path we are on.')
|
||||
reset := fp.bool('reset', `r`, false, 'If we want to reset')
|
||||
interactive := fp.bool('interactive', `i`, false, 'If we want to work interactive')
|
||||
scan := fp.bool('scan', `s`, false, 'If we want to scan')
|
||||
help_requested := fp.bool('help', `h`, false, 'Show help message')
|
||||
|
||||
if help_requested {
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
println(fp.usage())
|
||||
exit(0)
|
||||
}
|
||||
|
||||
additional_args := fp.finalize() or {
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln(err)
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if additional_args.len > 0 {
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
eprintln('Unexpected arguments: ${additional_args.join(' ')}')
|
||||
println(fp.usage())
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// reset bool // regenerate all, dangerous !!!
|
||||
// interactive bool //if we want to ask
|
||||
// path string
|
||||
|
||||
|
||||
|
||||
if path.trim_space() == "." {
|
||||
if path.trim_space() == '.' {
|
||||
path = os.getwd()
|
||||
}
|
||||
|
||||
if ! scan {
|
||||
generator.do(path:path, reset:reset, interactive:interactive)!
|
||||
}else{
|
||||
generator.scan(path:path, reset:reset, interactive:interactive)!
|
||||
if !scan {
|
||||
generator.do(path: path, reset: reset, interactive: interactive)!
|
||||
} else {
|
||||
generator.scan(path: path, reset: reset, interactive: interactive)!
|
||||
}
|
||||
|
||||
@@ -4,46 +4,45 @@ import os
|
||||
import flag
|
||||
|
||||
fn addtoscript(tofind string, toadd string) ! {
|
||||
home_dir := os.home_dir()
|
||||
mut rc_file := '${home_dir}/.zshrc'
|
||||
if !os.exists(rc_file) {
|
||||
rc_file = '${home_dir}/.bashrc'
|
||||
if !os.exists(rc_file) {
|
||||
return error('No .zshrc or .bashrc found in home directory')
|
||||
}
|
||||
}
|
||||
home_dir := os.home_dir()
|
||||
mut rc_file := '${home_dir}/.zshrc'
|
||||
if !os.exists(rc_file) {
|
||||
rc_file = '${home_dir}/.bashrc'
|
||||
if !os.exists(rc_file) {
|
||||
return error('No .zshrc or .bashrc found in home directory')
|
||||
}
|
||||
}
|
||||
|
||||
// Read current content
|
||||
mut content := os.read_file(rc_file)!
|
||||
|
||||
// Remove existing alias if present
|
||||
lines := content.split('\n')
|
||||
mut new_lines := []string{}
|
||||
mut prev_is_emtpy := false
|
||||
for line in lines {
|
||||
if prev_is_emtpy {
|
||||
if line.trim_space() == ""{
|
||||
continue
|
||||
}else{
|
||||
prev_is_emtpy = false
|
||||
}
|
||||
}
|
||||
if line.trim_space() == ""{
|
||||
prev_is_emtpy = true
|
||||
}
|
||||
// Read current content
|
||||
mut content := os.read_file(rc_file)!
|
||||
|
||||
if !line.contains(tofind) {
|
||||
new_lines << line
|
||||
}
|
||||
}
|
||||
new_lines << toadd
|
||||
new_lines << ""
|
||||
// Write back to file
|
||||
new_content := new_lines.join('\n')
|
||||
os.write_file(rc_file, new_content)!
|
||||
// Remove existing alias if present
|
||||
lines := content.split('\n')
|
||||
mut new_lines := []string{}
|
||||
mut prev_is_emtpy := false
|
||||
for line in lines {
|
||||
if prev_is_emtpy {
|
||||
if line.trim_space() == '' {
|
||||
continue
|
||||
} else {
|
||||
prev_is_emtpy = false
|
||||
}
|
||||
}
|
||||
if line.trim_space() == '' {
|
||||
prev_is_emtpy = true
|
||||
}
|
||||
|
||||
if !line.contains(tofind) {
|
||||
new_lines << line
|
||||
}
|
||||
}
|
||||
new_lines << toadd
|
||||
new_lines << ''
|
||||
// Write back to file
|
||||
new_content := new_lines.join('\n')
|
||||
os.write_file(rc_file, new_content)!
|
||||
}
|
||||
|
||||
|
||||
vroot := @VROOT
|
||||
abs_dir_of_script := dir(@FILE)
|
||||
|
||||
@@ -52,29 +51,29 @@ println('Resetting all symlinks...')
|
||||
os.rm('${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {}
|
||||
|
||||
// Create necessary directories
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
||||
}
|
||||
|
||||
// Create new symlinks
|
||||
os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {
|
||||
panic('Failed to create herolib symlink: ${err}')
|
||||
panic('Failed to create herolib symlink: ${err}')
|
||||
}
|
||||
|
||||
println('Herolib installation completed successfully!')
|
||||
|
||||
// Add vtest alias
|
||||
addtoscript('alias vtest=', 'alias vtest=\'v -stats -enable-globals -show-c-output -n -w -cg -gc none -cc tcc test\' ') or {
|
||||
eprintln('Failed to add vtest alias: ${err}')
|
||||
addtoscript('alias vtest=', "alias vtest='v -stats -enable-globals -show-c-output -n -w -cg -gc none -cc tcc test' ") or {
|
||||
eprintln('Failed to add vtest alias: ${err}')
|
||||
}
|
||||
|
||||
// Add vrun alias
|
||||
addtoscript('alias vrun=', 'alias vrun=\'v -stats -enable-globals -show-c-output -n -w -cg -gc none -cc tcc run\' ') or {
|
||||
eprintln('Failed to add vrun alias: ${err}')
|
||||
addtoscript('alias vrun=', "alias vrun='v -stats -enable-globals -show-c-output -n -w -cg -gc none -cc tcc run' ") or {
|
||||
eprintln('Failed to add vrun alias: ${err}')
|
||||
}
|
||||
|
||||
addtoscript('HOME/hero/bin', 'export PATH="\$PATH:\$HOME/hero/bin"') or {
|
||||
eprintln('Failed to add path to hero, ${err}')
|
||||
eprintln('Failed to add path to hero, ${err}')
|
||||
}
|
||||
|
||||
// ulimit -n 32000
|
||||
|
||||
@@ -7,6 +7,6 @@ import os
|
||||
|
||||
// your checking & initialization code if needed
|
||||
fn (mut ws RepromptWorkspace) reprompt() !string {
|
||||
//TODO: fill in template based on selection
|
||||
return ""
|
||||
// TODO: fill in template based on selection
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ pub mut:
|
||||
selections []string // paths selected in the RepromptDir
|
||||
}
|
||||
|
||||
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ RepromptWorkspace) !RepromptWorkspace {
|
||||
mut mycfg := mycfg_
|
||||
@@ -37,13 +36,13 @@ fn obj_init(mycfg_ RepromptWorkspace) !RepromptWorkspace {
|
||||
/////////////NORMALLY NO NEED TO TOUCH
|
||||
|
||||
pub fn heroscript_dumps(obj RepromptWorkspace) !string {
|
||||
//create heroscript following template
|
||||
//check for our homedir on our machine and replace in the heroscript to @HOME in path
|
||||
// create heroscript following template
|
||||
// check for our homedir on our machine and replace in the heroscript to @HOME in path
|
||||
return encoderhero.encode[RepromptWorkspace](obj)!
|
||||
}
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !RepromptWorkspace {
|
||||
//TODO: parse heroscript populate RepromptWorkspace
|
||||
// TODO: parse heroscript populate RepromptWorkspace
|
||||
mut obj := encoderhero.decode[RepromptWorkspace](heroscript)!
|
||||
return obj
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.web.docusaurus
|
||||
import os
|
||||
import cli { Command, Flag }
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
|
||||
pub fn cmd_docusaurus(mut cmdroot Command) Command {
|
||||
mut cmd_run := Command{
|
||||
@@ -113,94 +114,98 @@ pub fn cmd_docusaurus(mut cmdroot Command) Command {
|
||||
// description: 'create a new docusaurus site.'
|
||||
// })
|
||||
|
||||
cmd_run.add_flag(Flag{
|
||||
flag: .bool
|
||||
required: false
|
||||
name: 'reset'
|
||||
abbrev: 'r'
|
||||
description: 'reset the docusaurus building process, reinstall all.'
|
||||
})
|
||||
|
||||
cmdroot.add_command(cmd_run)
|
||||
return cmdroot
|
||||
}
|
||||
|
||||
fn cmd_docusaurus_execute(cmd Command) ! {
|
||||
// ---------- FLAGS ----------
|
||||
mut open := cmd.flags.get_bool('open') or { false }
|
||||
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 }
|
||||
mut new := cmd.flags.get_bool('new') or { false }
|
||||
mut reset := cmd.flags.get_bool('reset') or { false }
|
||||
// (the earlier duplicate reset flag has been removed)
|
||||
|
||||
// --- Build Path Logic ---
|
||||
mut build_path := cmd.flags.get_string('buildpath') or { '' }
|
||||
if build_path == '' {
|
||||
build_path = '${os.home_dir()}/hero/var/docusaurus'
|
||||
}
|
||||
|
||||
// --- Path Logic ---
|
||||
mut provided_path := cmd.flags.get_string('path') or { '' }
|
||||
// ---------- PATH LOGIC ----------
|
||||
// Resolve the source directory that contains a “cfg” sub‑directory.
|
||||
mut path := cmd.flags.get_string('path') or { '' }
|
||||
mut source_path := ''
|
||||
|
||||
if provided_path != '' {
|
||||
if !os.exists(provided_path) || !os.is_dir(provided_path) {
|
||||
return error('Provided path "${provided_path}" does not exist or is not a directory.')
|
||||
if path != '' {
|
||||
// user supplied a path
|
||||
if !os.exists(path) || !os.is_dir(path) {
|
||||
return error('Provided path "${path}" does not exist or is not a directory.')
|
||||
}
|
||||
|
||||
// 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) {
|
||||
source_path = provided_path
|
||||
cfg_subdir := os.join_path(path, 'cfg')
|
||||
source_path = if os.exists(cfg_subdir) && os.is_dir(cfg_subdir) {
|
||||
path
|
||||
} else if path.ends_with('cfg') {
|
||||
os.dir(path)
|
||||
} else {
|
||||
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.')
|
||||
}
|
||||
return error('Provided path "${path}" does not contain a “cfg” subdirectory.')
|
||||
}
|
||||
} else {
|
||||
mut cwd := os.getwd()
|
||||
// default to current working directory
|
||||
cwd := os.getwd()
|
||||
cfg_dir := os.join_path(cwd, 'cfg')
|
||||
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.')
|
||||
return error('No path supplied and "./cfg" not found in the current directory.')
|
||||
}
|
||||
source_path = cwd
|
||||
}
|
||||
|
||||
console.print_header('Running Docusaurus for: ${source_path}')
|
||||
|
||||
// Use the centralized site processing function from docusaurus module
|
||||
mysite := docusaurus.process_site_from_path(source_path, '')!
|
||||
site_name := mysite.siteconfig.name
|
||||
// ---------- BUILD PLAYBOOK ----------
|
||||
// Build a PlayBook from the source directory (it contains the HeroScript actions)
|
||||
mut plbook := playbook.new(path: source_path)!
|
||||
|
||||
// Set up the docusaurus factory
|
||||
docusaurus.factory_set(
|
||||
path_build: build_path
|
||||
reset: reset
|
||||
install: reset
|
||||
template_update: reset
|
||||
)!
|
||||
// If the user asked for a CLI‑level reset we inject a temporary define action
|
||||
// so that the underlying factory_set receives `reset:true`.
|
||||
if reset {
|
||||
// prepend a temporary docusaurus.define action (this is safe because the playbook
|
||||
// already contains the real definitions, the extra one will just be ignored later)
|
||||
mut reset_action := playbook.Action{
|
||||
actor: 'docusaurus'
|
||||
name: 'define'
|
||||
params: {
|
||||
'reset': 'true'
|
||||
}
|
||||
done: false
|
||||
}
|
||||
// Insert at the front of the action list
|
||||
plbook.actions.prepend(reset_action)
|
||||
}
|
||||
|
||||
// Add the docusaurus site
|
||||
mut dsite := docusaurus.dsite_add(
|
||||
sitename: site_name
|
||||
path: source_path
|
||||
play: false // Site already processed
|
||||
)!
|
||||
// ---------- RUN DOCUSUROUS ----------
|
||||
// This will:
|
||||
// * read the generic `site.*` definitions,
|
||||
// * create a Docusaurus factory (or reuse an existing one),
|
||||
// * add the site to the factory via `dsite_add`.
|
||||
docusaurus.play(mut plbook)!
|
||||
|
||||
// Execute the requested action directly
|
||||
// After `play` we should have exactly one site in the global map.
|
||||
// Retrieve it – if more than one exists we pick the one whose source path matches.
|
||||
mut dsite_opt := docusaurus.dsite_get(plbook.ensure_once(filter: 'site.define')!.params.get('name')!) or {
|
||||
// fallback: take the first entry
|
||||
if docusaurus_sites.len == 0 {
|
||||
return error('No Docusaurus site was created by the playbook.')
|
||||
}
|
||||
docusaurus_sites.values()[0]!
|
||||
}
|
||||
|
||||
// ---------- ACTIONS ----------
|
||||
if buildpublish {
|
||||
dsite.build_publish()!
|
||||
dsite_opt.build_publish()!
|
||||
} else if builddevpublish {
|
||||
dsite.build()!
|
||||
dsite_opt.build()!
|
||||
} else if dev {
|
||||
dsite.dev(
|
||||
dsite_opt.dev(
|
||||
open: open
|
||||
watch_changes: false
|
||||
)!
|
||||
} else {
|
||||
dsite.build()!
|
||||
// default: just build the static site
|
||||
dsite_opt.build()!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
module herocmds
|
||||
|
||||
// import freeflowuniverse.herolib.web.mdbook
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import cli { Command, Flag }
|
||||
import os
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
// path string //if location on filessytem, if exists, this has prio on git_url
|
||||
// git_url string // location of where the hero scripts are
|
||||
// git_pull bool // means when getting new repo will pull even when repo is already there
|
||||
// git_pullreset bool // means we will force a pull and reset old content
|
||||
// coderoot string //the location of coderoot if its another one
|
||||
pub fn cmd_mdbook(mut cmdroot Command) {
|
||||
mut cmd_mdbook := Command{
|
||||
name: 'mdbook'
|
||||
usage: '
|
||||
## Manage your MDBooks
|
||||
|
||||
example:
|
||||
|
||||
hero mdbook -u https://git.threefold.info/tfgrid/info_tfgrid/src/branch/main/heroscript
|
||||
|
||||
If you do -gp it will pull newest book content from git and give error if there are local changes.
|
||||
If you do -gr it will pull newest book content from git and overwrite local changes (careful).
|
||||
|
||||
'
|
||||
description: 'create, edit, show mdbooks'
|
||||
required_args: 0
|
||||
execute: cmd_mdbook_execute
|
||||
}
|
||||
|
||||
cmd_run_add_flags(mut cmd_mdbook)
|
||||
|
||||
cmd_mdbook.add_flag(Flag{
|
||||
flag: .string
|
||||
name: 'name'
|
||||
abbrev: 'n'
|
||||
description: 'name of the mdbook.'
|
||||
})
|
||||
|
||||
// cmd_mdbook.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'edit'
|
||||
// description: 'will open vscode for collections & summary.'
|
||||
// })
|
||||
|
||||
cmd_mdbook.add_flag(Flag{
|
||||
flag: .bool
|
||||
required: false
|
||||
name: 'open'
|
||||
abbrev: 'o'
|
||||
description: 'will open the generated book.'
|
||||
})
|
||||
|
||||
mut cmd_list := Command{
|
||||
sort_flags: true
|
||||
name: 'list'
|
||||
execute: cmd_mdbook_list
|
||||
description: 'will list existing mdbooks'
|
||||
}
|
||||
|
||||
cmd_mdbook.add_command(cmd_list)
|
||||
cmdroot.add_command(cmd_mdbook)
|
||||
}
|
||||
|
||||
fn cmd_mdbook_list(cmd Command) ! {
|
||||
console.print_header('MDBooks:')
|
||||
build_path := os.join_path(os.home_dir(), 'hero/var/mdbuild')
|
||||
mut build_dir := pathlib.get_dir(path: build_path)!
|
||||
list := build_dir.list(
|
||||
recursive: false
|
||||
dirs_only: true
|
||||
)!
|
||||
for path in list.paths {
|
||||
console.print_stdout(path.name())
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_mdbook_execute(cmd Command) ! {
|
||||
mut name := cmd.flags.get_string('name') or { '' }
|
||||
|
||||
mut url := cmd.flags.get_string('url') or { '' }
|
||||
mut path := cmd.flags.get_string('path') or { '' }
|
||||
if path.len > 0 || url.len > 0 {
|
||||
// execute the attached plbook
|
||||
mut plbook, _ := plbook_run(cmd)!
|
||||
// get name from the book.generate action
|
||||
if name == '' {
|
||||
mut a := plbook.get(filter: 'book.define')!
|
||||
name = a.params.get('name') or { '' }
|
||||
}
|
||||
} else {
|
||||
mdbook_help(cmd)
|
||||
}
|
||||
|
||||
if name == '' {
|
||||
console.print_debug('did not find name of book to generate, check in heroscript or specify with --name')
|
||||
mdbook_help(cmd)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
edit := cmd.flags.get_bool('edit') or { false }
|
||||
open := cmd.flags.get_bool('open') or { false }
|
||||
if edit || open {
|
||||
// mdbook.book_open(name)!
|
||||
}
|
||||
|
||||
if edit {
|
||||
// mdbook.book_edit(name)!
|
||||
}
|
||||
}
|
||||
|
||||
fn mdbook_help(cmd Command) {
|
||||
console.clear()
|
||||
console.print_header('Instructions for mdbook:')
|
||||
console.print_lf(1)
|
||||
console.print_stdout(cmd.help_message())
|
||||
console.print_lf(5)
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
module herocmds
|
||||
|
||||
// import freeflowuniverse.herolib.web.starlight
|
||||
import os
|
||||
import cli
|
||||
|
||||
// pub fn cmd_starlight(mut cmdroot Command) {
|
||||
// mut cmd_run := Command{
|
||||
// name: 'starlight'
|
||||
// description: 'Generate, build, run starlight sites.'
|
||||
// required_args: 0
|
||||
// execute: cmd_starlight_execute
|
||||
// }
|
||||
|
||||
// // cmd_run.add_flag(Flag{
|
||||
// // flag: .bool
|
||||
// // required: false
|
||||
// // name: 'reset'
|
||||
// // abbrev: 'r'
|
||||
// // description: 'will reset.'
|
||||
// // })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .string
|
||||
// required: false
|
||||
// name: 'url'
|
||||
// abbrev: 'u'
|
||||
// // default: ''
|
||||
// description: 'Url where starlight source is.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .string
|
||||
// required: false
|
||||
// name: 'path'
|
||||
// abbrev: 'p'
|
||||
// // default: ''
|
||||
// description: 'Path where starlight source is.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .string
|
||||
// required: false
|
||||
// name: 'deploykey'
|
||||
// abbrev: 'dk'
|
||||
// // default: ''
|
||||
// description: 'Path of SSH Key used to deploy.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .string
|
||||
// required: false
|
||||
// name: 'publish'
|
||||
// // default: ''
|
||||
// description: 'Path where to publish.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'buildpublish'
|
||||
// abbrev: 'bp'
|
||||
// description: 'build and publish.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'builddevpublish'
|
||||
// abbrev: 'bpd'
|
||||
// description: 'build dev version and publish.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'update'
|
||||
// description: 'update your environment the template and the repo you are working on (git pull).'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'dev'
|
||||
// abbrev: 'd'
|
||||
// description: 'Run your dev environment on local browser.'
|
||||
// })
|
||||
|
||||
// cmd_run.add_flag(Flag{
|
||||
// flag: .bool
|
||||
// required: false
|
||||
// name: 'new'
|
||||
// abbrev: 'n'
|
||||
// description: 'create a new starlight site.'
|
||||
// })
|
||||
|
||||
// cmdroot.add_command(cmd_run)
|
||||
// }
|
||||
|
||||
// fn cmd_starlight_execute(cmd Command) ! {
|
||||
// mut update := cmd.flags.get_bool('update') or { false }
|
||||
// mut init := cmd.flags.get_bool('new') or { false }
|
||||
// mut url := cmd.flags.get_string('url') or { '' }
|
||||
// mut publish_path := cmd.flags.get_string('publish') or { '' }
|
||||
// mut deploykey := cmd.flags.get_string('deploykey') or { '' }
|
||||
|
||||
// mut path := cmd.flags.get_string('path') 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 }
|
||||
|
||||
// // if build== false && build== false && build== false {
|
||||
// // eprintln("specify build, builddev or dev")
|
||||
// // exit(1)
|
||||
// // }
|
||||
|
||||
// mut docs := starlight.new(update: update)!
|
||||
// mut site := docs.get(
|
||||
// url: url
|
||||
// path: path
|
||||
// update: update
|
||||
// publish_path: publish_path
|
||||
// deploykey: deploykey
|
||||
// init: init
|
||||
// )!
|
||||
|
||||
// if publish_path.len > 0 {
|
||||
// site.build()!
|
||||
// }
|
||||
|
||||
// if buildpublish {
|
||||
// site.build_publish()!
|
||||
// }
|
||||
|
||||
// if builddevpublish {
|
||||
// site.build_dev_publish()!
|
||||
// }
|
||||
|
||||
// if dev {
|
||||
// site.dev(host: 'localhost', port: 3000)!
|
||||
// }
|
||||
// }
|
||||
@@ -92,21 +92,21 @@ pub fn (mut plbook PlayBook) find(args FindArgs) ![]&Action {
|
||||
return res
|
||||
}
|
||||
|
||||
//use this in play function to make sure we only have one of those actions, the one action is then returned
|
||||
pub fn (mut plbook PlayBook) ensure_once(args FindArgs) !&Action {
|
||||
// use this in play function to make sure we only have one of those actions, the one action is then returned
|
||||
pub fn (mut plbook PlayBook) ensure_once(args FindArgs) !&Action {
|
||||
mut res := plbook.find(args) or { [] }
|
||||
if res.len == 0 {
|
||||
return error('No actions found based on filter: ${args.filter}')
|
||||
}
|
||||
|
||||
if res.len > 1 {
|
||||
return error("More than 1 action found based on filter: ${args.filter}, this Playbook only supports 1.")
|
||||
return error('More than 1 action found based on filter: ${args.filter}, this Playbook only supports 1.')
|
||||
}
|
||||
return res[0] or { panic('bug') }
|
||||
}
|
||||
|
||||
//check its once, if not say that playbook only can have one action
|
||||
pub fn (mut plbook PlayBook)exists_once (args FindArgs) bool {
|
||||
// check its once, if not say that playbook only can have one action
|
||||
pub fn (mut plbook PlayBook) exists_once(args FindArgs) bool {
|
||||
mut res := plbook.find(args) or { [] }
|
||||
return res.len == 1
|
||||
}
|
||||
|
||||
@@ -21,27 +21,27 @@ pub mut:
|
||||
}
|
||||
|
||||
pub fn run(args_ PlayArgs) ! {
|
||||
mut args := args_
|
||||
mut plbook := args.plbook or {
|
||||
playbook.new(text: args.heroscript, path: args.heroscript_path)!
|
||||
}
|
||||
mut args := args_
|
||||
mut plbook := args.plbook or {
|
||||
playbook.new(text: args.heroscript, path: args.heroscript_path)!
|
||||
}
|
||||
|
||||
// Core actions
|
||||
play_core(mut plbook)!
|
||||
// Git actions
|
||||
play_git(mut plbook)!
|
||||
// Core actions
|
||||
play_core(mut plbook)!
|
||||
// Git actions
|
||||
play_git(mut plbook)!
|
||||
|
||||
// Business model (e.g. currency, bizmodel)
|
||||
bizmodel.play(mut plbook)!
|
||||
// Business model (e.g. currency, bizmodel)
|
||||
bizmodel.play(mut plbook)!
|
||||
|
||||
// OpenAI client
|
||||
openai.play(mut plbook)!
|
||||
// OpenAI client
|
||||
openai.play(mut plbook)!
|
||||
|
||||
// Website / docs
|
||||
site.play(mut plbook)!
|
||||
doctree.play(mut plbook)!
|
||||
docusaurus.play(mut plbook)!
|
||||
// Website / docs
|
||||
site.play(mut plbook)!
|
||||
doctree.play(mut plbook)!
|
||||
docusaurus.play(mut plbook)!
|
||||
|
||||
// Ensure we did not leave any actions un‑processed
|
||||
plbook.empty_check()!
|
||||
// Ensure we did not leave any actions un‑processed
|
||||
plbook.empty_check()!
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn (mut site DocSite) generate() ! {
|
||||
mut aa := site.path_src.dir_get('docs')!
|
||||
aa.copy(dest: '${f.path_build.path}/docs', delete: true)!
|
||||
}
|
||||
|
||||
|
||||
mut main_file := pathlib.get_file(path: '${cfg_path}/main.json', create: true)!
|
||||
main_file.write(json.encode_pretty(site.config.main))!
|
||||
|
||||
@@ -56,11 +56,10 @@ pub fn (mut site DocSite) generate() ! {
|
||||
mut footer_file := pathlib.get_file(path: '${cfg_path}/footer.json', create: true)!
|
||||
footer_file.write(json.encode_pretty(site.config.footer))!
|
||||
|
||||
|
||||
// Generate the actual docs content from the processed site configuration
|
||||
docs_path := '${f.path_build.path}/docs'
|
||||
|
||||
//TODO: check site vs website
|
||||
// TODO: check site vs website
|
||||
website := site.website
|
||||
generate_docs(
|
||||
path: docs_path
|
||||
@@ -72,11 +71,12 @@ pub fn (mut site DocSite) generate() ! {
|
||||
|
||||
pub fn (mut site DocSite) process_imports() ! {
|
||||
mut gs := gittools.new()!
|
||||
mut f:=factory_get()!
|
||||
mut f := factory_get()!
|
||||
|
||||
for item in site.website.siteconfig.imports {
|
||||
|
||||
if true{panic("not implemented import")}
|
||||
if true {
|
||||
panic('not implemented import')
|
||||
}
|
||||
|
||||
mypath := gs.get_path(
|
||||
pull: false
|
||||
@@ -88,7 +88,7 @@ pub fn (mut site DocSite) process_imports() ! {
|
||||
mypatho.copy(dest: '${f.path_build.path}/docs/${item.dest}', delete: false)!
|
||||
|
||||
println(item)
|
||||
//replace: {'NAME': 'MyName', 'URGENCY': 'red'}
|
||||
// replace: {'NAME': 'MyName', 'URGENCY': 'red'}
|
||||
mut ri := regext.regex_instructions_new()
|
||||
for key, val in item.replace {
|
||||
ri.add_item('\{${key}\}', val)!
|
||||
|
||||
@@ -8,8 +8,6 @@ import freeflowuniverse.herolib.web.site
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.osal.core as osal
|
||||
|
||||
|
||||
|
||||
@[params]
|
||||
pub struct AddArgs {
|
||||
pub mut:
|
||||
@@ -71,7 +69,7 @@ pub fn dsite_add(args_ AddArgs) !&DocSite {
|
||||
|
||||
// Get the site object after processing, this is the website which is a generic definition of a site
|
||||
mut website := site.get(name: args.sitename)!
|
||||
|
||||
|
||||
// Create the DocSite instance
|
||||
mut dsite := &DocSite{
|
||||
name: args.sitename
|
||||
|
||||
@@ -15,7 +15,7 @@ mut:
|
||||
client &doctreeclient.DocTreeClient
|
||||
flat bool // if flat then won't use sitenames as subdir's
|
||||
site Site
|
||||
errors []string // collect errors here
|
||||
errors []string // collect errors here
|
||||
}
|
||||
|
||||
@[params]
|
||||
@@ -23,7 +23,7 @@ struct SiteGeneratorArgs {
|
||||
mut:
|
||||
path string
|
||||
flat bool // if flat then won't use sitenames as subdir's
|
||||
site Site //this is the generic website we are feeding
|
||||
site Site // this is the generic website we are feeding
|
||||
}
|
||||
|
||||
// Generate docs from site configuration
|
||||
@@ -51,16 +51,13 @@ pub fn generate_docs(args SiteGeneratorArgs) ! {
|
||||
if gen.errors.len > 0 {
|
||||
return error('Errors occurred during site generation:\n${gen.errors.join('\n\n')}\nPlease fix the errors and try again.\nPage List: is header collection and page name per collection.\nAvailable pages:\n${gen.client.list_markdown()!}')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fn (mut mysite SiteGenerator) error( msg string) ! {
|
||||
fn (mut mysite SiteGenerator) error(msg string) ! {
|
||||
console.print_stderr('Error: ${msg}')
|
||||
mysite.errors << msg
|
||||
}
|
||||
|
||||
|
||||
fn (mut mysite SiteGenerator) page_generate(args_ Page) ! {
|
||||
mut args := args_
|
||||
|
||||
@@ -69,7 +66,7 @@ fn (mut mysite SiteGenerator) page_generate(args_ Page) ! {
|
||||
mut parts := args.src.split(':')
|
||||
if parts.len != 2 {
|
||||
mysite.error("Invalid src format for page '${args.src}', expected format: collection:page_name, TODO: fix in ${args.path}, check the collection & page_name exists in the pagelist")!
|
||||
return
|
||||
return
|
||||
}
|
||||
collection_name := parts[0]
|
||||
page_name := parts[1]
|
||||
@@ -129,7 +126,7 @@ fn (mut mysite SiteGenerator) page_generate(args_ Page) ! {
|
||||
|
||||
c += '\n${page_content}\n'
|
||||
|
||||
if args.path.ends_with('/') || args.path.trim_space()=="" {
|
||||
if args.path.ends_with('/') || args.path.trim_space() == '' {
|
||||
// means is dir
|
||||
args.path += page_name
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
import freeflowuniverse.herolib.web.site
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
|
||||
if !plbook.exists(filter: 'docusaurus.') {
|
||||
return
|
||||
}
|
||||
@@ -36,9 +35,9 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
dsite_add(
|
||||
sitename: site_name
|
||||
path: p.get_default('path', '')!
|
||||
git_url: p.get_default('git_url','')!
|
||||
git_url: p.get_default('git_url', '')!
|
||||
git_reset: p.get_default_false('git_reset')
|
||||
git_root: p.get_default('git_root','')!
|
||||
git_root: p.get_default('git_root', '')!
|
||||
git_pull: p.get_default_false('git_pull')
|
||||
path_publish: p.get_default('path_publish', f.path_publish.path)!
|
||||
)!
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module site
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook { Action, PlayBook }
|
||||
import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import time
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'site.'){
|
||||
if !plbook.exists(filter: 'site.') {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
mut p := config_action.params
|
||||
name := p.get_default('name', 'default')! // Use 'default' as fallback name
|
||||
|
||||
//configure the website
|
||||
// configure the website
|
||||
mut website := new(name: name)!
|
||||
mut config := &website.siteconfig
|
||||
|
||||
@@ -30,7 +30,6 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
config.base_url = p.get_default('base_url', '/')!
|
||||
config.url_home = p.get_default('url_home', '')!
|
||||
|
||||
|
||||
// Process !!site.config_meta for specific metadata overrides
|
||||
mut meta_action := plbook.ensure_once(filter: 'site.config_meta')!
|
||||
mut p_meta := meta_action.params
|
||||
@@ -53,10 +52,8 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
play_build_dest_dev(mut plbook, mut config)!
|
||||
|
||||
play_pages(mut plbook, mut website)!
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn play_import(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
mut import_actions := plbook.find(filter: 'site.import')!
|
||||
// println('import_actions: ${import_actions}')
|
||||
|
||||
@@ -81,103 +81,89 @@ pub fn start(args FactoryArgs) ! {
|
||||
// Routes
|
||||
|
||||
// Redirect root to /admin
|
||||
@[get; '/']
|
||||
@['/'; get]
|
||||
pub fn (app &App) root(mut ctx Context) veb.Result {
|
||||
return ctx.redirect('/admin')
|
||||
}
|
||||
|
||||
// Admin home page
|
||||
@[get; '/admin']
|
||||
@['/admin'; get]
|
||||
pub fn (app &App) admin_index(mut ctx Context) veb.Result {
|
||||
return ctx.html(app.render_admin('/', 'Welcome'))
|
||||
}
|
||||
|
||||
// HeroScript editor page
|
||||
@[get; '/admin/heroscript']
|
||||
@['/admin/heroscript'; get]
|
||||
pub fn (app &App) admin_heroscript(mut ctx Context) veb.Result {
|
||||
return ctx.html(app.render_heroscript())
|
||||
}
|
||||
|
||||
// Chat page
|
||||
@[get; '/admin/chat']
|
||||
@['/admin/chat'; get]
|
||||
pub fn (app &App) admin_chat(mut ctx Context) veb.Result {
|
||||
return ctx.html(app.render_chat())
|
||||
}
|
||||
|
||||
// Static CSS files
|
||||
@[get; '/static/css/colors.css']
|
||||
@['/static/css/colors.css'; get]
|
||||
pub fn (app &App) serve_colors_css(mut ctx Context) veb.Result {
|
||||
css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'colors.css')
|
||||
css_content := os.read_file(css_path) or {
|
||||
return ctx.text('/* CSS file not found */')
|
||||
}
|
||||
css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') }
|
||||
ctx.set_content_type('text/css')
|
||||
return ctx.text(css_content)
|
||||
}
|
||||
|
||||
@[get; '/static/css/main.css']
|
||||
@['/static/css/main.css'; get]
|
||||
pub fn (app &App) serve_main_css(mut ctx Context) veb.Result {
|
||||
css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'main.css')
|
||||
css_content := os.read_file(css_path) or {
|
||||
return ctx.text('/* CSS file not found */')
|
||||
}
|
||||
css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') }
|
||||
ctx.set_content_type('text/css')
|
||||
return ctx.text(css_content)
|
||||
}
|
||||
|
||||
// Static JS files
|
||||
@[get; '/static/js/theme.js']
|
||||
@['/static/js/theme.js'; get]
|
||||
pub fn (app &App) serve_theme_js(mut ctx Context) veb.Result {
|
||||
js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'theme.js')
|
||||
js_content := os.read_file(js_path) or {
|
||||
return ctx.text('/* JS file not found */')
|
||||
}
|
||||
js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') }
|
||||
ctx.set_content_type('application/javascript')
|
||||
return ctx.text(js_content)
|
||||
}
|
||||
|
||||
@[get; '/static/js/heroscript.js']
|
||||
@['/static/js/heroscript.js'; get]
|
||||
pub fn (app &App) serve_heroscript_js(mut ctx Context) veb.Result {
|
||||
js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'heroscript.js')
|
||||
js_content := os.read_file(js_path) or {
|
||||
return ctx.text('/* JS file not found */')
|
||||
}
|
||||
js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') }
|
||||
ctx.set_content_type('application/javascript')
|
||||
return ctx.text(js_content)
|
||||
}
|
||||
|
||||
@[get; '/static/js/chat.js']
|
||||
@['/static/js/chat.js'; get]
|
||||
pub fn (app &App) serve_chat_js(mut ctx Context) veb.Result {
|
||||
js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'chat.js')
|
||||
js_content := os.read_file(js_path) or {
|
||||
return ctx.text('/* JS file not found */')
|
||||
}
|
||||
js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') }
|
||||
ctx.set_content_type('application/javascript')
|
||||
return ctx.text(js_content)
|
||||
}
|
||||
|
||||
@[get; '/static/css/heroscript.css']
|
||||
@['/static/css/heroscript.css'; get]
|
||||
pub fn (app &App) serve_heroscript_css(mut ctx Context) veb.Result {
|
||||
css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'heroscript.css')
|
||||
css_content := os.read_file(css_path) or {
|
||||
return ctx.text('/* CSS file not found */')
|
||||
}
|
||||
css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') }
|
||||
ctx.set_content_type('text/css')
|
||||
return ctx.text(css_content)
|
||||
}
|
||||
|
||||
@[get; '/static/css/chat.css']
|
||||
@['/static/css/chat.css'; get]
|
||||
pub fn (app &App) serve_chat_css(mut ctx Context) veb.Result {
|
||||
css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'chat.css')
|
||||
css_content := os.read_file(css_path) or {
|
||||
return ctx.text('/* CSS file not found */')
|
||||
}
|
||||
css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') }
|
||||
ctx.set_content_type('text/css')
|
||||
return ctx.text(css_content)
|
||||
}
|
||||
|
||||
// Catch-all content under /admin/*
|
||||
@[get; '/admin/:path...']
|
||||
@['/admin/:path...'; get]
|
||||
pub fn (app &App) admin_section(mut ctx Context, path string) veb.Result {
|
||||
// Render current path in the main content
|
||||
return ctx.html(app.render_admin(path, 'Content'))
|
||||
@@ -188,16 +174,16 @@ pub fn (app &App) admin_section(mut ctx Context, path string) veb.Result {
|
||||
fn (app &App) render_admin(path string, heading string) string {
|
||||
// Get the template file path relative to the module
|
||||
template_path := os.join_path(os.dir(@FILE), 'templates', 'admin_layout.html')
|
||||
|
||||
|
||||
// Read the template file
|
||||
template_content := os.read_file(template_path) or {
|
||||
// Fallback to inline template if file not found
|
||||
return app.render_admin_fallback(path, heading)
|
||||
}
|
||||
|
||||
|
||||
// Generate menu HTML
|
||||
menu_content := menu_html(app.menu, 0, 'm')
|
||||
|
||||
|
||||
// Simple template variable replacement
|
||||
mut result := template_content
|
||||
result = result.replace('{{.title}}', app.title)
|
||||
@@ -207,7 +193,7 @@ fn (app &App) render_admin(path string, heading string) string {
|
||||
result = result.replace('{{.css_colors_url}}', '/static/css/colors.css')
|
||||
result = result.replace('{{.css_main_url}}', '/static/css/main.css')
|
||||
result = result.replace('{{.js_theme_url}}', '/static/js/theme.js')
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -215,16 +201,16 @@ fn (app &App) render_admin(path string, heading string) string {
|
||||
fn (app &App) render_heroscript() string {
|
||||
// Get the template file path relative to the module
|
||||
template_path := os.join_path(os.dir(@FILE), 'templates', 'heroscript_editor.html')
|
||||
|
||||
|
||||
// Read the template file
|
||||
template_content := os.read_file(template_path) or {
|
||||
// Fallback to basic template if file not found
|
||||
return app.render_heroscript_fallback()
|
||||
}
|
||||
|
||||
|
||||
// Generate menu HTML
|
||||
menu_content := menu_html(app.menu, 0, 'm')
|
||||
|
||||
|
||||
// Simple template variable replacement
|
||||
mut result := template_content
|
||||
result = result.replace('{{.title}}', app.title)
|
||||
@@ -234,7 +220,7 @@ fn (app &App) render_heroscript() string {
|
||||
result = result.replace('{{.css_heroscript_url}}', '/static/css/heroscript.css')
|
||||
result = result.replace('{{.js_theme_url}}', '/static/js/theme.js')
|
||||
result = result.replace('{{.js_heroscript_url}}', '/static/js/heroscript.js')
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -242,16 +228,16 @@ fn (app &App) render_heroscript() string {
|
||||
fn (app &App) render_chat() string {
|
||||
// Get the template file path relative to the module
|
||||
template_path := os.join_path(os.dir(@FILE), 'templates', 'chat.html')
|
||||
|
||||
|
||||
// Read the template file
|
||||
template_content := os.read_file(template_path) or {
|
||||
// Fallback to basic template if file not found
|
||||
return app.render_chat_fallback()
|
||||
}
|
||||
|
||||
|
||||
// Generate menu HTML
|
||||
menu_content := menu_html(app.menu, 0, 'm')
|
||||
|
||||
|
||||
// Simple template variable replacement
|
||||
mut result := template_content
|
||||
result = result.replace('{{.title}}', app.title)
|
||||
@@ -261,7 +247,7 @@ fn (app &App) render_chat() string {
|
||||
result = result.replace('{{.css_chat_url}}', '/static/css/chat.css')
|
||||
result = result.replace('{{.js_theme_url}}', '/static/js/theme.js')
|
||||
result = result.replace('{{.js_chat_url}}', '/static/js/chat.js')
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -376,7 +362,8 @@ fn (app &App) render_admin_fallback(path string, heading string) string {
|
||||
<div class="p-2">
|
||||
<div class="menu-section">Navigation</div>
|
||||
<div class="list-group list-group-flush">
|
||||
${menu_html(app.menu, 0, 'm')}
|
||||
${menu_html(app.menu,
|
||||
0, 'm')}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
@@ -411,10 +398,14 @@ fn menu_html(items []MenuItem, depth int, prefix string) string {
|
||||
if it.children.len > 0 {
|
||||
// expandable group
|
||||
out << '<div class="list-group-item">'
|
||||
out << '<a class="menu-toggle d-flex align-items-center justify-content-between" data-bs-toggle="collapse" href="#${id}" role="button" aria-expanded="${if depth == 0 { "true" } else { "false" }}" aria-controls="${id}">'
|
||||
out << '<a class="menu-toggle d-flex align-items-center justify-content-between" data-bs-toggle="collapse" href="#${id}" role="button" aria-expanded="${if depth == 0 {
|
||||
'true'
|
||||
} else {
|
||||
'false'
|
||||
}}" aria-controls="${id}">'
|
||||
out << '<span>${it.title}</span><span class="chev">›</span>'
|
||||
out << '</a>'
|
||||
out << '<div class="collapse ${if depth == 0 { "show" } else { "" }}" id="${id}">'
|
||||
out << '<div class="collapse ${if depth == 0 { 'show' } else { '' }}" id="${id}">'
|
||||
out << '<div class="ms-2 mt-1">'
|
||||
out << menu_html(it.children, depth + 1, id)
|
||||
out << '</div>'
|
||||
@@ -422,7 +413,11 @@ fn menu_html(items []MenuItem, depth int, prefix string) string {
|
||||
out << '</div>'
|
||||
} else {
|
||||
// leaf
|
||||
out << '<div class="list-group-item menu-leaf"><a href="${if it.href.len > 0 { it.href } else { "/admin" }}">${it.title}</a></div>'
|
||||
out << '<div class="list-group-item menu-leaf"><a href="${if it.href.len > 0 {
|
||||
it.href
|
||||
} else {
|
||||
'/admin'
|
||||
}}">${it.title}</a></div>'
|
||||
}
|
||||
}
|
||||
return out.join('\n')
|
||||
@@ -433,45 +428,75 @@ fn default_menu() []MenuItem {
|
||||
return [
|
||||
MenuItem{
|
||||
title: 'Dashboard'
|
||||
href: '/admin'
|
||||
href: '/admin'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'HeroScript'
|
||||
href: '/admin/heroscript'
|
||||
href: '/admin/heroscript'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Chat'
|
||||
href: '/admin/chat'
|
||||
href: '/admin/chat'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Users'
|
||||
title: 'Users'
|
||||
children: [
|
||||
MenuItem{ title: 'Overview', href: '/admin/users/overview' },
|
||||
MenuItem{ title: 'Create', href: '/admin/users/create' },
|
||||
MenuItem{ title: 'Roles', href: '/admin/users/roles' },
|
||||
MenuItem{
|
||||
title: 'Overview'
|
||||
href: '/admin/users/overview'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Create'
|
||||
href: '/admin/users/create'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Roles'
|
||||
href: '/admin/users/roles'
|
||||
},
|
||||
]
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Content'
|
||||
title: 'Content'
|
||||
children: [
|
||||
MenuItem{ title: 'Pages', href: '/admin/content/pages' },
|
||||
MenuItem{ title: 'Media', href: '/admin/content/media' },
|
||||
MenuItem{
|
||||
title: 'Settings'
|
||||
title: 'Pages'
|
||||
href: '/admin/content/pages'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Media'
|
||||
href: '/admin/content/media'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Settings'
|
||||
children: [
|
||||
MenuItem{ title: 'SEO', href: '/admin/content/settings/seo' },
|
||||
MenuItem{ title: 'Themes', href: '/admin/content/settings/themes' },
|
||||
MenuItem{
|
||||
title: 'SEO'
|
||||
href: '/admin/content/settings/seo'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Themes'
|
||||
href: '/admin/content/settings/themes'
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
MenuItem{
|
||||
title: 'System'
|
||||
title: 'System'
|
||||
children: [
|
||||
MenuItem{ title: 'Status', href: '/admin/system/status' },
|
||||
MenuItem{ title: 'Logs', href: '/admin/system/logs' },
|
||||
MenuItem{ title: 'Backups', href: '/admin/system/backups' },
|
||||
MenuItem{
|
||||
title: 'Status'
|
||||
href: '/admin/system/status'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Logs'
|
||||
href: '/admin/system/logs'
|
||||
},
|
||||
MenuItem{
|
||||
title: 'Backups'
|
||||
href: '/admin/system/backups'
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ fn startupcmd() ![]zinit.ZProcessNewArgs {
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
fn running() !bool {
|
||||
res := os.execute('${osal.profile_path_source_and()!} caddy version')
|
||||
if res.exit_code == 0 {
|
||||
@@ -82,7 +81,6 @@ fn upload() ! {
|
||||
// )!
|
||||
}
|
||||
|
||||
|
||||
fn install() ! {
|
||||
console.print_header('install caddy')
|
||||
|
||||
@@ -160,9 +158,6 @@ fn destroy() ! {
|
||||
// ")!
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// configure caddy as default webserver & start
|
||||
// node, path, domain
|
||||
// path e.g. /var/www
|
||||
|
||||
@@ -8,8 +8,6 @@ import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.installers.lang.golang
|
||||
import os
|
||||
|
||||
|
||||
|
||||
pub fn install_caddy_from_release() ! {
|
||||
version := '2.8.4'
|
||||
mut url := ''
|
||||
|
||||
13
release.vsh
13
release.vsh
@@ -18,7 +18,6 @@ fn get_latest_release() !string {
|
||||
return release.tag_name
|
||||
}
|
||||
|
||||
|
||||
// Show current version
|
||||
latest_release := get_latest_release() or {
|
||||
eprintln('Error getting latest release: ${err}')
|
||||
@@ -81,17 +80,12 @@ lines[version_line_idx] = ' version: \'${new_version}\''
|
||||
os.write_file(hero_v_path, lines.join_lines()) or {
|
||||
eprintln('Error writing to ${hero_v_path}: ${err}')
|
||||
// Restore backup
|
||||
os.cp('${hero_v_path}.backup', hero_v_path) or {
|
||||
eprintln('Error restoring backup: ${err}')
|
||||
}
|
||||
os.cp('${hero_v_path}.backup', hero_v_path) or { eprintln('Error restoring backup: ${err}') }
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Clean up backup
|
||||
os.rm('${hero_v_path}.backup') or {
|
||||
eprintln('Warning: Could not remove backup file: ${err}')
|
||||
}
|
||||
|
||||
os.rm('${hero_v_path}.backup') or { eprintln('Warning: Could not remove backup file: ${err}') }
|
||||
|
||||
// Update version in install_hero.sh
|
||||
install_hero_path := '${ourdir}/install_hero.sh'
|
||||
@@ -130,8 +124,7 @@ os.rm('${install_hero_path}.backup') or {
|
||||
eprintln('Warning: Could not remove backup file of install_hero.sh: ${err}')
|
||||
}
|
||||
|
||||
|
||||
cmd:='
|
||||
cmd := '
|
||||
git add . -A
|
||||
git commit -am "bump version to ${new_version}"
|
||||
git push
|
||||
|
||||
@@ -25,63 +25,58 @@ pub mut:
|
||||
|
||||
pub fn biz_model_example(name string) BizModel {
|
||||
mut biz_model := BizModel{
|
||||
name: name
|
||||
name: name
|
||||
intlist: []int{len: 10, init: rand.intn(100) or { 0 }}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
}
|
||||
|
||||
for i in 0 .. 100 {
|
||||
sub_item := SubItem{
|
||||
name: 'SubItem ${i}'
|
||||
name: 'SubItem ${i}'
|
||||
intlist: []int{len: 5, init: rand.intn(50) or { 0 }}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
}
|
||||
biz_model.mymap['item_${i}'] = sub_item
|
||||
}
|
||||
|
||||
return biz_model
|
||||
|
||||
}
|
||||
|
||||
pub fn get(name string) !BizModel {
|
||||
rlock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
if name !in bizmodels {
|
||||
return error("can't find bizmodel: ${name}")
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return error("bug")
|
||||
return error('bug')
|
||||
}
|
||||
|
||||
|
||||
pub fn getset(name string) BizModel {
|
||||
lock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
set(biz_model_example(name))
|
||||
if name !in bizmodels {
|
||||
set(biz_model_example(name))
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return BizModel{} //weird we need to do this
|
||||
return BizModel{} // weird we need to do this
|
||||
}
|
||||
|
||||
pub fn set(bizmodel BizModel) {
|
||||
|
||||
lock bizmodels {
|
||||
bizmodels[bizmodel.name] = bizmodel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn fill_biz_models(nr int) {
|
||||
for i in 0 .. nr {
|
||||
getset("bm${i}")
|
||||
getset('bm${i}')
|
||||
}
|
||||
rlock bizmodels{
|
||||
//check we have enough bizmodels in mem
|
||||
rlock bizmodels {
|
||||
// check we have enough bizmodels in mem
|
||||
assert bizmodels.len == nr
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn get_memory_usage() i64 {
|
||||
@@ -93,41 +88,39 @@ fn get_memory_usage() i64 {
|
||||
fn main() {
|
||||
sw := time.new_stopwatch()
|
||||
|
||||
nr:=100
|
||||
nr_new :=100000 //make small changes, the garbage collector should keep it clean
|
||||
nr := 100
|
||||
nr_new := 100000 // make small changes, the garbage collector should keep it clean
|
||||
|
||||
fill_biz_models(nr)
|
||||
|
||||
|
||||
memory_usage_1 := get_memory_usage()
|
||||
println('Memory usage after creating ${nr} BizModels: ${memory_usage_1} KB')
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
for _ in 0 .. nr_new {
|
||||
currentnr:=rand.intn(nr-1) or {panic(err)}
|
||||
mut new_model:= get("bm${currentnr}")!
|
||||
//new_model.intlist = new_model.intlist.map(it + rand.intn(10) or { 0 })
|
||||
currentnr := rand.intn(nr - 1) or { panic(err) }
|
||||
mut new_model := get('bm${currentnr}')!
|
||||
// new_model.intlist = new_model.intlist.map(it + rand.intn(10) or { 0 })
|
||||
new_model.intstr = new_model.intstr.map(it + rand.string(2))
|
||||
mut new_model2:= get("bm${currentnr}")!
|
||||
assert new_model2.intstr != new_model.intstr //should be different because was not a reference
|
||||
mut new_model2 := get('bm${currentnr}')!
|
||||
assert new_model2.intstr != new_model.intstr // should be different because was not a reference
|
||||
set(new_model)
|
||||
mut new_model3:= get("bm${currentnr}")!
|
||||
assert new_model3.intstr == new_model.intstr //should be different because was not a reference
|
||||
|
||||
mut new_model3 := get('bm${currentnr}')!
|
||||
assert new_model3.intstr == new_model.intstr // should be different because was not a reference
|
||||
}
|
||||
|
||||
rlock bizmodels{
|
||||
//check we have enough bizmodels in mem
|
||||
rlock bizmodels {
|
||||
// check we have enough bizmodels in mem
|
||||
assert bizmodels.len == nr
|
||||
}
|
||||
}
|
||||
|
||||
println("wait 1 sec")
|
||||
//lets make sure garbage collector works
|
||||
println('wait 1 sec')
|
||||
// lets make sure garbage collector works
|
||||
time.sleep(1 * time.second)
|
||||
|
||||
|
||||
memory_usage_2 := get_memory_usage()
|
||||
println('Memory usage after creating ${nr_new} random BizModels: ${memory_usage_2} KB')
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
println("QUESTION: why does memory go up?, we didn't add to the memory should have been equal...")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,62 +26,58 @@ pub mut:
|
||||
|
||||
pub fn biz_model_example(name string) BizModel {
|
||||
mut biz_model := BizModel{
|
||||
name: name
|
||||
name: name
|
||||
intlist: []int{len: 10, init: rand.intn(100) or { 0 }}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
}
|
||||
|
||||
for i in 0 .. 100 {
|
||||
sub_item := SubItem{
|
||||
name: 'SubItem ${i}'
|
||||
name: 'SubItem ${i}'
|
||||
intlist: []int{len: 5, init: rand.intn(50) or { 0 }}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
}
|
||||
biz_model.mymap['item_${i}'] = sub_item
|
||||
}
|
||||
|
||||
return biz_model
|
||||
|
||||
}
|
||||
|
||||
pub fn get(name string) !BizModel {
|
||||
rlock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
if name !in bizmodels {
|
||||
return error("can't find bizmodel: ${name}")
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return error("bug")
|
||||
return error('bug')
|
||||
}
|
||||
|
||||
|
||||
pub fn getset(name string) BizModel {
|
||||
lock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
set(biz_model_example(name))
|
||||
if name !in bizmodels {
|
||||
set(biz_model_example(name))
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return BizModel{} //weird we need to do this
|
||||
return BizModel{} // weird we need to do this
|
||||
}
|
||||
|
||||
pub fn set(bizmodel BizModel) {
|
||||
lock bizmodels {
|
||||
bizmodels[bizmodel.name] = bizmodel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn fill_biz_models(nr int) {
|
||||
for i in 0 .. nr {
|
||||
getset("bm${i}")
|
||||
getset('bm${i}')
|
||||
}
|
||||
rlock bizmodels{
|
||||
//check we have enough bizmodels in mem
|
||||
rlock bizmodels {
|
||||
// check we have enough bizmodels in mem
|
||||
assert bizmodels.len == nr
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn get_memory_usage() i64 {
|
||||
@@ -93,33 +89,32 @@ fn get_memory_usage() i64 {
|
||||
fn main() {
|
||||
sw := time.new_stopwatch()
|
||||
|
||||
nr:=100
|
||||
nr_new :=100000 //make small changes, the garbage collector should keep it clean
|
||||
nr := 100
|
||||
nr_new := 100000 // make small changes, the garbage collector should keep it clean
|
||||
|
||||
fill_biz_models(nr)
|
||||
|
||||
println("wait 0.5 sec")
|
||||
//lets make sure garbage collector works
|
||||
time.sleep(0.5 * time.second)
|
||||
|
||||
println('wait 0.5 sec')
|
||||
// lets make sure garbage collector works
|
||||
time.sleep(0.5 * time.second)
|
||||
|
||||
memory_usage_1 := get_memory_usage()
|
||||
println('Memory usage after creating ${nr} BizModels: ${memory_usage_1} KB')
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
for _ in 0 .. nr_new {
|
||||
currentnr:=rand.intn(nr-1) or {panic(err)}
|
||||
//println(currentnr)
|
||||
set(biz_model_example("bm${currentnr}")) //will keep on overwriting
|
||||
currentnr := rand.intn(nr - 1) or { panic(err) }
|
||||
// println(currentnr)
|
||||
set(biz_model_example('bm${currentnr}')) // will keep on overwriting
|
||||
}
|
||||
|
||||
println("wait 1 sec")
|
||||
//lets make sure garbage collector works
|
||||
println('wait 1 sec')
|
||||
// lets make sure garbage collector works
|
||||
time.sleep(1 * time.second)
|
||||
|
||||
|
||||
memory_usage_2 := get_memory_usage()
|
||||
println('Memory usage after creating ${nr_new} random BizModels: ${memory_usage_2} KB')
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
println("QUESTION: this seems ok, memory doesn't go up much\nDon't understand why the globals_example does increase.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,62 +25,58 @@ pub mut:
|
||||
|
||||
pub fn biz_model_example(name string) BizModel {
|
||||
mut biz_model := BizModel{
|
||||
name: name
|
||||
name: name
|
||||
intlist: []int{len: 10, init: rand.intn(100) or { 0 }}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
intstr: []string{len: 10, init: rand.string(5)}
|
||||
mymap: map[string]SubItem{}
|
||||
}
|
||||
|
||||
for i in 0 .. 100 {
|
||||
sub_item := SubItem{
|
||||
name: 'SubItem ${i}'
|
||||
name: 'SubItem ${i}'
|
||||
intlist: []int{len: 5, init: rand.intn(50) or { 0 }}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
intstr: []string{len: 5, init: rand.string(3)}
|
||||
}
|
||||
biz_model.mymap['item_${i}'] = sub_item
|
||||
}
|
||||
|
||||
return biz_model
|
||||
|
||||
}
|
||||
|
||||
pub fn get(name string) !&BizModel {
|
||||
rlock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
if name !in bizmodels {
|
||||
return error("can't find bizmodel: ${name}")
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return error("bug")
|
||||
return error('bug')
|
||||
}
|
||||
|
||||
|
||||
pub fn getset(name string) &BizModel {
|
||||
lock bizmodels {
|
||||
if ! (name in bizmodels) {
|
||||
//println("getset ${name}")
|
||||
new(biz_model_example(name))
|
||||
if name !in bizmodels {
|
||||
// println("getset ${name}")
|
||||
new(biz_model_example(name))
|
||||
}
|
||||
return bizmodels[name] or { panic("bug") }
|
||||
return bizmodels[name] or { panic('bug') }
|
||||
}
|
||||
return &BizModel{} //weird we need to do this
|
||||
return &BizModel{} // weird we need to do this
|
||||
}
|
||||
|
||||
pub fn new(bizmodel BizModel) {
|
||||
lock bizmodels {
|
||||
bizmodels[bizmodel.name] = &bizmodel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn fill_biz_models(nr int) {
|
||||
for i in 0 .. nr {
|
||||
getset("bm${i}")
|
||||
getset('bm${i}')
|
||||
}
|
||||
rlock bizmodels{
|
||||
rlock bizmodels {
|
||||
assert bizmodels.len == nr
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn get_memory_usage() i64 {
|
||||
@@ -92,28 +88,27 @@ fn get_memory_usage() i64 {
|
||||
fn main() {
|
||||
sw := time.new_stopwatch()
|
||||
|
||||
nr:=100
|
||||
nr_new :=100000 //make small changes, the garbage collector should keep it clean
|
||||
nr := 100
|
||||
nr_new := 100000 // make small changes, the garbage collector should keep it clean
|
||||
|
||||
fill_biz_models(nr)
|
||||
|
||||
|
||||
memory_usage_1 := get_memory_usage()
|
||||
println('Memory usage after creating ${nr} BizModels: ${memory_usage_1} KB')
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
for _ in 0 .. nr_new {
|
||||
currentnr:=rand.intn(nr-1) or {panic(err)}
|
||||
mut new_model:= get("bm${currentnr}")!
|
||||
//new_model.intlist = new_model.intlist.map(it + rand.intn(10) or { 0 })
|
||||
currentnr := rand.intn(nr - 1) or { panic(err) }
|
||||
mut new_model := get('bm${currentnr}')!
|
||||
// new_model.intlist = new_model.intlist.map(it + rand.intn(10) or { 0 })
|
||||
new_model.intstr = new_model.intstr.map(it + rand.string(2))
|
||||
//set(new_model) //SHOULD NOT BE NEEDED TO SET BECAUSE IS REFERENCE
|
||||
mut new_model2:= get("bm${currentnr}")!
|
||||
assert new_model2.intstr == new_model.intstr //should be same because was a reference
|
||||
|
||||
// set(new_model) //SHOULD NOT BE NEEDED TO SET BECAUSE IS REFERENCE
|
||||
mut new_model2 := get('bm${currentnr}')!
|
||||
assert new_model2.intstr == new_model.intstr // should be same because was a reference
|
||||
}
|
||||
|
||||
println("wait 1 sec")
|
||||
//lets make sure garbage collector works, didn't make a difference though
|
||||
println('wait 1 sec')
|
||||
// lets make sure garbage collector works, didn't make a difference though
|
||||
time.sleep(1 * time.second)
|
||||
|
||||
memory_usage_2 := get_memory_usage()
|
||||
@@ -121,4 +116,4 @@ fn main() {
|
||||
println('Time taken: ${sw.elapsed().milliseconds()} ms')
|
||||
|
||||
println("QUESTION: why does memory go up?, we didn't add to the memory should have been equal... its also not lower compared to the references one")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user