This commit is contained in:
2025-03-17 11:13:39 +01:00
parent c47002430e
commit b27f0a5017
72 changed files with 698 additions and 134 deletions

View File

@@ -1 +0,0 @@
module biz

View File

@@ -1 +0,0 @@
testdata

View File

@@ -0,0 +1,31 @@
# HR Params
## Engineering
Costs can be grouped in cost centers which can then be used to futher process e.g. transcactions between companies.
```js
!!bizmodel.costcenter_define bizname:'test'
name:'tfdmcc'
descr:'TFDMCC executes on near source agreement for TFTech'
min_month:'10000USD'
max_month:'100000USD'
end_date:'1/1/2026' //when does agreement stop
!!bizmodel.costcenter_define bizname:'test'
name:'cs_tftech'
descr:'Nearsource agreement for TFTech towards Codescalers'
min_month:'10000USD'
max_month:'100000USD'
end_date:'1/1/2026'
!!bizmodel.costcenter_define bizname:'test'
name:'cs_tfcloud'
descr:'Nearsource agreement for TFCloud towards Codescalers'
min_month:'10000USD'
max_month:'100000USD'
end_date:'1/1/2026'
```

View File

@@ -0,0 +1,39 @@
# Generic Overhead Costs
possible parameters
- name
- descr: description of the cost
- cost: is 'month:amount,month:amount, ...', no extrapolation
- cost_growth: is 'month:amount,month:amount, ..., or just a nr', will extrapolate
- type: travel, admin, legal, varia, office
- cost_percent_revenue e.g. 4%, will make sure the cost will be at least 4% of revenue
- indexation, e.g. 2%
Other financial flows can be mentioned here as well.
```js
!!bizmodel.cost_define bizname:'test'
name:'rental'
descr:'Office Rental in BE.'
cost:'5000'
indexation:'2%'
type:'office'
!!bizmodel.cost_define bizname:'test'
name:'oneoff'
descr:'Event in Z.'
cost_one:'3:50000'
type:'event'
!!bizmodel.cost_define bizname:'test'
name:'cloud'
descr:'Datacenter and Cloud Costs'
cost:'2000eur'
cost_percent_revenue:'2%'
type:'cloud'
```

View File

@@ -0,0 +1,20 @@
# Department Params
```js
!!bizmodel.department_define bizname:'test'
name:'ops'
title:'Operations'
order:5
!!bizmodel.department_define bizname:'test'
name:'coordination'
title:'Coordination'
order:1
!!bizmodel.department_define bizname:'test'
name:'engineering'
title:'Engineering'
order:4
```

View File

@@ -0,0 +1,29 @@
# Funding Params
possible parameters
- name, e.g. for a specific person
- descr: description of the funding
- investment is month:amount,month:amount, ...
- type: loan or capital
Other financial flows can be mentioned here as well.
```js
!!bizmodel.funding_define bizname:'test'
name:'our_investor'
descr:'A fantastic super investor.'
investment:'3:1000000EUR'
type:'capital'
!!bizmodel.funding_define bizname:'test'
name:'a_founder'
descr:'Together Are Strong'
investment:'2000000'
type:'loan'
```

View File

