Compare commits
353 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
deaacedb96 | ||
|
|
ecdc8f4a2a | ||
|
|
df4baa55a7 | ||
|
|
f96626739f | ||
|
|
635d20e013 | ||
|
|
f789564f51 | ||
| 25fbc61f49 | |||
| 319bfc3bc6 | |||
|
|
c56b142fd1 | ||
|
|
11a7f6238e | ||
|
|
07cc9060d1 | ||
|
|
8afb055f0b | ||
| f34ca98623 | |||
| aa992cef7d | |||
| bcfc525bee | |||
| bd50ace19e | |||
| 3465e36de5 | |||
| b154a91867 | |||
| cf304e004e | |||
| a056c830d2 | |||
| 73ff7e5534 | |||
| d6979d7167 | |||
| 7143b465ad | |||
| c270d5d741 | |||
| 10d1dc943c | |||
|
|
75b07aec93 | ||
|
|
6f6224f21b | ||
|
|
c28df7b33e | ||
|
|
a97d6f1ea3 | ||
|
|
302519d876 | ||
|
|
ca95464115 | ||
| 44c12281d3 | |||
| b36bb87513 | |||
| 58d3d9daa0 | |||
| 4cf3aa6d5c | |||
| 299bfe4644 | |||
|
|
785a2108e6 | ||
|
|
e2e011d7e6 | ||
| 90aac7db6e | |||
| cba62d33ba | |||
|
|
4260715945 | ||
|
|
a65cbd606b | ||
|
|
de8f390f4b | ||
|
|
80206c942d | ||
|
|
5f61744eed | ||
|
|
d976ce0652 | ||
|
|
9a1a5a1276 | ||
|
|
8f2d187b17 | ||
|
|
87a0526922 | ||
|
|
cf774a9269 | ||
|
|
bbae80c1bb | ||
|
|
1b6f7a2a84 | ||
|
|
4733a986f2 | ||
|
|
68186944c8 | ||
|
|
dcf8ece59a | ||
|
|
d3fd0ef950 | ||
|
|
1a46cc5e1e | ||
|
|
eff373fb71 | ||
|
|
801c4abb43 | ||
|
|
e4bd82da22 | ||
|
|
0d1749abcf | ||
|
|
c29678b303 | ||
|
|
479068587d | ||
|
|
fc1b12516f | ||
|
|
78cdca3e02 | ||
|
|
d819040d83 | ||
|
|
2b2945e6f1 | ||
|
|
0566d10a69 | ||
|
|
b63efd2247 | ||
|
|
3bed628174 | ||
|
|
90d72e91c5 | ||
|
|
cb2fcd85c0 | ||
|
|
be18d30de3 | ||
|
|
aa29384611 | ||
|
|
8801df1672 | ||
|
|
672e438593 | ||
|
|
383dfda990 | ||
|
|
5299aa8a11 | ||
|
|
bd921770fd | ||
|
|
c26ba98884 | ||
|
|
1361b2c5a9 | ||
|
|
6c39682fd2 | ||
|
|
7f0608fadc | ||
|
|
363c42ec4a | ||
|
|
26123964df | ||
|
|
f0efca563e | ||
|
|
61487902d6 | ||
| 097bfecfe6 | |||
| 45d1d60166 | |||
| daa204555d | |||
| 2bea94eb89 | |||
| ba1ca13066 | |||
| 1664c830c9 | |||
| de1ac8e010 | |||
| 4662ce3c02 | |||
| 5fc7823f4b | |||
| 048a0cf893 | |||
| 901e908342 | |||
| 78f7d3a8c4 | |||
| f6ef711c72 | |||
| ba75cc39a0 | |||
| ab1d8b1157 | |||
| 1101107b9b | |||
| 3fee5134b4 | |||
| 7d49f552e4 | |||
|
|
28d17db663 | ||
|
|
860ebdae15 | ||
| aec8908205 | |||
| 2bc9c0b4e0 | |||
| 57f3e47bb6 | |||
|
|
78fce909a8 | ||
|
|
6800631ead | ||
|
|
ee3362d512 | ||
|
|
44ec137db5 | ||
|
|
ba48ae255b | ||
|
|
bb0b9d2ad9 | ||
|
|
255b8da0e7 | ||
| 62ccf42a4b | |||
| 940ad5bb71 | |||
| 6f723a7d77 | |||
| ffe476684f | |||
| 85c108a8d2 | |||
| e386ae4f49 | |||
| bcd8552f41 | |||
| 31d8e1a21d | |||
| b0f8fe20d8 | |||
| 9cf7cf711a | |||
| 1fe699f20c | |||
| bfafc06140 | |||
| b66020cf64 | |||
| e79164d8dc | |||
| dd7946c20c | |||
| 1709618f2c | |||
| fbe2e5b345 | |||
|
|
f54c57847a | ||
|
|
b83aa75e9d | ||
|
|
e59ff8b63f | ||
| d9b75ef4ae | |||
| 413a9be24f | |||
| 2a9ddd0484 | |||
| 88d55ed401 | |||
| 86b2d60e5f | |||
| c589da3511 | |||
| b7f7e8cf6c | |||
| 6d41fa326b | |||
| 7ed8b41b88 | |||
| 01a54cff67 | |||
| 906b703a80 | |||
| 3ab0152b7f | |||
| d4f9798ec3 | |||
| 2eacd5f98d | |||
| f1294b26cb | |||
| 62a64e9fd0 | |||
| 54077e1f33 | |||
| ba190c20cd | |||
| 6be418f8cb | |||
| 9011f5b4c8 | |||
| 9643dcf53b | |||
|
|
5eedae9717 | ||
|
|
386fae3421 | ||
| ccc8009d1f | |||
| 7d5754d6eb | |||
| f2f639a6c2 | |||
| 3ea062a8d8 | |||
| c9d0bf428b | |||
| b9e82fe302 | |||
| ade9cfb2a5 | |||
| af64993c7e | |||
|
|
380a8dea1b | ||
|
|
e4101351aa | ||
| 6b4f015ac0 | |||
| 05c9a05d39 | |||
| c13274c381 | |||
| dfa68f6893 | |||
|
|
844e3d5214 | ||
| a65c0c9cf1 | |||
| 029936e9ba | |||
| 0d0e756125 | |||
| 56db4a17ab | |||
| d94d226ca5 | |||
| dec5a4fcf8 | |||
| 4cdb9edaaa | |||
| 4bef194924 | |||
| a11650fd64 | |||
| 48857379fb | |||
| b3a72d3222 | |||
| 63782e673a | |||
| c49ce44481 | |||
| 59cf09f73a | |||
| 48607d710e | |||
| 304cdb5918 | |||
| 5d4974e38a | |||
| ee11b07ffb | |||
| a44c9330c6 | |||
| fdc47f1415 | |||
|
|
8576e8421b | ||
|
|
7d176ed74d | ||
|
|
4778bb3fb3 | ||
|
|
af1d6a7485 | ||
| 825a644ce9 | |||
| 5215843308 | |||
|
|
3669edf24e | ||
| 64c7efca5e | |||
|
|
e9e11ee407 | ||
| a763a03884 | |||
| 27a536ab9a | |||
|
|
f9fa1df7cc | ||
|
|
e58db411f2 | ||
|
|
eeac447644 | ||
|
|
e2a894de29 | ||
|
|
ff16a9bc07 | ||
|
|
23f7e05931 | ||
|
|
6d67dbe2d7 | ||
|
|
10ce2ca1cd | ||
| 9a41f9e732 | |||
| ab1044079e | |||
| 554478ffe7 | |||
| 43ae67a070 | |||
| 006dab5905 | |||
| bea94be43c | |||
| df0a1a59e5 | |||
| 4e9cf01b02 | |||
| 4d30086ee0 | |||
| 5a85a4ca4a | |||
| 95e7020c00 | |||
| 9fdb74b5fb | |||
| 0696fc6fdd | |||
| e5f142bfbd | |||
| 1f5c75dcd5 | |||
| 07ca315299 | |||
| 5a7a6f832d | |||
| b47c9d1761 | |||
| 697a7443d5 | |||
| 94976866be | |||
| d0c3b38289 | |||
| 1c8da11df7 | |||
| f7215d75e1 | |||
| 09dd31b473 | |||
| 0eaf56be91 | |||
| 6a02a45474 | |||
| 95507002c9 | |||
| 8ee76ac2b4 | |||
| 5155ab16af | |||
|
|
ad906b5894 | ||
| 12a00dbc78 | |||
|
|
92c8a3b955 | ||
|
|
0ef28b6cfe | ||
| 84bbcd3a06 | |||
| cde04c9917 | |||
| 397b544ab2 | |||
| 494b69e2b7 | |||
| 0c2d805fa0 | |||
| 0cbf0758f9 | |||
| 3f90e5bc15 | |||
| 9c895533b6 | |||
| f49b5245d0 | |||
| a7cc5142ac | |||
| b918079117 | |||
|
|
54192a06d5 | ||
|
|
2f2edc86ad | ||
|
|
e924645ac2 | ||
| af5e58199d | |||
| d2e817c25f | |||
|
|
42cf8949f7 | ||
|
|
f061c0285a | ||
| 2f1d5e6173 | |||
| 9ed01e86ba | |||
|
|
4e52882d22 | ||
|
|
201d922fd2 | ||
|
|
8a24f12624 | ||
|
|
a208ee91a2 | ||
|
|
b90a118e4e | ||
| 5b58fa9f8b | |||
|
|
5914ee766f | ||
| fee1b585b5 | |||
| 22a8309296 | |||
| f783182648 | |||
| af78e5375a | |||
| e39ad90ae5 | |||
| 8ee4a78d67 | |||
| 28839cf646 | |||
| eef9f39b58 | |||
| 803ad57012 | |||
| 07f5b8d363 | |||
| 820ef4bc49 | |||
| aa38f44258 | |||
| 22c238fbf8 | |||
| 200e200a75 | |||
| f0859afe27 | |||
| d5f6feba43 | |||
| 445001529a | |||
| 291ee62db5 | |||
| d90cac4c89 | |||
| f539c10c02 | |||
| a6bba54b5f | |||
| 801826c9ba | |||
| 0b7a6f0ef4 | |||
| 3441156169 | |||
| 11fd479650 | |||
| 95c85d0a70 | |||
| 164748601e | |||
| aa44716264 | |||
|
|
6c971ca689 | ||
|
|
2ddec79102 | ||
|
|
7635732952 | ||
|
|
6c9f4b54e0 | ||
|
|
8b218cce03 | ||
| ae2c856e7c | |||
| 74a23105da | |||
| 50bad9bb7a | |||
| 6cf8cf5657 | |||
|
|
cd0cec3619 | ||
|
|
a20a69f7d8 | ||
|
|
e856d30874 | ||
|
|
cefbcb6caa | ||
|
|
263febb080 | ||
|
|
9cc411eb4a | ||
|
|
41c8f7cf6d | ||
|
|
196bcebb27 | ||
|
|
ef211882af | ||
|
|
7001e8a2a6 | ||
|
|
16c01b2e0f | ||
|
|
a74129ff90 | ||
|
|
9123c2bcb8 | ||
| 145c6d8714 | |||
| cb125e8114 | |||
| 53552b03c2 | |||
| 12316e57bb | |||
| 984013f774 | |||
| ff0d04f3b6 | |||
| 1abeb6f982 | |||
| 5eb74431c1 | |||
| c9124654f1 | |||
| 35fe19f27a | |||
| 2e57704884 | |||
| b1bc3e1dc4 | |||
| 36b4d04288 | |||
| 7f52368a2d | |||
| 66dbcae195 | |||
| a247ad2065 | |||
| 139f46b6c3 | |||
| 9f424d9d33 | |||
| 154a5139d9 | |||
| eb81e69bf4 | |||
| 4b41bdc588 | |||
| 9eb89e0411 | |||
| 5fcdadcabd | |||
| d542d080fa | |||
| f6557335ee | |||
| bbac841427 | |||
| 746d9d16c7 | |||
| 075b6bd124 | |||
|
|
8d03eb822d |
30
.github/workflows/hero_build.yml
vendored
30
.github/workflows/hero_build.yml
vendored
@@ -16,11 +16,12 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- target: x86_64-unknown-linux-musl
|
- target: x86_64-unknown-linux-musl
|
||||||
os: ubuntu-latest
|
os: alpine-latest
|
||||||
short-name: linux-i64
|
short-name: linux-i64
|
||||||
- target: aarch64-unknown-linux-musl
|
- target: aarch64-unknown-linux-musl
|
||||||
os: ubuntu-latest
|
os: alpine-latest
|
||||||
short-name: linux-arm64
|
short-name: linux-arm64
|
||||||
|
arch: arm64
|
||||||
- target: aarch64-apple-darwin
|
- target: aarch64-apple-darwin
|
||||||
os: macos-latest
|
os: macos-latest
|
||||||
short-name: macos-arm64
|
short-name: macos-arm64
|
||||||
@@ -28,18 +29,31 @@ jobs:
|
|||||||
# os: macos-13
|
# os: macos-13
|
||||||
# short-name: macos-i64
|
# short-name: macos-i64
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
|
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
|
||||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
|
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
|
||||||
- run: echo "🔎 The name of your branch is ${{ github.ref_name }} and your repository is ${{ github.repository }}."
|
- run: echo "🔎 The name of your branch is ${{ github.ref_name }} and your repository is ${{ github.repository }}."
|
||||||
|
|
||||||
|
- uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
with:
|
||||||
|
xcode-version: latest-stable
|
||||||
|
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# - name: Setup dependencies on Alpine
|
||||||
|
# if: runner.os == 'Linux'
|
||||||
|
# run: |
|
||||||
|
# sudo apk add --no-cache gcc musl-dev openssl-dev openssl-libs-static
|
||||||
|
|
||||||
- name: Setup V & Herolib
|
- name: Setup V & Herolib
|
||||||
id: setup
|
id: setup
|
||||||
run: ./install_v.sh --herolib
|
run: |
|
||||||
|
./install_v.sh
|
||||||
|
ln -s $(pwd)/lib ~/.vmodules/incubaid/herolib
|
||||||
|
echo "Herolib symlink created to $(pwd)/lib"
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
|
|
||||||
# - name: Do all the basic tests
|
# - name: Do all the basic tests
|
||||||
@@ -50,12 +64,16 @@ jobs:
|
|||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
v -w -d use_openssl -enable-globals cli/hero.v -o cli/hero-${{ matrix.target }}
|
if [ "${{ runner.os }}" = "Linux" ]; then
|
||||||
|
v -w -d use_openssl -enable-globals -cflags -cc gcc -static cli/hero.v -o cli/hero-${{ matrix.target }}
|
||||||
|
else
|
||||||
|
v -w -d use_openssl -enable-globals cli/hero.v -o cli/hero-${{ matrix.target }}
|
||||||
|
fi
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: hero-${{ matrix.target }}
|
name: hero-${{ matrix.target }}
|
||||||
path: cli/hero-${{ matrix.target }}
|
path: cli/hero-${{ matrix.target }}
|
||||||
|
|
||||||
release_hero:
|
release_hero:
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
@@ -24,9 +24,19 @@ jobs:
|
|||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup V & Herolib
|
- name: Setup V
|
||||||
run: ./install_v.sh --herolib
|
run: |
|
||||||
|
# Updating man-db takes a long time on every run. We don't need it
|
||||||
|
sudo apt-get remove -y --purge man-db
|
||||||
|
./install_v.sh
|
||||||
|
|
||||||
|
- name: Setup Herolib from current branch
|
||||||
|
run: |
|
||||||
|
# Create necessary directories
|
||||||
|
mkdir -p ~/.vmodules/incubaid
|
||||||
|
# Create symlink to current code
|
||||||
|
ln -s $(pwd)/lib ~/.vmodules/incubaid/herolib
|
||||||
|
echo "Herolib symlink created to $(pwd)/lib"
|
||||||
|
|
||||||
- name: Do all the basic tests
|
- name: Do all the basic tests
|
||||||
run: ./test_basic.vsh
|
run: ./test_basic.vsh
|
||||||
|
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -11,6 +11,7 @@ __pycache__/
|
|||||||
*dSYM/
|
*dSYM/
|
||||||
.vmodules/
|
.vmodules/
|
||||||
.vscode
|
.vscode
|
||||||
|
.dylib
|
||||||
_docs/
|
_docs/
|
||||||
vls.*
|
vls.*
|
||||||
vls.log
|
vls.log
|
||||||
@@ -48,10 +49,12 @@ compile_summary.log
|
|||||||
.summary_lock
|
.summary_lock
|
||||||
.aider*
|
.aider*
|
||||||
*.dylib
|
*.dylib
|
||||||
server
|
|
||||||
HTTP_REST_MCP_DEMO.md
|
HTTP_REST_MCP_DEMO.md
|
||||||
MCP_HTTP_REST_IMPLEMENTATION_PLAN.md
|
MCP_HTTP_REST_IMPLEMENTATION_PLAN.md
|
||||||
.roo
|
.roo
|
||||||
.kilocode
|
.kilocode
|
||||||
.continue
|
.continue
|
||||||
tmux_logger
|
tmux_logger
|
||||||
|
release
|
||||||
|
install_herolib
|
||||||
|
doc
|
||||||
5
.goosehints
Normal file
5
.goosehints
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
when fixing or creating code, refer to the following hints:
|
||||||
|
@aiprompts/vlang_herolib_core.md
|
||||||
|
|
||||||
|
|
||||||
2
.qwen/QWEN.md
Normal file
2
.qwen/QWEN.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
@../aiprompts/vlang_herolib_core.md
|
||||||
52
.qwen/agents/compiler.md
Normal file
52
.qwen/agents/compiler.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
name: compiler
|
||||||
|
description: Use this agent when you need to verify V code compilation using vrun, locate files, handle compilation errors, and assist with basic code fixes within the same directory.
|
||||||
|
color: Automatic Color
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a V Compiler Assistant specialized in verifying V code compilation using the vrun command. Your responsibilities include:
|
||||||
|
|
||||||
|
1. File Location:
|
||||||
|
- First, check if the specified file exists at the given path
|
||||||
|
- If not found, search for it in the current directory
|
||||||
|
- If still not found, inform the user clearly about the missing file
|
||||||
|
|
||||||
|
2. Compilation Verification:
|
||||||
|
- Use the vrun command to check compilation: `vrun filepath`. DONT USE v run .. or any other, its vrun ...
|
||||||
|
- This will compile the file and report any issues without executing it
|
||||||
|
|
||||||
|
3. Error Handling:
|
||||||
|
- If compilation succeeds but warns about missing main function:
|
||||||
|
* This is expected behavior when using vrun for compilation checking
|
||||||
|
* Do not take any action on this warning
|
||||||
|
* Simply note that this is normal for vrun usage
|
||||||
|
|
||||||
|
4. Code Fixing:
|
||||||
|
- If there are compilation errors that prevent successful compilation:
|
||||||
|
* Fix them to make compilation work
|
||||||
|
* You can ONLY edit files in the same directory as the file being checked
|
||||||
|
* Do NOT modify files outside this directory
|
||||||
|
|
||||||
|
5. Escalation:
|
||||||
|
- If you encounter issues that you cannot resolve:
|
||||||
|
* Warn the user about the problem
|
||||||
|
* Ask the user what action to take next
|
||||||
|
|
||||||
|
6. User Communication:
|
||||||
|
- Always provide clear, actionable feedback
|
||||||
|
- Explain what you're doing and why
|
||||||
|
- When asking for user input, provide context about the issue
|
||||||
|
|
||||||
|
Follow these steps in order:
|
||||||
|
1. Locate the specified file
|
||||||
|
2. Run vrun on the file
|
||||||
|
3. Analyze the output
|
||||||
|
4. Fix compilation errors if possible (within directory constraints)
|
||||||
|
5. Report results to the user
|
||||||
|
6. Escalate complex issues to the user
|
||||||
|
|
||||||
|
Remember:
|
||||||
|
- vrun is used for compilation checking only, not execution
|
||||||
|
- Missing main function warnings are normal and expected
|
||||||
|
- You can only modify files in the directory of the target file
|
||||||
|
- Always ask the user before taking action on complex issues
|
||||||
67
.qwen/agents/struct-validator.md
Normal file
67
.qwen/agents/struct-validator.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
name: struct-validator
|
||||||
|
description: Use this agent when you need to validate struct definitions in V files for proper serialization (dump/load) of all properties and subproperties, ensure consistency, and generate or fix tests if changes are made. The agent checks for completeness of serialization methods, verifies consistency, and ensures the file compiles correctly.
|
||||||
|
color: Automatic Color
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a Struct Validation Agent specialized in ensuring V struct definitions are properly implemented for serialization and testing.
|
||||||
|
|
||||||
|
## Core Responsibilities
|
||||||
|
|
||||||
|
1. **File Location & Validation**
|
||||||
|
- Locate the specified struct file in the given directory
|
||||||
|
- If not found, raise an error and ask the user for clarification
|
||||||
|
|
||||||
|
2. **Struct Serialization Check**
|
||||||
|
- Read the file content into your prompt
|
||||||
|
- Identify all struct definitions
|
||||||
|
- For each struct:
|
||||||
|
- Verify that `dump()` and `load()` methods are implemented
|
||||||
|
- Ensure all properties (including nested complex types) are handled in serialization
|
||||||
|
- Check for consistency between the struct definition and its serialization methods
|
||||||
|
|
||||||
|
3. **Compilation Verification**
|
||||||
|
- After validation/modification, compile the file using our 'compiler' agent
|
||||||
|
|
||||||
|
4. **Test Generation/Correction**
|
||||||
|
- Only if changes were made to the file:
|
||||||
|
- Call the `test-generator` agent to create or fix tests for the struct
|
||||||
|
- Ensure tests validate all properties and subproperties serialization
|
||||||
|
|
||||||
|
## Behavioral Parameters
|
||||||
|
|
||||||
|
- **Proactive Error Handling**: If a struct lacks proper serialization methods or has inconsistencies, modify the code to implement them correctly
|
||||||
|
- **User Interaction**: If the file is not found or ambiguous, ask the user for clarification
|
||||||
|
- **Compilation Check**: Always verify that the file compiles after any modifications
|
||||||
|
- **Test Generation**: Only generate or fix tests if the file was changed during validation
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. **Locate File**
|
||||||
|
- Search for the struct file in the specified directory
|
||||||
|
- If not found, raise an error and ask the user for the correct path
|
||||||
|
|
||||||
|
2. **Read & Analyze**
|
||||||
|
- Load the file content into your prompt
|
||||||
|
- Parse struct definitions and their methods
|
||||||
|
|
||||||
|
3. **Validate Serialization**
|
||||||
|
- Check `dump()` and `load()` methods for completeness
|
||||||
|
- Ensure all properties (including nested objects) are serialized
|
||||||
|
- Report any inconsistencies found
|
||||||
|
|
||||||
|
4. **Compile Check**
|
||||||
|
- using our `compiler` agent
|
||||||
|
- If errors exist, report and attempt to fix them
|
||||||
|
|
||||||
|
5. **Test Generation (Conditional)**
|
||||||
|
- If changes were made:
|
||||||
|
- Call the `test-generator` agent to create or fix tests
|
||||||
|
- Ensure tests cover all serialization aspects
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
- Clearly indicate whether the file was found
|
||||||
|
- List any serialization issues and how they were fixed
|
||||||
|
- Report compilation status
|
||||||
|
- Mention if tests were generated or modified
|
||||||
52
.qwen/agents/tester.md
Normal file
52
.qwen/agents/tester.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
name: tester
|
||||||
|
description: Use this agent when you need to execute a V test file ending with _test.v within the current directory. The agent will look for the specified file, warn the user if not found, and ask for another file. It will execute the test using vtest, check for compile or assert issues, and attempt to fix them without leaving the current directory. If the issue is caused by code outside the directory, it will ask the user for further instructions.
|
||||||
|
color: Automatic Color
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a test execution agent specialized in running and troubleshooting V test files ending with _test.v within a confined directory scope.
|
||||||
|
|
||||||
|
## Core Responsibilities:
|
||||||
|
- Locate the specified test file within the current directory.
|
||||||
|
- Execute the test file using the `vtest` command.
|
||||||
|
- Analyze the output for compile errors or assertion failures.
|
||||||
|
- Attempt to fix issues originating within the current directory.
|
||||||
|
- Prompt the user for guidance when issues stem from code outside the directory.
|
||||||
|
|
||||||
|
## Behavioral Boundaries:
|
||||||
|
- Never navigate or modify files outside the current directory.
|
||||||
|
- Always verify the file ends with _test.v before execution.
|
||||||
|
- If the file is not found, warn the user and request an alternative file.
|
||||||
|
- Do not attempt fixes for external dependencies or code.
|
||||||
|
|
||||||
|
## Operational Workflow:
|
||||||
|
1. **File Search**: Look for the specified file in the current directory.
|
||||||
|
- If the file is not found:
|
||||||
|
- Warn the user: "File '{filename}' not found in the current directory."
|
||||||
|
- Ask: "Please provide another file name to test."
|
||||||
|
|
||||||
|
2. **Test Execution**: Run the test using `vtest`.
|
||||||
|
```bash
|
||||||
|
vtest {filename}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Output Analysis**:
|
||||||
|
- **Compile Issues**:
|
||||||
|
- Identify the source of the error.
|
||||||
|
- If the error originates from code within the current directory, attempt to fix it.
|
||||||
|
- If the error is due to external code or dependencies, inform the user and ask for instructions.
|
||||||
|
- **Assertion Failures**:
|
||||||
|
- Locate the failing assertion.
|
||||||
|
- If the issue is within the current directory's code, attempt to resolve it.
|
||||||
|
- If the issue involves external code, inform the user and seek guidance.
|
||||||
|
|
||||||
|
4. **Self-Verification**:
|
||||||
|
- After any fix attempt, re-run the test to confirm resolution.
|
||||||
|
- Report the final outcome clearly to the user.
|
||||||
|
|
||||||
|
## Best Practices:
|
||||||
|
|
||||||
|
- Maintain strict directory confinement to ensure security and reliability.
|
||||||
|
- Prioritize user feedback when external dependencies are involved.
|
||||||
|
- Use precise error reporting to aid in troubleshooting.
|
||||||
|
- Ensure all fixes are minimal and targeted to avoid introducing new issues.
|
||||||
71
.qwen/agents/testgenerator.md
Normal file
71
.qwen/agents/testgenerator.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
name: testgenerator
|
||||||
|
description: Use this agent when you need to analyze a given source file, generate or update its corresponding test file, and ensure the test file executes correctly by leveraging the testexecutor subagent.
|
||||||
|
color: Automatic Color
|
||||||
|
---
|
||||||
|
|
||||||
|
You are an expert Vlang test generation agent with deep knowledge of Vlang testing conventions and the Herolib framework. Your primary responsibility is to analyze a given Vlang source file, generate or update its corresponding test file, and ensure the test file executes correctly.
|
||||||
|
|
||||||
|
## Core Responsibilities
|
||||||
|
|
||||||
|
1. **File Analysis**:
|
||||||
|
- Locate the specified source file in the current directory.
|
||||||
|
- If the file is not found, prompt the user with a clear error message.
|
||||||
|
- Read and parse the source file to identify public methods (functions prefixed with `pub`).
|
||||||
|
|
||||||
|
2. **Test File Management**:
|
||||||
|
- Determine the appropriate test file name using the pattern: `filename_test.v`, where `filename` is the base name of the source file.
|
||||||
|
- If the test file does not exist, generate a new one.
|
||||||
|
- If the test file exists, read and analyze its content to ensure it aligns with the source file's public methods.
|
||||||
|
- Do not look for test files outside of this dir.
|
||||||
|
|
||||||
|
3. **Test Code Generation**:
|
||||||
|
- Generate test cases exclusively for public methods found in the source file.
|
||||||
|
- Ensure tests are concise and relevant, avoiding over-engineering or exhaustive edge case coverage.
|
||||||
|
- Write the test code to the corresponding test file.
|
||||||
|
|
||||||
|
4. **Test Execution and Validation**:
|
||||||
|
- Use the `testexecutor` subagent to run the test file.
|
||||||
|
- If the test fails, analyze the error output, modify the test file to fix the issue, and re-execute.
|
||||||
|
- Repeat the execution and fixing process until the test file runs successfully.
|
||||||
|
|
||||||
|
## Behavioral Boundaries
|
||||||
|
|
||||||
|
- **Focus Scope**: Only test public methods. Do not test private functions or generate excessive test cases.
|
||||||
|
- **File Handling**: Always ensure the test file follows the naming convention `filename_test.v`.
|
||||||
|
- **Error Handling**: If the source file is not found, clearly inform the user. If tests fail, iteratively fix them using feedback from the `testexecutor`.
|
||||||
|
- **Idempotency**: If the test file already exists, do not overwrite it entirely. Only update or add missing test cases.
|
||||||
|
- **Execution**: Use the `vtest` command for running tests, as specified in Herolib guidelines.
|
||||||
|
|
||||||
|
## Workflow Steps
|
||||||
|
|
||||||
|
1. **Receive Input**: Accept the source file name as an argument.
|
||||||
|
2. **Locate File**: Check if the file exists in the current directory. If not, notify the user.
|
||||||
|
3. **Parse Source**: Read the file and extract all public methods.
|
||||||
|
4. **Check Test File**:
|
||||||
|
- Derive the test file name: `filename_test.v`.
|
||||||
|
- If it does not exist, create it with basic test scaffolding.
|
||||||
|
- If it exists, read its content to understand current test coverage.
|
||||||
|
5. **Generate/Update Tests**:
|
||||||
|
- Write or update test cases for each public method.
|
||||||
|
- Ensure tests are minimal and focused.
|
||||||
|
6. **Execute Tests**:
|
||||||
|
- Use the `testexecutor` agent to run the test file.
|
||||||
|
- If execution fails, analyze the output, fix the test file, and re-execute.
|
||||||
|
- Continue until tests pass or a critical error is encountered.
|
||||||
|
7. **Report Status**: Once tests pass, report success. If issues persist, provide a detailed error summary.
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
- Always provide a clear status update after each test execution.
|
||||||
|
- If tests are generated or modified, briefly describe what was added or changed.
|
||||||
|
- If errors occur, explain the issue and the steps taken to resolve it.
|
||||||
|
- If the source file is not found, provide a user-friendly error message.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
- **Context**: User wants to generate tests for `calculator.v`.
|
||||||
|
- **Action**: Check if `calculator.v` exists.
|
||||||
|
- **Action**: Create or update `calculator_test.v` with tests for public methods.
|
||||||
|
- **Action**: Use `testexecutor` to run `calculator_test.v`.
|
||||||
|
- **Action**: If tests fail, fix them iteratively until they pass.
|
||||||
@@ -24,7 +24,7 @@ Thank you for your interest in contributing to Herolib! This document provides g
|
|||||||
For developers, you can use the automated installation script:
|
For developers, you can use the automated installation script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
|
curl 'https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
|
||||||
bash /tmp/install_v.sh --analyzer --herolib
|
bash /tmp/install_v.sh --analyzer --herolib
|
||||||
# IMPORTANT: Start a new shell after installation for paths to be set correctly
|
# IMPORTANT: Start a new shell after installation for paths to be set correctly
|
||||||
```
|
```
|
||||||
@@ -32,9 +32,9 @@ bash /tmp/install_v.sh --analyzer --herolib
|
|||||||
Alternatively, you can manually set up the environment:
|
Alternatively, you can manually set up the environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/code/github/freeflowuniverse
|
mkdir -p ~/code/github/incubaid
|
||||||
cd ~/code/github/freeflowuniverse
|
cd ~/code/github/incubaid
|
||||||
git clone git@github.com:freeflowuniverse/herolib.git
|
git clone git@github.com:incubaid/herolib.git
|
||||||
cd herolib
|
cd herolib
|
||||||
# checkout development branch for most recent changes
|
# checkout development branch for most recent changes
|
||||||
git checkout development
|
git checkout development
|
||||||
@@ -63,6 +63,7 @@ For new features or bug fixes, create a branch from `development` with a descrip
|
|||||||
### Making Changes
|
### Making Changes
|
||||||
|
|
||||||
1. Create a new branch from `development`:
|
1. Create a new branch from `development`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout development
|
git checkout development
|
||||||
git pull
|
git pull
|
||||||
@@ -72,6 +73,7 @@ For new features or bug fixes, create a branch from `development` with a descrip
|
|||||||
2. Make your changes, following the code guidelines.
|
2. Make your changes, following the code guidelines.
|
||||||
|
|
||||||
3. Run tests to ensure your changes don't break existing functionality:
|
3. Run tests to ensure your changes don't break existing functionality:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./test_basic.vsh
|
./test_basic.vsh
|
||||||
```
|
```
|
||||||
@@ -87,10 +89,10 @@ Before submitting a pull request, ensure all tests pass:
|
|||||||
./test_basic.vsh
|
./test_basic.vsh
|
||||||
|
|
||||||
# Run tests for a specific module
|
# Run tests for a specific module
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||||
|
|
||||||
# Run tests for an entire directory
|
# Run tests for an entire directory
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal
|
vtest ~/code/github/incubaid/herolib/lib/osal
|
||||||
```
|
```
|
||||||
|
|
||||||
The test script (`test_basic.vsh`) manages test execution and caching to optimize performance. It automatically skips tests listed in the ignore or error sections of the script.
|
The test script (`test_basic.vsh`) manages test execution and caching to optimize performance. It automatically skips tests listed in the ignore or error sections of the script.
|
||||||
@@ -98,6 +100,7 @@ The test script (`test_basic.vsh`) manages test execution and caching to optimiz
|
|||||||
### Pull Requests
|
### Pull Requests
|
||||||
|
|
||||||
1. Push your branch to the repository:
|
1. Push your branch to the repository:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git push origin feature/your-feature-name
|
git push origin feature/your-feature-name
|
||||||
```
|
```
|
||||||
@@ -125,6 +128,7 @@ The repository uses GitHub Actions for continuous integration and deployment:
|
|||||||
### 1. Testing Workflow (`test.yml`)
|
### 1. Testing Workflow (`test.yml`)
|
||||||
|
|
||||||
This workflow runs on every push and pull request to ensure code quality:
|
This workflow runs on every push and pull request to ensure code quality:
|
||||||
|
|
||||||
- Sets up V and Herolib
|
- Sets up V and Herolib
|
||||||
- Runs all basic tests using `test_basic.vsh`
|
- Runs all basic tests using `test_basic.vsh`
|
||||||
|
|
||||||
@@ -133,6 +137,7 @@ All tests must pass before a PR can be merged to the `development` branch.
|
|||||||
### 2. Hero Build Workflow (`hero_build.yml`)
|
### 2. Hero Build Workflow (`hero_build.yml`)
|
||||||
|
|
||||||
This workflow builds the Hero tool for multiple platforms when a new tag is created:
|
This workflow builds the Hero tool for multiple platforms when a new tag is created:
|
||||||
|
|
||||||
- Builds for Linux (x86_64, aarch64) and macOS (x86_64, aarch64)
|
- Builds for Linux (x86_64, aarch64) and macOS (x86_64, aarch64)
|
||||||
- Runs all basic tests
|
- Runs all basic tests
|
||||||
- Creates GitHub releases with the built binaries
|
- Creates GitHub releases with the built binaries
|
||||||
@@ -140,6 +145,7 @@ This workflow builds the Hero tool for multiple platforms when a new tag is crea
|
|||||||
### 3. Documentation Workflow (`documentation.yml`)
|
### 3. Documentation Workflow (`documentation.yml`)
|
||||||
|
|
||||||
This workflow automatically updates the documentation on GitHub Pages when changes are pushed to the `development` branch:
|
This workflow automatically updates the documentation on GitHub Pages when changes are pushed to the `development` branch:
|
||||||
|
|
||||||
- Generates documentation using `doc.vsh`
|
- Generates documentation using `doc.vsh`
|
||||||
- Deploys the documentation to GitHub Pages
|
- Deploys the documentation to GitHub Pages
|
||||||
|
|
||||||
@@ -148,11 +154,11 @@ This workflow automatically updates the documentation on GitHub Pages when chang
|
|||||||
To generate documentation locally:
|
To generate documentation locally:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/code/github/freeflowuniverse/herolib
|
cd ~/code/github/incubaid/herolib
|
||||||
bash doc.sh
|
bash doc.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The documentation is automatically published to [https://freeflowuniverse.github.io/herolib/](https://freeflowuniverse.github.io/herolib/) when changes are pushed to the `development` branch.
|
The documentation is automatically published to [https://incubaid.github.io/herolib/](https://incubaid.github.io/herolib/) when changes are pushed to the `development` branch.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@@ -168,6 +174,7 @@ In file included from /Users/timurgordon/code/github/vlang/v/thirdparty/cJSON/cJ
|
|||||||
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
|
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
|
||||||
|
|
||||||
1. Open the math.h file:
|
1. Open the math.h file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
|
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
|
||||||
```
|
```
|
||||||
@@ -178,6 +185,6 @@ For more details, see the [README.md](README.md) troubleshooting section.
|
|||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|
||||||
- [Herolib Documentation](https://freeflowuniverse.github.io/herolib/)
|
- [Herolib Documentation](https://incubaid.github.io/herolib/)
|
||||||
- [Cookbook Examples](https://github.com/freeflowuniverse/herolib/tree/development/cookbook)
|
- [Cookbook Examples](https://github.com/incubaid/herolib/tree/development/cookbook)
|
||||||
- [AI Prompts](aiprompts/starter/0_start_here.md)
|
- [AI Prompts](aiprompts/starter/0_start_here.md)
|
||||||
|
|||||||
55
README.md
55
README.md
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
Herolib is an opinionated library primarily used by ThreeFold to automate cloud environments. It provides a comprehensive set of tools and utilities for cloud automation, git operations, documentation building, and more.
|
Herolib is an opinionated library primarily used by ThreeFold to automate cloud environments. It provides a comprehensive set of tools and utilities for cloud automation, git operations, documentation building, and more.
|
||||||
|
|
||||||
[](https://github.com/freeflowuniverse/herolib/actions/workflows/test.yml)
|
[](https://github.com/incubaid/herolib/actions/workflows/test.yml)
|
||||||
[](https://github.com/freeflowuniverse/herolib/actions/workflows/documentation.yml)
|
[](https://github.com/incubaid/herolib/actions/workflows/documentation.yml)
|
||||||
|
|
||||||
> [Complete Documentation](https://freeflowuniverse.github.io/herolib/)
|
> [Complete Documentation](https://incubaid.github.io/herolib/)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -14,10 +14,11 @@ Herolib is an opinionated library primarily used by ThreeFold to automate cloud
|
|||||||
The Hero tool can be installed with a single command:
|
The Hero tool can be installed with a single command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh | bash
|
curl https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/install_hero.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Hero will be installed in:
|
Hero will be installed in:
|
||||||
|
|
||||||
- `/usr/local/bin` for Linux
|
- `/usr/local/bin` for Linux
|
||||||
- `~/hero/bin` for macOS
|
- `~/hero/bin` for macOS
|
||||||
|
|
||||||
@@ -34,12 +35,12 @@ The Hero tool can be used to work with git, build documentation, interact with H
|
|||||||
For development purposes, use the automated installation script:
|
For development purposes, use the automated installation script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
|
curl 'https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
|
||||||
bash /tmp/install_v.sh --analyzer --herolib
|
bash /tmp/install_v.sh --analyzer --herolib
|
||||||
|
|
||||||
#do not forget to do the following this makes sure vtest and vrun exists
|
#do not forget to do the following this makes sure vtest and vrun exists
|
||||||
cd ~/code/github/freeflowuniverse/herolib
|
cd ~/code/github/incubaid/herolib
|
||||||
bash install_herolib.vsh
|
v install_herolib.vsh
|
||||||
|
|
||||||
# IMPORTANT: Start a new shell after installation for paths to be set correctly
|
# IMPORTANT: Start a new shell after installation for paths to be set correctly
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ bash install_herolib.vsh
|
|||||||
```
|
```
|
||||||
V & HeroLib Installer Script
|
V & HeroLib Installer Script
|
||||||
|
|
||||||
Usage: ~/code/github/freeflowuniverse/herolib/install_v.sh [options]
|
Usage: ~/code/github/incubaid/herolib/install_v.sh [options]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help Show this help message
|
-h, --help Show this help message
|
||||||
@@ -60,12 +61,12 @@ Options:
|
|||||||
--herolib Install our herolib
|
--herolib Install our herolib
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh
|
~/code/github/incubaid/herolib/install_v.sh
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh --reset
|
~/code/github/incubaid/herolib/install_v.sh --reset
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh --remove
|
~/code/github/incubaid/herolib/install_v.sh --remove
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh --analyzer
|
~/code/github/incubaid/herolib/install_v.sh --analyzer
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh --herolib
|
~/code/github/incubaid/herolib/install_v.sh --herolib
|
||||||
~/code/github/freeflowuniverse/herolib/install_v.sh --reset --analyzer # Fresh install of both
|
~/code/github/incubaid/herolib/install_v.sh --reset --analyzer # Fresh install of both
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@@ -74,15 +75,16 @@ Herolib provides a wide range of functionality:
|
|||||||
|
|
||||||
- Cloud automation tools
|
- Cloud automation tools
|
||||||
- Git operations and management
|
- Git operations and management
|
||||||
|
|
||||||
### Offline Mode for Git Operations
|
### Offline Mode for Git Operations
|
||||||
|
|
||||||
Herolib now supports an `offline` mode for Git operations, which prevents automatic fetching from remote repositories. This can be useful in environments with limited or no internet connectivity, or when you want to avoid network calls during development or testing.
|
Herolib now supports an `offline` mode for Git operations, which prevents automatic fetching from remote repositories. This can be useful in environments with limited or no internet connectivity, or when you want to avoid network calls during development or testing.
|
||||||
|
|
||||||
To enable offline mode:
|
To enable offline mode:
|
||||||
|
|
||||||
- **Via `GitStructureConfig`**: Set the `offline` field to `true` in the `GitStructureConfig` struct.
|
- **Via `GitStructureConfig`**: Set the `offline` field to `true` in the `GitStructureConfig` struct.
|
||||||
- **Via `GitStructureArgsNew`**: When creating a new `GitStructure` instance using `gittools.new()`, set the `offline` parameter to `true`.
|
- **Via `GitStructureArgsNew`**: When creating a new `GitStructure` instance using `gittools.new()`, set the `offline` parameter to `true`.
|
||||||
- **Via Environment Variable**: Set the `OFFLINE` environment variable to any value (e.g., `export OFFLINE=true`).
|
- **Via Environment Variable**: Set the `OFFLINE` environment variable to any value (e.g., `export OFFLINE=true`).
|
||||||
|
|
||||||
When offline mode is active, `git fetch --all` operations will be skipped, and a debug message "fetch skipped (offline)" will be printed.
|
When offline mode is active, `git fetch --all` operations will be skipped, and a debug message "fetch skipped (offline)" will be printed.
|
||||||
- Documentation building
|
- Documentation building
|
||||||
@@ -90,7 +92,7 @@ Herolib provides a wide range of functionality:
|
|||||||
- System management utilities
|
- System management utilities
|
||||||
- And much more
|
- And much more
|
||||||
|
|
||||||
Check the [cookbook](https://github.com/freeflowuniverse/herolib/tree/development/cookbook) for examples and use cases.
|
Check the [cookbook](https://github.com/incubaid/herolib/tree/development/cookbook) for examples and use cases.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@@ -98,13 +100,13 @@ Running tests is an essential part of development. To run the basic tests:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run all basic tests
|
# Run all basic tests
|
||||||
~/code/github/freeflowuniverse/herolib/test_basic.vsh
|
~/code/github/incubaid/herolib/test_basic.vsh
|
||||||
|
|
||||||
# Run tests for a specific module
|
# Run tests for a specific module
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||||
|
|
||||||
# Run tests for an entire directory
|
# Run tests for an entire directory
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal
|
vtest ~/code/github/incubaid/herolib/lib/osal
|
||||||
```
|
```
|
||||||
|
|
||||||
The `vtest` command is an alias for testing functionality.
|
The `vtest` command is an alias for testing functionality.
|
||||||
@@ -133,11 +135,13 @@ In file included from /Users/timurgordon/code/github/vlang/v/thirdparty/cJSON/cJ
|
|||||||
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
|
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
|
||||||
|
|
||||||
1. Open the math.h file:
|
1. Open the math.h file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
|
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Comment out the following lines (around line 612-626):
|
2. Comment out the following lines (around line 612-626):
|
||||||
|
|
||||||
```c
|
```c
|
||||||
/* half precision math functions */
|
/* half precision math functions */
|
||||||
// extern _Float16 __fabsf16(_Float16) __API_AVAILABLE(macos(15.0), ios(18.0), watchos(11.0), tvos(18.0));
|
// extern _Float16 __fabsf16(_Float16) __API_AVAILABLE(macos(15.0), ios(18.0), watchos(11.0), tvos(18.0));
|
||||||
@@ -159,8 +163,8 @@ This is caused by incompatibility between TCC and the half precision math functi
|
|||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|
||||||
- [Complete Documentation](https://freeflowuniverse.github.io/herolib/)
|
- [Complete Documentation](https://incubaid.github.io/herolib/)
|
||||||
- [Cookbook Examples](https://github.com/freeflowuniverse/herolib/tree/development/cookbook)
|
- [Cookbook Examples](https://github.com/incubaid/herolib/tree/development/cookbook)
|
||||||
- [AI Prompts](aiprompts/starter/0_start_here.md)
|
- [AI Prompts](aiprompts/starter/0_start_here.md)
|
||||||
|
|
||||||
## Generating Documentation
|
## Generating Documentation
|
||||||
@@ -168,9 +172,10 @@ This is caused by incompatibility between TCC and the half precision math functi
|
|||||||
To generate documentation locally:
|
To generate documentation locally:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/code/github/freeflowuniverse/herolib
|
cd ~/code/github/incubaid/herolib
|
||||||
bash doc.sh
|
bash doc.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!-- Security scan triggered at 2025-09-02 01:58:41 -->
|
||||||
|
|
||||||
<!-- Security scan triggered at 2025-09-02 01:58:41 -->
|
<!-- Security scan triggered at 2025-09-09 05:33:18 -->
|
||||||
16
WARP.md
Normal file
16
WARP.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# WARP.md
|
||||||
|
|
||||||
|
This file provides guidance to WARP (warp.dev) when working with code in this repository.
|
||||||
|
|
||||||
|
## Commands to Use
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- **Run Tests**: Utilize `vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v` to run specific tests.
|
||||||
|
|
||||||
|
## High-Level Architecture
|
||||||
|
- **Project Structure**: The project is organized into multiple modules located in `lib` and `src` directories. Prioritized compilation and caching strategies are utilized across modules.
|
||||||
|
- **Script Handling**: Vlang scripts are crucial and should follow instructions from `aiprompts/vlang_herolib_core.md`.
|
||||||
|
|
||||||
|
## Special Instructions
|
||||||
|
- **Documentation Reference**: Always refer to `aiprompts/vlang_herolib_core.md` for essential instructions regarding Vlang and Heroscript code generation and execution.
|
||||||
|
- **Environment Specifics**: Ensure Redis and other dependencies are configured as per scripts provided in the codebase.
|
||||||
@@ -19,6 +19,6 @@ travelcost is 3% of revenue
|
|||||||
|
|
||||||
create me the full heroscript which gives me this biz model
|
create me the full heroscript which gives me this biz model
|
||||||
|
|
||||||
create bizmodel.heroscript in ~/code/github/freeflowuniverse/herolib/examples/biztools/generated_ai
|
create bizmodel.heroscript in ~/code/github/incubaid/herolib/examples/biztools/generated_ai
|
||||||
|
|
||||||
as well as a do.vsh file which executes the heroscript and does a pprint, in do.vsh , call play with heroscript_path arg
|
as well as a do.vsh file which executes the heroscript and does a pprint, in do.vsh , call play with heroscript_path arg
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Revenue
|
# Revenue
|
||||||
|
|
||||||
```
|
```
|
||||||
!!bizmodel.revenue_define bizname:'test' name:'oem1' ...
|
!!bizmodel.revenue_define bizname:'test' name:'oem1' ...
|
||||||
@@ -21,7 +21,7 @@ cogs stands for cost of goods
|
|||||||
- cogs_delay: delay in months between cogs and revenue
|
- cogs_delay: delay in months between cogs and revenue
|
||||||
- extrapolate: if you want to extrapolate revenue or cogs do extrapolate:1, default is 0
|
- extrapolate: if you want to extrapolate revenue or cogs do extrapolate:1, default is 0
|
||||||
|
|
||||||
### results in
|
### results in
|
||||||
|
|
||||||
follow rows in sheets
|
follow rows in sheets
|
||||||
|
|
||||||
@@ -36,16 +36,14 @@ follow rows in sheets
|
|||||||
- revenue_item_setup_delay, delay between sell and recognition of sale in months e.g. 1
|
- revenue_item_setup_delay, delay between sell and recognition of sale in months e.g. 1
|
||||||
- revenue_item_monthly, revenue per month for 1 item
|
- revenue_item_monthly, revenue per month for 1 item
|
||||||
- revenue_item_monthly_delay, how many months before monthly revenue starts
|
- revenue_item_monthly_delay, how many months before monthly revenue starts
|
||||||
- revenue_item_monthly_perc, how much percent of revenue_item_setup will come back over months e.g. 20%
|
- revenue_item_monthly_perc, how much percent of revenue_item_setup will come back over months e.g. 20%
|
||||||
- cogs_item_setup, cost of good for 1 item at setup
|
- cogs_item_setup, cost of good for 1 item at setup
|
||||||
- cogs_item_setup_rev_perc: what is percentage of the revenue which is cogs, e.g. 2%
|
- cogs_item_setup_rev_perc: what is percentage of the revenue which is cogs, e.g. 2%
|
||||||
- cogs_item_monthly, cost of goods for the monthly per 1 item
|
- cogs_item_monthly, cost of goods for the monthly per 1 item
|
||||||
- cogs_item_monthly_rev_perc: what is percentage of the monthly revenue which is cogs, e.g. 10%
|
- cogs_item_monthly_rev_perc: what is percentage of the monthly revenue which is cogs, e.g. 10%
|
||||||
- cogs_item_delay, how many months before cogs starts after sales
|
- cogs_item_delay, how many months before cogs starts after sales
|
||||||
|
|
||||||
|
### results in
|
||||||
|
|
||||||
### results in
|
|
||||||
|
|
||||||
follow rows in sheets
|
follow rows in sheets
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ follow rows in sheets
|
|||||||
|
|
||||||
```v
|
```v
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript:="
|
heroscript:="
|
||||||
@@ -89,4 +87,4 @@ mut bm:=bizmodel.get("test")!
|
|||||||
|
|
||||||
bm.sheet.pprint()!
|
bm.sheet.pprint()!
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ This manual provides a comprehensive guide on how to leverage HeroLib's Docusaur
|
|||||||
|
|
||||||
To effectively create ebooks with HeroLib, it's crucial to understand the interplay of three core components:
|
To effectively create ebooks with HeroLib, it's crucial to understand the interplay of three core components:
|
||||||
|
|
||||||
* **HeroScript**: A concise scripting language used to define the structure, configuration, and content flow of your Docusaurus site. It acts as the declarative interface for the entire process.
|
* **HeroScript**: A concise scripting language used to define the structure, configuration, and content flow of your Docusaurus site. It acts as the declarative interface for the entire process.
|
||||||
* **Docusaurus**: A popular open-source static site generator. HeroLib uses Docusaurus as the underlying framework to render your ebook content into a navigable website.
|
* **Docusaurus**: A popular open-source static site generator. HeroLib uses Docusaurus as the underlying framework to render your ebook content into a navigable website.
|
||||||
* **Doctree**: HeroLib's content management system. Doctree organizes your markdown files into "collections" and "pages," allowing for structured content retrieval and reuse across multiple projects.
|
* **Doctree**: HeroLib's content management system. Doctree organizes your markdown files into "collections" and "pages," allowing for structured content retrieval and reuse across multiple projects.
|
||||||
|
|
||||||
## 2. Setting Up a Docusaurus Project with HeroLib
|
## 2. Setting Up a Docusaurus Project with HeroLib
|
||||||
|
|
||||||
@@ -30,10 +30,10 @@ The `docusaurus.define` HeroScript directive configures the global settings for
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* `path_build` (string, optional): The local path where the Docusaurus site will be built. Defaults to `~/hero/var/docusaurus/build`.
|
* `path_build` (string, optional): The local path where the Docusaurus site will be built. Defaults to `~/hero/var/docusaurus/build`.
|
||||||
* `path_publish` (string, optional): The local path where the final Docusaurus site will be published (e.g., for deployment). Defaults to `~/hero/var/docusaurus/publish`.
|
* `path_publish` (string, optional): The local path where the final Docusaurus site will be published (e.g., for deployment). Defaults to `~/hero/var/docusaurus/publish`.
|
||||||
* `production` (boolean, optional): If `true`, the site will be built for production (optimized). Default is `false`.
|
* `production` (boolean, optional): If `true`, the site will be built for production (optimized). Default is `false`.
|
||||||
* `update` (boolean, optional): If `true`, the Docusaurus template and dependencies will be updated. Default is `false`.
|
* `update` (boolean, optional): If `true`, the Docusaurus template and dependencies will be updated. Default is `false`.
|
||||||
|
|
||||||
### 2.2. Adding a Docusaurus Site (`docusaurus.add`)
|
### 2.2. Adding a Docusaurus Site (`docusaurus.add`)
|
||||||
|
|
||||||
@@ -61,19 +61,19 @@ The `docusaurus.add` directive defines an individual Docusaurus site (your ebook
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* `name` (string, optional): A unique name for your Docusaurus site/ebook. Defaults to "main".
|
* `name` (string, optional): A unique name for your Docusaurus site/ebook. Defaults to "main".
|
||||||
* `path` (string, optional): The local file system path to the root of your documentation content (e.g., where your `docs` and `cfg` directories are).
|
* `path` (string, optional): The local file system path to the root of your documentation content (e.g., where your `docs` and `cfg` directories are).
|
||||||
* `git_url` (string, optional): A Git URL to a repository containing your documentation content. HeroLib will clone/pull this repository.
|
* `git_url` (string, optional): A Git URL to a repository containing your documentation content. HeroLib will clone/pull this repository.
|
||||||
* `git_reset` (boolean, optional): If `true`, the Git repository will be reset to a clean state before pulling. Default is `false`.
|
* `git_reset` (boolean, optional): If `true`, the Git repository will be reset to a clean state before pulling. Default is `false`.
|
||||||
* `git_pull` (boolean, optional): If `true`, the Git repository will be pulled to get the latest changes. Default is `false`.
|
* `git_pull` (boolean, optional): If `true`, the Git repository will be pulled to get the latest changes. Default is `false`.
|
||||||
* `git_root` (string, optional): An optional root directory where Git repositories will be cloned.
|
* `git_root` (string, optional): An optional root directory where Git repositories will be cloned.
|
||||||
* `nameshort` (string, optional): A shorter name for the Docusaurus site. Defaults to the value of `name`.
|
* `nameshort` (string, optional): A shorter name for the Docusaurus site. Defaults to the value of `name`.
|
||||||
* `path_publish` (string, optional): Overrides the factory's `path_publish` for this specific site.
|
* `path_publish` (string, optional): Overrides the factory's `path_publish` for this specific site.
|
||||||
* `production` (boolean, optional): Overrides the factory's `production` setting for this specific site.
|
* `production` (boolean, optional): Overrides the factory's `production` setting for this specific site.
|
||||||
* `watch_changes` (boolean, optional): If `true`, HeroLib will watch for changes in your source `docs` directory and trigger rebuilds. Default is `true`.
|
* `watch_changes` (boolean, optional): If `true`, HeroLib will watch for changes in your source `docs` directory and trigger rebuilds. Default is `true`.
|
||||||
* `update` (boolean, optional): If `true`, this specific documentation will be updated. Default is `false`.
|
* `update` (boolean, optional): If `true`, this specific documentation will be updated. Default is `false`.
|
||||||
* `open` (boolean, optional): If `true`, the Docusaurus site will be opened in your default browser after generation/development server start. Default is `false`.
|
* `open` (boolean, optional): If `true`, the Docusaurus site will be opened in your default browser after generation/development server start. Default is `false`.
|
||||||
* `init` (boolean, optional): If `true`, the Docusaurus site will be initialized (e.g., creating missing `docs` directories). Default is `false`.
|
* `init` (boolean, optional): If `true`, the Docusaurus site will be initialized (e.g., creating missing `docs` directories). Default is `false`.
|
||||||
|
|
||||||
## 3. Structuring Content with HeroScript and Doctree
|
## 3. Structuring Content with HeroScript and Doctree
|
||||||
|
|
||||||
@@ -105,22 +105,22 @@ These directives define the fundamental properties and metadata of your Docusaur
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* **`site.config`**:
|
* **`site.config`**:
|
||||||
* `name` (string, required): Unique identifier for the site.
|
* `name` (string, required): Unique identifier for the site.
|
||||||
* `title` (string, optional): Main title of the site. Defaults to "My Documentation Site".
|
* `title` (string, optional): Main title of the site. Defaults to "My Documentation Site".
|
||||||
* `description` (string, optional): General site description.
|
* `description` (string, optional): General site description.
|
||||||
* `tagline` (string, optional): Short tagline for the site.
|
* `tagline` (string, optional): Short tagline for the site.
|
||||||
* `favicon` (string, optional): Path to the favicon. Defaults to "img/favicon.png".
|
* `favicon` (string, optional): Path to the favicon. Defaults to "img/favicon.png".
|
||||||
* `image` (string, optional): General site image (e.g., for social media previews). Defaults to "img/tf_graph.png".
|
* `image` (string, optional): General site image (e.g., for social media previews). Defaults to "img/tf_graph.png".
|
||||||
* `copyright` (string, optional): Copyright notice. Defaults to "© [Current Year] Example Organization".
|
* `copyright` (string, optional): Copyright notice. Defaults to "© [Current Year] Example Organization".
|
||||||
* `url` (string, optional): The main URL where the site will be hosted.
|
* `url` (string, optional): The main URL where the site will be hosted.
|
||||||
* `base_url` (string, optional): The base URL for Docusaurus (e.g., `/` or `/my-ebook/`).
|
* `base_url` (string, optional): The base URL for Docusaurus (e.g., `/` or `/my-ebook/`).
|
||||||
* `url_home` (string, optional): The path to the home page relative to `base_url`.
|
* `url_home` (string, optional): The path to the home page relative to `base_url`.
|
||||||
* **`site.config_meta`**: Overrides for specific SEO metadata.
|
* **`site.config_meta`**: Overrides for specific SEO metadata.
|
||||||
* `title` (string, optional): Specific title for SEO (e.g., `<meta property="og:title">`).
|
* `title` (string, optional): Specific title for SEO (e.g., `<meta property="og:title">`).
|
||||||
* `image` (string, optional): Specific image for SEO (e.g., `<meta property="og:image">`).
|
* `image` (string, optional): Specific image for SEO (e.g., `<meta property="og:image">`).
|
||||||
* `description` (string, optional): Specific description for SEO.
|
* `description` (string, optional): Specific description for SEO.
|
||||||
* `keywords` (string, optional): Comma-separated keywords for SEO.
|
* `keywords` (string, optional): Comma-separated keywords for SEO.
|
||||||
|
|
||||||
### 3.2. Navigation Bar (`site.navbar`, `site.navbar_item`)
|
### 3.2. Navigation Bar (`site.navbar`, `site.navbar_item`)
|
||||||
|
|
||||||
@@ -148,16 +148,16 @@ Define the main navigation menu of your Docusaurus site.
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* **`site.navbar`**:
|
* **`site.navbar`**:
|
||||||
* `title` (string, optional): Title displayed in the navbar. Defaults to `site.config.title`.
|
* `title` (string, optional): Title displayed in the navbar. Defaults to `site.config.title`.
|
||||||
* `logo_alt` (string, optional): Alt text for the logo.
|
* `logo_alt` (string, optional): Alt text for the logo.
|
||||||
* `logo_src` (string, optional): Path to the light mode logo.
|
* `logo_src` (string, optional): Path to the light mode logo.
|
||||||
* `logo_src_dark` (string, optional): Path to the dark mode logo.
|
* `logo_src_dark` (string, optional): Path to the dark mode logo.
|
||||||
* **`site.navbar_item`**:
|
* **`site.navbar_item`**:
|
||||||
* `label` (string, required): Text displayed for the menu item.
|
* `label` (string, required): Text displayed for the menu item.
|
||||||
* `href` (string, optional): External URL for the link.
|
* `href` (string, optional): External URL for the link.
|
||||||
* `to` (string, optional): Internal Docusaurus path (e.g., `/docs/my-page`).
|
* `to` (string, optional): Internal Docusaurus path (e.g., `/docs/my-page`).
|
||||||
* `position` (string, optional): "left" or "right" for placement in the navbar. Defaults to "right".
|
* `position` (string, optional): "left" or "right" for placement in the navbar. Defaults to "right".
|
||||||
|
|
||||||
### 3.3. Footer (`site.footer`, `site.footer_item`)
|
### 3.3. Footer (`site.footer`, `site.footer_item`)
|
||||||
|
|
||||||
@@ -182,13 +182,13 @@ Configure the footer section of your Docusaurus site.
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* **`site.footer`**:
|
* **`site.footer`**:
|
||||||
* `style` (string, optional): "dark" or "light" style for the footer. Defaults to "dark".
|
* `style` (string, optional): "dark" or "light" style for the footer. Defaults to "dark".
|
||||||
* **`site.footer_item`**:
|
* **`site.footer_item`**:
|
||||||
* `title` (string, required): The title under which this item will be grouped in the footer.
|
* `title` (string, required): The title under which this item will be grouped in the footer.
|
||||||
* `label` (string, required): Text displayed for the footer link.
|
* `label` (string, required): Text displayed for the footer link.
|
||||||
* `href` (string, optional): External URL for the link.
|
* `href` (string, optional): External URL for the link.
|
||||||
* `to` (string, optional): Internal Docusaurus path.
|
* `to` (string, optional): Internal Docusaurus path.
|
||||||
|
|
||||||
### 3.4. Build Destinations (`site.build_dest`, `site.build_dest_dev`)
|
### 3.4. Build Destinations (`site.build_dest`, `site.build_dest_dev`)
|
||||||
|
|
||||||
@@ -208,8 +208,8 @@ Specify where the built Docusaurus site should be deployed. This typically invol
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* `ssh_name` (string, required): The name of the SSH connection to use for deployment.
|
* `ssh_name` (string, required): The name of the SSH connection to use for deployment.
|
||||||
* `path` (string, required): The destination path on the remote server.
|
* `path` (string, required): The destination path on the remote server.
|
||||||
|
|
||||||
### 3.5. Importing External Content (`site.import`)
|
### 3.5. Importing External Content (`site.import`)
|
||||||
|
|
||||||
@@ -226,9 +226,9 @@ This powerful feature allows you to pull markdown content and assets from other
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* `url` (string, required): The Git URL of the repository or specific path within a repository to import.
|
* `url` (string, required): The Git URL of the repository or specific path within a repository to import.
|
||||||
* `dest` (string, required): The subdirectory within your Docusaurus `docs` folder where the imported content will be placed.
|
* `dest` (string, required): The subdirectory within your Docusaurus `docs` folder where the imported content will be placed.
|
||||||
* `replace` (string, optional): A comma-separated string of `KEY:VALUE` pairs. During import, all occurrences of `${KEY}` in the imported content will be replaced with `VALUE`.
|
* `replace` (string, optional): A comma-separated string of `KEY:VALUE` pairs. During import, all occurrences of `${KEY}` in the imported content will be replaced with `VALUE`.
|
||||||
|
|
||||||
### 3.6. Defining Pages and Categories (`site.page_category`, `site.page`)
|
### 3.6. Defining Pages and Categories (`site.page_category`, `site.page`)
|
||||||
|
|
||||||
@@ -250,20 +250,20 @@ This is where you define the actual content pages and how they are organized int
|
|||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
* **`site.page_category`**:
|
* **`site.page_category`**:
|
||||||
* `path` (string, required): The path to the category directory within your Docusaurus `docs` folder (e.g., `introduction` will create `docs/introduction/_category_.json`).
|
* `path` (string, required): The path to the category directory within your Docusaurus `docs` folder (e.g., `introduction` will create `docs/introduction/_category_.json`).
|
||||||
* `label` (string, required): The display name for the category in the sidebar.
|
* `label` (string, required): The display name for the category in the sidebar.
|
||||||
* `position` (int, optional): The order of the category in the sidebar.
|
* `position` (int, optional): The order of the category in the sidebar.
|
||||||
* `sitename` (string, optional): If you have multiple Docusaurus sites defined, specify which site this category belongs to. Defaults to the current site's name.
|
* `sitename` (string, optional): If you have multiple Docusaurus sites defined, specify which site this category belongs to. Defaults to the current site's name.
|
||||||
* **`site.page`**:
|
* **`site.page`**:
|
||||||
* `src` (string, required): **Crucial for Doctree integration.** This specifies the source of the page content in the format `collection_name:page_name`. HeroLib will fetch the markdown content from the specified Doctree collection and page.
|
* `src` (string, required): **Crucial for Doctree integration.** This specifies the source of the page content in the format `collection_name:page_name`. HeroLib will fetch the markdown content from the specified Doctree collection and page.
|
||||||
* `path` (string, required): The relative path and filename for the generated markdown file within your Docusaurus `docs` folder (e.g., `introduction/chapter_1.md`). If only a directory is provided (e.g., `introduction/`), the `page_name` from `src` will be used as the filename.
|
* `path` (string, required): The relative path and filename for the generated markdown file within your Docusaurus `docs` folder (e.g., `introduction/chapter_1.md`). If only a directory is provided (e.g., `introduction/`), the `page_name` from `src` will be used as the filename.
|
||||||
* `title` (string, optional): The title of the page. If not provided, HeroLib will attempt to extract it from the markdown content or use the `page_name`.
|
* `title` (string, optional): The title of the page. If not provided, HeroLib will attempt to extract it from the markdown content or use the `page_name`.
|
||||||
* `description` (string, optional): A short description for the page, used in frontmatter.
|
* `description` (string, optional): A short description for the page, used in frontmatter.
|
||||||
* `position` (int, optional): The order of the page within its category.
|
* `position` (int, optional): The order of the page within its category.
|
||||||
* `hide_title` (boolean, optional): If `true`, the title will not be displayed on the page itself.
|
* `hide_title` (boolean, optional): If `true`, the title will not be displayed on the page itself.
|
||||||
* `draft` (boolean, optional): If `true`, the page will be marked as a draft and not included in production builds.
|
* `draft` (boolean, optional): If `true`, the page will be marked as a draft and not included in production builds.
|
||||||
* `title_nr` (int, optional): If set, HeroLib will re-number the markdown headings (e.g., `title_nr:3` will make `# Heading` become `### Heading`). Useful for consistent heading levels across imported content.
|
* `title_nr` (int, optional): If set, HeroLib will re-number the markdown headings (e.g., `title_nr:3` will make `# Heading` become `### Heading`). Useful for consistent heading levels across imported content.
|
||||||
|
|
||||||
### 3.7. Doctree Integration Details
|
### 3.7. Doctree Integration Details
|
||||||
|
|
||||||
@@ -271,14 +271,16 @@ The `site.page` directive's `src` parameter (`collection_name:page_name`) is the
|
|||||||
|
|
||||||
**How Doctree Works:**
|
**How Doctree Works:**
|
||||||
|
|
||||||
1. **Collections**: Doctree organizes markdown files into logical groups called "collections." A collection is typically a directory containing markdown files and an empty `.collection` file.
|
1. **Collections**: Doctree organizes markdown files into logical groups called "collections." A collection is typically a directory containing markdown files and an empty `.collection` file.
|
||||||
2. **Scanning**: You define which collections Doctree should scan using `!!doctree.scan` in a HeroScript file (e.g., `doctree.heroscript`).
|
2. **Scanning**: You define which collections Doctree should scan using `!!doctree.scan` in a HeroScript file (e.g., `doctree.heroscript`).
|
||||||
**Example `doctree.heroscript`:**
|
**Example `doctree.heroscript`:**
|
||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!doctree.scan git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/collections"
|
!!doctree.scan git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/collections"
|
||||||
```
|
```
|
||||||
|
|
||||||
This will pull the `collections` directory from the specified Git URL and make its contents available to Doctree.
|
This will pull the `collections` directory from the specified Git URL and make its contents available to Doctree.
|
||||||
3. **Page Retrieval**: When `site.page` references `src:"my_collection:my_page"`, HeroLib's `doctreeclient` fetches the content of `my_page.md` from the `my_collection` collection that Doctree has scanned.
|
3. **Page Retrieval**: When `site.page` references `src:"my_collection:my_page"`, HeroLib's `doctreeclient` fetches the content of `my_page.md` from the `my_collection` collection that Doctree has scanned.
|
||||||
|
|
||||||
## 4. Building and Developing Your Ebook
|
## 4. Building and Developing Your Ebook
|
||||||
|
|
||||||
@@ -287,12 +289,13 @@ Once your HeroScript configuration is set up, HeroLib provides commands to build
|
|||||||
### 4.1. Generating Site Files (`site.generate()`)
|
### 4.1. Generating Site Files (`site.generate()`)
|
||||||
|
|
||||||
The `site.generate()` function (called internally by `build`, `dev`, etc.) performs the core file generation:
|
The `site.generate()` function (called internally by `build`, `dev`, etc.) performs the core file generation:
|
||||||
* Copies Docusaurus template files.
|
|
||||||
* Copies your site's `src` and `static` assets.
|
* Copies Docusaurus template files.
|
||||||
* Generates Docusaurus configuration JSON files (`main.json`, `navbar.json`, `footer.json`) from your HeroScript `site.config`, `site.navbar`, and `site.footer` directives.
|
* Copies your site's `src` and `static` assets.
|
||||||
* Copies your source `docs` directory.
|
* Generates Docusaurus configuration JSON files (`main.json`, `navbar.json`, `footer.json`) from your HeroScript `site.config`, `site.navbar`, and `site.footer` directives.
|
||||||
* Processes `site.page` and `site.page_category` directives using the `sitegen` module to create the final markdown files and `_category_.json` files in the Docusaurus `docs` directory, fetching content from Doctree.
|
* Copies your source `docs` directory.
|
||||||
* Handles `site.import` directives, pulling external content and performing replacements.
|
* Processes `site.page` and `site.page_category` directives using the `sitegen` module to create the final markdown files and `_category_.json` files in the Docusaurus `docs` directory, fetching content from Doctree.
|
||||||
|
* Handles `site.import` directives, pulling external content and performing replacements.
|
||||||
|
|
||||||
### 4.2. Local Development
|
### 4.2. Local Development
|
||||||
|
|
||||||
@@ -305,35 +308,34 @@ can be stored as example_docusaurus.vsh and then used to generate and develop an
|
|||||||
```v
|
```v
|
||||||
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.web.docusaurus
|
import incubaid.herolib.web.docusaurus
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const cfgpath = os.dir(@FILE)
|
const cfgpath = os.dir(@FILE)
|
||||||
|
|
||||||
docusaurus.new(
|
docusaurus.new(
|
||||||
heroscript: '
|
heroscript: '
|
||||||
|
|
||||||
// !!docusaurus.define
|
// !!docusaurus.define
|
||||||
// path_build: "/tmp/docusaurus_build"
|
// path_build: "/tmp/docusaurus_build"
|
||||||
// path_publish: "/tmp/docusaurus_publish"
|
// path_publish: "/tmp/docusaurus_publish"
|
||||||
|
|
||||||
!!docusaurus.add name:"tfgrid_docs"
|
!!docusaurus.add name:"tfgrid_docs"
|
||||||
path:"${cfgpath}"
|
path:"${cfgpath}"
|
||||||
|
|
||||||
!!docusaurus.dev
|
!!docusaurus.dev
|
||||||
|
|
||||||
'
|
'
|
||||||
)!
|
)!
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
the following script suggest to call it do.vsh and put in directory of where the ebook is
|
the following script suggest to call it do.vsh and put in directory of where the ebook is
|
||||||
|
|
||||||
```v
|
```v
|
||||||
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.web.docusaurus
|
import incubaid.herolib.web.docusaurus
|
||||||
|
|
||||||
const cfgpath = os.dir(@FILE) + '/cfg'
|
const cfgpath = os.dir(@FILE) + '/cfg'
|
||||||
|
|
||||||
@@ -341,4 +343,3 @@ docusaurus.new(heroscript_path:cfgpath)!
|
|||||||
```
|
```
|
||||||
|
|
||||||
by just called do.vsh we can execute on the ebook
|
by just called do.vsh we can execute on the ebook
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ The `list` method accepts a `ListArgs` struct to control its behavior:
|
|||||||
```v
|
```v
|
||||||
pub struct ListArgs {
|
pub struct ListArgs {
|
||||||
pub mut:
|
pub mut:
|
||||||
regex []string // A slice of regular expressions to filter files.
|
regex []string // A slice of regular expressions to filter files.
|
||||||
recursive bool = true // Whether to list files recursively (default true).
|
recursive bool = true // Whether to list files recursively (default true).
|
||||||
ignore_default bool = true // Whether to ignore files starting with . and _ (default true).
|
ignore_default bool = true // Whether to ignore files starting with . and _ (default true).
|
||||||
include_links bool // Whether to include symbolic links in the list.
|
include_links bool // Whether to include symbolic links in the list.
|
||||||
dirs_only bool // Whether to include only directories in the list.
|
dirs_only bool // Whether to include only directories in the list.
|
||||||
files_only bool // Whether to include only files in the list.
|
files_only bool // Whether to include only files in the list.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ Here are examples demonstrating how to use these advanced filtering options:
|
|||||||
You can use regular expressions to filter files based on their names or extensions. The `regex` parameter accepts a slice of strings, where each string is a regex pattern.
|
You can use regular expressions to filter files based on their names or extensions. The `regex` parameter accepts a slice of strings, where each string is a regex pattern.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
// Get a directory path
|
// Get a directory path
|
||||||
mut dir := pathlib.get('/some/directory')!
|
mut dir := pathlib.get('/some/directory')!
|
||||||
@@ -61,7 +61,7 @@ for path_obj in vlang_files.paths {
|
|||||||
By default, `list()` is recursive. You can disable recursion to list only items in the current directory.
|
By default, `list()` is recursive. You can disable recursion to list only items in the current directory.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
mut dir := pathlib.get('/some/directory')!
|
mut dir := pathlib.get('/some/directory')!
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ for path_obj in top_level_items.paths {
|
|||||||
The `ignore_default` parameter controls whether files and directories starting with `.` or `_` are ignored.
|
The `ignore_default` parameter controls whether files and directories starting with `.` or `_` are ignored.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
mut dir := pathlib.get('/some/directory')!
|
mut dir := pathlib.get('/some/directory')!
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ for path_obj in all_items.paths {
|
|||||||
By default, symbolic links are ignored when walking the directory structure. Set `include_links` to `true` to include them.
|
By default, symbolic links are ignored when walking the directory structure. Set `include_links` to `true` to include them.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
mut dir := pathlib.get('/some/directory')!
|
mut dir := pathlib.get('/some/directory')!
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ for path_obj in items_with_links.paths {
|
|||||||
Use `dirs_only` or `files_only` to restrict the results to only directories or only files.
|
Use `dirs_only` or `files_only` to restrict the results to only directories or only files.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
mut dir := pathlib.get('/some/directory')!
|
mut dir := pathlib.get('/some/directory')!
|
||||||
|
|
||||||
@@ -138,4 +138,4 @@ for path_obj in only_dirs.paths {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
By combining these parameters, you can create highly specific and powerful file system listing operations tailored to your needs.
|
By combining these parameters, you can create highly specific and powerful file system listing operations tailored to your needs.
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ The `builder` module in Herolib provides a powerful framework for automating sys
|
|||||||
|
|
||||||
## Key Components
|
## Key Components
|
||||||
|
|
||||||
- **`BuilderFactory`**: Responsible for creating and managing `Node` instances.
|
- **`BuilderFactory`**: Responsible for creating and managing `Node` instances.
|
||||||
- **`Node`**: Represents a target system (local or remote). It encapsulates system properties (platform, CPU type, environment variables) and provides methods for interaction.
|
- **`Node`**: Represents a target system (local or remote). It encapsulates system properties (platform, CPU type, environment variables) and provides methods for interaction.
|
||||||
- **`Executor`**: An interface (implemented by `ExecutorLocal` and `ExecutorSSH`) that handles the actual command execution and file operations on the target system.
|
- **`Executor`**: An interface (implemented by `ExecutorLocal` and `ExecutorSSH`) that handles the actual command execution and file operations on the target system.
|
||||||
- **NodeDB (via `Node.done` map)**: A key-value store within each `Node` for persistent state, caching, and tracking execution history.
|
- **NodeDB (via `Node.done` map)**: A key-value store within each `Node` for persistent state, caching, and tracking execution history.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ The `builder` module in Herolib provides a powerful framework for automating sys
|
|||||||
First, import the `builder` module and create a new `BuilderFactory` instance. Then, create a `Node` object, which can represent either the local machine or a remote server.
|
First, import the `builder` module and create a new `BuilderFactory` instance. Then, create a `Node` object, which can represent either the local machine or a remote server.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder
|
import incubaid.herolib.builder
|
||||||
|
|
||||||
// Create a new builder factory
|
// Create a new builder factory
|
||||||
mut b := builder.new()!
|
mut b := builder.new()!
|
||||||
@@ -68,7 +68,7 @@ The `Node` object provides methods to execute commands on the target system.
|
|||||||
Executes a command and returns its standard output.
|
Executes a command and returns its standard output.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { ExecArgs }
|
import incubaid.herolib.builder { ExecArgs }
|
||||||
|
|
||||||
// Execute a command with stdout
|
// Execute a command with stdout
|
||||||
result := node.exec(cmd: "ls -la /tmp", stdout: true)!
|
result := node.exec(cmd: "ls -la /tmp", stdout: true)!
|
||||||
@@ -101,7 +101,7 @@ node.exec_interactive("bash")!
|
|||||||
A more advanced command execution method that supports caching, periodic execution, and temporary script handling.
|
A more advanced command execution method that supports caching, periodic execution, and temporary script handling.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { NodeExecCmd }
|
import incubaid.herolib.builder { NodeExecCmd }
|
||||||
|
|
||||||
// Execute a command, cache its result for 24 hours (48*3600 seconds)
|
// Execute a command, cache its result for 24 hours (48*3600 seconds)
|
||||||
// and provide a description for logging.
|
// and provide a description for logging.
|
||||||
@@ -130,7 +130,7 @@ println(script_output)
|
|||||||
Executes a command with retries until it succeeds or a timeout is reached.
|
Executes a command with retries until it succeeds or a timeout is reached.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { ExecRetryArgs }
|
import incubaid.herolib.builder { ExecRetryArgs }
|
||||||
|
|
||||||
// Try to connect to a service, retrying every 100ms for up to 10 seconds
|
// Try to connect to a service, retrying every 100ms for up to 10 seconds
|
||||||
result := node.exec_retry(
|
result := node.exec_retry(
|
||||||
@@ -219,7 +219,7 @@ if node.dir_exists("/var/log") {
|
|||||||
Transfer files between the local machine and the target node using `rsync` or `scp`.
|
Transfer files between the local machine and the target node using `rsync` or `scp`.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { SyncArgs }
|
import incubaid.herolib.builder { SyncArgs }
|
||||||
|
|
||||||
// Upload a local file to the remote node
|
// Upload a local file to the remote node
|
||||||
node.upload(
|
node.upload(
|
||||||
@@ -286,7 +286,7 @@ node.hero_install()!
|
|||||||
Updates the Herolib code on the node, with options for syncing from local, git reset, or git pull.
|
Updates the Herolib code on the node, with options for syncing from local, git reset, or git pull.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { HeroUpdateArgs }
|
import incubaid.herolib.builder { HeroUpdateArgs }
|
||||||
|
|
||||||
// Sync local Herolib code to the remote node (full sync)
|
// Sync local Herolib code to the remote node (full sync)
|
||||||
node.hero_update(sync_from_local: true, sync_full: true)!
|
node.hero_update(sync_from_local: true, sync_full: true)!
|
||||||
@@ -300,7 +300,7 @@ node.hero_update(git_reset: true, branch: "dev")!
|
|||||||
Uploads and executes a Vlang script (`.vsh` or `.v`) on the remote node.
|
Uploads and executes a Vlang script (`.vsh` or `.v`) on the remote node.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { VScriptArgs }
|
import incubaid.herolib.builder { VScriptArgs }
|
||||||
|
|
||||||
// Upload and execute a local V script on the remote node
|
// Upload and execute a local V script on the remote node
|
||||||
node.vscript(path: "/local/path/to/my_script.vsh", sync_from_local: true)!
|
node.vscript(path: "/local/path/to/my_script.vsh", sync_from_local: true)!
|
||||||
@@ -311,7 +311,7 @@ node.vscript(path: "/local/path/to/my_script.vsh", sync_from_local: true)!
|
|||||||
The `portforward_to_local` function allows forwarding a remote port on an SSH host to a local port.
|
The `portforward_to_local` function allows forwarding a remote port on an SSH host to a local port.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder { portforward_to_local, ForwardArgsToLocal }
|
import incubaid.herolib.builder { portforward_to_local, ForwardArgsToLocal }
|
||||||
|
|
||||||
// Forward remote port 8080 on 192.168.1.100 to local port 9000
|
// Forward remote port 8080 on 192.168.1.100 to local port 9000
|
||||||
portforward_to_local(
|
portforward_to_local(
|
||||||
|
|||||||
@@ -1,508 +1,682 @@
|
|||||||
# OSAL Core Module (freeflowuniverse.herolib.osal.core)
|
# OSAL Core Module (incubaid.herolib.osal.core)
|
||||||
|
|
||||||
This document describes the core functionalities of the Operating System Abstraction Layer (OSAL) module, designed for platform-independent system operations in V.
|
This document describes the core functionalities of the Operating System Abstraction Layer (OSAL) module, designed for platform-independent system operations in V.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
//example how to get started
|
//example how to get started
|
||||||
|
|
||||||
import freeflowuniverse.herolib.osal.core as osal
|
import incubaid.herolib.osal.core as osal
|
||||||
|
|
||||||
osal.exec(...)!
|
osal.exec(...)!
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## 1. Process Management
|
## 1. Process Management
|
||||||
|
|
||||||
### `osal.exec(cmd: Command) !Job`
|
### `osal.exec(cmd: Command) !Job`
|
||||||
|
|
||||||
Executes a shell command with extensive configuration.
|
Executes a shell command with extensive configuration.
|
||||||
* **Parameters**:
|
|
||||||
* `cmd` (`Command` struct):
|
* **Parameters**:
|
||||||
* `cmd` (string): The command string.
|
* `cmd` (`Command` struct):
|
||||||
* `timeout` (int, default: 3600): Max execution time in seconds.
|
* `cmd` (string): The command string.
|
||||||
* `retry` (int): Number of retries on failure.
|
* `timeout` (int, default: 3600): Max execution time in seconds.
|
||||||
* `work_folder` (string): Working directory.
|
* `retry` (int): Number of retries on failure.
|
||||||
* `environment` (map[string]string): Environment variables.
|
* `work_folder` (string): Working directory.
|
||||||
* `stdout` (bool, default: true): Show command output.
|
* `environment` (map[string]string): Environment variables.
|
||||||
* `stdout_log` (bool, default: true): Log stdout to internal buffer.
|
* `stdout` (bool, default: true): Show command output.
|
||||||
* `raise_error` (bool, default: true): Raise V error on failure.
|
* `stdout_log` (bool, default: true): Log stdout to internal buffer.
|
||||||
* `ignore_error` (bool): Do not raise error, just report.
|
* `raise_error` (bool, default: true): Raise V error on failure.
|
||||||
* `debug` (bool): Enable debug output.
|
* `ignore_error` (bool): Do not raise error, just report.
|
||||||
* `shell` (bool): Execute in interactive shell.
|
* `debug` (bool): Enable debug output.
|
||||||
* `interactive` (bool, default: true): Run in interactive mode.
|
* `shell` (bool): Execute in interactive shell.
|
||||||
* `async` (bool): Run command asynchronously.
|
* `interactive` (bool, default: true): Run in interactive mode.
|
||||||
* `runtime` (`RunTime` enum): Specify runtime (`.bash`, `.python`, etc.).
|
* `async` (bool): Run command asynchronously.
|
||||||
* **Returns**: `Job` struct (contains `status`, `output`, `error`, `exit_code`, `start`, `end`, `process`, `runnr`).
|
* `runtime` (`RunTime` enum): Specify runtime (`.bash`, `.python`, etc.).
|
||||||
* **Error Handling**: Returns `JobError` with `error_type` (`.exec`, `.timeout`, `.args`).
|
* **Returns**: `Job` struct (contains `status`, `output`, `error`, `exit_code`, `start`, `end`, `process`, `runnr`).
|
||||||
|
* **Error Handling**: Returns `JobError` with `error_type` (`.exec`, `.timeout`, `.args`).
|
||||||
|
|
||||||
### `osal.execute_silent(cmd string) !string`
|
### `osal.execute_silent(cmd string) !string`
|
||||||
|
|
||||||
Executes a command silently.
|
Executes a command silently.
|
||||||
* **Parameters**: `cmd` (string): The command string.
|
|
||||||
* **Returns**: `string` (command output).
|
* **Parameters**: `cmd` (string): The command string.
|
||||||
|
* **Returns**: `string` (command output).
|
||||||
|
|
||||||
### `osal.execute_debug(cmd string) !string`
|
### `osal.execute_debug(cmd string) !string`
|
||||||
|
|
||||||
Executes a command with debug output.
|
Executes a command with debug output.
|
||||||
* **Parameters**: `cmd` (string): The command string.
|
|
||||||
* **Returns**: `string` (command output).
|
* **Parameters**: `cmd` (string): The command string.
|
||||||
|
* **Returns**: `string` (command output).
|
||||||
|
|
||||||
### `osal.execute_stdout(cmd string) !string`
|
### `osal.execute_stdout(cmd string) !string`
|
||||||
|
|
||||||
Executes a command and prints output to stdout.
|
Executes a command and prints output to stdout.
|
||||||
* **Parameters**: `cmd` (string): The command string.
|
|
||||||
* **Returns**: `string` (command output).
|
* **Parameters**: `cmd` (string): The command string.
|
||||||
|
* **Returns**: `string` (command output).
|
||||||
|
|
||||||
### `osal.execute_interactive(cmd string) !`
|
### `osal.execute_interactive(cmd string) !`
|
||||||
|
|
||||||
### `osal.execute_ok(cmd string) bool`
|
### `osal.execute_ok(cmd string) bool`
|
||||||
|
|
||||||
Executes a command and returns `true` if the command exits with a zero status, `false` otherwise.
|
Executes a command and returns `true` if the command exits with a zero status, `false` otherwise.
|
||||||
* **Parameters**: `cmd` (string): The command string.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `cmd` (string): The command string.
|
||||||
|
* **Returns**: `bool`.
|
||||||
Executes a command in an interactive shell.
|
Executes a command in an interactive shell.
|
||||||
|
|
||||||
### `osal.exec_fast(cmd: CommandFast) !string`
|
### `osal.exec_fast(cmd: CommandFast) !string`
|
||||||
|
|
||||||
Executes a command quickly, with options for profile sourcing and environment variables.
|
Executes a command quickly, with options for profile sourcing and environment variables.
|
||||||
* **Parameters**:
|
|
||||||
* `cmd` (`CommandFast` struct):
|
* **Parameters**:
|
||||||
* `cmd` (string): The command string.
|
* `cmd` (`CommandFast` struct):
|
||||||
* `ignore_error` (bool): Do not raise error on non-zero exit code.
|
* `cmd` (string): The command string.
|
||||||
* `work_folder` (string): Working directory.
|
* `ignore_error` (bool): Do not raise error on non-zero exit code.
|
||||||
* `environment` (map[string]string): Environment variables.
|
* `work_folder` (string): Working directory.
|
||||||
* `ignore_error_codes` ([]int): List of exit codes to ignore.
|
* `environment` (map[string]string): Environment variables.
|
||||||
* `debug` (bool): Enable debug output.
|
* `ignore_error_codes` ([]int): List of exit codes to ignore.
|
||||||
* `includeprofile` (bool): Source the user's profile before execution.
|
* `debug` (bool): Enable debug output.
|
||||||
* `notempty` (bool): Return an error if the output is empty.
|
* `includeprofile` (bool): Source the user's profile before execution.
|
||||||
* **Returns**: `string` (command output).
|
* `notempty` (bool): Return an error if the output is empty.
|
||||||
* **Parameters**: `cmd` (string): The command string.
|
* **Returns**: `string` (command output).
|
||||||
|
* **Parameters**: `cmd` (string): The command string.
|
||||||
|
|
||||||
### `osal.cmd_exists(cmd string) bool`
|
### `osal.cmd_exists(cmd string) bool`
|
||||||
|
|
||||||
Checks if a command exists in the system's PATH.
|
Checks if a command exists in the system's PATH.
|
||||||
* **Parameters**: `cmd` (string): The command name.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `cmd` (string): The command name.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.processmap_get() !ProcessMap`
|
### `osal.processmap_get() !ProcessMap`
|
||||||
|
|
||||||
Scans and returns a map of all running processes.
|
Scans and returns a map of all running processes.
|
||||||
* **Returns**: `ProcessMap` struct (contains `processes` (`[]ProcessInfo`), `lastscan`, `state`, `pids`).
|
|
||||||
|
* **Returns**: `ProcessMap` struct (contains `processes` (`[]ProcessInfo`), `lastscan`, `state`, `pids`).
|
||||||
|
|
||||||
### `osal.processinfo_get(pid int) !ProcessInfo`
|
### `osal.processinfo_get(pid int) !ProcessInfo`
|
||||||
|
|
||||||
Retrieves detailed information for a specific process by PID.
|
Retrieves detailed information for a specific process by PID.
|
||||||
* **Parameters**: `pid` (int): Process ID.
|
|
||||||
* **Returns**: `ProcessInfo` struct (contains `cpu_perc`, `mem_perc`, `cmd`, `pid`, `ppid`, `rss`).
|
* **Parameters**: `pid` (int): Process ID.
|
||||||
|
* **Returns**: `ProcessInfo` struct (contains `cpu_perc`, `mem_perc`, `cmd`, `pid`, `ppid`, `rss`).
|
||||||
|
|
||||||
### `osal.processinfo_get_byname(name string) ![]ProcessInfo`
|
### `osal.processinfo_get_byname(name string) ![]ProcessInfo`
|
||||||
|
|
||||||
Retrieves detailed information for processes matching a given name.
|
Retrieves detailed information for processes matching a given name.
|
||||||
* **Parameters**: `name` (string): Process name (substring match).
|
|
||||||
* **Returns**: `[]ProcessInfo`.
|
* **Parameters**: `name` (string): Process name (substring match).
|
||||||
|
* **Returns**: `[]ProcessInfo`.
|
||||||
|
|
||||||
### `osal.process_exists(pid int) bool`
|
### `osal.process_exists(pid int) bool`
|
||||||
|
|
||||||
Checks if a process with a given PID exists.
|
Checks if a process with a given PID exists.
|
||||||
* **Parameters**: `pid` (int): Process ID.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `pid` (int): Process ID.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.processinfo_with_children(pid int) !ProcessMap`
|
### `osal.processinfo_with_children(pid int) !ProcessMap`
|
||||||
|
|
||||||
Returns a process and all its child processes.
|
Returns a process and all its child processes.
|
||||||
|
|
||||||
## 1.1. Done Context Management (`done.v`)
|
## 1.1. Done Context Management (`done.v`)
|
||||||
|
|
||||||
Functions for managing a "done" context or state using Redis.
|
Functions for managing a "done" context or state using Redis.
|
||||||
|
|
||||||
* **`osal.done_set(key string, val string) !`**: Sets a key-value pair in the "done" context.
|
* **`osal.done_set(key string, val string) !`**: Sets a key-value pair in the "done" context.
|
||||||
* **`osal.done_get(key string) ?string`**: Retrieves a value from the "done" context by key.
|
* **`osal.done_get(key string) ?string`**: Retrieves a value from the "done" context by key.
|
||||||
* **`osal.done_delete(key string) !`**: Deletes a key from the "done" context.
|
* **`osal.done_delete(key string) !`**: Deletes a key from the "done" context.
|
||||||
* **`osal.done_get_str(key string) string`**: Retrieves a string value from the "done" context by key (panics on error).
|
* **`osal.done_get_str(key string) string`**: Retrieves a string value from the "done" context by key (panics on error).
|
||||||
* **`osal.done_get_int(key string) int`**: Retrieves an integer value from the "done" context by key (panics on error).
|
* **`osal.done_get_int(key string) int`**: Retrieves an integer value from the "done" context by key (panics on error).
|
||||||
* **`osal.done_exists(key string) bool`**: Checks if a key exists in the "done" context.
|
* **`osal.done_exists(key string) bool`**: Checks if a key exists in the "done" context.
|
||||||
* **`osal.done_print() !`**: Prints all key-value pairs in the "done" context to debug output.
|
* **`osal.done_print() !`**: Prints all key-value pairs in the "done" context to debug output.
|
||||||
* **`osal.done_reset() !`**: Resets (deletes all keys from) the "done" context.
|
* **`osal.done_reset() !`**: Resets (deletes all keys from) the "done" context.
|
||||||
* **Parameters**: `pid` (int): Parent Process ID.
|
* **Parameters**: `pid` (int): Parent Process ID.
|
||||||
* **Returns**: `ProcessMap`.
|
* **Returns**: `ProcessMap`.
|
||||||
|
|
||||||
### `osal.processinfo_children(pid int) !ProcessMap`
|
### `osal.processinfo_children(pid int) !ProcessMap`
|
||||||
|
|
||||||
Returns all child processes for a given PID.
|
Returns all child processes for a given PID.
|
||||||
* **Parameters**: `pid` (int): Parent Process ID.
|
|
||||||
* **Returns**: `ProcessMap`.
|
* **Parameters**: `pid` (int): Parent Process ID.
|
||||||
|
* **Returns**: `ProcessMap`.
|
||||||
|
|
||||||
### `osal.process_kill_recursive(args: ProcessKillArgs) !`
|
### `osal.process_kill_recursive(args: ProcessKillArgs) !`
|
||||||
|
|
||||||
Kills a process and all its children by name or PID.
|
Kills a process and all its children by name or PID.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`ProcessKillArgs` struct):
|
* **Parameters**:
|
||||||
* `name` (string): Process name.
|
* `args` (`ProcessKillArgs` struct):
|
||||||
* `pid` (int): Process ID.
|
* `name` (string): Process name.
|
||||||
|
* `pid` (int): Process ID.
|
||||||
|
|
||||||
### `osal.process_exists_byname(name string) !bool`
|
### `osal.process_exists_byname(name string) !bool`
|
||||||
|
|
||||||
Checks if a process with a given name exists.
|
Checks if a process with a given name exists.
|
||||||
* **Parameters**: `name` (string): Process name (substring match).
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `name` (string): Process name (substring match).
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.whoami() !string`
|
### `osal.whoami() !string`
|
||||||
|
|
||||||
Returns the current username.
|
Returns the current username.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
## 2. Network Utilities
|
## 2. Network Utilities
|
||||||
|
|
||||||
### `osal.ping(args: PingArgs) ! bool`
|
### `osal.ping(args: PingArgs) ! bool`
|
||||||
|
|
||||||
Checks host reachability.
|
Checks host reachability.
|
||||||
* **Parameters**:
|
|
||||||
|
* **Parameters**:
|
||||||
|
|
||||||
### `osal.ipaddr_pub_get_check() !string`
|
### `osal.ipaddr_pub_get_check() !string`
|
||||||
|
|
||||||
Retrieves the public IP address and verifies it is bound to a local interface.
|
Retrieves the public IP address and verifies it is bound to a local interface.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.is_ip_on_local_interface(ip string) !bool`
|
### `osal.is_ip_on_local_interface(ip string) !bool`
|
||||||
|
|
||||||
Checks if a given IP address is bound to a local network interface.
|
Checks if a given IP address is bound to a local network interface.
|
||||||
* **Parameters**: `ip` (string): IP address to check.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `ip` (string): IP address to check.
|
||||||
* `args` (`PingArgs` struct):
|
* **Returns**: `bool`.
|
||||||
* `address` (string, required): IP address or hostname.
|
* `args` (`PingArgs` struct):
|
||||||
* `count` (u8, default: 1): Number of pings.
|
* `address` (string, required): IP address or hostname.
|
||||||
* `timeout` (u16, default: 1): Timeout in seconds per ping.
|
* `count` (u8, default: 1): Number of pings.
|
||||||
* `retry` (u8): Number of retry attempts.
|
* `timeout` (u16, default: 1): Timeout in seconds per ping.
|
||||||
* **Returns**: `PingResult` enum (`.ok`, `.timeout`, `.unknownhost`).
|
* `retry` (u8): Number of retry attempts.
|
||||||
|
* **Returns**: `PingResult` enum (`.ok`, `.timeout`, `.unknownhost`).
|
||||||
|
|
||||||
### `osal.tcp_port_test(args: TcpPortTestArgs) bool`
|
### `osal.tcp_port_test(args: TcpPortTestArgs) bool`
|
||||||
|
|
||||||
Tests if a TCP port is open on a given address.
|
Tests if a TCP port is open on a given address.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`TcpPortTestArgs` struct):
|
* **Parameters**:
|
||||||
* `address` (string, required): IP address or hostname.
|
* `args` (`TcpPortTestArgs` struct):
|
||||||
* `port` (int, default: 22): TCP port number.
|
* `address` (string, required): IP address or hostname.
|
||||||
* `timeout` (u16, default: 2000): Total timeout in milliseconds.
|
* `port` (int, default: 22): TCP port number.
|
||||||
* **Returns**: `bool`.
|
* `timeout` (u16, default: 2000): Total timeout in milliseconds.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.ipaddr_pub_get() !string`
|
### `osal.ipaddr_pub_get() !string`
|
||||||
|
|
||||||
Retrieves the public IP address.
|
Retrieves the public IP address.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.is_ip_on_local_interface(ip string) !bool`
|
### `osal.is_ip_on_local_interface(ip string) !bool`
|
||||||
|
|
||||||
Checks if a given IP address is bound to a local network interface.
|
Checks if a given IP address is bound to a local network interface.
|
||||||
* **Parameters**: `ip` (string): IP address to check.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `ip` (string): IP address to check.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
## 3. File System Operations
|
## 3. File System Operations
|
||||||
|
|
||||||
### `osal.file_write(path string, text string) !`
|
### `osal.file_write(path string, text string) !`
|
||||||
|
|
||||||
Writes text content to a file.
|
Writes text content to a file.
|
||||||
* **Parameters**:
|
|
||||||
* `path` (string): File path.
|
* **Parameters**:
|
||||||
* `text` (string): Content to write.
|
* `path` (string): File path.
|
||||||
|
* `text` (string): Content to write.
|
||||||
|
|
||||||
### `osal.file_read(path string) !string`
|
### `osal.file_read(path string) !string`
|
||||||
|
|
||||||
Reads content from a file.
|
Reads content from a file.
|
||||||
* **Parameters**: `path` (string): File path.
|
|
||||||
* **Returns**: `string` (file content).
|
* **Parameters**: `path` (string): File path.
|
||||||
|
* **Returns**: `string` (file content).
|
||||||
|
|
||||||
### `osal.dir_ensure(path string) !`
|
### `osal.dir_ensure(path string) !`
|
||||||
|
|
||||||
Ensures a directory exists, creating it if necessary.
|
Ensures a directory exists, creating it if necessary.
|
||||||
* **Parameters**: `path` (string): Directory path.
|
|
||||||
|
* **Parameters**: `path` (string): Directory path.
|
||||||
|
|
||||||
### `osal.dir_delete(path string) !`
|
### `osal.dir_delete(path string) !`
|
||||||
|
|
||||||
Deletes a directory if it exists.
|
Deletes a directory if it exists.
|
||||||
* **Parameters**: `path` (string): Directory path.
|
|
||||||
|
* **Parameters**: `path` (string): Directory path.
|
||||||
|
|
||||||
### `osal.dir_reset(path string) !`
|
### `osal.dir_reset(path string) !`
|
||||||
|
|
||||||
Deletes and then recreates a directory.
|
Deletes and then recreates a directory.
|
||||||
* **Parameters**: `path` (string): Directory path.
|
|
||||||
|
* **Parameters**: `path` (string): Directory path.
|
||||||
|
|
||||||
### `osal.rm(todelete string) !`
|
### `osal.rm(todelete string) !`
|
||||||
|
|
||||||
Removes files or directories.
|
Removes files or directories.
|
||||||
* **Parameters**: `todelete` (string): Comma or newline separated list of paths (supports `~` for home directory).
|
|
||||||
|
* **Parameters**: `todelete` (string): Comma or newline separated list of paths (supports `~` for home directory).
|
||||||
|
|
||||||
### `osal.env_get_all() map[string]string`
|
### `osal.env_get_all() map[string]string`
|
||||||
|
|
||||||
Returns all existing environment variables as a map.
|
Returns all existing environment variables as a map.
|
||||||
* **Returns**: `map[string]string`.
|
|
||||||
|
* **Returns**: `map[string]string`.
|
||||||
|
|
||||||
## 4. Environment Variables
|
## 4. Environment Variables
|
||||||
|
|
||||||
## 4.1. Package Management (`package.v`)
|
## 4.1. Package Management (`package.v`)
|
||||||
|
|
||||||
Functions for managing system packages.
|
Functions for managing system packages.
|
||||||
|
|
||||||
* **`osal.package_refresh() !`**: Updates the package list for the detected platform.
|
* **`osal.package_refresh() !`**: Updates the package list for the detected platform.
|
||||||
* **`osal.package_install(name_ string) !`**: Installs one or more packages.
|
* **`osal.package_install(name_ string) !`**: Installs one or more packages.
|
||||||
* **`osal.package_remove(name_ string) !`**: Removes one or more packages.
|
* **`osal.package_remove(name_ string) !`**: Removes one or more packages.
|
||||||
|
|
||||||
### `osal.env_set(args: EnvSet)`
|
### `osal.env_set(args: EnvSet)`
|
||||||
|
|
||||||
Sets an environment variable.
|
Sets an environment variable.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`EnvSet` struct):
|
* **Parameters**:
|
||||||
* `key` (string, required): Environment variable name.
|
* `args` (`EnvSet` struct):
|
||||||
* `value` (string, required): Value to set.
|
* `key` (string, required): Environment variable name.
|
||||||
* `overwrite` (bool, default: true): Overwrite if exists.
|
* `value` (string, required): Value to set.
|
||||||
|
* `overwrite` (bool, default: true): Overwrite if exists.
|
||||||
|
|
||||||
### `osal.env_unset(key string)`
|
### `osal.env_unset(key string)`
|
||||||
|
|
||||||
Unsets a specific environment variable.
|
Unsets a specific environment variable.
|
||||||
* **Parameters**: `key` (string): Environment variable name.
|
|
||||||
|
* **Parameters**: `key` (string): Environment variable name.
|
||||||
|
|
||||||
### `osal.env_unset_all()`
|
### `osal.env_unset_all()`
|
||||||
|
|
||||||
Unsets all environment variables.
|
Unsets all environment variables.
|
||||||
|
|
||||||
### `osal.env_set_all(args: EnvSetAll)`
|
### `osal.env_set_all(args: EnvSetAll)`
|
||||||
|
|
||||||
Sets multiple environment variables.
|
Sets multiple environment variables.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`EnvSetAll` struct):
|
* **Parameters**:
|
||||||
* `env` (map[string]string): Map of key-value pairs.
|
* `args` (`EnvSetAll` struct):
|
||||||
* `clear_before_set` (bool): Clear all existing variables before setting.
|
* `env` (map[string]string): Map of key-value pairs.
|
||||||
* `overwrite_if_exists` (bool, default: true): Overwrite existing variables.
|
* `clear_before_set` (bool): Clear all existing variables before setting.
|
||||||
|
* `overwrite_if_exists` (bool, default: true): Overwrite existing variables.
|
||||||
|
|
||||||
### `osal.env_get(key string) !string`
|
### `osal.env_get(key string) !string`
|
||||||
|
|
||||||
Retrieves the value of a specific environment variable.
|
Retrieves the value of a specific environment variable.
|
||||||
* **Parameters**: `key` (string): Environment variable name.
|
|
||||||
* **Returns**: `string` (variable value).
|
* **Parameters**: `key` (string): Environment variable name.
|
||||||
|
* **Returns**: `string` (variable value).
|
||||||
|
|
||||||
### `osal.env_exists(key string) !bool`
|
### `osal.env_exists(key string) !bool`
|
||||||
|
|
||||||
Checks if an environment variable exists.
|
Checks if an environment variable exists.
|
||||||
* **Parameters**: `key` (string): Environment variable name.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `key` (string): Environment variable name.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.env_get_default(key string, def string) string`
|
### `osal.env_get_default(key string, def string) string`
|
||||||
|
|
||||||
Retrieves an environment variable or a default value if not found.
|
Retrieves an environment variable or a default value if not found.
|
||||||
* **Parameters**:
|
|
||||||
* `key` (string): Environment variable name.
|
* **Parameters**:
|
||||||
* `def` (string): Default value.
|
* `key` (string): Environment variable name.
|
||||||
* **Returns**: `string`.
|
* `def` (string): Default value.
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.load_env_file(file_path string) !`
|
### `osal.load_env_file(file_path string) !`
|
||||||
|
|
||||||
Loads environment variables from a specified file.
|
Loads environment variables from a specified file.
|
||||||
* **Parameters**: `file_path` (string): Path to the environment file.
|
|
||||||
|
* **Parameters**: `file_path` (string): Path to the environment file.
|
||||||
|
|
||||||
## 5. Command & Profile Management
|
## 5. Command & Profile Management
|
||||||
|
|
||||||
### `osal.cmd_add(args: CmdAddArgs) !`
|
### `osal.cmd_add(args: CmdAddArgs) !`
|
||||||
|
|
||||||
Adds (copies or symlinks) a binary to system paths and updates user profiles.
|
Adds (copies or symlinks) a binary to system paths and updates user profiles.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`CmdAddArgs` struct):
|
* **Parameters**:
|
||||||
* `cmdname` (string): Name of the command (optional, derived from source if empty).
|
* `args` (`CmdAddArgs` struct):
|
||||||
* `source` (string, required): Path to the binary.
|
* `cmdname` (string): Name of the command (optional, derived from source if empty).
|
||||||
* `symlink` (bool): Create a symlink instead of copying.
|
* `source` (string, required): Path to the binary.
|
||||||
* `reset` (bool, default: true): Delete existing command if found.
|
* `symlink` (bool): Create a symlink instead of copying.
|
||||||
|
* `reset` (bool, default: true): Delete existing command if found.
|
||||||
|
|
||||||
### `osal.profile_path_add_hero() !string`
|
### `osal.profile_path_add_hero() !string`
|
||||||
|
|
||||||
Ensures the `~/hero/bin` path is added to the user's profile.
|
Ensures the `~/hero/bin` path is added to the user's profile.
|
||||||
* **Returns**: `string` (the `~/hero/bin` path).
|
|
||||||
|
* **Returns**: `string` (the `~/hero/bin` path).
|
||||||
|
|
||||||
### `osal.bin_path() !string`
|
### `osal.bin_path() !string`
|
||||||
|
|
||||||
Returns the preferred binary installation path (`~/hero/bin`).
|
Returns the preferred binary installation path (`~/hero/bin`).
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.hero_path() !string`
|
### `osal.hero_path() !string`
|
||||||
|
|
||||||
Returns the `~/hero` directory path.
|
Returns the `~/hero` directory path.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.usr_local_path() !string`
|
### `osal.usr_local_path() !string`
|
||||||
|
|
||||||
Returns `/usr/local` for Linux or `~/hero` for macOS.
|
Returns `/usr/local` for Linux or `~/hero` for macOS.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.cmd_exists_profile(cmd string) bool`
|
### `osal.cmd_exists_profile(cmd string) bool`
|
||||||
|
|
||||||
Checks if a command exists in the system's PATH, considering the user's profile.
|
Checks if a command exists in the system's PATH, considering the user's profile.
|
||||||
* **Parameters**: `cmd` (string): The command name.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `cmd` (string): The command name.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.profile_path_source() !string`
|
### `osal.profile_path_source() !string`
|
||||||
|
|
||||||
Returns a source statement for the preferred profile file (e.g., `. /home/user/.zprofile`).
|
Returns a source statement for the preferred profile file (e.g., `. /home/user/.zprofile`).
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.profile_path_source_and() !string`
|
### `osal.profile_path_source_and() !string`
|
||||||
|
|
||||||
Returns a source statement followed by `&&` for command chaining, or empty if profile doesn't exist.
|
Returns a source statement followed by `&&` for command chaining, or empty if profile doesn't exist.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`
|
### `osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`
|
||||||
|
|
||||||
Adds and/or removes paths from specified or preferred user profiles.
|
Adds and/or removes paths from specified or preferred user profiles.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`ProfilePathAddRemoveArgs` struct):
|
* **Parameters**:
|
||||||
* `paths_profile` (string): Comma/newline separated list of profile file paths (optional, uses preferred if empty).
|
* `args` (`ProfilePathAddRemoveArgs` struct):
|
||||||
* `paths2add` (string): Comma/newline separated list of paths to add.
|
* `paths_profile` (string): Comma/newline separated list of profile file paths (optional, uses preferred if empty).
|
||||||
* `paths2delete` (string): Comma/newline separated list of paths to delete.
|
* `paths2add` (string): Comma/newline separated list of paths to add.
|
||||||
* `allprofiles` (bool): Apply to all known profile files.
|
* `paths2delete` (string): Comma/newline separated list of paths to delete.
|
||||||
|
* `allprofiles` (bool): Apply to all known profile files.
|
||||||
|
|
||||||
### `osal.cmd_path(cmd string) !string`
|
### `osal.cmd_path(cmd string) !string`
|
||||||
|
|
||||||
Returns the full path of an executable command using `which`.
|
Returns the full path of an executable command using `which`.
|
||||||
* **Parameters**: `cmd` (string): Command name.
|
|
||||||
* **Returns**: `string` (full path).
|
* **Parameters**: `cmd` (string): Command name.
|
||||||
|
* **Returns**: `string` (full path).
|
||||||
|
|
||||||
### `osal.cmd_delete(cmd string) !`
|
### `osal.cmd_delete(cmd string) !`
|
||||||
|
|
||||||
Deletes commands from their found locations.
|
Deletes commands from their found locations.
|
||||||
* **Parameters**: `cmd` (string): Command name.
|
|
||||||
|
* **Parameters**: `cmd` (string): Command name.
|
||||||
|
|
||||||
### `osal.profile_paths_all() ![]string`
|
### `osal.profile_paths_all() ![]string`
|
||||||
|
|
||||||
Lists all possible profile file paths in the OS.
|
Lists all possible profile file paths in the OS.
|
||||||
* **Returns**: `[]string`.
|
|
||||||
|
* **Returns**: `[]string`.
|
||||||
|
|
||||||
### `osal.profile_paths_preferred() ![]string`
|
### `osal.profile_paths_preferred() ![]string`
|
||||||
|
|
||||||
## 5.1. SSH Key Management (`ssh_key.v`)
|
## 5.1. SSH Key Management (`ssh_key.v`)
|
||||||
|
|
||||||
Functions and structs for managing SSH keys.
|
Functions and structs for managing SSH keys.
|
||||||
|
|
||||||
### `struct SSHKey`
|
### `struct SSHKey`
|
||||||
|
|
||||||
Represents an SSH key pair.
|
Represents an SSH key pair.
|
||||||
* **Fields**: `name` (string), `directory` (string).
|
|
||||||
* **Methods**:
|
* **Fields**: `name` (string), `directory` (string).
|
||||||
* `public_key_path() !pathlib.Path`: Returns the path to the public key.
|
* **Methods**:
|
||||||
* `private_key_path() !pathlib.Path`: Returns the path to the private key.
|
* `public_key_path() !pathlib.Path`: Returns the path to the public key.
|
||||||
* `public_key() !string`: Returns the content of the public key.
|
* `private_key_path() !pathlib.Path`: Returns the path to the private key.
|
||||||
* `private_key() !string`: Returns the content of the private key.
|
* `public_key() !string`: Returns the content of the public key.
|
||||||
|
* `private_key() !string`: Returns the content of the private key.
|
||||||
|
|
||||||
### `struct SSHConfig`
|
### `struct SSHConfig`
|
||||||
|
|
||||||
Configuration for SSH key operations.
|
Configuration for SSH key operations.
|
||||||
* **Fields**: `directory` (string, default: `~/.ssh`).
|
|
||||||
|
* **Fields**: `directory` (string, default: `~/.ssh`).
|
||||||
|
|
||||||
### `osal.get_ssh_key(key_name string, config SSHConfig) ?SSHKey`
|
### `osal.get_ssh_key(key_name string, config SSHConfig) ?SSHKey`
|
||||||
|
|
||||||
Retrieves a specific SSH key by name.
|
Retrieves a specific SSH key by name.
|
||||||
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
|
|
||||||
* **Returns**: `?SSHKey` (optional SSHKey struct).
|
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
|
||||||
|
* **Returns**: `?SSHKey` (optional SSHKey struct).
|
||||||
|
|
||||||
### `osal.list_ssh_keys(config SSHConfig) ![]SSHKey`
|
### `osal.list_ssh_keys(config SSHConfig) ![]SSHKey`
|
||||||
|
|
||||||
Lists all SSH keys in the specified directory.
|
Lists all SSH keys in the specified directory.
|
||||||
* **Parameters**: `config` (`SSHConfig` struct).
|
|
||||||
* **Returns**: `[]SSHKey`.
|
* **Parameters**: `config` (`SSHConfig` struct).
|
||||||
|
* **Returns**: `[]SSHKey`.
|
||||||
|
|
||||||
### `osal.new_ssh_key(key_name string, config SSHConfig) !SSHKey`
|
### `osal.new_ssh_key(key_name string, config SSHConfig) !SSHKey`
|
||||||
|
|
||||||
Creates a new SSH key pair.
|
Creates a new SSH key pair.
|
||||||
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
|
|
||||||
* **Returns**: `SSHKey`.
|
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
|
||||||
|
* **Returns**: `SSHKey`.
|
||||||
Lists preferred profile file paths based on the operating system.
|
Lists preferred profile file paths based on the operating system.
|
||||||
* **Returns**: `[]string`.
|
* **Returns**: `[]string`.
|
||||||
|
|
||||||
### `osal.profile_path() !string`
|
### `osal.profile_path() !string`
|
||||||
|
|
||||||
Returns the most preferred profile file path.
|
Returns the most preferred profile file path.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
## 6. System Information & Utilities
|
## 6. System Information & Utilities
|
||||||
|
|
||||||
### `osal.platform() !PlatformType`
|
### `osal.platform() !PlatformType`
|
||||||
|
|
||||||
Identifies the operating system.
|
Identifies the operating system.
|
||||||
* **Returns**: `PlatformType` enum (`.unknown`, `.osx`, `.ubuntu`, `.alpine`, `.arch`, `.suse`).
|
|
||||||
|
* **Returns**: `PlatformType` enum (`.unknown`, `.osx`, `.ubuntu`, `.alpine`, `.arch`, `.suse`).
|
||||||
|
|
||||||
### `osal.cputype() !CPUType`
|
### `osal.cputype() !CPUType`
|
||||||
|
|
||||||
Identifies the CPU architecture.
|
Identifies the CPU architecture.
|
||||||
* **Returns**: `CPUType` enum (`.unknown`, `.intel`, `.arm`, `.intel32`, `.arm32`).
|
|
||||||
|
* **Returns**: `CPUType` enum (`.unknown`, `.intel`, `.arm`, `.intel32`, `.arm32`).
|
||||||
|
|
||||||
### `osal.is_linux() !bool`
|
### `osal.is_linux() !bool`
|
||||||
|
|
||||||
Checks if the current OS is Linux.
|
Checks if the current OS is Linux.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_osx() !bool`
|
### `osal.is_osx() !bool`
|
||||||
|
|
||||||
Checks if the current OS is macOS.
|
Checks if the current OS is macOS.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_ubuntu() !bool`
|
### `osal.is_ubuntu() !bool`
|
||||||
|
|
||||||
Checks if the current OS is Ubuntu.
|
Checks if the current OS is Ubuntu.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_osx_arm() !bool`
|
### `osal.is_osx_arm() !bool`
|
||||||
|
|
||||||
Checks if the current OS is macOS ARM.
|
Checks if the current OS is macOS ARM.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_linux_arm() !bool`
|
### `osal.is_linux_arm() !bool`
|
||||||
|
|
||||||
Checks if the current OS is Linux ARM.
|
Checks if the current OS is Linux ARM.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_osx_intel() !bool`
|
### `osal.is_osx_intel() !bool`
|
||||||
|
|
||||||
Checks if the current OS is macOS Intel.
|
Checks if the current OS is macOS Intel.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.is_linux_intel() !bool`
|
### `osal.is_linux_intel() !bool`
|
||||||
|
|
||||||
Checks if the current OS is Linux Intel.
|
Checks if the current OS is Linux Intel.
|
||||||
* **Returns**: `bool`.
|
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.hostname() !string`
|
### `osal.hostname() !string`
|
||||||
|
|
||||||
Returns the system hostname.
|
Returns the system hostname.
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.initname() !string`
|
### `osal.initname() !string`
|
||||||
|
|
||||||
Returns the init system name (e.g., `systemd`, `bash`, `zinit`).
|
Returns the init system name (e.g., `systemd`, `bash`, `zinit`).
|
||||||
* **Returns**: `string`.
|
|
||||||
|
* **Returns**: `string`.
|
||||||
|
|
||||||
### `osal.sleep(duration int)`
|
### `osal.sleep(duration int)`
|
||||||
|
|
||||||
Pauses execution for a specified duration.
|
Pauses execution for a specified duration.
|
||||||
* **Parameters**: `duration` (int): Sleep duration in seconds.
|
|
||||||
|
* **Parameters**: `duration` (int): Sleep duration in seconds.
|
||||||
|
|
||||||
### `osal.download(args: DownloadArgs) !pathlib.Path`
|
### `osal.download(args: DownloadArgs) !pathlib.Path`
|
||||||
|
|
||||||
Downloads a file from a URL.
|
Downloads a file from a URL.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`DownloadArgs` struct):
|
* **Parameters**:
|
||||||
* `url` (string, required): URL of the file.
|
* `args` (`DownloadArgs` struct):
|
||||||
* `name` (string): Optional, derived from filename if empty.
|
* `url` (string, required): URL of the file.
|
||||||
* `reset` (bool): Force download, remove existing.
|
* `name` (string): Optional, derived from filename if empty.
|
||||||
* `hash` (string): Hash for verification.
|
* `reset` (bool): Force download, remove existing.
|
||||||
* `dest` (string): Destination path.
|
* `hash` (string): Hash for verification.
|
||||||
* `timeout` (int, default: 180): Download timeout in seconds.
|
* `dest` (string): Destination path.
|
||||||
* `retry` (int, default: 3): Number of retries.
|
* `timeout` (int, default: 180): Download timeout in seconds.
|
||||||
* `minsize_kb` (u32, default: 10): Minimum expected size in KB.
|
* `retry` (int, default: 3): Number of retries.
|
||||||
* `maxsize_kb` (u32): Maximum expected size in KB.
|
* `minsize_kb` (u32, default: 10): Minimum expected size in KB.
|
||||||
* `expand_dir` (string): Directory to expand archive into.
|
* `maxsize_kb` (u32): Maximum expected size in KB.
|
||||||
* `expand_file` (string): File to expand archive into.
|
* `expand_dir` (string): Directory to expand archive into.
|
||||||
* **Returns**: `pathlib.Path` (path to the downloaded file/directory).
|
* `expand_file` (string): File to expand archive into.
|
||||||
|
* **Returns**: `pathlib.Path` (path to the downloaded file/directory).
|
||||||
|
|
||||||
### `osal.user_exists(username string) bool`
|
### `osal.user_exists(username string) bool`
|
||||||
|
|
||||||
Checks if a user exists on the system.
|
Checks if a user exists on the system.
|
||||||
* **Parameters**: `username` (string): Username to check.
|
|
||||||
* **Returns**: `bool`.
|
* **Parameters**: `username` (string): Username to check.
|
||||||
|
* **Returns**: `bool`.
|
||||||
|
|
||||||
### `osal.user_id_get(username string) !int`
|
### `osal.user_id_get(username string) !int`
|
||||||
|
|
||||||
Retrieves the user ID for a given username.
|
Retrieves the user ID for a given username.
|
||||||
* **Parameters**: `username` (string): Username.
|
|
||||||
* **Returns**: `int` (User ID).
|
* **Parameters**: `username` (string): Username.
|
||||||
|
* **Returns**: `int` (User ID).
|
||||||
|
|
||||||
### `osal.user_add(args: UserArgs) !int`
|
### `osal.user_add(args: UserArgs) !int`
|
||||||
|
|
||||||
Adds a new user to the system.
|
Adds a new user to the system.
|
||||||
* **Parameters**:
|
|
||||||
* `args` (`UserArgs` struct):
|
* **Parameters**:
|
||||||
* `name` (string, required): Username to add.
|
* `args` (`UserArgs` struct):
|
||||||
* **Returns**: `int` (User ID of the added user).
|
* `name` (string, required): Username to add.
|
||||||
|
* **Returns**: `int` (User ID of the added user).
|
||||||
|
|
||||||
## Enums & Structs
|
## Enums & Structs
|
||||||
|
|
||||||
### `enum PlatformType`
|
### `enum PlatformType`
|
||||||
|
|
||||||
Represents the detected operating system.
|
Represents the detected operating system.
|
||||||
* Values: `unknown`, `osx`, `ubuntu`, `alpine`, `arch`, `suse`.
|
|
||||||
|
* Values: `unknown`, `osx`, `ubuntu`, `alpine`, `arch`, `suse`.
|
||||||
|
|
||||||
### `enum CPUType`
|
### `enum CPUType`
|
||||||
|
|
||||||
Represents the detected CPU architecture.
|
Represents the detected CPU architecture.
|
||||||
* Values: `unknown`, `intel`, `arm`, `intel32`, `arm32`.
|
|
||||||
|
* Values: `unknown`, `intel`, `arm`, `intel32`, `arm32`.
|
||||||
|
|
||||||
### `enum RunTime`
|
### `enum RunTime`
|
||||||
|
|
||||||
Specifies the runtime environment for command execution.
|
Specifies the runtime environment for command execution.
|
||||||
* Values: `bash`, `python`, `heroscript`, `herocmd`, `v`.
|
|
||||||
|
* Values: `bash`, `python`, `heroscript`, `herocmd`, `v`.
|
||||||
|
|
||||||
### `enum JobStatus`
|
### `enum JobStatus`
|
||||||
|
|
||||||
Status of an executed command job.
|
Status of an executed command job.
|
||||||
* Values: `init`, `running`, `error_exec`, `error_timeout`, `error_args`, `done`.
|
|
||||||
|
* Values: `init`, `running`, `error_exec`, `error_timeout`, `error_args`, `done`.
|
||||||
|
|
||||||
### `enum ErrorType`
|
### `enum ErrorType`
|
||||||
|
|
||||||
Types of errors that can occur during job execution.
|
Types of errors that can occur during job execution.
|
||||||
* Values: `exec`, `timeout`, `args`.
|
|
||||||
|
* Values: `exec`, `timeout`, `args`.
|
||||||
|
|
||||||
### `enum PingResult`
|
### `enum PingResult`
|
||||||
|
|
||||||
Result of a ping operation.
|
Result of a ping operation.
|
||||||
* Values: `ok`, `timeout`, `unknownhost`.
|
|
||||||
|
* Values: `ok`, `timeout`, `unknownhost`.
|
||||||
|
|
||||||
### `struct Command`
|
### `struct Command`
|
||||||
|
|
||||||
Configuration for `osal.exec` function. (See `osal.exec` parameters for fields).
|
Configuration for `osal.exec` function. (See `osal.exec` parameters for fields).
|
||||||
|
|
||||||
### `struct Job`
|
### `struct Job`
|
||||||
|
|
||||||
Result object returned by `osal.exec`. (See `osal.exec` returns for fields).
|
Result object returned by `osal.exec`. (See `osal.exec` returns for fields).
|
||||||
|
|
||||||
### `struct JobError`
|
### `struct JobError`
|
||||||
|
|
||||||
Error details for failed jobs.
|
Error details for failed jobs.
|
||||||
|
|
||||||
### `struct PingArgs`
|
### `struct PingArgs`
|
||||||
|
|
||||||
Arguments for `osal.ping` function. (See `osal.ping` parameters for fields).
|
Arguments for `osal.ping` function. (See `osal.ping` parameters for fields).
|
||||||
|
|
||||||
### `struct TcpPortTestArgs`
|
### `struct TcpPortTestArgs`
|
||||||
|
|
||||||
Arguments for `osal.tcp_port_test` function. (See `osal.tcp_port_test` parameters for fields).
|
Arguments for `osal.tcp_port_test` function. (See `osal.tcp_port_test` parameters for fields).
|
||||||
|
|
||||||
### `struct EnvSet`
|
### `struct EnvSet`
|
||||||
|
|
||||||
Arguments for `osal.env_set` function. (See `osal.env_set` parameters for fields).
|
Arguments for `osal.env_set` function. (See `osal.env_set` parameters for fields).
|
||||||
|
|
||||||
### `struct EnvSetAll`
|
### `struct EnvSetAll`
|
||||||
|
|
||||||
Arguments for `osal.env_set_all` function. (See `osal.env_set_all` parameters for fields).
|
Arguments for `osal.env_set_all` function. (See `osal.env_set_all` parameters for fields).
|
||||||
|
|
||||||
### `struct CmdAddArgs`
|
### `struct CmdAddArgs`
|
||||||
|
|
||||||
Arguments for `osal.cmd_add` function. (See `osal.cmd_add` parameters for fields).
|
Arguments for `osal.cmd_add` function. (See `osal.cmd_add` parameters for fields).
|
||||||
|
|
||||||
### `struct ProfilePathAddRemoveArgs`
|
### `struct ProfilePathAddRemoveArgs`
|
||||||
|
|
||||||
Arguments for `osal.profile_path_add_remove` function. (See `osal.profile_path_add_remove` parameters for fields).
|
Arguments for `osal.profile_path_add_remove` function. (See `osal.profile_path_add_remove` parameters for fields).
|
||||||
|
|
||||||
### `struct ProcessMap`
|
### `struct ProcessMap`
|
||||||
|
|
||||||
Contains a list of `ProcessInfo` objects.
|
Contains a list of `ProcessInfo` objects.
|
||||||
|
|
||||||
### `struct ProcessInfo`
|
### `struct ProcessInfo`
|
||||||
|
|
||||||
Detailed information about a single process. (See `osal.processinfo_get` returns for fields).
|
Detailed information about a single process. (See `osal.processinfo_get` returns for fields).
|
||||||
|
|
||||||
### `struct ProcessKillArgs`
|
### `struct ProcessKillArgs`
|
||||||
|
|
||||||
Arguments for `osal.process_kill_recursive` function. (See `osal.process_kill_recursive` parameters for fields).
|
Arguments for `osal.process_kill_recursive` function. (See `osal.process_kill_recursive` parameters for fields).
|
||||||
|
|
||||||
### `struct DownloadArgs`
|
### `struct DownloadArgs`
|
||||||
|
|
||||||
Arguments for `osal.download` function. (See `osal.download` parameters for fields).
|
Arguments for `osal.download` function. (See `osal.download` parameters for fields).
|
||||||
|
|
||||||
### `struct UserArgs`
|
### `struct UserArgs`
|
||||||
|
|
||||||
Arguments for `osal.user_add` function. (See `osal.user_add` parameters for fields).
|
Arguments for `osal.user_add` function. (See `osal.user_add` parameters for fields).
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
|
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- Create time objects from strings or current time
|
- Create time objects from strings or current time
|
||||||
- Relative time expressions (e.g., `+1h`, `-2d`)
|
- Relative time expressions (e.g., `+1h`, `-2d`)
|
||||||
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
|
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
|
||||||
@@ -12,7 +13,7 @@ The `OurTime` module in V provides flexible time handling, supporting relative a
|
|||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.data.ourtime
|
import incubaid.herolib.data.ourtime
|
||||||
|
|
||||||
// Current time
|
// Current time
|
||||||
mut t := ourtime.now()
|
mut t := ourtime.now()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Herolib Spreadsheet Module for AI Prompt Engineering
|
# Herolib Spreadsheet Module for AI Prompt Engineering
|
||||||
|
|
||||||
This document provides an overview and usage instructions for the `freeflowuniverse.herolib.biz.spreadsheet` module, which offers a powerful software representation of a spreadsheet. This module is designed for business modeling, data analysis, and can be leveraged in AI prompt engineering scenarios where structured data manipulation and visualization are required.
|
This document provides an overview and usage instructions for the `incubaid.herolib.biz.spreadsheet` module, which offers a powerful software representation of a spreadsheet. This module is designed for business modeling, data analysis, and can be leveraged in AI prompt engineering scenarios where structured data manipulation and visualization are required.
|
||||||
|
|
||||||
## 1. Core Concepts
|
## 1. Core Concepts
|
||||||
|
|
||||||
@@ -10,16 +10,17 @@ The spreadsheet module revolves around three main entities: `Sheet`, `Row`, and
|
|||||||
|
|
||||||
The `Sheet` is the primary container, representing the entire spreadsheet.
|
The `Sheet` is the primary container, representing the entire spreadsheet.
|
||||||
|
|
||||||
* **Properties:**
|
* **Properties:**
|
||||||
* `name` (string): A unique identifier for the sheet.
|
* `name` (string): A unique identifier for the sheet.
|
||||||
* `rows` (map[string]&Row): A collection of `Row` objects, indexed by their names.
|
* `rows` (map[string]&Row): A collection of `Row` objects, indexed by their names.
|
||||||
* `nrcol` (int): The number of columns in the sheet (e.g., 60 for 5 years of monthly data).
|
* `nrcol` (int): The number of columns in the sheet (e.g., 60 for 5 years of monthly data).
|
||||||
* `params` (SheetParams): Configuration parameters, e.g., `visualize_cur` (boolean to display currency symbols).
|
* `params` (SheetParams): Configuration parameters, e.g., `visualize_cur` (boolean to display currency symbols).
|
||||||
* `currency` (currency.Currency): The default currency for the sheet (e.g., USD), used for automatic conversions.
|
* `currency` (currency.Currency): The default currency for the sheet (e.g., USD), used for automatic conversions.
|
||||||
|
|
||||||
|
* **Creation:**
|
||||||
|
|
||||||
* **Creation:**
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.biz.spreadsheet
|
import incubaid.herolib.biz.spreadsheet
|
||||||
|
|
||||||
// Create a new sheet named 'my_financial_sheet' with 60 columns (e.g., 60 months)
|
// Create a new sheet named 'my_financial_sheet' with 60 columns (e.g., 60 months)
|
||||||
mut my_sheet := spreadsheet.sheet_new(
|
mut my_sheet := spreadsheet.sheet_new(
|
||||||
@@ -33,28 +34,29 @@ The `Sheet` is the primary container, representing the entire spreadsheet.
|
|||||||
mut existing_sheet := spreadsheet.sheet_get('my_financial_sheet')!
|
mut existing_sheet := spreadsheet.sheet_get('my_financial_sheet')!
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Key Operations:**
|
* **Key Operations:**
|
||||||
* `sheet.row_get(name string) !&Row`: Retrieves a row by its name.
|
* `sheet.row_get(name string) !&Row`: Retrieves a row by its name.
|
||||||
* `sheet.cell_get(row string, col int) !&Cell`: Retrieves a cell by row name and column index.
|
* `sheet.cell_get(row string, col int) !&Cell`: Retrieves a cell by row name and column index.
|
||||||
* `sheet.row_delete(name string)` / `sheet.delete(name string)`: Deletes a row.
|
* `sheet.row_delete(name string)` / `sheet.delete(name string)`: Deletes a row.
|
||||||
* `sheet.cells_width(colnr int) !int`: Finds the maximum string length of cells in a given column.
|
* `sheet.cells_width(colnr int) !int`: Finds the maximum string length of cells in a given column.
|
||||||
* `sheet.rows_names_width_max() int`: Returns the maximum width of row names/aliases.
|
* `sheet.rows_names_width_max() int`: Returns the maximum width of row names/aliases.
|
||||||
* `sheet.rows_description_width_max() int`: Returns the maximum width of row descriptions.
|
* `sheet.rows_description_width_max() int`: Returns the maximum width of row descriptions.
|
||||||
* `sheet.header() ![]string`: Generates column headers (e.g., "M1", "Q1", "Y1") based on `nrcol`.
|
* `sheet.header() ![]string`: Generates column headers (e.g., "M1", "Q1", "Y1") based on `nrcol`.
|
||||||
|
|
||||||
### 1.2. Row
|
### 1.2. Row
|
||||||
|
|
||||||
A `Row` represents a single horizontal line of data within a `Sheet`.
|
A `Row` represents a single horizontal line of data within a `Sheet`.
|
||||||
|
|
||||||
* **Properties:**
|
* **Properties:**
|
||||||
* `name` (string): Unique identifier for the row.
|
* `name` (string): Unique identifier for the row.
|
||||||
* `alias` (string, optional): Alternative name.
|
* `alias` (string, optional): Alternative name.
|
||||||
* `description` (string): Textual description.
|
* `description` (string): Textual description.
|
||||||
* `tags` (string): Space-separated tags for categorization (e.g., "department:hr location:belgium").
|
* `tags` (string): Space-separated tags for categorization (e.g., "department:hr location:belgium").
|
||||||
* `cells` ([]Cell): List of `Cell` objects.
|
* `cells` ([]Cell): List of `Cell` objects.
|
||||||
* `aggregatetype` (RowAggregateType): Defines default aggregation for this row (`.sum`, `.avg`, `.max`, `.min`).
|
* `aggregatetype` (RowAggregateType): Defines default aggregation for this row (`.sum`, `.avg`, `.max`, `.min`).
|
||||||
|
|
||||||
|
* **Creation (within a Sheet):**
|
||||||
|
|
||||||
* **Creation (within a Sheet):**
|
|
||||||
```v
|
```v
|
||||||
// Assuming 'my_sheet' is an existing Sheet object
|
// Assuming 'my_sheet' is an existing Sheet object
|
||||||
mut salaries_row := my_sheet.row_new(
|
mut salaries_row := my_sheet.row_new(
|
||||||
@@ -65,21 +67,21 @@ A `Row` represents a single horizontal line of data within a `Sheet`.
|
|||||||
)!
|
)!
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Key Operations:**
|
* **Key Operations:**
|
||||||
* `row.values_get() []f64`: Returns all cell values in the row as a list of floats.
|
* `row.values_get() []f64`: Returns all cell values in the row as a list of floats.
|
||||||
|
|
||||||
### 1.3. Cell
|
### 1.3. Cell
|
||||||
|
|
||||||
A `Cell` is the fundamental unit of data, storing a numeric value.
|
A `Cell` is the fundamental unit of data, storing a numeric value.
|
||||||
|
|
||||||
* **Properties:**
|
* **Properties:**
|
||||||
* `val` (f64): The numeric value.
|
* `val` (f64): The numeric value.
|
||||||
* `empty` (bool): `true` if the cell is empty.
|
* `empty` (bool): `true` if the cell is empty.
|
||||||
|
|
||||||
* **Key Operations:**
|
* **Key Operations:**
|
||||||
* `cell.set(v string) !`: Sets the cell's value. Handles currency strings (e.g., "100 USD") by converting to the sheet's currency.
|
* `cell.set(v string) !`: Sets the cell's value. Handles currency strings (e.g., "100 USD") by converting to the sheet's currency.
|
||||||
* `cell.add(v f64)`: Adds a numeric value to the existing cell value.
|
* `cell.add(v f64)`: Adds a numeric value to the existing cell value.
|
||||||
* `cell.repr() string`: Returns a formatted string representation of the value (e.g., "100.00", or "-" if empty).
|
* `cell.repr() string`: Returns a formatted string representation of the value (e.g., "100.00", or "-" if empty).
|
||||||
|
|
||||||
## 2. Data Aggregation and Transformation
|
## 2. Data Aggregation and Transformation
|
||||||
|
|
||||||
@@ -144,10 +146,10 @@ csv_string := my_sheet.export_csv(path: '')!
|
|||||||
println(csv_string)
|
println(csv_string)
|
||||||
```
|
```
|
||||||
|
|
||||||
* **`ExportCSVArgs` Parameters:**
|
* **`ExportCSVArgs` Parameters:**
|
||||||
* `path` (string, optional): File path. Empty string returns content as string. `~` is expanded to home directory.
|
* `path` (string, optional): File path. Empty string returns content as string. `~` is expanded to home directory.
|
||||||
* `include_empty` (bool, optional, default: `false`): If `true`, empty cells are included.
|
* `include_empty` (bool, optional, default: `false`): If `true`, empty cells are included.
|
||||||
* `separator` (string, optional, default: `'|'`): Delimiter character.
|
* `separator` (string, optional, default: `'|'`): Delimiter character.
|
||||||
|
|
||||||
## 4. Charting Capabilities
|
## 4. Charting Capabilities
|
||||||
|
|
||||||
@@ -157,25 +159,26 @@ Integrates with ECharts for data visualization. Charting functions return an `ec
|
|||||||
|
|
||||||
Used across line, bar, and pie charts to specify data and presentation.
|
Used across line, bar, and pie charts to specify data and presentation.
|
||||||
|
|
||||||
* `rowname` (string, optional): Single row name or comma-separated list.
|
* `rowname` (string, optional): Single row name or comma-separated list.
|
||||||
* `namefilter` ([]string, optional): List of exact row names to include.
|
* `namefilter` ([]string, optional): List of exact row names to include.
|
||||||
* `includefilter` ([]string, optional): List of tags to include.
|
* `includefilter` ([]string, optional): List of tags to include.
|
||||||
* `excludefilter` ([]string, optional): List of tags to exclude.
|
* `excludefilter` ([]string, optional): List of tags to exclude.
|
||||||
* `period_type` (PeriodType, optional): X-axis period (`.month`, `.quarter`, `.year`).
|
* `period_type` (PeriodType, optional): X-axis period (`.month`, `.quarter`, `.year`).
|
||||||
* `aggregate` (bool, optional, default: `true`): Aggregate multiple matching rows.
|
* `aggregate` (bool, optional, default: `true`): Aggregate multiple matching rows.
|
||||||
* `aggregatetype` (RowAggregateType, optional, default: `.sum`): Aggregation type.
|
* `aggregatetype` (RowAggregateType, optional, default: `.sum`): Aggregation type.
|
||||||
* `unit` (UnitType, optional): Data unit.
|
* `unit` (UnitType, optional): Data unit.
|
||||||
* `title`, `title_sub` (string, optional): Chart titles.
|
* `title`, `title_sub` (string, optional): Chart titles.
|
||||||
* `size` (string, optional): For pie charts, defines radius (e.g., "70%").
|
* `size` (string, optional): For pie charts, defines radius (e.g., "70%").
|
||||||
* `rowname_show` (bool, optional, default: `true`): Show row name in legend.
|
* `rowname_show` (bool, optional, default: `true`): Show row name in legend.
|
||||||
* `descr_show` (bool, optional, default: `false`): Show row description (overrides `rowname_show`).
|
* `descr_show` (bool, optional, default: `false`): Show row description (overrides `rowname_show`).
|
||||||
* `description` (string, optional): General chart description.
|
* `description` (string, optional): General chart description.
|
||||||
|
|
||||||
### 4.2. Chart Types
|
### 4.2. Chart Types
|
||||||
|
|
||||||
* **Line Chart (`line_chart`)**: Visualizes trends over time.
|
* **Line Chart (`line_chart`)**: Visualizes trends over time.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.web.echarts // Required for EChartsOption type
|
import incubaid.herolib.web.echarts // Required for EChartsOption type
|
||||||
|
|
||||||
line_chart_option := my_sheet.line_chart(
|
line_chart_option := my_sheet.line_chart(
|
||||||
rowname: 'revenue_row,expenses_row',
|
rowname: 'revenue_row,expenses_row',
|
||||||
@@ -184,7 +187,8 @@ Used across line, bar, and pie charts to specify data and presentation.
|
|||||||
)!
|
)!
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Bar Chart (`bar_chart`)**: Compares discrete categories or values.
|
* **Bar Chart (`bar_chart`)**: Compares discrete categories or values.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
bar_chart_option := my_sheet.bar_chart(
|
bar_chart_option := my_sheet.bar_chart(
|
||||||
rowname: 'profit_row',
|
rowname: 'profit_row',
|
||||||
@@ -193,7 +197,8 @@ Used across line, bar, and pie charts to specify data and presentation.
|
|||||||
)!
|
)!
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Pie Chart (`pie_chart`)**: Shows proportions of categories.
|
* **Pie Chart (`pie_chart`)**: Shows proportions of categories.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
pie_chart_option := my_sheet.pie_chart(
|
pie_chart_option := my_sheet.pie_chart(
|
||||||
rowname: 'budget_allocation_row',
|
rowname: 'budget_allocation_row',
|
||||||
@@ -203,4 +208,4 @@ Used across line, bar, and pie charts to specify data and presentation.
|
|||||||
)!
|
)!
|
||||||
```
|
```
|
||||||
|
|
||||||
This documentation should provide sufficient information for an AI to understand and utilize the `lib/biz/spreadsheet` module effectively for various data manipulation and visualization tasks.
|
This documentation should provide sufficient information for an AI to understand and utilize the `lib/biz/spreadsheet` module effectively for various data manipulation and visualization tasks.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Chalk offers functions:- `console.color_fg(text string, color string)` - To chan
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
|
|
||||||
# basic usage
|
# basic usage
|
||||||
println('I am really ' + console.color_fg('happy', 'green'))
|
println('I am really ' + console.color_fg('happy', 'green'))
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ when I generate vlang scripts I will always use .vsh extension and use following
|
|||||||
As AI agent I should also execute .v or .vsh scripts with vrun
|
As AI agent I should also execute .v or .vsh scripts with vrun
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
vrun ~/code/github/incubaid/herolib/examples/biztools/bizmodel.vsh
|
||||||
```
|
```
|
||||||
|
|
||||||
## executing test scripts
|
## executing test scripts
|
||||||
@@ -35,7 +35,7 @@ vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
|||||||
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||||
```
|
```
|
||||||
|
|
||||||
- use ~ so it works over all machines
|
- use ~ so it works over all machines
|
||||||
|
|||||||
@@ -6,39 +6,39 @@ the following is a good pragmatic way to remember clients, installers as a globa
|
|||||||
|
|
||||||
module docsite
|
module docsite
|
||||||
|
|
||||||
import freeflowuniverse.herolib.core.texttools
|
import incubaid.herolib.core.texttools
|
||||||
|
|
||||||
__global (
|
__global (
|
||||||
siteconfigs map[string]&SiteConfig
|
siteconfigs map[string]&SiteConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
@[params]
|
@[params]
|
||||||
pub struct FactoryArgs {
|
pub struct FactoryArgs {
|
||||||
pub mut:
|
pub mut:
|
||||||
name string = "default"
|
name string = "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(args FactoryArgs) !&SiteConfig {
|
pub fn new(args FactoryArgs) !&SiteConfig {
|
||||||
name := texttools.name_fix(args.name)
|
name := texttools.name_fix(args.name)
|
||||||
siteconfigs[name] = &SiteConfig{
|
siteconfigs[name] = &SiteConfig{
|
||||||
name: name
|
name: name
|
||||||
}
|
}
|
||||||
return get(name:name)!
|
return get(name:name)!
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(args FactoryArgs) !&SiteConfig {
|
pub fn get(args FactoryArgs) !&SiteConfig {
|
||||||
name := texttools.name_fix(args.name)
|
name := texttools.name_fix(args.name)
|
||||||
mut sc := siteconfigs[name] or {
|
mut sc := siteconfigs[name] or {
|
||||||
return error('siteconfig with name "${name}" does not exist')
|
return error('siteconfig with name "${name}" does not exist')
|
||||||
}
|
}
|
||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() !&SiteConfig {
|
pub fn default() !&SiteConfig {
|
||||||
if siteconfigs.len == 0 {
|
if siteconfigs.len == 0 {
|
||||||
return new(name:'default')!
|
return new(name:'default')!
|
||||||
}
|
}
|
||||||
return get()!
|
return get()!
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -6,49 +6,49 @@ HeroScript is a concise scripting language with the following structure:
|
|||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!actor.action_name
|
!!actor.action_name
|
||||||
param1: 'value1'
|
param1: 'value1'
|
||||||
param2: 'value with spaces'
|
param2: 'value with spaces'
|
||||||
multiline_description: '
|
multiline_description: '
|
||||||
This is a multiline description.
|
This is a multiline description.
|
||||||
It can span multiple lines.
|
It can span multiple lines.
|
||||||
'
|
'
|
||||||
arg1 arg2 // Arguments without keys
|
arg1 arg2 // Arguments without keys
|
||||||
```
|
```
|
||||||
|
|
||||||
Key characteristics:
|
Key characteristics:
|
||||||
- **Actions**: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
|
|
||||||
- **Parameters**: Defined as `key:value`. Values can be quoted for spaces.
|
- **Actions**: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
|
||||||
- **Multiline Support**: Parameters like `description` can span multiple lines.
|
- **Parameters**: Defined as `key:value`. Values can be quoted for spaces.
|
||||||
- **Arguments**: Values without keys (e.g., `arg1`).
|
- **Multiline Support**: Parameters like `description` can span multiple lines.
|
||||||
|
- **Arguments**: Values without keys (e.g., `arg1`).
|
||||||
|
|
||||||
## Processing HeroScript in Vlang
|
## Processing HeroScript in Vlang
|
||||||
|
|
||||||
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters, this is used in most of the herolib modules, it allows configuration or actions in a structured way.
|
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters, this is used in most of the herolib modules, it allows configuration or actions in a structured way.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.playbook { PlayBook }
|
import incubaid.herolib.core.playbook { PlayBook }
|
||||||
import freeflowuniverse.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
|
|
||||||
pub fn play(mut plbook PlayBook) ! {
|
pub fn play(mut plbook PlayBook) ! {
|
||||||
|
|
||||||
if plbook.exists_once(filter: 'docusaurus.define') {
|
if plbook.exists_once(filter: 'docusaurus.define') {
|
||||||
mut action := plbook.get(filter: 'docusaurus.define')!
|
mut action := plbook.get(filter: 'docusaurus.define')!
|
||||||
mut p := action.params
|
mut p := action.params
|
||||||
//example how we get parameters from the action see core_params.md for more details
|
//example how we get parameters from the action see core_params.md for more details
|
||||||
ds = new(
|
ds = new(
|
||||||
path: p.get_default('path_publish', '')!
|
path: p.get_default('path_publish', '')!
|
||||||
production: p.get_default_false('production')
|
production: p.get_default_false('production')
|
||||||
)!
|
)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process 'docusaurus.add' actions to configure individual Docusaurus sites
|
// Process 'docusaurus.add' actions to configure individual Docusaurus sites
|
||||||
actions := plbook.find(filter: 'docusaurus.add')!
|
actions := plbook.find(filter: 'docusaurus.add')!
|
||||||
for action in actions {
|
for action in actions {
|
||||||
mut p := action.params
|
mut p := action.params
|
||||||
//do more processing here
|
//do more processing here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get_int()`, `p.get_default_true()`), refer to `aiprompts/ai_core/core_params.md`.
|
For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get_int()`, `p.get_default_true()`), refer to `aiprompts/ai_core/core_params.md`.
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters.
|
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
|
|
||||||
// path string
|
// path string
|
||||||
// text string
|
// text string
|
||||||
@@ -21,5 +21,3 @@ mut plbook := playbook.new(path: "....")!
|
|||||||
playcmds.run(mut plbook)!
|
playcmds.run(mut plbook)!
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting JSON, custom headers, retries, and caching.
|
The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting JSON, custom headers, retries, and caching.
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- Type-safe JSON methods
|
- Type-safe JSON methods
|
||||||
- Custom headers
|
- Custom headers
|
||||||
- Retry mechanism
|
- Retry mechanism
|
||||||
@@ -12,7 +13,7 @@ The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting
|
|||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.httpconnection
|
import incubaid.herolib.core.httpconnection
|
||||||
|
|
||||||
// Create a new HTTP connection
|
// Create a new HTTP connection
|
||||||
mut conn := httpconnection.new(
|
mut conn := httpconnection.new(
|
||||||
@@ -30,17 +31,17 @@ To integrate `HTTPConnection` into a management class (e.g., `HetznerManager`),
|
|||||||
```v
|
```v
|
||||||
// Example: HetznerManager
|
// Example: HetznerManager
|
||||||
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
|
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
|
||||||
mut c := h.conn or {
|
mut c := h.conn or {
|
||||||
mut c2 := httpconnection.new(
|
mut c2 := httpconnection.new(
|
||||||
name: 'hetzner_${h.name}'
|
name: 'hetzner_${h.name}'
|
||||||
url: h.baseurl
|
url: h.baseurl
|
||||||
cache: true
|
cache: true
|
||||||
retry: 3
|
retry: 3
|
||||||
)!
|
)!
|
||||||
c2.basic_auth(h.user, h.password)
|
c2.basic_auth(h.user, h.password)
|
||||||
c2
|
c2
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
# OSAL Core Module - Key Capabilities (freeflowuniverse.herolib.osal.core)
|
# OSAL Core Module - Key Capabilities (incubaid.herolib.osal.core)
|
||||||
|
|
||||||
|
> **Note:** Platform detection functions (`platform()` and `cputype()`) have moved to `incubaid.herolib.core`.
|
||||||
|
> Use `import incubaid.herolib.core` and call `core.platform()!` and `core.cputype()!` instead.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
//example how to get started
|
//example how to get started
|
||||||
|
|
||||||
import freeflowuniverse.herolib.osal.core as osal
|
import incubaid.herolib.osal.core as osal
|
||||||
|
|
||||||
job := osal.exec(cmd: 'ls /')!
|
job := osal.exec(cmd: 'ls /')!
|
||||||
```
|
```
|
||||||
@@ -12,70 +15,70 @@ This document describes the core functionalities of the Operating System Abstrac
|
|||||||
|
|
||||||
## 1. Process Execution
|
## 1. Process Execution
|
||||||
|
|
||||||
* **`osal.exec(cmd: Command) !Job`**: Execute a shell command.
|
* **`osal.exec(cmd: Command) !Job`**: Execute a shell command.
|
||||||
* **Key Parameters**: `cmd` (string), `timeout` (int), `retry` (int), `work_folder` (string), `environment` (map[string]string), `stdout` (bool), `raise_error` (bool).
|
* **Key Parameters**: `cmd` (string), `timeout` (int), `retry` (int), `work_folder` (string), `environment` (map[string]string), `stdout` (bool), `raise_error` (bool).
|
||||||
* **Returns**: `Job` (status, output, error, exit code).
|
* **Returns**: `Job` (status, output, error, exit code).
|
||||||
* **`osal.execute_silent(cmd string) !string`**: Execute silently, return output.
|
* **`osal.execute_silent(cmd string) !string`**: Execute silently, return output.
|
||||||
* **`osal.execute_debug(cmd string) !string`**: Execute with debug output, return output.
|
* **`osal.execute_debug(cmd string) !string`**: Execute with debug output, return output.
|
||||||
* **`osal.execute_stdout(cmd string) !string`**: Execute and print output to stdout, return output.
|
* **`osal.execute_stdout(cmd string) !string`**: Execute and print output to stdout, return output.
|
||||||
* **`osal.execute_interactive(cmd string) !`**: Execute in an interactive shell.
|
* **`osal.execute_interactive(cmd string) !`**: Execute in an interactive shell.
|
||||||
* **`osal.cmd_exists(cmd string) bool`**: Check if a command exists.
|
* **`osal.cmd_exists(cmd string) bool`**: Check if a command exists.
|
||||||
|
|
||||||
## 2. Network Utilities
|
## 2. Network Utilities
|
||||||
|
|
||||||
* **`osal.ping(args: PingArgs) !bool`**: Check host reachability.
|
* **`osal.ping(args: PingArgs) !bool`**: Check host reachability.
|
||||||
- address string = "8.8.8.8"
|
- address string = "8.8.8.8"
|
||||||
- nr_ping u16 = 3 // amount of ping requests we will do
|
- nr_ping u16 = 3 // amount of ping requests we will do
|
||||||
- nr_ok u16 = 3 //how many of them need to be ok
|
- nr_ok u16 = 3 //how many of them need to be ok
|
||||||
- retry u8 //how many times fo we retry above sequence, basically we ping ourselves with -c 1
|
- retry u8 //how many times fo we retry above sequence, basically we ping ourselves with -c 1
|
||||||
**`osal.ipaddr_pub_get() !string`**: Get public IP address.
|
**`osal.ipaddr_pub_get() !string`**: Get public IP address.
|
||||||
|
|
||||||
## 3. File System Operations
|
## 3. File System Operations
|
||||||
|
|
||||||
* **`osal.file_write(path string, text string) !`**: Write text to a file.
|
* **`osal.file_write(path string, text string) !`**: Write text to a file.
|
||||||
* **`osal.file_read(path string) !string`**: Read content from a file.
|
* **`osal.file_read(path string) !string`**: Read content from a file.
|
||||||
* **`osal.dir_ensure(path string) !`**: Ensure a directory exists.
|
* **`osal.dir_ensure(path string) !`**: Ensure a directory exists.
|
||||||
* **`osal.rm(todelete string) !`**: Remove files/directories.
|
* **`osal.rm(todelete string) !`**: Remove files/directories.
|
||||||
|
|
||||||
## 4. Environment Variables
|
## 4. Environment Variables
|
||||||
|
|
||||||
* **`osal.env_set(args: EnvSet)`**: Set an environment variable.
|
* **`osal.env_set(args: EnvSet)`**: Set an environment variable.
|
||||||
* **Key Parameters**: `key` (string), `value` (string).
|
* **Key Parameters**: `key` (string), `value` (string).
|
||||||
* **`osal.env_unset(key string)`**: Unset a specific environment variable.
|
* **`osal.env_unset(key string)`**: Unset a specific environment variable.
|
||||||
* **`osal.env_unset_all()`**: Unset all environment variables.
|
* **`osal.env_unset_all()`**: Unset all environment variables.
|
||||||
* **`osal.env_set_all(args: EnvSetAll)`**: Set multiple environment variables.
|
* **`osal.env_set_all(args: EnvSetAll)`**: Set multiple environment variables.
|
||||||
* **Key Parameters**: `env` (map[string]string), `clear_before_set` (bool), `overwrite_if_exists` (bool).
|
* **Key Parameters**: `env` (map[string]string), `clear_before_set` (bool), `overwrite_if_exists` (bool).
|
||||||
* **`osal.env_get(key string) !string`**: Get an environment variable's value.
|
* **`osal.env_get(key string) !string`**: Get an environment variable's value.
|
||||||
* **`osal.env_exists(key string) !bool`**: Check if an environment variable exists.
|
* **`osal.env_exists(key string) !bool`**: Check if an environment variable exists.
|
||||||
* **`osal.env_get_default(key string, def string) string`**: Get an environment variable or a default value.
|
* **`osal.env_get_default(key string, def string) string`**: Get an environment variable or a default value.
|
||||||
* **`osal.load_env_file(file_path string) !`**: Load variables from a file.
|
* **`osal.load_env_file(file_path string) !`**: Load variables from a file.
|
||||||
|
|
||||||
## 5. Command & Profile Management
|
## 5. Command & Profile Management
|
||||||
|
|
||||||
* **`osal.cmd_add(args: CmdAddArgs) !`**: Add a binary to system paths and update profiles.
|
* **`osal.cmd_add(args: CmdAddArgs) !`**: Add a binary to system paths and update profiles.
|
||||||
* **Key Parameters**: `source` (string, required), `cmdname` (string).
|
* **Key Parameters**: `source` (string, required), `cmdname` (string).
|
||||||
* **`osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`**: Add/remove paths from profiles.
|
* **`osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`**: Add/remove paths from profiles.
|
||||||
* **Key Parameters**: `paths2add` (string), `paths2delete` (string).
|
* **Key Parameters**: `paths2add` (string), `paths2delete` (string).
|
||||||
|
|
||||||
## 6. System Information & Utilities
|
## 6. System Information & Utilities
|
||||||
|
|
||||||
* **`osal.processmap_get() !ProcessMap`**: Get a map of all running processes.
|
* **`osal.processmap_get() !ProcessMap`**: Get a map of all running processes.
|
||||||
* **`osal.processinfo_get(pid int) !ProcessInfo`**: Get detailed information for a specific process.
|
* **`osal.processinfo_get(pid int) !ProcessInfo`**: Get detailed information for a specific process.
|
||||||
* **`osal.processinfo_get_byname(name string) ![]ProcessInfo`**: Get info for processes matching a name.
|
* **`osal.processinfo_get_byname(name string) ![]ProcessInfo`**: Get info for processes matching a name.
|
||||||
* **`osal.process_exists(pid int) bool`**: Check if a process exists by PID.
|
* **`osal.process_exists(pid int) bool`**: Check if a process exists by PID.
|
||||||
* **`osal.processinfo_with_children(pid int) !ProcessMap`**: Get a process and its children.
|
* **`osal.processinfo_with_children(pid int) !ProcessMap`**: Get a process and its children.
|
||||||
* **`osal.processinfo_children(pid int) !ProcessMap`**: Get children of a process.
|
* **`osal.processinfo_children(pid int) !ProcessMap`**: Get children of a process.
|
||||||
* **`osal.process_kill_recursive(args: ProcessKillArgs) !`**: Kill a process and its children.
|
* **`osal.process_kill_recursive(args: ProcessKillArgs) !`**: Kill a process and its children.
|
||||||
* **Key Parameters**: `name` (string), `pid` (int).
|
* **Key Parameters**: `name` (string), `pid` (int).
|
||||||
* **`osal.whoami() !string`**: Return the current username.
|
* **`osal.whoami() !string`**: Return the current username.
|
||||||
* **`osal.platform() !PlatformType`**: Identify the operating system.
|
* ~~**`osal.platform() !PlatformType`**: Identify the operating system.~~ → **Moved to `incubaid.herolib.core`**
|
||||||
* **`osal.cputype() !CPUType`**: Identify the CPU architecture.
|
* ~~**`osal.cputype() !CPUType`**: Identify the CPU architecture.~~ → **Moved to `incubaid.herolib.core`**
|
||||||
* **`osal.hostname() !string`**: Get system hostname.
|
* **`osal.hostname() !string`**: Get system hostname.
|
||||||
* **`osal.sleep(duration int)`**: Pause execution for a specified duration.
|
* **`osal.sleep(duration int)`**: Pause execution for a specified duration.
|
||||||
* **`osal.download(args: DownloadArgs) !pathlib.Path`**: Download a file from a URL.
|
* **`osal.download(args: DownloadArgs) !pathlib.Path`**: Download a file from a URL.
|
||||||
* `pathlib.Path` is from `freeflowuniverse.herolib.core.pathlib`
|
* `pathlib.Path` is from `incubaid.herolib.core.pathlib`
|
||||||
* **Key Parameters**: `url` (string), `dest` (string), `timeout` (int), `retry` (int).
|
* **Key Parameters**: `url` (string), `dest` (string), `timeout` (int), `retry` (int).
|
||||||
* **`osal.user_exists(username string) bool`**: Check if a user exists.
|
* **`osal.user_exists(username string) bool`**: Check if a user exists.
|
||||||
* **`osal.user_id_get(username string) !int`**: Get user ID.
|
* **`osal.user_id_get(username string) !int`**: Get user ID.
|
||||||
* **`osal.user_add(args: UserArgs) !int`**: Add a user.
|
* **`osal.user_add(args: UserArgs) !int`**: Add a user.
|
||||||
* **Key Parameters**: `name` (string).
|
* **Key Parameters**: `name` (string).
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
|
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- Create time objects from strings or current time
|
- Create time objects from strings or current time
|
||||||
- Relative time expressions (e.g., `+1h`, `-2d`)
|
- Relative time expressions (e.g., `+1h`, `-2d`)
|
||||||
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
|
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
|
||||||
@@ -12,7 +13,7 @@ The `OurTime` module in V provides flexible time handling, supporting relative a
|
|||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.data.ourtime
|
import incubaid.herolib.data.ourtime
|
||||||
|
|
||||||
// Current time
|
// Current time
|
||||||
mut t := ourtime.now()
|
mut t := ourtime.now()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ This document details the `paramsparser` module, essential for handling paramete
|
|||||||
## Obtaining a `paramsparser` Instance
|
## Obtaining a `paramsparser` Instance
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.data.paramsparser
|
import incubaid.herolib.data.paramsparser
|
||||||
|
|
||||||
// Create new params from a string
|
// Create new params from a string
|
||||||
params := paramsparser.new("color:red size:'large' priority:1 enable:true")!
|
params := paramsparser.new("color:red size:'large' priority:1 enable:true")!
|
||||||
@@ -19,12 +19,13 @@ params.set("color", "red")
|
|||||||
|
|
||||||
The parser supports various input formats:
|
The parser supports various input formats:
|
||||||
|
|
||||||
1. **Key-value pairs**: `key:value`
|
1. **Key-value pairs**: `key:value`
|
||||||
2. **Quoted values**: `key:'value with spaces'` (single or double quotes)
|
2. **Quoted values**: `key:'value with spaces'` (single or double quotes)
|
||||||
3. **Arguments without keys**: `arg1 arg2` (accessed by index)
|
3. **Arguments without keys**: `arg1 arg2` (accessed by index)
|
||||||
4. **Comments**: `// this is a comment` (ignored during parsing)
|
4. **Comments**: `// this is a comment` (ignored during parsing)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
text := "name:'John Doe' age:30 active:true // user details"
|
text := "name:'John Doe' age:30 active:true // user details"
|
||||||
params := paramsparser.new(text)!
|
params := paramsparser.new(text)!
|
||||||
@@ -36,74 +37,74 @@ The `paramsparser` module provides a comprehensive set of methods for retrieving
|
|||||||
|
|
||||||
### Basic Retrieval
|
### Basic Retrieval
|
||||||
|
|
||||||
- `get(key string) !string`: Retrieves a string value by key. Returns an error if the key does not exist.
|
- `get(key string) !string`: Retrieves a string value by key. Returns an error if the key does not exist.
|
||||||
- `get_default(key string, defval string) !string`: Retrieves a string value by key, or returns `defval` if the key is not found.
|
- `get_default(key string, defval string) !string`: Retrieves a string value by key, or returns `defval` if the key is not found.
|
||||||
- `exists(key string) bool`: Checks if a keyword argument (`key:value`) exists.
|
- `exists(key string) bool`: Checks if a keyword argument (`key:value`) exists.
|
||||||
- `exists_arg(key string) bool`: Checks if an argument (value without a key) exists.
|
- `exists_arg(key string) bool`: Checks if an argument (value without a key) exists.
|
||||||
|
|
||||||
### Argument Retrieval (Positional)
|
### Argument Retrieval (Positional)
|
||||||
|
|
||||||
- `get_arg(nr int) !string`: Retrieves an argument by its 0-based index. Returns an error if the index is out of bounds.
|
- `get_arg(nr int) !string`: Retrieves an argument by its 0-based index. Returns an error if the index is out of bounds.
|
||||||
- `get_arg_default(nr int, defval string) !string`: Retrieves an argument by index, or returns `defval` if the index is out of bounds.
|
- `get_arg_default(nr int, defval string) !string`: Retrieves an argument by index, or returns `defval` if the index is out of bounds.
|
||||||
|
|
||||||
### Type-Specific Retrieval
|
### Type-Specific Retrieval
|
||||||
|
|
||||||
- `get_int(key string) !int`: Converts and retrieves an integer (int32).
|
- `get_int(key string) !int`: Converts and retrieves an integer (int32).
|
||||||
- `get_int_default(key string, defval int) !int`: Retrieves an integer with a default.
|
- `get_int_default(key string, defval int) !int`: Retrieves an integer with a default.
|
||||||
- `get_u32(key string) !u32`: Converts and retrieves an unsigned 32-bit integer.
|
- `get_u32(key string) !u32`: Converts and retrieves an unsigned 32-bit integer.
|
||||||
- `get_u32_default(key string, defval u32) !u32`: Retrieves a u32 with a default.
|
- `get_u32_default(key string, defval u32) !u32`: Retrieves a u32 with a default.
|
||||||
- `get_u64(key string) !u64`: Converts and retrieves an unsigned 64-bit integer.
|
- `get_u64(key string) !u64`: Converts and retrieves an unsigned 64-bit integer.
|
||||||
- `get_u64_default(key string, defval u64) !u64`: Retrieves a u64 with a default.
|
- `get_u64_default(key string, defval u64) !u64`: Retrieves a u64 with a default.
|
||||||
- `get_u8(key string) !u8`: Converts and retrieves an unsigned 8-bit integer.
|
- `get_u8(key string) !u8`: Converts and retrieves an unsigned 8-bit integer.
|
||||||
- `get_u8_default(key string, defval u8) !u8`: Retrieves a u8 with a default.
|
- `get_u8_default(key string, defval u8) !u8`: Retrieves a u8 with a default.
|
||||||
- `get_float(key string) !f64`: Converts and retrieves a 64-bit float.
|
- `get_float(key string) !f64`: Converts and retrieves a 64-bit float.
|
||||||
- `get_float_default(key string, defval f64) !f64`: Retrieves a float with a default.
|
- `get_float_default(key string, defval f64) !f64`: Retrieves a float with a default.
|
||||||
- `get_percentage(key string) !f64`: Converts a percentage string (e.g., "80%") to a float (0.8).
|
- `get_percentage(key string) !f64`: Converts a percentage string (e.g., "80%") to a float (0.8).
|
||||||
- `get_percentage_default(key string, defval string) !f64`: Retrieves a percentage with a default.
|
- `get_percentage_default(key string, defval string) !f64`: Retrieves a percentage with a default.
|
||||||
|
|
||||||
### Boolean Retrieval
|
### Boolean Retrieval
|
||||||
|
|
||||||
- `get_default_true(key string) bool`: Returns `true` if the value is empty, "1", "true", "y", or "yes". Otherwise `false`.
|
- `get_default_true(key string) bool`: Returns `true` if the value is empty, "1", "true", "y", or "yes". Otherwise `false`.
|
||||||
- `get_default_false(key string) bool`: Returns `false` if the value is empty, "0", "false", "n", or "no". Otherwise `true`.
|
- `get_default_false(key string) bool`: Returns `false` if the value is empty, "0", "false", "n", or "no". Otherwise `true`.
|
||||||
|
|
||||||
### List Retrieval
|
### List Retrieval
|
||||||
|
|
||||||
Lists are typically comma-separated strings (e.g., `users: "john,jane,bob"`).
|
Lists are typically comma-separated strings (e.g., `users: "john,jane,bob"`).
|
||||||
|
|
||||||
- `get_list(key string) ![]string`: Retrieves a list of strings.
|
- `get_list(key string) ![]string`: Retrieves a list of strings.
|
||||||
- `get_list_default(key string, def []string) ![]string`: Retrieves a list of strings with a default.
|
- `get_list_default(key string, def []string) ![]string`: Retrieves a list of strings with a default.
|
||||||
- `get_list_int(key string) ![]int`: Retrieves a list of integers.
|
- `get_list_int(key string) ![]int`: Retrieves a list of integers.
|
||||||
- `get_list_int_default(key string, def []int) []int`: Retrieves a list of integers with a default.
|
- `get_list_int_default(key string, def []int) []int`: Retrieves a list of integers with a default.
|
||||||
- `get_list_f32(key string) ![]f32`: Retrieves a list of 32-bit floats.
|
- `get_list_f32(key string) ![]f32`: Retrieves a list of 32-bit floats.
|
||||||
- `get_list_f32_default(key string, def []f32) []f32`: Retrieves a list of f32 with a default.
|
- `get_list_f32_default(key string, def []f32) []f32`: Retrieves a list of f32 with a default.
|
||||||
- `get_list_f64(key string) ![]f64`: Retrieves a list of 64-bit floats.
|
- `get_list_f64(key string) ![]f64`: Retrieves a list of 64-bit floats.
|
||||||
- `get_list_f64_default(key string, def []f64) []f64`: Retrieves a list of f64 with a default.
|
- `get_list_f64_default(key string, def []f64) []f64`: Retrieves a list of f64 with a default.
|
||||||
- `get_list_i8(key string) ![]i8`: Retrieves a list of 8-bit signed integers.
|
- `get_list_i8(key string) ![]i8`: Retrieves a list of 8-bit signed integers.
|
||||||
- `get_list_i8_default(key string, def []i8) []i8`: Retrieves a list of i8 with a default.
|
- `get_list_i8_default(key string, def []i8) []i8`: Retrieves a list of i8 with a default.
|
||||||
- `get_list_i16(key string) ![]i16`: Retrieves a list of 16-bit signed integers.
|
- `get_list_i16(key string) ![]i16`: Retrieves a list of 16-bit signed integers.
|
||||||
- `get_list_i16_default(key string, def []i16) []i16`: Retrieves a list of i16 with a default.
|
- `get_list_i16_default(key string, def []i16) []i16`: Retrieves a list of i16 with a default.
|
||||||
- `get_list_i64(key string) ![]i64`: Retrieves a list of 64-bit signed integers.
|
- `get_list_i64(key string) ![]i64`: Retrieves a list of 64-bit signed integers.
|
||||||
- `get_list_i64_default(key string, def []i64) []i64`: Retrieves a list of i64 with a default.
|
- `get_list_i64_default(key string, def []i64) []i64`: Retrieves a list of i64 with a default.
|
||||||
- `get_list_u16(key string) ![]u16`: Retrieves a list of 16-bit unsigned integers.
|
- `get_list_u16(key string) ![]u16`: Retrieves a list of 16-bit unsigned integers.
|
||||||
- `get_list_u16_default(key string, def []u16) []u16`: Retrieves a list of u16 with a default.
|
- `get_list_u16_default(key string, def []u16) []u16`: Retrieves a list of u16 with a default.
|
||||||
- `get_list_u32(key string) ![]u32`: Retrieves a list of 32-bit unsigned integers.
|
- `get_list_u32(key string) ![]u32`: Retrieves a list of 32-bit unsigned integers.
|
||||||
- `get_list_u32_default(key string, def []u32) []u32`: Retrieves a list of u32 with a default.
|
- `get_list_u32_default(key string, def []u32) []u32`: Retrieves a list of u32 with a default.
|
||||||
- `get_list_u64(key string) ![]u64`: Retrieves a list of 64-bit unsigned integers.
|
- `get_list_u64(key string) ![]u64`: Retrieves a list of 64-bit unsigned integers.
|
||||||
- `get_list_u64_default(key string, def []u64) []u64`: Retrieves a list of u64 with a default.
|
- `get_list_u64_default(key string, def []u64) []u64`: Retrieves a list of u64 with a default.
|
||||||
- `get_list_namefix(key string) ![]string`: Retrieves a list of strings, normalizing each item (e.g., "My Name" -> "my_name").
|
- `get_list_namefix(key string) ![]string`: Retrieves a list of strings, normalizing each item (e.g., "My Name" -> "my_name").
|
||||||
- `get_list_namefix_default(key string, def []string) ![]string`: Retrieves a list of name-fixed strings with a default.
|
- `get_list_namefix_default(key string, def []string) ![]string`: Retrieves a list of name-fixed strings with a default.
|
||||||
|
|
||||||
### Specialized Retrieval
|
### Specialized Retrieval
|
||||||
|
|
||||||
- `get_map() map[string]string`: Returns all parameters as a map.
|
- `get_map() map[string]string`: Returns all parameters as a map.
|
||||||
- `get_path(key string) !string`: Retrieves a path string.
|
- `get_path(key string) !string`: Retrieves a path string.
|
||||||
- `get_path_create(key string) !string`: Retrieves a path string, creating the directory if it doesn't exist.
|
- `get_path_create(key string) !string`: Retrieves a path string, creating the directory if it doesn't exist.
|
||||||
- `get_from_hashmap(key string, defval string, hashmap map[string]string) !string`: Retrieves a value from a provided hashmap based on the parameter's value.
|
- `get_from_hashmap(key string, defval string, hashmap map[string]string) !string`: Retrieves a value from a provided hashmap based on the parameter's value.
|
||||||
- `get_storagecapacity_in_bytes(key string) !u64`: Converts storage capacity strings (e.g., "10 GB", "500 MB") to bytes (u64).
|
- `get_storagecapacity_in_bytes(key string) !u64`: Converts storage capacity strings (e.g., "10 GB", "500 MB") to bytes (u64).
|
||||||
- `get_storagecapacity_in_bytes_default(key string, defval u64) !u64`: Retrieves storage capacity in bytes with a default.
|
- `get_storagecapacity_in_bytes_default(key string, defval u64) !u64`: Retrieves storage capacity in bytes with a default.
|
||||||
- `get_storagecapacity_in_gigabytes(key string) !u64`: Converts storage capacity strings to gigabytes (u64).
|
- `get_storagecapacity_in_gigabytes(key string) !u64`: Converts storage capacity strings to gigabytes (u64).
|
||||||
- `get_time(key string) !ourtime.OurTime`: Parses a time string (relative or absolute) into an `ourtime.OurTime` object.
|
- `get_time(key string) !ourtime.OurTime`: Parses a time string (relative or absolute) into an `ourtime.OurTime` object.
|
||||||
- `get_time_default(key string, defval ourtime.OurTime) !ourtime.OurTime`: Retrieves time with a default.
|
- `get_time_default(key string, defval ourtime.OurTime) !ourtime.OurTime`: Retrieves time with a default.
|
||||||
- `get_time_interval(key string) !Duration`: Parses a time interval string into a `Duration` object.
|
- `get_time_interval(key string) !Duration`: Parses a time interval string into a `Duration` object.
|
||||||
- `get_timestamp(key string) !Duration`: Parses a timestamp string into a `Duration` object.
|
- `get_timestamp(key string) !Duration`: Parses a timestamp string into a `Duration` object.
|
||||||
- `get_timestamp_default(key string, defval Duration) !Duration`: Retrieves a timestamp with a default.
|
- `get_timestamp_default(key string, defval Duration) !Duration`: Retrieves a timestamp with a default.
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ The pathlib module provides a comprehensive interface for handling file system o
|
|||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
### Importing pathlib
|
### Importing pathlib
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating Path Objects
|
### Creating Path Objects
|
||||||
@@ -33,6 +34,7 @@ mut dir_path := pathlib.get("path/to/directory")
|
|||||||
if you know in advance if you expect a dir or file its better to use `pathlib.get_dir(path:...,create:true)` or `pathlib.get_file(path:...,create:true)`.
|
if you know in advance if you expect a dir or file its better to use `pathlib.get_dir(path:...,create:true)` or `pathlib.get_file(path:...,create:true)`.
|
||||||
|
|
||||||
### Basic Path Operations
|
### Basic Path Operations
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Get absolute path
|
// Get absolute path
|
||||||
abs_path := file_path.absolute()
|
abs_path := file_path.absolute()
|
||||||
@@ -49,6 +51,7 @@ if file_path.exists() {
|
|||||||
## Path Properties and Methods
|
## Path Properties and Methods
|
||||||
|
|
||||||
### Path Types
|
### Path Types
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Check if path is a file
|
// Check if path is a file
|
||||||
if file_path.is_file() {
|
if file_path.is_file() {
|
||||||
@@ -67,6 +70,7 @@ if file_path.is_link() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Path Normalization
|
### Path Normalization
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Normalize path (remove extra slashes, resolve . and ..)
|
// Normalize path (remove extra slashes, resolve . and ..)
|
||||||
normalized_path := file_path.path_normalize()
|
normalized_path := file_path.path_normalize()
|
||||||
@@ -81,6 +85,7 @@ name_no_ext := file_path.name_no_ext()
|
|||||||
## File and Directory Operations
|
## File and Directory Operations
|
||||||
|
|
||||||
### File Operations
|
### File Operations
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Write to file
|
// Write to file
|
||||||
file_path.write("Content to write")!
|
file_path.write("Content to write")!
|
||||||
@@ -93,6 +98,7 @@ file_path.delete()!
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Directory Operations
|
### Directory Operations
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Create directory
|
// Create directory
|
||||||
mut dir := pathlib.get_dir(
|
mut dir := pathlib.get_dir(
|
||||||
@@ -108,6 +114,7 @@ dir.delete()!
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Symlink Operations
|
### Symlink Operations
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Create symlink
|
// Create symlink
|
||||||
file_path.link("path/to/symlink", delete_exists: true)!
|
file_path.link("path/to/symlink", delete_exists: true)!
|
||||||
@@ -119,12 +126,14 @@ real_path := file_path.realpath()
|
|||||||
## Advanced Operations
|
## Advanced Operations
|
||||||
|
|
||||||
### Path Copying
|
### Path Copying
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Copy file to destination
|
// Copy file to destination
|
||||||
file_path.copy(dest: "path/to/destination")!
|
file_path.copy(dest: "path/to/destination")!
|
||||||
```
|
```
|
||||||
|
|
||||||
### Recursive Operations
|
### Recursive Operations
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// List directory recursively
|
// List directory recursively
|
||||||
mut recursive_list := dir.list(recursive: true)!
|
mut recursive_list := dir.list(recursive: true)!
|
||||||
@@ -134,6 +143,7 @@ dir.delete()!
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Path Filtering
|
### Path Filtering
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// List files matching pattern
|
// List files matching pattern
|
||||||
mut filtered_list := dir.list(
|
mut filtered_list := dir.list(
|
||||||
@@ -145,6 +155,7 @@ mut filtered_list := dir.list(
|
|||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
### Error Handling
|
### Error Handling
|
||||||
|
|
||||||
```v
|
```v
|
||||||
if file_path.exists() {
|
if file_path.exists() {
|
||||||
// Safe to operate
|
// Safe to operate
|
||||||
@@ -152,4 +163,3 @@ if file_path.exists() {
|
|||||||
// Handle missing file
|
// Handle missing file
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ The `redisclient` module in Herolib provides a comprehensive client for interact
|
|||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- **Direct Redis Commands**: Access to a wide range of Redis commands (strings, hashes, lists, keys, etc.).
|
- **Direct Redis Commands**: Access to a wide range of Redis commands (strings, hashes, lists, keys, etc.).
|
||||||
- **Caching**: Built-in caching mechanism with namespace support and expiration.
|
- **Caching**: Built-in caching mechanism with namespace support and expiration.
|
||||||
- **Queues**: Simple queue implementation using Redis lists.
|
- **Queues**: Simple queue implementation using Redis lists.
|
||||||
- **RPC**: Remote Procedure Call (RPC) functionality over Redis queues for inter-service communication.
|
- **RPC**: Remote Procedure Call (RPC) functionality over Redis queues for inter-service communication.
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
To get a Redis client instance, use `redisclient.core_get()`. By default, it connects to `127.0.0.1:6379`. You can specify a different address and port using the `RedisURL` struct.
|
To get a Redis client instance, use `redisclient.core_get()`. By default, it connects to `127.0.0.1:6379`. You can specify a different address and port using the `RedisURL` struct.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.redisclient
|
import incubaid.herolib.core.redisclient
|
||||||
|
|
||||||
// Connect to default Redis instance (127.0.0.1:6379)
|
// Connect to default Redis instance (127.0.0.1:6379)
|
||||||
mut redis := redisclient.core_get()!
|
mut redis := redisclient.core_get()!
|
||||||
@@ -42,13 +42,13 @@ The `Redis` object provides methods for most standard Redis commands. Here are s
|
|||||||
|
|
||||||
### String Commands
|
### String Commands
|
||||||
|
|
||||||
- `set(key string, value string) !`: Sets the string value of a key.
|
- `set(key string, value string) !`: Sets the string value of a key.
|
||||||
- `get(key string) !string`: Gets the string value of a key.
|
- `get(key string) !string`: Gets the string value of a key.
|
||||||
- `set_ex(key string, value string, ex string) !`: Sets a key with an expiration time in seconds.
|
- `set_ex(key string, value string, ex string) !`: Sets a key with an expiration time in seconds.
|
||||||
- `incr(key string) !int`: Increments the integer value of a key by one.
|
- `incr(key string) !int`: Increments the integer value of a key by one.
|
||||||
- `decr(key string) !int`: Decrements the integer value of a key by one.
|
- `decr(key string) !int`: Decrements the integer value of a key by one.
|
||||||
- `append(key string, value string) !int`: Appends a value to a key.
|
- `append(key string, value string) !int`: Appends a value to a key.
|
||||||
- `strlen(key string) !int`: Gets the length of the value stored in a key.
|
- `strlen(key string) !int`: Gets the length of the value stored in a key.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
redis.set('counter', '10')!
|
redis.set('counter', '10')!
|
||||||
@@ -58,11 +58,11 @@ val := redis.get('counter')! // "11"
|
|||||||
|
|
||||||
### Hash Commands
|
### Hash Commands
|
||||||
|
|
||||||
- `hset(key string, skey string, value string) !`: Sets the string value of a hash field.
|
- `hset(key string, skey string, value string) !`: Sets the string value of a hash field.
|
||||||
- `hget(key string, skey string) !string`: Gets the value of a hash field.
|
- `hget(key string, skey string) !string`: Gets the value of a hash field.
|
||||||
- `hgetall(key string) !map[string]string`: Gets all fields and values in a hash.
|
- `hgetall(key string) !map[string]string`: Gets all fields and values in a hash.
|
||||||
- `hexists(key string, skey string) !bool`: Checks if a hash field exists.
|
- `hexists(key string, skey string) !bool`: Checks if a hash field exists.
|
||||||
- `hdel(key string, skey string) !int`: Deletes one or more hash fields.
|
- `hdel(key string, skey string) !int`: Deletes one or more hash fields.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
redis.hset('user:1', 'name', 'John Doe')!
|
redis.hset('user:1', 'name', 'John Doe')!
|
||||||
@@ -73,12 +73,12 @@ user_data := redis.hgetall('user:1')! // map['name':'John Doe', 'email':'john@ex
|
|||||||
|
|
||||||
### List Commands
|
### List Commands
|
||||||
|
|
||||||
- `lpush(key string, element string) !int`: Inserts all specified values at the head of the list stored at key.
|
- `lpush(key string, element string) !int`: Inserts all specified values at the head of the list stored at key.
|
||||||
- `rpush(key string, element string) !int`: Inserts all specified values at the tail of the list stored at key.
|
- `rpush(key string, element string) !int`: Inserts all specified values at the tail of the list stored at key.
|
||||||
- `lpop(key string) !string`: Removes and returns the first element of the list stored at key.
|
- `lpop(key string) !string`: Removes and returns the first element of the list stored at key.
|
||||||
- `rpop(key string) !string`: Removes and returns the last element of the list stored at key.
|
- `rpop(key string) !string`: Removes and returns the last element of the list stored at key.
|
||||||
- `llen(key string) !int`: Gets the length of a list.
|
- `llen(key string) !int`: Gets the length of a list.
|
||||||
- `lrange(key string, start int, end int) ![]resp.RValue`: Gets a range of elements from a list.
|
- `lrange(key string, start int, end int) ![]resp.RValue`: Gets a range of elements from a list.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
redis.lpush('mylist', 'item1')!
|
redis.lpush('mylist', 'item1')!
|
||||||
@@ -88,8 +88,8 @@ first_item := redis.lpop('mylist')! // "item1"
|
|||||||
|
|
||||||
### Set Commands
|
### Set Commands
|
||||||
|
|
||||||
- `sadd(key string, members []string) !int`: Adds the specified members to the set stored at key.
|
- `sadd(key string, members []string) !int`: Adds the specified members to the set stored at key.
|
||||||
- `smismember(key string, members []string) ![]int`: Returns if member is a member of the set stored at key.
|
- `smismember(key string, members []string) ![]int`: Returns if member is a member of the set stored at key.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
redis.sadd('myset', ['member1', 'member2'])!
|
redis.sadd('myset', ['member1', 'member2'])!
|
||||||
@@ -98,13 +98,13 @@ is_member := redis.smismember('myset', ['member1', 'member3'])! // [1, 0]
|
|||||||
|
|
||||||
### Key Management
|
### Key Management
|
||||||
|
|
||||||
- `keys(pattern string) ![]string`: Finds all keys matching the given pattern.
|
- `keys(pattern string) ![]string`: Finds all keys matching the given pattern.
|
||||||
- `del(key string) !int`: Deletes a key.
|
- `del(key string) !int`: Deletes a key.
|
||||||
- `expire(key string, seconds int) !int`: Sets a key's time to live in seconds.
|
- `expire(key string, seconds int) !int`: Sets a key's time to live in seconds.
|
||||||
- `ttl(key string) !int`: Gets the time to live for a key in seconds.
|
- `ttl(key string) !int`: Gets the time to live for a key in seconds.
|
||||||
- `flushall() !`: Deletes all the keys of all the existing databases.
|
- `flushall() !`: Deletes all the keys of all the existing databases.
|
||||||
- `flushdb() !`: Deletes all the keys of the currently selected database.
|
- `flushdb() !`: Deletes all the keys of the currently selected database.
|
||||||
- `selectdb(database int) !`: Changes the selected database.
|
- `selectdb(database int) !`: Changes the selected database.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
redis.set('temp_key', 'value')!
|
redis.set('temp_key', 'value')!
|
||||||
@@ -116,7 +116,7 @@ redis.expire('temp_key', 60)! // Expires in 60 seconds
|
|||||||
The `RedisCache` struct provides a convenient way to implement caching using Redis.
|
The `RedisCache` struct provides a convenient way to implement caching using Redis.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.redisclient
|
import incubaid.herolib.core.redisclient
|
||||||
|
|
||||||
mut redis := redisclient.core_get()!
|
mut redis := redisclient.core_get()!
|
||||||
mut cache := redis.cache('my_app_cache')
|
mut cache := redis.cache('my_app_cache')
|
||||||
@@ -145,7 +145,7 @@ cache.reset()!
|
|||||||
The `RedisQueue` struct provides a simple queue mechanism using Redis lists.
|
The `RedisQueue` struct provides a simple queue mechanism using Redis lists.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.redisclient
|
import incubaid.herolib.core.redisclient
|
||||||
import time
|
import time
|
||||||
|
|
||||||
mut redis := redisclient.core_get()!
|
mut redis := redisclient.core_get()!
|
||||||
@@ -169,7 +169,7 @@ task2 := my_queue.pop()!
|
|||||||
The `RedisRpc` struct enables Remote Procedure Call (RPC) over Redis, allowing services to communicate by sending messages to queues and waiting for responses.
|
The `RedisRpc` struct enables Remote Procedure Call (RPC) over Redis, allowing services to communicate by sending messages to queues and waiting for responses.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.redisclient
|
import incubaid.herolib.core.redisclient
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -201,4 +201,4 @@ response := rpc_client.call(
|
|||||||
// In a real application, this would be in a loop or a background worker
|
// In a real application, this would be in a loop or a background worker
|
||||||
// return_queue_name := rpc_client.process(my_rpc_processor, timeout: 1000)!
|
// return_queue_name := rpc_client.process(my_rpc_processor, timeout: 1000)!
|
||||||
// result := rpc_client.result(1000, return_queue_name)!
|
// result := rpc_client.result(1000, return_queue_name)!
|
||||||
// println('Processed result: ${result}')
|
// println('Processed result: ${result}')
|
||||||
|
|||||||
@@ -2,96 +2,124 @@
|
|||||||
|
|
||||||
The `texttools` module provides a comprehensive set of utilities for text manipulation and processing.
|
The `texttools` module provides a comprehensive set of utilities for text manipulation and processing.
|
||||||
|
|
||||||
## Functions and Examples:
|
## Functions and Examples
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.core.texttools
|
import incubaid.herolib.core.texttools
|
||||||
|
|
||||||
assert hello_world == texttools.name_fix("Hello World!")
|
assert hello_world == texttools.name_fix("Hello World!")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Name/Path Processing
|
### Name/Path Processing
|
||||||
* `name_fix(name string) string`: Normalizes filenames and paths.
|
|
||||||
* `name_fix_keepspace(name string) !string`: Like name_fix but preserves spaces.
|
* `name_fix(name string) string`: Normalizes filenames and paths.
|
||||||
* `name_fix_no_ext(name_ string) string`: Removes file extension.
|
* `name_fix_keepspace(name string) !string`: Like name_fix but preserves spaces.
|
||||||
* `name_fix_snake_to_pascal(name string) string`: Converts snake_case to PascalCase.
|
* `name_fix_no_ext(name_ string) string`: Removes file extension.
|
||||||
|
* `name_fix_snake_to_pascal(name string) string`: Converts snake_case to PascalCase.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
name := texttools.name_fix_snake_to_pascal("hello_world") // Result: "HelloWorld"
|
name := texttools.name_fix_snake_to_pascal("hello_world") // Result: "HelloWorld"
|
||||||
```
|
```
|
||||||
* `snake_case(name string) string`: Converts PascalCase to snake_case.
|
|
||||||
|
* `snake_case(name string) string`: Converts PascalCase to snake_case.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
name := texttools.snake_case("HelloWorld") // Result: "hello_world"
|
name := texttools.snake_case("HelloWorld") // Result: "hello_world"
|
||||||
```
|
```
|
||||||
* `name_split(name string) !(string, string)`: Splits name into site and page components.
|
|
||||||
|
|
||||||
|
* `name_split(name string) !(string, string)`: Splits name into site and page components.
|
||||||
|
|
||||||
### Text Cleaning
|
### Text Cleaning
|
||||||
* `name_clean(r string) string`: Normalizes names by removing special characters.
|
|
||||||
|
* `name_clean(r string) string`: Normalizes names by removing special characters.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
name := texttools.name_clean("Hello@World!") // Result: "HelloWorld"
|
name := texttools.name_clean("Hello@World!") // Result: "HelloWorld"
|
||||||
```
|
```
|
||||||
* `ascii_clean(r string) string`: Removes all non-ASCII characters.
|
|
||||||
* `remove_empty_lines(text string) string`: Removes empty lines from text.
|
* `ascii_clean(r string) string`: Removes all non-ASCII characters.
|
||||||
|
* `remove_empty_lines(text string) string`: Removes empty lines from text.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
text := texttools.remove_empty_lines("line1\n\nline2\n\n\nline3") // Result: "line1\nline2\nline3"
|
text := texttools.remove_empty_lines("line1\n\nline2\n\n\nline3") // Result: "line1\nline2\nline3"
|
||||||
```
|
```
|
||||||
* `remove_double_lines(text string) string`: Removes consecutive empty lines.
|
|
||||||
* `remove_empty_js_blocks(text string) string`: Removes empty code blocks (```...```).
|
* `remove_double_lines(text string) string`: Removes consecutive empty lines.
|
||||||
|
* `remove_empty_js_blocks(text string) string`: Removes empty code blocks (```...```).
|
||||||
|
|
||||||
### Command Line Parsing
|
### Command Line Parsing
|
||||||
* `cmd_line_args_parser(text string) ![]string`: Parses command line arguments with support for quotes and escaping.
|
|
||||||
|
* `cmd_line_args_parser(text string) ![]string`: Parses command line arguments with support for quotes and escaping.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
args := texttools.cmd_line_args_parser("'arg with spaces' --flag=value") // Result: ['arg with spaces', '--flag=value']
|
args := texttools.cmd_line_args_parser("'arg with spaces' --flag=value") // Result: ['arg with spaces', '--flag=value']
|
||||||
```
|
```
|
||||||
* `text_remove_quotes(text string) string`: Removes quoted sections from text.
|
|
||||||
* `check_exists_outside_quotes(text string, items []string) bool`: Checks if items exist in text outside of quotes.
|
* `text_remove_quotes(text string) string`: Removes quoted sections from text.
|
||||||
|
* `check_exists_outside_quotes(text string, items []string) bool`: Checks if items exist in text outside of quotes.
|
||||||
|
|
||||||
### Text Expansion
|
### Text Expansion
|
||||||
* `expand(txt_ string, l int, expand_with string) string`: Expands text to a specified length with a given character.
|
|
||||||
|
* `expand(txt_ string, l int, expand_with string) string`: Expands text to a specified length with a given character.
|
||||||
|
|
||||||
### Indentation
|
### Indentation
|
||||||
* `indent(text string, prefix string) string`: Adds indentation prefix to each line.
|
|
||||||
|
* `indent(text string, prefix string) string`: Adds indentation prefix to each line.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
text := texttools.indent("line1\nline2", " ") // Result: " line1\n line2\n"
|
text := texttools.indent("line1\nline2", " ") // Result: " line1\n line2\n"
|
||||||
```
|
```
|
||||||
* `dedent(text string) string`: Removes common leading whitespace from every line.
|
|
||||||
|
* `dedent(text string) string`: Removes common leading whitespace from every line.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
text := texttools.dedent(" line1\n line2") // Result: "line1\nline2"
|
text := texttools.dedent(" line1\n line2") // Result: "line1\nline2"
|
||||||
```
|
```
|
||||||
|
|
||||||
### String Validation
|
### String Validation
|
||||||
* `is_int(text string) bool`: Checks if text contains only digits.
|
|
||||||
* `is_upper_text(text string) bool`: Checks if text contains only uppercase letters.
|
* `is_int(text string) bool`: Checks if text contains only digits.
|
||||||
|
* `is_upper_text(text string) bool`: Checks if text contains only uppercase letters.
|
||||||
|
|
||||||
### Multiline Processing
|
### Multiline Processing
|
||||||
* `multiline_to_single(text string) !string`: Converts multiline text to a single line with proper escaping.
|
|
||||||
|
* `multiline_to_single(text string) !string`: Converts multiline text to a single line with proper escaping.
|
||||||
|
|
||||||
### Text Splitting
|
### Text Splitting
|
||||||
* `split_smart(t string, delimiter_ string) []string`: Intelligent string splitting that respects quotes.
|
|
||||||
|
* `split_smart(t string, delimiter_ string) []string`: Intelligent string splitting that respects quotes.
|
||||||
|
|
||||||
### Tokenization
|
### Tokenization
|
||||||
* `tokenize(text_ string) TokenizerResult`: Tokenizes text into meaningful parts.
|
|
||||||
* `text_token_replace(text string, tofind string, replacewith string) !string`: Replaces tokens in text.
|
* `tokenize(text_ string) TokenizerResult`: Tokenizes text into meaningful parts.
|
||||||
|
* `text_token_replace(text string, tofind string, replacewith string) !string`: Replaces tokens in text.
|
||||||
|
|
||||||
### Version Parsing
|
### Version Parsing
|
||||||
* `version(text_ string) int`: Converts version strings to comparable integers.
|
|
||||||
|
* `version(text_ string) int`: Converts version strings to comparable integers.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
ver := texttools.version("v0.4.36") // Result: 4036
|
ver := texttools.version("v0.4.36") // Result: 4036
|
||||||
ver = texttools.version("v1.4.36") // Result: 1004036
|
ver = texttools.version("v1.4.36") // Result: 1004036
|
||||||
```
|
```
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
* `format_rfc1123(t time.Time) string`: Formats a time.Time object into RFC 1123 format.
|
|
||||||
|
|
||||||
|
|
||||||
|
* `format_rfc1123(t time.Time) string`: Formats a time.Time object into RFC 1123 format.
|
||||||
|
|
||||||
### Array Operations
|
### Array Operations
|
||||||
* `to_array(r string) []string`: Converts a comma or newline separated list to an array of strings.
|
|
||||||
|
* `to_array(r string) []string`: Converts a comma or newline separated list to an array of strings.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
text := "item1,item2,item3"
|
text := "item1,item2,item3"
|
||||||
array := texttools.to_array(text) // Result: ['item1', 'item2', 'item3']
|
array := texttools.to_array(text) // Result: ['item1', 'item2', 'item3']
|
||||||
```
|
```
|
||||||
* `to_array_int(r string) []int`: Converts a text list to an array of integers.
|
|
||||||
* `to_map(mapstring string, line string, delimiter_ string) map[string]string`: Intelligent mapping of a line to a map based on a template.
|
* `to_array_int(r string) []int`: Converts a text list to an array of integers.
|
||||||
|
* `to_map(mapstring string, line string, delimiter_ string) map[string]string`: Intelligent mapping of a line to a map based on a template.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
r := texttools.to_map("name,-,-,-,-,pid,-,-,-,-,path",
|
r := texttools.to_map("name,-,-,-,-,pid,-,-,-,-,path",
|
||||||
"root 304 0.0 0.0 408185328 1360 ?? S 16Dec23 0:34.06 /usr/sbin/distnoted")
|
"root 304 0.0 0.0 408185328 1360 ?? S 16Dec23 0:34.06 /usr/sbin/distnoted")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ has mechanisms to print better to console, see the methods below
|
|||||||
import as
|
import as
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -24,23 +24,23 @@ fn color_fg(c ForegroundColor) string
|
|||||||
|
|
||||||
struct PrintArgs {
|
struct PrintArgs {
|
||||||
pub mut:
|
pub mut:
|
||||||
foreground ForegroundColor
|
foreground ForegroundColor
|
||||||
background BackgroundColor
|
background BackgroundColor
|
||||||
text string
|
text string
|
||||||
style Style
|
style Style
|
||||||
reset_before bool = true
|
reset_before bool = true
|
||||||
reset_after bool = true
|
reset_after bool = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cprint(args PrintArgs)
|
fn cprint(args PrintArgs)
|
||||||
// print with colors, reset...
|
// print with colors, reset...
|
||||||
// ```
|
// ```
|
||||||
// foreground ForegroundColor
|
// foreground ForegroundColor
|
||||||
// background BackgroundColor
|
// background BackgroundColor
|
||||||
// text string
|
// text string
|
||||||
// style Style
|
// style Style
|
||||||
// reset_before bool = true
|
// reset_before bool = true
|
||||||
// reset_after bool = true
|
// reset_after bool = true
|
||||||
// ```
|
// ```
|
||||||
|
|
||||||
fn cprintln(args_ PrintArgs)
|
fn cprintln(args_ PrintArgs)
|
||||||
@@ -95,11 +95,11 @@ Is used to ask feedback to users
|
|||||||
|
|
||||||
struct UIConsole {
|
struct UIConsole {
|
||||||
pub mut:
|
pub mut:
|
||||||
x_max int = 80
|
x_max int = 80
|
||||||
y_max int = 60
|
y_max int = 60
|
||||||
prev_lf bool
|
prev_lf bool
|
||||||
prev_title bool
|
prev_title bool
|
||||||
prev_item bool
|
prev_item bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//DropDownArgs:
|
//DropDownArgs:
|
||||||
@@ -150,51 +150,51 @@ fn (mut c UIConsole) status() string
|
|||||||
|
|
||||||
```v
|
```v
|
||||||
enum BackgroundColor {
|
enum BackgroundColor {
|
||||||
default_color = 49 // 'default' is a reserved keyword in V
|
default_color = 49 // 'default' is a reserved keyword in V
|
||||||
black = 40
|
black = 40
|
||||||
red = 41
|
red = 41
|
||||||
green = 42
|
green = 42
|
||||||
yellow = 43
|
yellow = 43
|
||||||
blue = 44
|
blue = 44
|
||||||
magenta = 45
|
magenta = 45
|
||||||
cyan = 46
|
cyan = 46
|
||||||
light_gray = 47
|
light_gray = 47
|
||||||
dark_gray = 100
|
dark_gray = 100
|
||||||
light_red = 101
|
light_red = 101
|
||||||
light_green = 102
|
light_green = 102
|
||||||
light_yellow = 103
|
light_yellow = 103
|
||||||
light_blue = 104
|
light_blue = 104
|
||||||
light_magenta = 105
|
light_magenta = 105
|
||||||
light_cyan = 106
|
light_cyan = 106
|
||||||
white = 107
|
white = 107
|
||||||
}
|
}
|
||||||
enum ForegroundColor {
|
enum ForegroundColor {
|
||||||
default_color = 39 // 'default' is a reserved keyword in V
|
default_color = 39 // 'default' is a reserved keyword in V
|
||||||
white = 97
|
white = 97
|
||||||
black = 30
|
black = 30
|
||||||
red = 31
|
red = 31
|
||||||
green = 32
|
green = 32
|
||||||
yellow = 33
|
yellow = 33
|
||||||
blue = 34
|
blue = 34
|
||||||
magenta = 35
|
magenta = 35
|
||||||
cyan = 36
|
cyan = 36
|
||||||
light_gray = 37
|
light_gray = 37
|
||||||
dark_gray = 90
|
dark_gray = 90
|
||||||
light_red = 91
|
light_red = 91
|
||||||
light_green = 92
|
light_green = 92
|
||||||
light_yellow = 93
|
light_yellow = 93
|
||||||
light_blue = 94
|
light_blue = 94
|
||||||
light_magenta = 95
|
light_magenta = 95
|
||||||
light_cyan = 96
|
light_cyan = 96
|
||||||
}
|
}
|
||||||
enum Style {
|
enum Style {
|
||||||
normal = 99
|
normal = 99
|
||||||
bold = 1
|
bold = 1
|
||||||
dim = 2
|
dim = 2
|
||||||
underline = 4
|
underline = 4
|
||||||
blink = 5
|
blink = 5
|
||||||
reverse = 7
|
reverse = 7
|
||||||
hidden = 8
|
hidden = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ this is how we want example scripts to be, see the first line
|
|||||||
```v
|
```v
|
||||||
#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib...
|
import incubaid.herolib...
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
the files are in ~/code/github/freeflowuniverse/herolib/examples for herolib
|
the files are in ~/code/github/incubaid/herolib/examples for herolib
|
||||||
|
|
||||||
## important instructions
|
## important instructions
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ when I generate vlang scripts I will always use .vsh extension and use following
|
|||||||
As AI agent I should also execute v or .vsh scripts with vrun
|
As AI agent I should also execute v or .vsh scripts with vrun
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
vrun ~/code/github/incubaid/herolib/examples/biztools/bizmodel.vsh
|
||||||
```
|
```
|
||||||
|
|
||||||
## executing test scripts
|
## executing test scripts
|
||||||
@@ -31,7 +31,7 @@ vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
|||||||
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||||
```
|
```
|
||||||
|
|
||||||
- use ~ so it works over all machines
|
- use ~ so it works over all machines
|
||||||
|
|||||||
819
aiprompts/heromodel_instruct.md
Normal file
819
aiprompts/heromodel_instruct.md
Normal file
@@ -0,0 +1,819 @@
|
|||||||
|
# HeroModels Implementation Guide
|
||||||
|
|
||||||
|
This guide provides comprehensive instructions for creating new models in the HeroModels system, including best practices for model structure, serialization/deserialization, testing, and integration with the HeroModels factory.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Model Structure Overview](#model-structure-overview)
|
||||||
|
2. [Creating a New Model](#creating-a-new-model)
|
||||||
|
3. [Serialization and Deserialization](#serialization-and-deserialization)
|
||||||
|
4. [Database Operations](#database-operations)
|
||||||
|
5. [API Handler Implementation](#api-handler-implementation)
|
||||||
|
6. [Testing Models](#testing-models)
|
||||||
|
7. [Integration with Factory](#integration-with-factory)
|
||||||
|
8. [Advanced Features](#advanced-features)
|
||||||
|
9. [Best Practices](#best-practices)
|
||||||
|
10. [Example Implementation](#example-implementation)
|
||||||
|
|
||||||
|
## Model Structure Overview
|
||||||
|
|
||||||
|
Each model in the HeroModels system consists of several components:
|
||||||
|
|
||||||
|
1. **Model Struct**: The core data structure inheriting from `db.Base`
|
||||||
|
2. **DB Wrapper Struct**: Provides database operations for the model
|
||||||
|
3. **Argument Struct**: Used for creating and updating model instances
|
||||||
|
4. **API Handler Function**: Handles RPC calls for the model
|
||||||
|
5. **List Arguments Struct**: Used for filtering when listing instances
|
||||||
|
|
||||||
|
### Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/hero/heromodels/
|
||||||
|
├── model_name.v # Main model file
|
||||||
|
├── model_name_test.v # Tests for the model
|
||||||
|
└── factory.v # Factory integration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating a New Model
|
||||||
|
|
||||||
|
### 1. Define the Model Struct
|
||||||
|
|
||||||
|
Create a new file `model_name.v` in the `lib/hero/heromodels` directory.
|
||||||
|
|
||||||
|
```v
|
||||||
|
module heromodels
|
||||||
|
|
||||||
|
import incubaid.herolib.core.db
|
||||||
|
import incubaid.herolib.core.encoder
|
||||||
|
import incubaid.herolib.core.ourtime
|
||||||
|
import incubaid.herolib.core.jsonrpc { Response }
|
||||||
|
import json
|
||||||
|
|
||||||
|
// Model struct - inherits from db.Base
|
||||||
|
pub struct ModelName {
|
||||||
|
pub mut:
|
||||||
|
db.Base // Inherit from db.Base
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
created_at u64
|
||||||
|
updated_at u64
|
||||||
|
// Add additional fields as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeName returns the type name used for serialization
|
||||||
|
pub fn (self ModelName) type_name() string {
|
||||||
|
return 'heromodels.ModelName'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Define the Argument Struct for Model Creation/Updates
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Argument struct for creating/updating models with params attribute
|
||||||
|
@[params]
|
||||||
|
pub struct ModelNameArg {
|
||||||
|
pub mut:
|
||||||
|
id u32 // Optional for updates, ignored for creation
|
||||||
|
name string @[required] // Required field
|
||||||
|
description string
|
||||||
|
// Add additional fields as needed
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Define the List Arguments Struct for Filtering
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Arguments for filtering when listing models
|
||||||
|
@[params]
|
||||||
|
pub struct ModelNameListArg {
|
||||||
|
pub mut:
|
||||||
|
// Add filter fields (e.g., status, type, etc.)
|
||||||
|
limit int = 100 // Default limit
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Create the DB Wrapper Struct
|
||||||
|
|
||||||
|
```v
|
||||||
|
// DB Wrapper struct for database operations
|
||||||
|
pub struct DBModelName {
|
||||||
|
pub mut:
|
||||||
|
db &db.DB
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Serialization and Deserialization
|
||||||
|
|
||||||
|
Implement the `dump` and `load` methods for serialization/deserialization.
|
||||||
|
|
||||||
|
### Dump Method (Serialization)
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Dump serializes the model to the encoder
|
||||||
|
pub fn (self ModelName) dump(mut e encoder.Encoder) ! {
|
||||||
|
// Always dump the Base first
|
||||||
|
self.Base.dump(mut e)!
|
||||||
|
|
||||||
|
// Dump model-specific fields in the same order they will be loaded
|
||||||
|
e.add_string(self.name)!
|
||||||
|
e.add_string(self.description)!
|
||||||
|
e.add_u64(self.created_at)!
|
||||||
|
e.add_u64(self.updated_at)!
|
||||||
|
// Add more fields in the exact order they should be loaded
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Load Method (Deserialization)
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Load deserializes the model from the decoder
|
||||||
|
pub fn (mut self DBModelName) load(mut obj ModelName, mut d encoder.Decoder) ! {
|
||||||
|
// Always load the Base first
|
||||||
|
obj.Base.load(mut d)!
|
||||||
|
|
||||||
|
// Load model-specific fields in the same order they were dumped
|
||||||
|
obj.name = d.get_string()!
|
||||||
|
obj.description = d.get_string()!
|
||||||
|
obj.created_at = d.get_u64()!
|
||||||
|
obj.updated_at = d.get_u64()!
|
||||||
|
// Add more fields in the exact order they were dumped
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Operations
|
||||||
|
|
||||||
|
Implement the standard CRUD operations and additional methods.
|
||||||
|
|
||||||
|
### New Instance Creation
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Create a new model instance from arguments
|
||||||
|
pub fn (mut self DBModelName) new(args ModelNameArg) !ModelName {
|
||||||
|
mut o := ModelName{
|
||||||
|
name: args.name
|
||||||
|
description: args.description
|
||||||
|
// Initialize other fields
|
||||||
|
created_at: ourtime.now().unix()
|
||||||
|
updated_at: ourtime.now().unix()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional initialization logic
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set (Create or Update)
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Save or update a model instance
|
||||||
|
pub fn (mut self DBModelName) set(o ModelName) !ModelName {
|
||||||
|
return self.db.set[ModelName](o)!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Retrieve a model instance by ID
|
||||||
|
pub fn (mut self DBModelName) get(id u32) !ModelName {
|
||||||
|
mut o, data := self.db.get_data[ModelName](id)!
|
||||||
|
mut e_decoder := encoder.decoder_new(data)
|
||||||
|
self.load(mut o, mut e_decoder)!
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Delete a model instance by ID
|
||||||
|
pub fn (mut self DBModelName) delete(id u32) !bool {
|
||||||
|
// Check if the item exists before trying to delete
|
||||||
|
if !self.db.exists[ModelName](id)! {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
self.db.delete[ModelName](id)!
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exist
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Check if a model instance exists by ID
|
||||||
|
pub fn (mut self DBModelName) exist(id u32) !bool {
|
||||||
|
return self.db.exists[ModelName](id)!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### List with Filtering
|
||||||
|
|
||||||
|
```v
|
||||||
|
// List model instances with optional filtering
|
||||||
|
pub fn (mut self DBModelName) list(args ModelNameListArg) ![]ModelName {
|
||||||
|
// Get all instances
|
||||||
|
all_items := self.db.list[ModelName]()!.map(self.get(it)!)
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
mut filtered_items := []ModelName{}
|
||||||
|
for item in all_items {
|
||||||
|
// Apply your filter conditions here
|
||||||
|
// Example:
|
||||||
|
// if args.some_filter && item.some_property != args.filter_value {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
filtered_items << item
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit
|
||||||
|
mut limit := args.limit
|
||||||
|
if limit > 100 {
|
||||||
|
limit = 100
|
||||||
|
}
|
||||||
|
if filtered_items.len > limit {
|
||||||
|
return filtered_items[..limit]
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered_items
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Handler Implementation
|
||||||
|
|
||||||
|
Create the handler function for RPC requests.
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Handler for RPC calls to this model
|
||||||
|
pub fn model_name_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
|
||||||
|
match method {
|
||||||
|
'get' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
res := f.model_name.get(id)!
|
||||||
|
return new_response(rpcid, json.encode_pretty(res))
|
||||||
|
}
|
||||||
|
'set' {
|
||||||
|
mut args := db.decode_generic[ModelNameArg](params)!
|
||||||
|
mut o := f.model_name.new(args)!
|
||||||
|
if args.id != 0 {
|
||||||
|
o.id = args.id
|
||||||
|
}
|
||||||
|
o = f.model_name.set(o)!
|
||||||
|
return new_response_int(rpcid, int(o.id))
|
||||||
|
}
|
||||||
|
'delete' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
deleted := f.model_name.delete(id)!
|
||||||
|
if deleted {
|
||||||
|
return new_response_true(rpcid)
|
||||||
|
} else {
|
||||||
|
return new_error(rpcid,
|
||||||
|
code: 404
|
||||||
|
message: 'ModelName with ID ${id} not found'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'exist' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
if f.model_name.exist(id)! {
|
||||||
|
return new_response_true(rpcid)
|
||||||
|
} else {
|
||||||
|
return new_response_false(rpcid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'list' {
|
||||||
|
args := db.decode_generic[ModelNameListArg](params)!
|
||||||
|
res := f.model_name.list(args)!
|
||||||
|
return new_response(rpcid, json.encode_pretty(res))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new_error(rpcid,
|
||||||
|
code: 32601
|
||||||
|
message: 'Method ${method} not found on model_name'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Models
|
||||||
|
|
||||||
|
Create a `model_name_test.v` file to test your model.
|
||||||
|
|
||||||
|
```v
|
||||||
|
module heromodels
|
||||||
|
|
||||||
|
fn test_model_name_crud() ! {
|
||||||
|
// Initialize DB for testing
|
||||||
|
mut mydb := db.new_test()!
|
||||||
|
mut db_model := DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create
|
||||||
|
mut args := ModelNameArg{
|
||||||
|
name: 'Test Model'
|
||||||
|
description: 'A test model'
|
||||||
|
}
|
||||||
|
|
||||||
|
mut model := db_model.new(args)!
|
||||||
|
model = db_model.set(model)!
|
||||||
|
model_id := model.id
|
||||||
|
|
||||||
|
// Verify ID assignment
|
||||||
|
assert model_id > 0
|
||||||
|
|
||||||
|
// Read
|
||||||
|
retrieved_model := db_model.get(model_id)!
|
||||||
|
assert retrieved_model.name == 'Test Model'
|
||||||
|
assert retrieved_model.description == 'A test model'
|
||||||
|
|
||||||
|
// Update
|
||||||
|
retrieved_model.description = 'Updated description'
|
||||||
|
updated_model := db_model.set(retrieved_model)!
|
||||||
|
assert updated_model.description == 'Updated description'
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
deleted := db_model.delete(model_id)!
|
||||||
|
assert deleted == true
|
||||||
|
|
||||||
|
// Verify deletion
|
||||||
|
exists := db_model.exist(model_id)!
|
||||||
|
assert exists == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_model_name_type_name() ! {
|
||||||
|
// Initialize DB for testing
|
||||||
|
mut mydb := db.new_test()!
|
||||||
|
mut db_model := DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a model
|
||||||
|
mut model := db_model.new(
|
||||||
|
name: 'Type Test'
|
||||||
|
description: 'Testing type_name'
|
||||||
|
)!
|
||||||
|
|
||||||
|
// Test type_name method
|
||||||
|
assert model.type_name() == 'heromodels.ModelName'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_model_name_description() ! {
|
||||||
|
// Initialize DB for testing
|
||||||
|
mut mydb := db.new_test()!
|
||||||
|
mut db_model := DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a model
|
||||||
|
mut model := db_model.new(
|
||||||
|
name: 'Description Test'
|
||||||
|
description: 'Testing description method'
|
||||||
|
)!
|
||||||
|
|
||||||
|
// Test description method for each methodname
|
||||||
|
assert model.description('set') == 'Create or update a model. Returns the ID of the model.'
|
||||||
|
assert model.description('get') == 'Retrieve a model by ID. Returns the model object.'
|
||||||
|
assert model.description('delete') == 'Delete a model by ID. Returns true if successful.'
|
||||||
|
assert model.description('exist') == 'Check if a model exists by ID. Returns true or false.'
|
||||||
|
assert model.description('list') == 'List all models. Returns an array of model objects.'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_model_name_example() ! {
|
||||||
|
// Initialize DB for testing
|
||||||
|
mut mydb := db.new_test()!
|
||||||
|
mut db_model := DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a model
|
||||||
|
mut model := db_model.new(
|
||||||
|
name: 'Example Test'
|
||||||
|
description: 'Testing example method'
|
||||||
|
)!
|
||||||
|
|
||||||
|
// Test example method for each methodname
|
||||||
|
set_call, set_result := model.example('set')
|
||||||
|
// Assert expected call and result format
|
||||||
|
|
||||||
|
get_call, get_result := model.example('get')
|
||||||
|
// Assert expected call and result format
|
||||||
|
|
||||||
|
delete_call, delete_result := model.example('delete')
|
||||||
|
// Assert expected call and result format
|
||||||
|
|
||||||
|
exist_call, exist_result := model.example('exist')
|
||||||
|
// Assert expected call and result format
|
||||||
|
|
||||||
|
list_call, list_result := model.example('list')
|
||||||
|
// Assert expected call and result format
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_model_name_encoding_decoding() ! {
|
||||||
|
// Initialize DB for testing
|
||||||
|
mut mydb := db.new_test()!
|
||||||
|
mut db_model := DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a model with all fields populated
|
||||||
|
mut args := ModelNameArg{
|
||||||
|
name: 'Encoding Test'
|
||||||
|
description: 'Testing encoding/decoding'
|
||||||
|
// Set other fields
|
||||||
|
}
|
||||||
|
|
||||||
|
mut model := db_model.new(args)!
|
||||||
|
|
||||||
|
// Save the model
|
||||||
|
model = db_model.set(model)!
|
||||||
|
model_id := model.id
|
||||||
|
|
||||||
|
// Retrieve and verify all fields were properly encoded/decoded
|
||||||
|
retrieved_model := db_model.get(model_id)!
|
||||||
|
|
||||||
|
// Verify all fields match the original
|
||||||
|
assert retrieved_model.name == 'Encoding Test'
|
||||||
|
assert retrieved_model.description == 'Testing encoding/decoding'
|
||||||
|
// Check other fields
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with Factory
|
||||||
|
|
||||||
|
Update the `factory.v` file to include your new model.
|
||||||
|
|
||||||
|
### 1. Add the Model to the Factory Struct
|
||||||
|
|
||||||
|
```v
|
||||||
|
// In factory.v
|
||||||
|
pub struct ModelsFactory {
|
||||||
|
pub mut:
|
||||||
|
db &db.DB
|
||||||
|
user DBUser
|
||||||
|
group DBGroup
|
||||||
|
// Add your new model
|
||||||
|
model_name DBModelName
|
||||||
|
// Other models...
|
||||||
|
rpc_handler &jsonrpc.Handler
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Initialize the Model in the Factory New Method
|
||||||
|
|
||||||
|
```v
|
||||||
|
// In factory.v, in the new() function
|
||||||
|
pub fn new(args ModelsFactoryArgs) !&ModelsFactory {
|
||||||
|
// Existing code...
|
||||||
|
|
||||||
|
mut f := ModelsFactory{
|
||||||
|
db: &mydb
|
||||||
|
user: DBUser{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
// Add your new model
|
||||||
|
model_name: DBModelName{
|
||||||
|
db: &mydb
|
||||||
|
}
|
||||||
|
// Other models...
|
||||||
|
rpc_handler: &h
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing code...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Add Handler Registration to the Factory API Handler
|
||||||
|
|
||||||
|
```v
|
||||||
|
// In factory.v, in the group_api_handler function
|
||||||
|
pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname string, methodname string, params string) !jsonrpc.Response {
|
||||||
|
// Existing code...
|
||||||
|
|
||||||
|
match actorname {
|
||||||
|
// Existing cases...
|
||||||
|
|
||||||
|
'model_name' {
|
||||||
|
return model_name_handle(mut f, rpcid, servercontext, userref, methodname, params)!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing cases...
|
||||||
|
|
||||||
|
else {
|
||||||
|
// Error handling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Custom Methods
|
||||||
|
|
||||||
|
You can add custom methods to your model for specific business logic:
|
||||||
|
|
||||||
|
```v
|
||||||
|
// Add a custom method to the model
|
||||||
|
pub fn (mut self ModelName) custom_operation(param string) !string {
|
||||||
|
// Custom business logic
|
||||||
|
self.updated_at = ourtime.now().unix()
|
||||||
|
return 'Performed ${param} operation'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enhanced RPC Handling
|
||||||
|
|
||||||
|
Extend the RPC handler to support your custom methods:
|
||||||
|
|
||||||
|
```v
|
||||||
|
// In the model_name_handle function
|
||||||
|
match method {
|
||||||
|
// Standard CRUD methods...
|
||||||
|
|
||||||
|
'custom_operation' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
mut model := f.model_name.get(id)!
|
||||||
|
|
||||||
|
// Extract parameter from JSON
|
||||||
|
param_struct := json.decode(struct { param string }, params) or {
|
||||||
|
return new_error(rpcid,
|
||||||
|
code: 32602
|
||||||
|
message: 'Invalid parameters for custom_operation'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := model.custom_operation(param_struct.param)!
|
||||||
|
model = f.model_name.set(model)! // Save changes
|
||||||
|
return new_response(rpcid, json.encode(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// Error handling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Field Order**: Keep field ordering consistent between `dump` and `load` methods
|
||||||
|
2. **Error Handling**: Use the `!` operator consistently for error propagation
|
||||||
|
3. **Timestamp Management**: Initialize timestamps using `ourtime.now().unix()`
|
||||||
|
4. **Required Fields**: Mark mandatory fields with `@[required]` attribute
|
||||||
|
5. **Limits**: Enforce list limits (default 100)
|
||||||
|
6. **ID Handling**: Always check existence before operations like delete
|
||||||
|
7. **Validation**: Add validation in the `new` and `set` methods
|
||||||
|
8. **API Methods**: Implement the standard CRUD operations (get, set, delete, exist, list)
|
||||||
|
9. **Comments**: Document all fields and methods
|
||||||
|
10. **Testing**: Create comprehensive tests covering all methods
|
||||||
|
|
||||||
|
## Example Implementation
|
||||||
|
|
||||||
|
Here is a complete example of a simple "Project" model:
|
||||||
|
|
||||||
|
```v
|
||||||
|
module heromodels
|
||||||
|
|
||||||
|
import incubaid.herolib.core.db
|
||||||
|
import incubaid.herolib.core.encoder
|
||||||
|
import incubaid.herolib.core.ourtime
|
||||||
|
import incubaid.herolib.core.jsonrpc { Response }
|
||||||
|
import json
|
||||||
|
|
||||||
|
// Project model
|
||||||
|
pub struct Project {
|
||||||
|
pub mut:
|
||||||
|
db.Base // Inherit from db.Base
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
status ProjectStatus
|
||||||
|
owner_id u32
|
||||||
|
members []u32
|
||||||
|
created_at u64
|
||||||
|
updated_at u64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project status enum
|
||||||
|
pub enum ProjectStatus {
|
||||||
|
active
|
||||||
|
completed
|
||||||
|
archived
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeName for serialization
|
||||||
|
pub fn (self Project) type_name() string {
|
||||||
|
return 'heromodels.Project'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump serializes the model
|
||||||
|
pub fn (self Project) dump(mut e encoder.Encoder) ! {
|
||||||
|
self.Base.dump(mut e)!
|
||||||
|
e.add_string(self.name)!
|
||||||
|
e.add_string(self.description)!
|
||||||
|
e.add_u8(u8(self.status))!
|
||||||
|
e.add_u32(self.owner_id)!
|
||||||
|
e.add_array_u32(self.members)!
|
||||||
|
e.add_u64(self.created_at)!
|
||||||
|
e.add_u64(self.updated_at)!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project argument struct
|
||||||
|
@[params]
|
||||||
|
pub struct ProjectArg {
|
||||||
|
pub mut:
|
||||||
|
id u32
|
||||||
|
name string @[required]
|
||||||
|
description string
|
||||||
|
status ProjectStatus = .active
|
||||||
|
owner_id u32 @[required]
|
||||||
|
members []u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project list argument struct
|
||||||
|
@[params]
|
||||||
|
pub struct ProjectListArg {
|
||||||
|
pub mut:
|
||||||
|
status ProjectStatus
|
||||||
|
owner_id u32
|
||||||
|
limit int = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// DB wrapper struct
|
||||||
|
pub struct DBProject {
|
||||||
|
pub mut:
|
||||||
|
db &db.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load deserializes the model
|
||||||
|
pub fn (mut self DBProject) load(mut obj Project, mut d encoder.Decoder) ! {
|
||||||
|
obj.Base.load(mut d)!
|
||||||
|
obj.name = d.get_string()!
|
||||||
|
obj.description = d.get_string()!
|
||||||
|
obj.status = unsafe { ProjectStatus(d.get_u8()!) }
|
||||||
|
obj.owner_id = d.get_u32()!
|
||||||
|
obj.members = d.get_array_u32()!
|
||||||
|
obj.created_at = d.get_u64()!
|
||||||
|
obj.updated_at = d.get_u64()!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Project
|
||||||
|
pub fn (mut self DBProject) new(args ProjectArg) !Project {
|
||||||
|
mut o := Project{
|
||||||
|
name: args.name
|
||||||
|
description: args.description
|
||||||
|
status: args.status
|
||||||
|
owner_id: args.owner_id
|
||||||
|
members: args.members
|
||||||
|
created_at: ourtime.now().unix()
|
||||||
|
updated_at: ourtime.now().unix()
|
||||||
|
}
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save or update a Project
|
||||||
|
pub fn (mut self DBProject) set(o Project) !Project {
|
||||||
|
return self.db.set[Project](o)!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a Project by ID
|
||||||
|
pub fn (mut self DBProject) get(id u32) !Project {
|
||||||
|
mut o, data := self.db.get_data[Project](id)!
|
||||||
|
mut e_decoder := encoder.decoder_new(data)
|
||||||
|
self.load(mut o, mut e_decoder)!
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a Project by ID
|
||||||
|
pub fn (mut self DBProject) delete(id u32) !bool {
|
||||||
|
if !self.db.exists[Project](id)! {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
self.db.delete[Project](id)!
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a Project exists
|
||||||
|
pub fn (mut self DBProject) exist(id u32) !bool {
|
||||||
|
return self.db.exists[Project](id)!
|
||||||
|
}
|
||||||
|
|
||||||
|
// List Projects with filtering
|
||||||
|
pub fn (mut self DBProject) list(args ProjectListArg) ![]Project {
|
||||||
|
all_projects := self.db.list[Project]()!.map(self.get(it)!)
|
||||||
|
|
||||||
|
mut filtered_projects := []Project{}
|
||||||
|
for project in all_projects {
|
||||||
|
// Filter by status if provided
|
||||||
|
if args.status != .active && project.status != args.status {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by owner_id if provided
|
||||||
|
if args.owner_id != 0 && project.owner_id != args.owner_id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered_projects << project
|
||||||
|
}
|
||||||
|
|
||||||
|
mut limit := args.limit
|
||||||
|
if limit > 100 {
|
||||||
|
limit = 100
|
||||||
|
}
|
||||||
|
if filtered_projects.len > limit {
|
||||||
|
return filtered_projects[..limit]
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered_projects
|
||||||
|
}
|
||||||
|
|
||||||
|
// API description method
|
||||||
|
pub fn (self Project) description(methodname string) string {
|
||||||
|
match methodname {
|
||||||
|
'set' { return 'Create or update a project. Returns the ID of the project.' }
|
||||||
|
'get' { return 'Retrieve a project by ID. Returns the project object.' }
|
||||||
|
'delete' { return 'Delete a project by ID. Returns true if successful.' }
|
||||||
|
'exist' { return 'Check if a project exists by ID. Returns true or false.' }
|
||||||
|
'list' { return 'List all projects. Returns an array of project objects.' }
|
||||||
|
else { return 'This is generic method for the root object, TODO fill in, ...' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API example method
|
||||||
|
pub fn (self Project) example(methodname string) (string, string) {
|
||||||
|
match methodname {
|
||||||
|
'set' {
|
||||||
|
return '{"project": {"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}}', '1'
|
||||||
|
}
|
||||||
|
'get' {
|
||||||
|
return '{"id": 1}', '{"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}'
|
||||||
|
}
|
||||||
|
'delete' {
|
||||||
|
return '{"id": 1}', 'true'
|
||||||
|
}
|
||||||
|
'exist' {
|
||||||
|
return '{"id": 1}', 'true'
|
||||||
|
}
|
||||||
|
'list' {
|
||||||
|
return '{}', '[{"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}]'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '{}', '{}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API handler function
|
||||||
|
pub fn project_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
|
||||||
|
match method {
|
||||||
|
'get' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
res := f.project.get(id)!
|
||||||
|
return new_response(rpcid, json.encode_pretty(res))
|
||||||
|
}
|
||||||
|
'set' {
|
||||||
|
mut args := db.decode_generic[ProjectArg](params)!
|
||||||
|
mut o := f.project.new(args)!
|
||||||
|
if args.id != 0 {
|
||||||
|
o.id = args.id
|
||||||
|
}
|
||||||
|
o = f.project.set(o)!
|
||||||
|
return new_response_int(rpcid, int(o.id))
|
||||||
|
}
|
||||||
|
'delete' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
deleted := f.project.delete(id)!
|
||||||
|
if deleted {
|
||||||
|
return new_response_true(rpcid)
|
||||||
|
} else {
|
||||||
|
return new_error(rpcid,
|
||||||
|
code: 404
|
||||||
|
message: 'Project with ID ${id} not found'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'exist' {
|
||||||
|
id := db.decode_u32(params)!
|
||||||
|
if f.project.exist(id)! {
|
||||||
|
return new_response_true(rpcid)
|
||||||
|
} else {
|
||||||
|
return new_response_false(rpcid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'list' {
|
||||||
|
args := db.decode_generic[ProjectListArg](params)!
|
||||||
|
res := f.project.list(args)!
|
||||||
|
return new_response(rpcid, json.encode_pretty(res))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new_error(rpcid,
|
||||||
|
code: 32601
|
||||||
|
message: 'Method ${method} not found on project'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This complete guide should provide all the necessary information to create and maintain models in the HeroModels system following the established patterns and best practices.
|
||||||
1454
aiprompts/instructions/herodb_base_fs.md
Normal file
1454
aiprompts/instructions/herodb_base_fs.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
params:
|
params:
|
||||||
|
|
||||||
- filepath: /Users/despiegk/code/github/freeflowuniverse/herolib/lib/clients/openai
|
- filepath: /Users/despiegk/code/github/incubaid/herolib/lib/clients/openai
|
||||||
|
|
||||||
make a dense overview of the code above, easy to understand for AI
|
make a dense overview of the code above, easy to understand for AI
|
||||||
|
|
||||||
@@ -18,8 +18,8 @@ the template is as follows
|
|||||||
## factory
|
## factory
|
||||||
|
|
||||||
is there factory, which one and quick example how to call, don’t say in which file not relevant
|
is there factory, which one and quick example how to call, don’t say in which file not relevant
|
||||||
show how to import the module is as follows: import freeflowuniverse.herolib.
|
show how to import the module is as follows: import incubaid.herolib.
|
||||||
and then starting from lib e.g. lib/clients/mycelium would result in import freeflowuniverse.herolib. clients.mycelium
|
and then starting from lib e.g. lib/clients/mycelium would result in import incubaid.herolib. clients.mycelium
|
||||||
|
|
||||||
## overview
|
## overview
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ don't mention what we don't show because of rules above.
|
|||||||
|
|
||||||
the only output we want is markdown file as follows
|
the only output we want is markdown file as follows
|
||||||
|
|
||||||
===WRITE===
|
===WRITE===
|
||||||
$filepath
|
$filepath
|
||||||
===CONTENT===
|
===CONTENT===
|
||||||
$the content of the generated markdown file
|
$the content of the generated markdown file
|
||||||
===END===
|
===END===
|
||||||
|
|||||||
@@ -10,13 +10,11 @@ start of output file is:
|
|||||||
## factory
|
## factory
|
||||||
|
|
||||||
is there factory, which one and quick example how to call, don’t say in which file not relevant
|
is there factory, which one and quick example how to call, don’t say in which file not relevant
|
||||||
show how to import the module is as follows: import freeflowuniverse.herolib.
|
show how to import the module is as follows: import incubaid.herolib.
|
||||||
and then starting from lib e.g. lib/clients/mycelium would result in import freeflowuniverse.herolib. clients.mycelium
|
and then starting from lib e.g. lib/clients/mycelium would result in import incubaid.herolib. clients.mycelium
|
||||||
|
|
||||||
## structs and methods
|
## structs and methods
|
||||||
|
|
||||||
quick overview as list with identations, of the structs and its methods
|
quick overview as list with identations, of the structs and its methods
|
||||||
|
|
||||||
|
|
||||||
ONLY OUTPUT THE MARKDOWN FILE, NOTHING ELSE
|
ONLY OUTPUT THE MARKDOWN FILE, NOTHING ELSE
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ $NAME = calendar
|
|||||||
walk over all models from biz: db/heromodels/src/models/$NAME in the rust repo
|
walk over all models from biz: db/heromodels/src/models/$NAME in the rust repo
|
||||||
create nice structured public models in Vlang (V) see instructions in herlolib
|
create nice structured public models in Vlang (V) see instructions in herlolib
|
||||||
|
|
||||||
put the results in /Users/despiegk/code/github/freeflowuniverse/herolib/lib/hero/models/$NAME
|
put the results in /Users/despiegk/code/github/incubaid/herolib/lib/hero/models/$NAME
|
||||||
|
|
||||||
put decorator on fields which need to be indexed: use @[index] for that at end of line of the property of the struct
|
put decorator on fields which need to be indexed: use @[index] for that at end of line of the property of the struct
|
||||||
|
|
||||||
@@ -17,16 +17,14 @@ don't do anything additional for modules, don't do import
|
|||||||
|
|
||||||
at top of each file we have ```module $NAME```
|
at top of each file we have ```module $NAME```
|
||||||
|
|
||||||
|
|
||||||
make sure all time related fields are in u64 format, use unix timestamp for that
|
make sure all time related fields are in u64 format, use unix timestamp for that
|
||||||
|
|
||||||
don't create management classes, only output the structs, don't create a mod.v, don't make .v scripts executatble, don't create a main.v
|
don't create management classes, only output the structs, don't create a mod.v, don't make .v scripts executatble, don't create a main.v
|
||||||
|
|
||||||
|
|
||||||
## now also make sure we use core.base as follows
|
## now also make sure we use core.base as follows
|
||||||
|
|
||||||
```
|
```
|
||||||
import freeflowuniverse.herolib.hero.models.core
|
import incubaid.herolib.hero.models.core
|
||||||
|
|
||||||
// Account represents a financial account for tracking balances and transactions
|
// Account represents a financial account for tracking balances and transactions
|
||||||
// Supports multiple account types (checking, savings, investment, etc.)
|
// Supports multiple account types (checking, savings, investment, etc.)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ for governance and legal
|
|||||||
|
|
||||||
make sure we use core.base as follows
|
make sure we use core.base as follows
|
||||||
|
|
||||||
import freeflowuniverse.herolib.hero.models.core
|
import incubaid.herolib.hero.models.core
|
||||||
|
|
||||||
// Account represents a financial account for tracking balances and transactions
|
// Account represents a financial account for tracking balances and transactions
|
||||||
// Supports multiple account types (checking, savings, investment, etc.)
|
// Supports multiple account types (checking, savings, investment, etc.)
|
||||||
|
|||||||
3614
aiprompts/todo/refactor_herofs.md
Normal file
3614
aiprompts/todo/refactor_herofs.md
Normal file
File diff suppressed because it is too large
Load Diff
1475
aiprompts/vlang_herolib_core.md
Normal file
1475
aiprompts/vlang_herolib_core.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -30,8 +30,23 @@ if additional_args.len > 0 {
|
|||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change to the hero directory
|
// Determine the hero directory dynamically
|
||||||
hero_dir := os.join_path(os.home_dir(), 'code/github/freeflowuniverse/herolib/cli')
|
// Get the directory where this script is located
|
||||||
|
script_dir := os.dir(os.executable())
|
||||||
|
// The script is in cli/, so the herolib root is one level up
|
||||||
|
herolib_root := os.dir(script_dir)
|
||||||
|
hero_dir := os.join_path(herolib_root, 'cli')
|
||||||
|
|
||||||
|
// Verify the directory exists and contains hero.v
|
||||||
|
if !os.exists(hero_dir) {
|
||||||
|
panic('Hero CLI directory not found: ${hero_dir}')
|
||||||
|
}
|
||||||
|
hero_v_path := os.join_path(hero_dir, 'hero.v')
|
||||||
|
if !os.exists(hero_v_path) {
|
||||||
|
panic('hero.v not found in: ${hero_dir}')
|
||||||
|
}
|
||||||
|
|
||||||
|
println('Using hero directory: ${hero_dir}')
|
||||||
os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}') }
|
os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}') }
|
||||||
|
|
||||||
// Set HEROPATH based on OS
|
// Set HEROPATH based on OS
|
||||||
@@ -49,9 +64,9 @@ compile_cmd := if os.user_os() == 'macos' {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if prod_mode {
|
if prod_mode {
|
||||||
'v -cg -enable-globals -parallel-cc -w -n hero.v'
|
'v -cg -enable-globals -parallel-cc -w -n -d use_openssl hero.v'
|
||||||
} else {
|
} else {
|
||||||
'v -cg -enable-globals -w -n hero.v'
|
'v -cg -enable-globals -w -n -d use_openssl hero.v'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ fn hero_upload() ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// os.execute_or_panic('${os.home_dir()}/code/github/freeflowuniverse/herolib/cli/compile.vsh -p')
|
// os.execute_or_panic('${os.home_dir()}/code/github/incubaid/herolib/cli/compile.vsh -p')
|
||||||
println('compile hero can take 60 sec+ on osx.')
|
println('compile hero can take 60 sec+ on osx.')
|
||||||
os.execute_or_panic('${os.home_dir()}/code/github/freeflowuniverse/herolib/cli/compile.vsh -p')
|
os.execute_or_panic('${os.home_dir()}/code/github/incubaid/herolib/cli/compile.vsh -p')
|
||||||
println('upload:')
|
println('upload:')
|
||||||
hero_upload() or {
|
hero_upload() or {
|
||||||
eprintln(err)
|
eprintln(err)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ if additional_args.len > 0 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change to the vdo directory
|
// Change to the vdo directory
|
||||||
hero_dir := os.join_path(os.home_dir(), 'code/github/freeflowuniverse/herolib/cli')
|
hero_dir := os.join_path(os.home_dir(), 'code/github/incubaid/herolib/cli')
|
||||||
os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}') }
|
os.chdir(hero_dir) or { panic('Failed to change directory to ${hero_dir}: ${err}') }
|
||||||
|
|
||||||
// Set HEROPATH based on OS
|
// Set HEROPATH based on OS
|
||||||
|
|||||||
32
cli/hero.v
32
cli/hero.v
@@ -2,14 +2,14 @@ module main
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import cli { Command }
|
import cli { Command }
|
||||||
import freeflowuniverse.herolib.core.herocmds
|
import incubaid.herolib.core.herocmds
|
||||||
import freeflowuniverse.herolib.installers.base
|
import incubaid.herolib.installers.base
|
||||||
import freeflowuniverse.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
import freeflowuniverse.herolib.ui
|
import incubaid.herolib.ui
|
||||||
import freeflowuniverse.herolib.osal.core as osal
|
import incubaid.herolib.osal.core as osal
|
||||||
import freeflowuniverse.herolib.core
|
import incubaid.herolib.core
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
|
|
||||||
fn playcmds_do(path string) ! {
|
fn playcmds_do(path string) ! {
|
||||||
mut plbook := playbook.new(path: path)!
|
mut plbook := playbook.new(path: path)!
|
||||||
@@ -38,7 +38,12 @@ fn do() ! {
|
|||||||
|
|
||||||
if os.args.len == 2 {
|
if os.args.len == 2 {
|
||||||
mypath := os.args[1]
|
mypath := os.args[1]
|
||||||
if mypath.to_lower().ends_with('.hero') || mypath.to_lower().ends_with('.heroscript') || mypath.to_lower().ends_with('.hs') {
|
if mypath == '.' {
|
||||||
|
playcmds_do(os.getwd())!
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if mypath.to_lower().ends_with('.hero') || mypath.to_lower().ends_with('.heroscript')
|
||||||
|
|| mypath.to_lower().ends_with('.hs') {
|
||||||
// hero was called from a file
|
// hero was called from a file
|
||||||
playcmds_do(mypath)!
|
playcmds_do(mypath)!
|
||||||
return
|
return
|
||||||
@@ -48,7 +53,7 @@ fn do() ! {
|
|||||||
mut cmd := Command{
|
mut cmd := Command{
|
||||||
name: 'hero'
|
name: 'hero'
|
||||||
description: 'Your HERO toolset.'
|
description: 'Your HERO toolset.'
|
||||||
version: '1.0.30'
|
version: '1.0.34'
|
||||||
}
|
}
|
||||||
|
|
||||||
// herocmds.cmd_run_add_flags(mut cmd)
|
// herocmds.cmd_run_add_flags(mut cmd)
|
||||||
@@ -81,7 +86,6 @@ fn do() ! {
|
|||||||
|
|
||||||
base.redis_install()!
|
base.redis_install()!
|
||||||
|
|
||||||
herocmds.cmd_run(mut cmd)
|
|
||||||
herocmds.cmd_git(mut cmd)
|
herocmds.cmd_git(mut cmd)
|
||||||
herocmds.cmd_generator(mut cmd)
|
herocmds.cmd_generator(mut cmd)
|
||||||
herocmds.cmd_docusaurus(mut cmd)
|
herocmds.cmd_docusaurus(mut cmd)
|
||||||
@@ -99,8 +103,4 @@ fn main() {
|
|||||||
print_backtrace()
|
print_backtrace()
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn pre_func(cmd Command) ! {
|
|
||||||
// herocmds.plbook_run(cmd)!
|
|
||||||
// }
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
import freeflowuniverse.herolib.mcp.v_do
|
import incubaid.herolib.mcp.v_do
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Create and start the MCP server
|
// Create and start the MCP server
|
||||||
|
|||||||
15
doc.vsh
15
doc.vsh
@@ -6,15 +6,22 @@ abs_dir_of_script := dir(@FILE)
|
|||||||
|
|
||||||
// Format code
|
// Format code
|
||||||
println('Formatting code...')
|
println('Formatting code...')
|
||||||
if os.system('v fmt -w ${abs_dir_of_script}/examples') != 0 {
|
// v fmt returns:
|
||||||
eprintln('Warning: Failed to format examples')
|
// - 0: all files already formatted (no changes)
|
||||||
|
// - 5: files were formatted (changes made) - this is SUCCESS
|
||||||
|
// - other: actual errors (syntax errors, file access issues, etc.)
|
||||||
|
fmt_examples_result := os.system('v fmt -w ${abs_dir_of_script}/examples')
|
||||||
|
if fmt_examples_result != 0 && fmt_examples_result != 5 {
|
||||||
|
eprintln('Error: Failed to format examples (exit code: ${fmt_examples_result})')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.system('v fmt -w ${abs_dir_of_script}/lib') != 0 {
|
fmt_lib_result := os.system('v fmt -w ${abs_dir_of_script}/lib')
|
||||||
eprintln('Warning: Failed to format herolib')
|
if fmt_lib_result != 0 && fmt_lib_result != 5 {
|
||||||
|
eprintln('Error: Failed to format herolib (exit code: ${fmt_lib_result})')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
println('✓ Code formatting completed')
|
||||||
|
|
||||||
// Clean existing docs
|
// Clean existing docs
|
||||||
println('Cleaning existing documentation...')
|
println('Cleaning existing documentation...')
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ abs_dir_of_script := dir(@FILE)
|
|||||||
|
|
||||||
// Reset symlinks if requested
|
// Reset symlinks if requested
|
||||||
println('Resetting all symlinks...')
|
println('Resetting all symlinks...')
|
||||||
os.rm('${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {}
|
os.rm('${os.home_dir()}/.vmodules/incubaid/herolib') or {}
|
||||||
|
|
||||||
// Create necessary directories
|
// Create necessary directories
|
||||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
os.mkdir_all('${os.home_dir()}/.vmodules/incubaid') or {
|
||||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
panic('Failed to create directory ~/.vmodules/incubaid: ${err}')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new symlinks
|
// Create new symlinks
|
||||||
os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {
|
os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/incubaid/herolib') or {
|
||||||
panic('Failed to create herolib symlink: ${err}')
|
panic('Failed to create herolib symlink: ${err}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ function os_update {
|
|||||||
|
|
||||||
|
|
||||||
function hero_lib_pull {
|
function hero_lib_pull {
|
||||||
pushd $DIR_CODE/github/freeflowuniverse/herolib 2>&1 >> /dev/null
|
pushd $DIR_CODE/github/incubaid/herolib 2>&1 >> /dev/null
|
||||||
if [[ $(git status -s) ]]; then
|
if [[ $(git status -s) ]]; then
|
||||||
echo "There are uncommitted changes in the Git repository herolib."
|
echo "There are uncommitted changes in the Git repository herolib."
|
||||||
return 1
|
return 1
|
||||||
@@ -218,13 +218,13 @@ function hero_lib_pull {
|
|||||||
|
|
||||||
function hero_lib_get {
|
function hero_lib_get {
|
||||||
|
|
||||||
mkdir -p $DIR_CODE/github/freeflowuniverse
|
mkdir -p $DIR_CODE/github/incubaid
|
||||||
if [[ -d "$DIR_CODE/github/freeflowuniverse/herolib" ]]
|
if [[ -d "$DIR_CODE/github/incubaid/herolib" ]]
|
||||||
then
|
then
|
||||||
hero_lib_pull
|
hero_lib_pull
|
||||||
else
|
else
|
||||||
pushd $DIR_CODE/github/freeflowuniverse 2>&1 >> /dev/null
|
pushd $DIR_CODE/github/incubaid 2>&1 >> /dev/null
|
||||||
git clone --depth 1 --no-single-branch https://github.com/freeflowuniverse/herolib.git
|
git clone --depth 1 --no-single-branch https://github.com/incubaid/herolib.git
|
||||||
popd 2>&1 >> /dev/null
|
popd 2>&1 >> /dev/null
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -461,7 +461,7 @@ check_and_start_redis
|
|||||||
|
|
||||||
if [ "$HEROLIB" = true ]; then
|
if [ "$HEROLIB" = true ]; then
|
||||||
hero_lib_get
|
hero_lib_get
|
||||||
~/code/github/freeflowuniverse/herolib/install_herolib.vsh
|
~/code/github/incubaid/herolib/install_herolib.vsh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import freeflowuniverse.herolib.clients.openai
|
import incubaid.herolib.clients.openai
|
||||||
import os
|
import os
|
||||||
|
|
||||||
fn test1(mut client openai.OpenAI) ! {
|
fn test1(mut client openai.OpenAI) ! {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.mcp.aitools
|
import incubaid.herolib.mcp.aitools
|
||||||
|
|
||||||
// aitools.convert_pug("/root/code/github/freeflowuniverse/herolauncher/pkg/herolauncher/web/templates/admin")!
|
// aitools.convert_pug("/root/code/github/incubaid/herolauncher/pkg/herolauncher/web/templates/admin")!
|
||||||
|
|
||||||
aitools.convert_pug('/root/code/github/freeflowuniverse/herolauncher/pkg/zaz/webui/templates')!
|
aitools.convert_pug('/root/code/github/incubaid/herolauncher/pkg/zaz/webui/templates')!
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.jina
|
import incubaid.herolib.clients.jina
|
||||||
|
|
||||||
mut jina_client := jina.get()!
|
mut jina_client := jina.get()!
|
||||||
health := jina_client.health()!
|
health := jina_client.health()!
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.qdrant
|
import incubaid.herolib.clients.qdrant
|
||||||
import freeflowuniverse.herolib.installers.db.qdrant_installer
|
import incubaid.herolib.installers.db.qdrant_installer
|
||||||
import freeflowuniverse.herolib.core.httpconnection
|
import incubaid.herolib.core.httpconnection
|
||||||
import rand
|
import rand
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.hero.bootstrap
|
import incubaid.herolib.hero.bootstrap
|
||||||
|
|
||||||
mut al := bootstrap.new_alpine_loader()
|
mut al := bootstrap.new_alpine_loader()
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.investortool
|
import incubaid.herolib.biz.investortool
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
mut plbook := playbook.new(
|
mut plbook := playbook.new(
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#!/usr/bin/env -S v -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
// #!/usr/bin/env -S v -cg -enable-globals run
|
// #!/usr/bin/env -S v -cg -enable-globals run
|
||||||
import freeflowuniverse.herolib.data.doctree
|
import incubaid.herolib.data.doctree
|
||||||
import freeflowuniverse.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
import freeflowuniverse.herolib.web.mdbook
|
import incubaid.herolib.web.mdbook
|
||||||
import freeflowuniverse.herolib.biz.spreadsheet
|
import incubaid.herolib.biz.spreadsheet
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const name = 'tf9_budget'
|
const name = 'tf9_budget'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const playbook_path = os.dir(@FILE) + '/playbook'
|
const playbook_path = os.dir(@FILE) + '/playbook'
|
||||||
@@ -14,5 +14,5 @@ println(model.sheet)
|
|||||||
// println(model.sheet.export()!)
|
// println(model.sheet.export()!)
|
||||||
|
|
||||||
model.sheet.pprint()!
|
model.sheet.pprint()!
|
||||||
// model.sheet.export(path: '~/code/github/freeflowuniverse/starlight_template/src/content/test.csv')!
|
// model.sheet.export(path: '~/code/github/incubaid/starlight_template/src/content/test.csv')!
|
||||||
// model.sheet
|
// model.sheet
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript_path := os.join_path(os.dir(@FILE), 'examples/complete.heroscript')
|
heroscript_path := os.join_path(os.dir(@FILE), 'examples/complete.heroscript')
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ this will make sure we load the appropriate biz model
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
!!bizmodel.load name:'default' url:'https://github.com/freeflowuniverse/herolib/tree/development/bizmodel/example/data'
|
!!bizmodel.load name:'default' url:'https://github.com/incubaid/herolib/tree/development/bizmodel/example/data'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript_path := os.join_path(os.dir(@FILE), 'examples/complete.heroscript')
|
heroscript_path := os.join_path(os.dir(@FILE), 'examples/complete.heroscript')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript_path := os.join_path(os.dir(@FILE), 'examples/full')
|
heroscript_path := os.join_path(os.dir(@FILE), 'examples/full')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.biz.bizmodel
|
import incubaid.herolib.biz.bizmodel
|
||||||
import freeflowuniverse.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import os
|
import os
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Remote Executor Example
|
# Remote Executor Example
|
||||||
|
|
||||||
This example demonstrates how to compile and execute V code remotely using SSH.
|
This example demonstrates how to compile and execute V code remotely using SSH.
|
||||||
|
|
||||||
It shows a practical implementation of the herolib builder's remote execution capabilities, its good for debugging.
|
It shows a practical implementation of the herolib builder's remote execution capabilities, its good for debugging.
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ A V program that demonstrates remote execution of system operations:
|
|||||||
### `run.sh`
|
### `run.sh`
|
||||||
|
|
||||||
A bash script that:
|
A bash script that:
|
||||||
|
|
||||||
1. Compiles the V program
|
1. Compiles the V program
|
||||||
2. Copies it to a remote machine using SCP
|
2. Copies it to a remote machine using SCP
|
||||||
3. Executes it remotely using SSH
|
3. Executes it remotely using SSH
|
||||||
@@ -45,16 +46,19 @@ Modify these values to match your remote system configuration.
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. Set the required environment variable:
|
1. Set the required environment variable:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export SECRET=your_secret_value
|
export SECRET=your_secret_value
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Make the script executable:
|
2. Make the script executable:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x run.sh
|
chmod +x run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run the script:
|
3. Run the script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./run.sh
|
./run.sh
|
||||||
```
|
```
|
||||||
@@ -66,9 +70,8 @@ This example demonstrates practical usage of the herolib builder module's remote
|
|||||||
The builder module provides a more structured way to manage remote nodes and execute commands:
|
The builder module provides a more structured way to manage remote nodes and execute commands:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import freeflowuniverse.herolib.builder
|
import incubaid.herolib.builder
|
||||||
mut b := builder.new()!
|
mut b := builder.new()!
|
||||||
mut n := b.node_new(ipaddr:"user@host:port")!
|
mut n := b.node_new(ipaddr:"user@host:port")!
|
||||||
// Execute commands on the remote node
|
// Execute commands on the remote node
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
import freeflowuniverse.herolib.core
|
import incubaid.herolib.core
|
||||||
|
|
||||||
fn do() ! {
|
fn do() ! {
|
||||||
// base.uninstall_brew()!
|
// base.uninstall_brew()!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.builder
|
import incubaid.herolib.builder
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
fn do1() ! {
|
fn do1() ! {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.builder
|
import incubaid.herolib.builder
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
mut b := builder.new()!
|
mut b := builder.new()!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.builder
|
import incubaid.herolib.builder
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
mut b := builder.new()!
|
mut b := builder.new()!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.openai
|
import incubaid.herolib.clients.openai
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
|
|
||||||
playcmds.run(
|
playcmds.run(
|
||||||
heroscript: '
|
heroscript: '
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -g -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -g -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.core.playcmds
|
import incubaid.herolib.core.playcmds
|
||||||
import freeflowuniverse.herolib.clients.giteaclient
|
import incubaid.herolib.clients.giteaclient
|
||||||
|
|
||||||
heroscript := "
|
heroscript := "
|
||||||
!!giteaclient.configure
|
!!giteaclient.configure
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.jina
|
import incubaid.herolib.clients.jina
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.mailclient
|
import incubaid.herolib.clients.mailclient
|
||||||
|
|
||||||
// remove the previous one, otherwise the env variables are not read
|
// remove the previous one, otherwise the env variables are not read
|
||||||
mailclient.config_delete(name: 'test')!
|
mailclient.config_delete(name: 'test')!
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.clients.mycelium
|
import incubaid.herolib.clients.mycelium
|
||||||
import freeflowuniverse.herolib.installers.net.mycelium_installer
|
import incubaid.herolib.installers.net.mycelium_installer
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import encoding.base64
|
import encoding.base64
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
// Mycelium RPC Client Example
|
// Mycelium RPC Client Example
|
||||||
// This example demonstrates how to use the new Mycelium JSON-RPC client
|
// This example demonstrates how to use the new Mycelium JSON-RPC client
|
||||||
// to interact with a Mycelium node's admin API
|
// to interact with a Mycelium node's admin API
|
||||||
import freeflowuniverse.herolib.clients.mycelium_rpc
|
import incubaid.herolib.clients.mycelium_rpc
|
||||||
import freeflowuniverse.herolib.installers.net.mycelium_installer
|
import incubaid.herolib.installers.net.mycelium_installer
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import encoding.base64
|
import encoding.base64
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core
|
import incubaid.herolib.core
|
||||||
import freeflowuniverse.herolib.clients.postgresql_client
|
import incubaid.herolib.clients.postgresql_client
|
||||||
|
|
||||||
// Configure PostgreSQL client
|
// Configure PostgreSQL client
|
||||||
heroscript := "
|
heroscript := "
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import freeflowuniverse.herolib.clients.zinit
|
import incubaid.herolib.clients.zinit
|
||||||
import freeflowuniverse.herolib.installers.infra.zinit_installer
|
import incubaid.herolib.installers.infra.zinit_installer
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.data.ourtime
|
import incubaid.herolib.data.ourtime
|
||||||
import freeflowuniverse.herolib.core.jobs.model
|
import incubaid.herolib.core.jobs.model
|
||||||
|
|
||||||
// Create a test agent with some sample data
|
// Create a test agent with some sample data
|
||||||
mut agent := model.Agent{
|
mut agent := model.Agent{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.base
|
import incubaid.herolib.core.base
|
||||||
|
|
||||||
pub struct MyClient[T] {
|
pub struct MyClient[T] {
|
||||||
base.BaseConfig[T]
|
base.BaseConfig[T]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import freeflowuniverse.herolib.core.base
|
import incubaid.herolib.core.base
|
||||||
|
|
||||||
pub struct MyClient[T] {
|
pub struct MyClient[T] {
|
||||||
base.BaseConfig[T]
|
base.BaseConfig[T]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.base
|
import incubaid.herolib.core.base
|
||||||
import freeflowuniverse.herolib.develop.gittools
|
import incubaid.herolib.develop.gittools
|
||||||
|
|
||||||
pub struct MyClass {
|
pub struct MyClass {
|
||||||
base.Base
|
base.Base
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env -S v -gc none -cc tcc -d use_openssl -enable-globals run
|
#!/usr/bin/env -S v -gc none -cc tcc -d use_openssl -enable-globals run
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import freeflowuniverse.herolib.core.smartid
|
import incubaid.herolib.core.smartid
|
||||||
import freeflowuniverse.herolib.data.ourtime
|
import incubaid.herolib.data.ourtime
|
||||||
import freeflowuniverse.herolib.core.db
|
import incubaid.herolib.core.db
|
||||||
|
|
||||||
pub struct MyStruct {
|
pub struct MyStruct {
|
||||||
db.Base
|
db.Base
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.generator.generic as generator
|
import incubaid.herolib.core.generator.generic as generator
|
||||||
import freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
|
|
||||||
// mut args := generator.GeneratorArgs{
|
// mut args := generator.GeneratorArgs{
|
||||||
// path: '~/code/github/freeflowuniverse/herolib/lib/clients'
|
// path: '~/code/github/incubaid/herolib/lib/clients'
|
||||||
// force: true
|
// force: true
|
||||||
// }
|
// }
|
||||||
|
|
||||||
mut args2 := generator.GeneratorArgs{
|
mut args2 := generator.GeneratorArgs{
|
||||||
path: '~/code/github/freeflowuniverse/herolib/lib/develop/heroprompt'
|
path: '~/code/github/incubaid/herolib/lib/develop/heroprompt'
|
||||||
force: true
|
force: true
|
||||||
}
|
}
|
||||||
generator.scan(args2)!
|
generator.scan(args2)!
|
||||||
|
|
||||||
// mut args := generator.GeneratorArgs{
|
// mut args := generator.GeneratorArgs{
|
||||||
// path: '~/code/github/freeflowuniverse/herolib/lib/installers'
|
// path: '~/code/github/incubaid/herolib/lib/installers'
|
||||||
// force: true
|
// force: true
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.logger
|
import incubaid.herolib.core.logger
|
||||||
|
|
||||||
mut l := logger.new(path: '/tmp/vlogs')!
|
mut l := logger.new(path: '/tmp/vlogs')!
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import freeflowuniverse.herolib.core.openapi.gen
|
import incubaid.herolib.core.openapi.gen
|
||||||
|
|
||||||
const spec_path = '${os.dir(@FILE)}/openapi.json'
|
const spec_path = '${os.dir(@FILE)}/openapi.json'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module openrpc_client
|
module openrpc_client
|
||||||
|
|
||||||
import freeflowuniverse.herolib.data.jsonrpc { JsonRpcRequest }
|
import incubaid.herolib.data.jsonrpc { JsonRpcRequest }
|
||||||
import net.websocket
|
import net.websocket
|
||||||
|
|
||||||
struct Client {
|
struct Client {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module petstore_client
|
module petstore_client
|
||||||
|
|
||||||
import freeflowuniverse.herolib.data.jsonrpc { JsonRpcRequest }
|
import incubaid.herolib.data.jsonrpc { JsonRpcRequest }
|
||||||
import net.websocket
|
import net.websocket
|
||||||
|
|
||||||
struct Client {
|
struct Client {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module petstore_client
|
module petstore_client
|
||||||
|
|
||||||
import freeflowuniverse.herolib.data.jsonrpc
|
import incubaid.herolib.data.jsonrpc
|
||||||
|
|
||||||
// get_pets finds pets in the system that the user has access to by tags and within a limit
|
// get_pets finds pets in the system that the user has access to by tags and within a limit
|
||||||
// - tags: tags to filter by
|
// - tags: tags to filter by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const testpath3 = os.dir(@FILE) + '/../../..'
|
const testpath3 = os.dir(@FILE) + '/../../..'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const testpath4 = os.dir(@FILE) + '../../'
|
const testpath4 = os.dir(@FILE) + '../../'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import freeflowuniverse.herolib.data.paramsparser
|
import incubaid.herolib.data.paramsparser
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const testpath3 = os.dir(@FILE) + '/../..'
|
const testpath3 = os.dir(@FILE) + '/../..'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/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 freeflowuniverse.herolib.core.pathlib
|
import incubaid.herolib.core.pathlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const testpath4 = os.dir(@FILE) + '/paths_sha256.vsh'
|
const testpath4 = os.dir(@FILE) + '/paths_sha256.vsh'
|
||||||
|
|||||||
1
examples/crypt/.gitignore
vendored
Normal file
1
examples/crypt/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
crypt_example
|
||||||
103
examples/crypt/crypt_example.vsh
Executable file
103
examples/crypt/crypt_example.vsh
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals -no-skip-unused run
|
||||||
|
|
||||||
|
import incubaid.herolib.crypt.herocrypt
|
||||||
|
import time
|
||||||
|
|
||||||
|
// Initialize the HeroCrypt client
|
||||||
|
// Assumes herodb is running on localhost:6381
|
||||||
|
mut client := herocrypt.new_default()!
|
||||||
|
|
||||||
|
println('HeroCrypt client initialized')
|
||||||
|
|
||||||
|
// -- Stateless (Ephemeral) Workflow --
|
||||||
|
println('\n--- Stateless (Ephemeral) Workflow ---')
|
||||||
|
|
||||||
|
// 1. Generate ephemeral encryption keypair
|
||||||
|
println('Generating ephemeral encryption keypair...')
|
||||||
|
enc_keypair := client.gen_enc_keypair()!
|
||||||
|
recipient_pub := enc_keypair[0]
|
||||||
|
identity_sec := enc_keypair[1]
|
||||||
|
println(' Recipient Public Key: ${recipient_pub[..30]}...')
|
||||||
|
println(' Identity Secret Key: ${identity_sec[..30]}...')
|
||||||
|
|
||||||
|
// 2. Encrypt a message
|
||||||
|
message := 'Hello, Stateless World!'
|
||||||
|
println('\nEncrypting message: "${message}"')
|
||||||
|
ciphertext := client.encrypt(recipient_pub, message)!
|
||||||
|
println(' Ciphertext: ${ciphertext[..30]}...')
|
||||||
|
|
||||||
|
// 3. Decrypt the message
|
||||||
|
println('\nDecrypting ciphertext...')
|
||||||
|
decrypted_message := client.decrypt(identity_sec, ciphertext)!
|
||||||
|
println(' Decrypted Message: ${decrypted_message}')
|
||||||
|
assert decrypted_message == message
|
||||||
|
|
||||||
|
// 4. Generate ephemeral signing keypair
|
||||||
|
println('\nGenerating ephemeral signing keypair...')
|
||||||
|
sign_keypair := client.gen_sign_keypair()!
|
||||||
|
verify_pub_b64 := sign_keypair[0]
|
||||||
|
sign_sec_b64 := sign_keypair[1]
|
||||||
|
println(' Verify Public Key (b64): ${verify_pub_b64[..30]}...')
|
||||||
|
println(' Sign Secret Key (b64): ${sign_sec_b64[..30]}...')
|
||||||
|
|
||||||
|
// 5. Sign a message
|
||||||
|
sign_message := 'This message is signed.'
|
||||||
|
println('\nSigning message: "${sign_message}"')
|
||||||
|
signature := client.sign(sign_sec_b64, sign_message)!
|
||||||
|
println(' Signature: ${signature[..30]}...')
|
||||||
|
|
||||||
|
// 6. Verify the signature
|
||||||
|
println('\nVerifying signature...')
|
||||||
|
is_valid := client.verify(verify_pub_b64, sign_message, signature)!
|
||||||
|
println(' Signature is valid: ${is_valid}')
|
||||||
|
assert is_valid
|
||||||
|
|
||||||
|
// -- Key-Managed (Persistent, Named) Workflow --
|
||||||
|
println('\n--- Key-Managed (Persistent, Named) Workflow ---')
|
||||||
|
|
||||||
|
// 1. Generate and persist a named encryption keypair
|
||||||
|
enc_key_name := 'my_app_enc_key'
|
||||||
|
println('\nGenerating and persisting named encryption keypair: "${enc_key_name}"')
|
||||||
|
client.keygen(enc_key_name)!
|
||||||
|
|
||||||
|
// 2. Encrypt a message by name
|
||||||
|
persistent_message := 'Hello, Persistent World!'
|
||||||
|
println('Encrypting message by name: "${persistent_message}"')
|
||||||
|
persistent_ciphertext := client.encrypt_by_name(enc_key_name, persistent_message)!
|
||||||
|
println(' Ciphertext: ${persistent_ciphertext[..30]}...')
|
||||||
|
|
||||||
|
// 3. Decrypt the message by name
|
||||||
|
println('Decrypting ciphertext by name...')
|
||||||
|
decrypted_persistent_message := client.decrypt_by_name(enc_key_name, persistent_ciphertext)!
|
||||||
|
println(' Decrypted Message: ${decrypted_persistent_message}')
|
||||||
|
assert decrypted_persistent_message == persistent_message
|
||||||
|
|
||||||
|
// 4. Generate and persist a named signing keypair
|
||||||
|
sign_key_name := 'my_app_sign_key'
|
||||||
|
println('\nGenerating and persisting named signing keypair: "${sign_key_name}"')
|
||||||
|
client.sign_keygen(sign_key_name)!
|
||||||
|
|
||||||
|
// 5. Sign a message by name
|
||||||
|
persistent_sign_message := 'This persistent message is signed.'
|
||||||
|
println('Signing message by name: "${persistent_sign_message}"')
|
||||||
|
persistent_signature := client.sign_by_name(sign_key_name, persistent_sign_message)!
|
||||||
|
println(' Signature: ${persistent_signature[..30]}...')
|
||||||
|
|
||||||
|
// 6. Verify the signature by name
|
||||||
|
println('Verifying signature by name...')
|
||||||
|
is_persistent_valid := client.verify_by_name(sign_key_name, persistent_sign_message, persistent_signature)!
|
||||||
|
println(' Signature is valid: ${is_persistent_valid}')
|
||||||
|
assert is_persistent_valid
|
||||||
|
|
||||||
|
// // 7. List all stored keys
|
||||||
|
// println('\n--- Listing Stored Keys ---')
|
||||||
|
// keys := client.list_keys()!
|
||||||
|
// println('Stored keys: ${keys}')
|
||||||
|
|
||||||
|
// // -- Clean up created keys --
|
||||||
|
// println('\n--- Cleaning up ---')
|
||||||
|
// client.redis_client.del('age:enc:${enc_key_name}')!
|
||||||
|
// client.redis_client.del('age:sign:${sign_key_name}')!
|
||||||
|
// println('Cleaned up persistent keys.')
|
||||||
|
|
||||||
|
println('\nHeroCrypt example finished successfully!')
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user