feat: improve build and serialization logic
- Update v fmt exit code handling - Support dynamic organization for symlinks - Add f32 and list f64 serialization/deserialization - Improve JSON decoding for bid requirements/pricing - Add basic tests for Bid and Node creation
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -57,3 +57,4 @@ MCP_HTTP_REST_IMPLEMENTATION_PLAN.md
|
||||
tmux_logger
|
||||
release
|
||||
install_herolib
|
||||
doc
|
||||
15
doc.vsh
15
doc.vsh
@@ -6,15 +6,22 @@ abs_dir_of_script := dir(@FILE)
|
||||
|
||||
// Format code
|
||||
println('Formatting code...')
|
||||
if os.system('v fmt -w ${abs_dir_of_script}/examples') != 0 {
|
||||
eprintln('Warning: Failed to format examples')
|
||||
// v fmt returns:
|
||||
// - 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)
|
||||
}
|
||||
|
||||
if os.system('v fmt -w ${abs_dir_of_script}/lib') != 0 {
|
||||
eprintln('Warning: Failed to format herolib')
|
||||
fmt_lib_result := os.system('v fmt -w ${abs_dir_of_script}/lib')
|
||||
if fmt_lib_result != 0 && fmt_lib_result != 5 {
|
||||
eprintln('Error: Failed to format herolib (exit code: ${fmt_lib_result})')
|
||||
exit(1)
|
||||
}
|
||||
println('✓ Code formatting completed')
|
||||
|
||||
// Clean existing docs
|
||||
println('Cleaning existing documentation...')
|
||||
|
||||
@@ -47,7 +47,7 @@ abs_dir_of_script := dir(@FILE)
|
||||
println('Script directory: ${abs_dir_of_script}')
|
||||
|
||||
// Determine the organization name from the current path
|
||||
// This makes the script work with any organization (incubaid, freeflowuniverse, etc.)
|
||||
// This makes the script work with any organization (incubaid, etc.)
|
||||
path_parts := abs_dir_of_script.split('/')
|
||||
mut org_name := 'incubaid' // default fallback
|
||||
for i, part in path_parts {
|
||||
@@ -60,32 +60,35 @@ for i, part in path_parts {
|
||||
println('Detected organization: ${org_name}')
|
||||
println('Will create symlink: ${os.home_dir()}/.vmodules/${org_name}/herolib -> ${abs_dir_of_script}/lib')
|
||||
|
||||
// Reset symlinks for both possible organizations (cleanup)
|
||||
// Reset symlinks (cleanup)
|
||||
println('Resetting all symlinks...')
|
||||
os.rm('${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {}
|
||||
os.rm('${os.home_dir()}/.vmodules/incubaid/herolib') or {}
|
||||
os.rm('${os.home_dir()}/.vmodules/${org_name}/herolib') or {}
|
||||
|
||||
// Create necessary directories
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or {
|
||||
panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}')
|
||||
os.mkdir_all('${os.home_dir()}/.vmodules/${org_name}') or {
|
||||
panic('Failed to create directory ~/.vmodules/${org_name}: ${err}')
|
||||
}
|
||||
|
||||
// Create new symlinks
|
||||
os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {
|
||||
panic('Failed to create herolib symlink: ${err}')
|
||||
}
|
||||
symlink_target := '${abs_dir_of_script}/lib'
|
||||
symlink_path := '${os.home_dir()}/.vmodules/${org_name}/herolib'
|
||||
|
||||
os.symlink(symlink_target, symlink_path) or { panic('Failed to create herolib symlink: ${err}') }
|
||||
|
||||
// Verify the symlink was created
|
||||
symlink_path := '${os.home_dir()}/.vmodules/${org_name}/herolib'
|
||||
if os.exists(symlink_path) {
|
||||
println('✓ Symlink created successfully: ${symlink_path}')
|
||||
// Verify it points to the right location
|
||||
// Note: os.exists() may return false for broken symlinks, so we check if it's a link first
|
||||
if os.is_link(symlink_path) {
|
||||
println('✓ Confirmed: ${symlink_path} is a symbolic link')
|
||||
println('✓ Symlink created successfully: ${symlink_path}')
|
||||
println('✓ Points to: ${symlink_target}')
|
||||
// Verify the target exists
|
||||
if os.exists(symlink_target) {
|
||||
println('✓ Target directory exists and is accessible')
|
||||
} else {
|
||||
eprintln('⚠ Warning: Symlink target does not exist: ${symlink_target}')
|
||||
}
|
||||
} else {
|
||||
panic('Failed to verify herolib symlink at ${symlink_path}')
|
||||
panic('Failed to create herolib symlink at ${symlink_path}')
|
||||
}
|
||||
|
||||
println('Herolib installation completed successfully!')
|
||||
|
||||
@@ -136,6 +136,14 @@ pub fn (mut d Decoder) get_f64() !f64 {
|
||||
return f
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_f32() !f32 {
|
||||
// Get the u32 bits first and then convert back to f32
|
||||
bits := d.get_u32()!
|
||||
// Use unsafe to convert bits to f32
|
||||
f := unsafe { *(&f32(&bits)) }
|
||||
return f
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_time() !time.Time {
|
||||
secs_ := d.get_u32()!
|
||||
secs := i64(secs_)
|
||||
@@ -229,6 +237,15 @@ pub fn (mut d Decoder) get_list_u64() ![]u64 {
|
||||
return v
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_list_f64() ![]f64 {
|
||||
n := d.get_u16()!
|
||||
mut v := []f64{len: int(n)}
|
||||
for i in 0 .. n {
|
||||
v[i] = d.get_f64()!
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_map_string() !map[string]string {
|
||||
n := d.get_u16()!
|
||||
mut v := map[string]string{}
|
||||
|
||||
@@ -115,6 +115,13 @@ pub fn (mut b Encoder) add_f64(data f64) {
|
||||
b.add_u64(bits)
|
||||
}
|
||||
|
||||
// adds a float32 value
|
||||
pub fn (mut b Encoder) add_f32(data f32) {
|
||||
// Convert f32 to bits first, then store as u32
|
||||
bits := unsafe { *(&u32(&data)) }
|
||||
b.add_u32(bits)
|
||||
}
|
||||
|
||||
// adds gid as a string
|
||||
pub fn (mut b Encoder) add_gid(data gid.GID) {
|
||||
b.add_string(data.str())
|
||||
@@ -185,6 +192,16 @@ pub fn (mut b Encoder) add_list_u64(data []u64) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut b Encoder) add_list_f64(data []f64) {
|
||||
if data.len > 64 * kb {
|
||||
panic('list cannot have more than 64kb items.')
|
||||
}
|
||||
b.add_u16(u16(data.len)) // how many items in list
|
||||
for item in data {
|
||||
b.add_f64(item)
|
||||
}
|
||||
}
|
||||
|
||||
// when complicated hash e.g. map of other object need to serialize each sub object
|
||||
pub fn (mut b Encoder) add_map_string(data map[string]string) {
|
||||
if data.len > 64 * kb {
|
||||
|
||||
@@ -3,7 +3,7 @@ module models_tfgrid
|
||||
import incubaid.herolib.data.encoder
|
||||
import incubaid.herolib.data.ourtime
|
||||
import incubaid.herolib.hero.db
|
||||
import incubaid.herolib.data.json
|
||||
import json
|
||||
|
||||
// Bid - ROOT OBJECT
|
||||
@[heap]
|
||||
@@ -106,8 +106,10 @@ pub fn (self Bid) dump(mut e encoder.Encoder) ! {
|
||||
|
||||
fn (mut self DBBid) load(mut o Bid, mut e encoder.Decoder) ! {
|
||||
o.customer_id = e.get_u32()!
|
||||
o.requirements = json.decode[map[string]string](e.get_string()!)!
|
||||
o.pricing = json.decode[map[string]string](e.get_string()!)!
|
||||
requirements_str := e.get_string()!
|
||||
o.requirements = json.decode(map[string]string, requirements_str)!
|
||||
pricing_str := e.get_string()!
|
||||
o.pricing = json.decode(map[string]string, pricing_str)!
|
||||
o.status = unsafe { BidStatus(e.get_int()!) }
|
||||
o.obligation = e.get_bool()!
|
||||
o.start_date = e.get_u32()!
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
module models_tfgrid
|
||||
|
||||
// Re-export all the root objects and their supporting structures
|
||||
pub use node
|
||||
pub use nodegroup
|
||||
pub use bid
|
||||
pub use contract
|
||||
pub use reputation
|
||||
39
lib/threefold/models_tfgrid/models_tfgrid_test.v
Normal file
39
lib/threefold/models_tfgrid/models_tfgrid_test.v
Normal file
@@ -0,0 +1,39 @@
|
||||
module models_tfgrid
|
||||
|
||||
fn test_bid_creation() {
|
||||
// Just a simple test to verify the module compiles
|
||||
bid := Bid{
|
||||
customer_id: 123
|
||||
requirements: {
|
||||
'compute_nodes': '10'
|
||||
}
|
||||
pricing: {
|
||||
'compute_nodes': '10.2'
|
||||
}
|
||||
status: .pending
|
||||
obligation: true
|
||||
start_date: 1234567890
|
||||
end_date: 1234567890
|
||||
signature_user: 'test_signature'
|
||||
billing_period: .monthly
|
||||
}
|
||||
|
||||
assert bid.customer_id == 123
|
||||
assert bid.status == .pending
|
||||
}
|
||||
|
||||
fn test_node_creation() {
|
||||
// Just a simple test to verify the module compiles
|
||||
node := Node{
|
||||
nodegroupid: 456
|
||||
country: 'US'
|
||||
uptime: 99
|
||||
pubkey: 'test_pubkey'
|
||||
signature_node: 'test_sig_node'
|
||||
signature_farmer: 'test_sig_farmer'
|
||||
}
|
||||
|
||||
assert node.nodegroupid == 456
|
||||
assert node.country == 'US'
|
||||
assert node.uptime == 99
|
||||
}
|
||||
Reference in New Issue
Block a user