@@ -0,0 +1,73 @@
# HR Params
## Engineering
possible parameters
- descr, description of the function (e.g. master architect)
- cost, any currency eg. 1000usd
- in case cost changes over time e.g. 1:10000USD,20:20000USD,60:30000USD
- indexation, e.g. 2%
- department
- name, e.g. for a specific person
- nrpeople: how many people per month, growth over time notation e.g. 1:10,60:20 means 10 in month 1 growing to 20 month 60
- cost_percent_revenue e.g. 4%, will make sure the cost will be at least 4% of revenue
```js
!!bizmodel.employee_define bizname:'test'
sid:2
descr:'Senior Engineer'
cost:'1:12000,12:14000' //cost is always per person
department:'engineering'
nrpeople:'0:5,20:5'
!!bizmodel.employee_define bizname:'test'
name:'despiegk'
title: 'CTO and crazy inventor.'
sid:3
descr:'CTO'
cost:'12000EUR' //the salary is the cost independent of the fulltime status
indexation:'10%'
department:'coordination'
page:'cto.md'
fulltime: "50%" //100% means yes
!!bizmodel.employee_define bizname:'test'
descr:'Senior Architect'
cost:'10000USD' indexation:'5%'
department:'engineering'
nrpeople:'0:5,20:10'
!!bizmodel.employee_define bizname:'test'
descr:'Junior Engineer'
cost:'4000USD' indexation:'5%'
department:'engineering'
nrpeople:'0:5,20:10'
```
## Operations
```js
!!bizmodel.employee_define bizname:'test'
descr:'Ops Manager'
cost:'1:8000,12:14000'
department:'ops'
!!bizmodel.employee_define bizname:'test'
descr:'Support Junior'
cost:'2000EUR' indexation:'5%'
department:'ops'
nrpeople:'7:5,18:10'
cost_percent_revenue:'1%'
!!bizmodel.employee_define bizname:'test'
descr:'Support Senior'
cost:'5000EUR' indexation:'5%'
department:'ops'
nrpeople:'3:5,20:10'
cost_percent_revenue:'1%'
costcenter:'tfdmcc:25,cs_tfcloud:75'
generate_page:'../employees/support_senior.md'
```

View File

@@ -0,0 +1,14 @@
# Bizmodel Params
In this section we can find all the parameters for the bizmodel.
## how to use and read
The params are defined in the different instruction files e.g. revenue_params.md
Often you will see something like `revenue_growth:'10:1000,20:1100'` this can be read as month 10 it 1000, month 20 its 1100.
The software will extrapolate.

View File

@@ -0,0 +1,85 @@
# HR Params
## Revenue Items (non recurring)
This company is a cloud company ...
- name, e.g. for a specific project
- descr, description of the revenue line item
- revenue_items: does one of revenue, is not exterpolated
- revenue_growth: is a revenue stream which is being extrapolated
- revenue_setup, revenue for 1 item '1000usd'
- revenue_setup_delay
- revenue_monthly, revenue per month for 1 item
- revenue_monthly_delay, how many months before monthly revenue starts
- maintenance_month_perc, how much percent of revenue_setup will come back over months
- cogs_setup, cost of good for 1 item at setup
- cogs_setup_delay, how many months before setup cogs starts, after sales
- cogs_setup_perc: what is percentage of the cogs (can change over time) for setup e.g. 0:50%
- cogs_monthly, cost of goods for the monthly per 1 item
- cogs_monthly_delay, how many months before monthly cogs starts, after sales
- cogs_monthly_perc: what is percentage of the cogs (can change over time) for monthly e.g. 0:5%,12:10%
- nr_sold: how many do we sell per month (is in growth format e.g. 10:100,20:200, default is 1)
- nr_months_recurring: how many months is recurring, if 0 then no recurring
```js
!!bizmodel.revenue_define bizname:'test'
descr:'OEM Deals'
revenue_items:'10:1000000EUR,15:3333,20:1200000'
cogs_setup_perc: '1:5%,20:10%'
!!bizmodel.revenue_define bizname:'test'
descr:'License Deals'
revenue_growth:'10:1000,20:1100'
cogs_perc: '10%'
rev_delay_month: 1
!!bizmodel.revenue_define bizname:'test'
descr:'3NODE License Sales 1 Time'
//means revenue is 100 month 1, 200 month 60
revenue_item:'1:100,60:200'
revenue_nr:'10:1000,24:2000,60:40000'
cogs_perc: '10%'
rev_delay_month: 1
```
## Revenue Items Recurring
possible parameters
- name, e.g. for a specific project
- descr, description of the revenue line item
- revenue_setup, revenue for 1 item '1000usd'
- revenue_monthly, revenue per month for 1 item
- revenue_setup_delay, how many months before revenue comes in after sales
- revenue_monthly_delay, how many months before monthly revenue starts
- cogs_setup, cost of good for 1 item at setup
- cogs_setup_perc: what is percentage of the cogs (can change over time) for setup e.g. 0:50%
- cogs_monthly, cost of goods for the monthly per 1 item
- cogs_monthly_perc: what is percentage of the cogs (can change over time) for monthly e.g. 0:5%,12:10%
- nr_sold: how many do we sell per month (is in growth format e.g. 10:100,20:200)
- nr_months: how many months is recurring
if currency not specified then is always in USD
```js
!!bizmodel.revenue_recurring_define bizname:'test'
name: '3node_lic'
descr:'3NODE License Sales Recurring Basic'
revenue_setup:'1:100,60:50'
// revenue_setup:'5'
revenue_monthly_delay:3
revenue_monthly:'1:1,60:1'
// cogs_setup:'1:0'
cogs_setup_perc:'50%'
revenue_setup_delay:1
cogs_monthly_perc:'50%'
nr_sold:'10:1000,24:2000,60:40000'
60 is the default
nr_months:60
```

View File

@@ -0,0 +1,90 @@
module bizmodel
import os
import freeflowuniverse.herolib.core.pathlib
@[params]
pub struct ExportCSVArgs {
pub mut:
path string
include_empty bool = false // whether to include empty cells or not
separator string = '|' // separator character for CSV
}
// export_csv exports the business model data to CSV files
pub fn (model BizModel) export_csv(args ExportCSVArgs) ! {
mut path := args.path
if path == '' {
path = os.join_path(os.home_dir(), 'hero/var/bizmodel/exports')
}
mut dir := pathlib.get_dir(path: path, create: true)!
// Export employees data
mut employees_data := []string{}
header := ['Name', 'Role', 'Department', 'Cost', 'Start Date'].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
employees_data << header
for _, employee in model.employees {
row := [
employee.name,
employee.role,
employee.department,
employee.cost.str(),
if start_date := employee.start_date { start_date.str() } else { '' }
].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
employees_data << row
}
mut emp_file := pathlib.get_file(path: os.join_path(dir.path, 'employees.csv'), create: true, delete: true)!
emp_file.write(employees_data.join('\n'))!
// Export products data
mut products_data := []string{}
products_header := ['Name', 'Description'].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
products_data << products_header
for _, product in model.products {
row := [
product.name,
product.description,
].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
products_data << row
}
mut prod_file := pathlib.get_file(path: os.join_path(dir.path, 'products.csv'), create: true, delete: true)!
prod_file.write(products_data.join('\n'))!
// Export departments data
mut departments_data := []string{}
departments_header := ['Name', 'Description'].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
departments_data << departments_header
for _, department in model.departments {
row := [
department.name,
department.description
].map(fn [args] (s string) string {
return format_csv_value(s, args.separator)
}).join(args.separator)
departments_data << row
}
mut dept_file := pathlib.get_file(path: os.join_path(dir.path, 'departments.csv'), create: true, delete: true)!
dept_file.write(departments_data.join('\n'))!
}
// format_csv_value formats a value for CSV export, handling special characters
fn format_csv_value(val string, separator string) string {
// If value contains the separator, quotes, or newlines, wrap in quotes and escape quotes
if val.contains(separator) || val.contains('"') || val.contains('\n') {
return '"${val.replace('"', '""')}"'
}
return val
}

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
import os
import freeflowuniverse.herolib.biz.bizmodel
bizmodel_name := 'test'
export_path := '${os.home_dir}/Downloads/bizmodel'
playbook_path := os.dir(@FILE) + '/exampledata'
mut model := bizmodel.generate(bizmodel_name, playbook_path)!
// Export to CSV
model.export_csv(
path: export_path
include_empty: false
separator: '|'
)!
// // Verify files were created
// employees_path := os.join_path(export_path, 'employees.csv')
// products_path := os.join_path(export_path, 'products.csv')
// departments_path := os.join_path(export_path, 'departments.csv')
// assert os.exists(employees_path), 'employees.csv should exist'
// assert os.exists(products_path), 'products.csv should exist'
// assert os.exists(departments_path), 'departments.csv should exist'
// // Read and verify content
// employees_content := os.read_file(employees_path)!
// assert employees_content.contains('Name|Role|Department|Cost|Start Date'), 'employees.csv should have correct header'
// products_content := os.read_file(products_path)!
// assert products_content.contains('Name|Description|Price|Cost'), 'products.csv should have correct header'
// departments_content := os.read_file(departments_path)!
// assert departments_content.contains('Name|Description|Budget'), 'departments.csv should have correct header'

View File

@@ -4,7 +4,7 @@ import os
import freeflowuniverse.herolib.web.docusaurus
const bizmodel_name = 'test'
const export_path = os.join_path(os.dir(@FILE), 'testdata')
const export_path = os.join_path(os.dir(@FILE), 'exampledata')
pub fn test_export_report() ! {
model := getset(bizmodel_name)!

View File

@@ -1,6 +1,7 @@
module bizmodel
import freeflowuniverse.herolib.biz.spreadsheet
import freeflowuniverse.herolib.core.playbook
__global (
bizmodels shared map[string]&BizModel
@@ -32,6 +33,16 @@ pub fn getset(name string) !&BizModel {
panic('bug')
}
pub fn generate(name string, path string) !&BizModel {
mut model:=getset(name)!
mut pb := playbook.new(path: path)!
model.play(mut pb)!
return model
}
pub fn set(bizmodel BizModel) {
lock bizmodels {
bizmodels[bizmodel.name] = &bizmodel

View File

@@ -2,6 +2,7 @@ module bizmodel
import os
import freeflowuniverse.herolib.biz.spreadsheet
import freeflowuniverse.herolib.data.ourtime
pub struct BizModel {
pub mut:
@@ -21,6 +22,7 @@ pub:
description string
title string
department string
role string
cost string
cost_percent_revenue f64
nrpeople string
@@ -28,6 +30,7 @@ pub:
cost_center string
page string
fulltime_perc f64
start_date ?ourtime.OurTime
}
pub struct Department {

View File

@@ -32,11 +32,19 @@ pub fn play(mut plbook PlayBook) ! {
pub fn (mut m BizModel) play(mut plbook PlayBook) ! {
mut actions := plbook.actions_find(actor: 'bizmodel')!
for action in actions.filter(it.name in action_priorities[0]) {
console.print_debug(action)
m.act(*action)!
}
if true{
println(actions)
exit(0)
}
m.cost_total()!
m.revenue_total()!
m.funding_total()!

View File

@@ -15,7 +15,38 @@ If we have 60 months representation (5 year), we have 60 columns
A sheet can also be represented per year or per quarter, if per year then there would be 5 columns only.
There is also functionality to export a sheet to wiki (markdown) or html representation.
There is also functionality to export a sheet to wiki (markdown), html representation, or CSV format.
## Exporting to CSV
You can export sheet data to CSV format with pipe separation (or custom separator) using the `export_csv` method:
```v
// Create a sheet
mut sheet := sheet_new(name: 'my_sheet', nrcol: 12)!
// Add rows and data to the sheet
// ...
// Export to a CSV file with default pipe separator
sheet.export_csv(path: '~/output.csv')!
// Export with custom separator and include empty cells
csv_content := sheet.export_csv(
path: '~/output.csv',
separator: ',',
include_empty: true
)!
// Export to string only (no file)
csv_string := sheet.export_csv(path: '')!
```
The CSV export includes the following features:
- Default pipe (`|`) separator (configurable)
- Proper handling of special characters in text fields
- Option to include or exclude empty cells
- Automatic formatting of numeric values
## offline

View File

@@ -0,0 +1,81 @@
module spreadsheet
import os
import freeflowuniverse.herolib.core.pathlib
@[params]
pub struct ExportCSVArgs {
pub mut:
path string
include_empty bool = false // whether to include empty cells or not
separator string = '|' // separator character for CSV
}
// format_csv_value formats a value for CSV export, handling special characters
fn format_csv_value(val string, separator string) string {
// If value contains the separator, quotes, or newlines, wrap in quotes and escape quotes
if val.contains(separator) || val.contains('"') || val.contains('\n') {
return '"${val.replace('"', '""')}"'
}
return val
}
// format_number_csv formats a number for CSV export
fn format_number_csv(val f64, include_empty bool) string {
if val < 0.001 && val > -0.001 {
if include_empty {
return '0'
}
return ''
}
if val >= 1000.0 || val <= -1000.0 {
return int(val).str()
}
// Format small numbers with up to 3 decimal places, removing trailing zeros
str := '${val:.3f}'
// Remove trailing zeros and decimal point if needed
if str.contains('.') {
str_trimmed := str.trim_right('0').trim_right('.')
return str_trimmed
}
return str
}
// export_csv exports the sheet data to a CSV file with pipe separation
pub fn (mut s Sheet) export_csv(args ExportCSVArgs) !string {
mut result := []string{}
mut separator := args.separator
// Add headers
mut header_row := ['Name', 'Description', 'AggregateType', 'Tags', 'Subgroup']
header_row << s.header()!
result << header_row.map(format_csv_value(it, separator)).join(separator)
// Add rows
for _, row in s.rows {
mut row_data := [
format_csv_value(row.name, separator),
format_csv_value(row.description, separator),
format_csv_value(row.aggregatetype.str(), separator),
format_csv_value(row.tags, separator),
format_csv_value(row.subgroup, separator)
]
for cell in row.cells {
if cell.empty && !args.include_empty {
row_data << ''
} else {
val_str := format_number_csv(cell.val, args.include_empty)
row_data << format_csv_value(val_str, separator)
}
}
result << row_data.join(separator)
}
if args.path.len > 0 {
mut p := pathlib.get_file(path: args.path.replace('~', os.home_dir()), create: true, delete: true)!
p.write(result.join('\n'))!
}
return result.join('\n')
}

View File

@@ -0,0 +1,80 @@
module spreadsheet
fn test_sheet_export_csv() {
// Create a test sheet
mut sheet := sheet_new(name: 'test_sheet', nrcol: 12)!
// Add some test rows with data
mut row1 := sheet.row_new(
name: 'row1',
descr: 'First test row',
tags: 'test,row,first'
)!
mut row2 := sheet.row_new(
name: 'row2',
descr: 'Second test row with | pipe character',
tags: 'test,row,second'
)!
// Set some cell values
row1.cells[0].val = 10.5
row1.cells[0].empty = false
row1.cells[1].val = 20.75
row1.cells[1].empty = false
row1.cells[2].val = 1500
row1.cells[2].empty = false
row1.cells[3].val = 0.0
row1.cells[3].empty = false
row2.cells[0].val = 5.25
row2.cells[0].empty = false
row2.cells[1].val = 0.0
row2.cells[1].empty = false
row2.cells[2].val = 2500
row2.cells[2].empty = false
row2.cells[3].val = 3.333
row2.cells[3].empty = false
// Test default export with pipe separator
csv_output := sheet.export_csv(path: '')!
lines := csv_output.split('\n')
// Verify header line
assert lines.len > 0
assert lines[0].starts_with('Name|Description|AggregateType|Tags|Subgroup|')
// Verify data lines
assert lines.len >= 3 // Header + 2 data rows
assert lines[1].starts_with('row1|First test row|sum|test,row,first|')
// Check for the cell values in the output
assert lines[1].contains('|10.5|')
assert lines[1].contains('|20.75|')
assert lines[1].contains('|1500|')
// Test with custom separator and include_empty option
csv_output2 := sheet.export_csv(
path: '',
separator: ',',
include_empty: true
)!
lines2 := csv_output2.split('\n')
// Verify that empty cells are included as '0'
assert lines2[1].contains('0')
// When using comma separator, the comma in tags should be quoted, not the pipe character
assert lines2[2].contains('Second test row with | pipe character')
assert lines2[2].contains('"test,row,second"')
// Test with different separator
csv_output3 := sheet.export_csv(
path: '',
separator: ';'
)!
lines3 := csv_output3.split('\n')
// Verify separator is used correctly
assert lines3[0].starts_with('Name;Description;AggregateType;Tags;Subgroup;')
}

View File

@@ -7,7 +7,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.osal.screen
import freeflowuniverse.herolib.ui
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time
import json

View File

@@ -10,7 +10,7 @@ import freeflowuniverse.herolib.data.encoderhero
@end
@if model.cat == .installer
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
@end

View File

@@ -10,7 +10,7 @@ import freeflowuniverse.herolib.data.encoderhero
@end
@if model.cat == .installer
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
@end

View File

@@ -3,7 +3,7 @@ module base
import freeflowuniverse.herolib.osal
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.core
import time
import os

View File

@@ -3,7 +3,7 @@ module cometbft
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module meilisearch_installer
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module postgresql
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module zerodb
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module zerofs
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module coredns
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module gitea
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module livekit
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module screen
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module zinit_installer
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module golang
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module nodejs
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module python
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module rust
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -3,7 +3,7 @@ module mycelium_installer
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module wireguard_installer
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module yggdrasil
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module actrunner
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module b2
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -3,7 +3,7 @@ module daguserver
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module fungistor
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -3,7 +3,7 @@ module garage_s3
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -2,7 +2,7 @@ module grafana
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -2,7 +2,7 @@ module prometheus
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.httpconnection
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import os
import time

View File

@@ -3,7 +3,7 @@ module rclone
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module restic
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module s3
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module griddriver
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module cloudhypervisor
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module docker
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module pacman
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module podman
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module youki
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module bun
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module imagemagick
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module lighttpd
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module tailwind
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -2,7 +2,7 @@ module tailwind4
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -3,7 +3,7 @@ module traefik
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time

View File

@@ -2,7 +2,7 @@ module zola
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
import freeflowuniverse.herolib.osal.zinit
__global (

View File

@@ -1,7 +1,7 @@
# startup manager
```go
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.startupmanager
mut sm:=startupmanager.get()!

View File

@@ -103,19 +103,22 @@ pub mut:
pub struct Main {
pub mut:
name string
title string
title string = 'Docusaurus'
tagline string
favicon string
url string
favicon string = 'img/favicon.png'
url string = 'http://localhost'
url_home string
base_url string @[json: 'baseUrl']
image string
base_url string = '/' @[json: 'baseUrl']
image string = 'img/tf_graph.png' @[required]
metadata MainMetadata
build_dest []string
build_dest_dev []string
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:
@@ -144,22 +147,6 @@ pub mut:
title string = 'Docusaurus'
}
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']
}
pub struct MyImport {
pub mut:
@@ -199,56 +186,9 @@ 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
// 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) or {
eprintln('footer.json in ${cfg_dir} is not in the right format please fix.\nError: ${err}')
exit(99)
}
// 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.json in ${cfg_dir} is not in the right format please fix.\nError: ${err}')
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"]
}
// Load and parse navbar config
navbar_content := os.read_file(os.join_path(cfg_dir, 'navbar.json'))!
navbar := json.decode(Navbar, navbar_content) or {
eprintln('navbar.json in ${cfg_dir} is not in the right format please fix.\nError: $err')
exit(99)
}
pub struct ImportSource {
pub mut: