From e34d804dda70295e47f6ea37721d30d226b485e5 Mon Sep 17 00:00:00 2001 From: despiegk Date: Fri, 7 Feb 2025 11:59:52 +0300 Subject: [PATCH] ... --- examples/clients/mail.vsh | 19 +- examples/clients/psql.vsh | 8 +- examples/data/heroencoder_simple.vsh | 9 +- examples/data/jsonexample.vsh | 22 +- examples/data/location/location_example.vsh | 3 +- .../data/location/location_example_tcc.vsh | 3 +- examples/installers/gitea.vsh | 11 +- lib/clients/mailclient/mailclient_factory_.v | 141 +++---- lib/clients/mailclient/mailclient_model.v | 22 +- lib/core/base/context.v | 1 - lib/core/herocmds/docusaurus.v | 15 +- lib/data/location/db.v | 22 +- lib/data/location/factory.v | 6 +- lib/data/location/geonames.v | 3 +- lib/data/location/importer.v | 157 ++++---- lib/data/location/models.v | 58 +-- lib/data/location/search.v | 10 +- lib/develop/gittools/repository_load.v | 4 +- lib/installers/infra/gitea/gitea_actions.v | 113 +++--- lib/installers/infra/gitea/gitea_factory_.v | 372 +++++++++--------- lib/installers/infra/gitea/gitea_model.v | 42 +- lib/osal/tmux/tmux_window_test.v | 24 +- lib/web/docusaurus/dsite.v | 188 +++++---- lib/web/docusaurus/factory.v | 2 +- lib/web/docusaurus/template.v | 5 +- manual/create_tag.md | 8 + 26 files changed, 600 insertions(+), 668 deletions(-) create mode 100644 manual/create_tag.md diff --git a/examples/clients/mail.vsh b/examples/clients/mail.vsh index a61074d5..c1578eba 100755 --- a/examples/clients/mail.vsh +++ b/examples/clients/mail.vsh @@ -1,11 +1,9 @@ #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run +import freeflowuniverse.herolib.clients.mailclient -import freeflowuniverse.herolib.clients. mailclient - - -//remove the previous one, otherwise the env variables are not read -mailclient.config_delete(name:"test")! +// remove the previous one, otherwise the env variables are not read +mailclient.config_delete(name: 'test')! // env variables which need to be set are: // - MAIL_FROM=... @@ -14,11 +12,14 @@ mailclient.config_delete(name:"test")! // - MAIL_SERVER=... // - MAIL_USERNAME=... - -mut client:= mailclient.get(name:"test")! +mut client := mailclient.get(name: 'test')! println(client) -client.send(subject:'this is a test',to:'kristof@incubaid.com',body:' +client.send( + subject: 'this is a test' + to: 'kristof@incubaid.com' + body: ' this is my email content - ')! \ No newline at end of file + ' +)! diff --git a/examples/clients/psql.vsh b/examples/clients/psql.vsh index 7b64441b..f38db93f 100755 --- a/examples/clients/psql.vsh +++ b/examples/clients/psql.vsh @@ -3,7 +3,6 @@ import freeflowuniverse.herolib.core import freeflowuniverse.herolib.clients.postgresql_client - // Configure PostgreSQL client heroscript := " !!postgresql_client.configure @@ -19,7 +18,7 @@ heroscript := " postgresql_client.play(heroscript: heroscript)! // Get the configured client -mut db_client := postgresql_client.get(name: "test")! +mut db_client := postgresql_client.get(name: 'test')! // Check if test database exists, create if not if !db_client.db_exists('test')! { @@ -31,15 +30,14 @@ if !db_client.db_exists('test')! { db_client.dbname = 'test' // Create table if not exists -create_table_sql := "CREATE TABLE IF NOT EXISTS users ( +create_table_sql := 'CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -)" +)' println('Creating table users if not exists...') db_client.exec(create_table_sql)! println('Database and table setup completed successfully!') - diff --git a/examples/data/heroencoder_simple.vsh b/examples/data/heroencoder_simple.vsh index c0db981a..6b798a92 100755 --- a/examples/data/heroencoder_simple.vsh +++ b/examples/data/heroencoder_simple.vsh @@ -12,8 +12,8 @@ mut: } mut person := Person{ - name: 'Bob' - birthday: time.now() + name: 'Bob' + birthday: time.now() } heroscript := encoderhero.encode[Person](person)! @@ -22,9 +22,8 @@ println(heroscript) person2 := encoderhero.decode[Person](heroscript)! println(person2) -//show that it doesn't matter which action & method is used -heroscript2:="!!a.b name:Bob age:20 birthday:'2025-02-06 09:57:30'" +// show that it doesn't matter which action & method is used +heroscript2 := "!!a.b name:Bob age:20 birthday:'2025-02-06 09:57:30'" person3 := encoderhero.decode[Person](heroscript)! println(person3) - diff --git a/examples/data/jsonexample.vsh b/examples/data/jsonexample.vsh index a50936e3..f44a85ee 100755 --- a/examples/data/jsonexample.vsh +++ b/examples/data/jsonexample.vsh @@ -1,23 +1,22 @@ #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run - import json enum JobTitle { - manager - executive - worker + manager + executive + worker } struct Employee { mut: - name string - family string @[json: '-'] // this field will be skipped - age int - salary f32 - title JobTitle @[json: 'ETitle'] // the key for this field will be 'ETitle', not 'title' - notes string @[omitempty] // the JSON property is not created if the string is equal to '' (an empty string). - // TODO: document @[raw] + name string + family string @[json: '-'] // this field will be skipped + age int + salary f32 + title JobTitle @[json: 'ETitle'] // the key for this field will be 'ETitle', not 'title' + notes string @[omitempty] // the JSON property is not created if the string is equal to '' (an empty string). + // TODO: document @[raw] } x := Employee{'Peter', 'Begins', 28, 95000.5, .worker, ''} @@ -34,4 +33,3 @@ println(y) ss := json.encode(y) println('JSON encoding of employee y: ${ss}') assert ss == s - diff --git a/examples/data/location/location_example.vsh b/examples/data/location/location_example.vsh index 94c3f1ba..1ebb0bfb 100755 --- a/examples/data/location/location_example.vsh +++ b/examples/data/location/location_example.vsh @@ -18,8 +18,7 @@ heroscript := " postgresql_client.play(heroscript: heroscript)! // Get the configured client -mut db_client := postgresql_client.get(name: "test")! - +mut db_client := postgresql_client.get(name: 'test')! // Create a new location instance mut loc := location.new(mut db_client, false) or { panic(err) } diff --git a/examples/data/location/location_example_tcc.vsh b/examples/data/location/location_example_tcc.vsh index ab1a7efe..66a00fcb 100755 --- a/examples/data/location/location_example_tcc.vsh +++ b/examples/data/location/location_example_tcc.vsh @@ -18,8 +18,7 @@ heroscript := " postgresql_client.play(heroscript: heroscript)! // Get the configured client -mut db_client := postgresql_client.get(name: "test")! - +mut db_client := postgresql_client.get(name: 'test')! // Create a new location instance mut loc := location.new(mut db_client, false) or { panic(err) } diff --git a/examples/installers/gitea.vsh b/examples/installers/gitea.vsh index d8df7013..8c737731 100755 --- a/examples/installers/gitea.vsh +++ b/examples/installers/gitea.vsh @@ -2,14 +2,15 @@ import freeflowuniverse.herolib.installers.infra.gitea as gitea_installer +mut installer := gitea_installer.get(name: 'test')! -mut installer:= gitea_installer.get(name:'test')! - -//if you want to configure using heroscript -gitea_installer.play(heroscript:" +// if you want to configure using heroscript +gitea_installer.play( + heroscript: " !!gitea.configure name:test passwd:'something' domain: 'docs.info.com' - ")! + " +)! installer.start()! diff --git a/lib/clients/mailclient/mailclient_factory_.v b/lib/clients/mailclient/mailclient_factory_.v index c100f937..371a80e8 100644 --- a/lib/clients/mailclient/mailclient_factory_.v +++ b/lib/clients/mailclient/mailclient_factory_.v @@ -1,127 +1,112 @@ - module mailclient import freeflowuniverse.herolib.core.base import freeflowuniverse.herolib.core.playbook import freeflowuniverse.herolib.ui.console - __global ( - mailclient_global map[string]&MailClient - mailclient_default string + mailclient_global map[string]&MailClient + mailclient_default string ) /////////FACTORY @[params] -pub struct ArgsGet{ +pub struct ArgsGet { pub mut: - name string + name string } -fn args_get (args_ ArgsGet) ArgsGet { - mut args:=args_ - if args.name == ""{ - args.name = mailclient_default - } - if args.name == ""{ - args.name = "default" - } - return args +fn args_get(args_ ArgsGet) ArgsGet { + mut args := args_ + if args.name == '' { + args.name = mailclient_default + } + if args.name == '' { + args.name = 'default' + } + return args } -pub fn get(args_ ArgsGet) !&MailClient { - mut args := args_get(args_) - if !(args.name in mailclient_global) { - if ! config_exists(args){ - config_save(args)! - } - config_load(args)! - } - return mailclient_global[args.name] or { - println(mailclient_global) - //bug if we get here because should be in globals - panic("could not get config for mailclient with name, is bug:${args.name}") - } +pub fn get(args_ ArgsGet) !&MailClient { + mut args := args_get(args_) + if args.name !in mailclient_global { + if !config_exists(args) { + config_save(args)! + } + config_load(args)! + } + return mailclient_global[args.name] or { + println(mailclient_global) + // bug if we get here because should be in globals + panic('could not get config for mailclient with name, is bug:${args.name}') + } } - - pub fn config_exists(args_ ArgsGet) bool { - mut args := args_get(args_) - mut context:=base.context() or { panic("bug") } - return context.hero_config_exists("mailclient",args.name) + mut args := args_get(args_) + mut context := base.context() or { panic('bug') } + return context.hero_config_exists('mailclient', args.name) } pub fn config_load(args_ ArgsGet) ! { - mut args := args_get(args_) - mut context:=base.context()! - mut heroscript := context.hero_config_get("mailclient",args.name)! - play(heroscript:heroscript)! + mut args := args_get(args_) + mut context := base.context()! + mut heroscript := context.hero_config_get('mailclient', args.name)! + play(heroscript: heroscript)! } pub fn config_save(args_ ArgsGet) ! { - mut args := args_get(args_) - mut context:=base.context()! - context.hero_config_set("mailclient",args.name,heroscript_default(instance:args.name)!)! + mut args := args_get(args_) + mut context := base.context()! + context.hero_config_set('mailclient', args.name, heroscript_default(instance: args.name)!)! } - pub fn config_delete(args_ ArgsGet) ! { - mut args := args_get(args_) - mut context:=base.context()! - context.hero_config_delete("mailclient",args.name)! + mut args := args_get(args_) + mut context := base.context()! + context.hero_config_delete('mailclient', args.name)! } -fn set(o MailClient)! { - mut o2:=obj_init(o)! - mailclient_global[o.name] = &o2 - mailclient_default = o.name +fn set(o MailClient) ! { + mut o2 := obj_init(o)! + mailclient_global[o.name] = &o2 + mailclient_default = o.name } - @[params] pub struct PlayArgs { pub mut: - heroscript string //if filled in then plbook will be made out of it - plbook ?playbook.PlayBook - reset bool + heroscript string // if filled in then plbook will be made out of it + plbook ?playbook.PlayBook + reset bool } pub fn play(args_ PlayArgs) ! { - - mut args:=args_ - - if args.heroscript == "" { - args.heroscript = heroscript_default()! - } - mut plbook := args.plbook or { - playbook.new(text: args.heroscript)! - } - - mut install_actions := plbook.find(filter: 'mailclient.configure')! - if install_actions.len > 0 { - for install_action in install_actions { - mut p := install_action.params - cfg_play(p)! - } - } + mut args := args_ + if args.heroscript == '' { + args.heroscript = heroscript_default()! + } + mut plbook := args.plbook or { playbook.new(text: args.heroscript)! } + mut install_actions := plbook.find(filter: 'mailclient.configure')! + if install_actions.len > 0 { + for install_action in install_actions { + mut p := install_action.params + cfg_play(p)! + } + } } - - - -//switch instance to be used for mailclient +// switch instance to be used for mailclient pub fn switch(name string) { - mailclient_default = name + mailclient_default = name } - -//helpers +// helpers @[params] -pub struct DefaultConfigArgs{ - instance string = 'default' +pub struct DefaultConfigArgs { + instance string = 'default' } diff --git a/lib/clients/mailclient/mailclient_model.v b/lib/clients/mailclient/mailclient_model.v index 85cde253..d9b431d9 100644 --- a/lib/clients/mailclient/mailclient_model.v +++ b/lib/clients/mailclient/mailclient_model.v @@ -1,4 +1,5 @@ module mailclient + import freeflowuniverse.herolib.data.paramsparser import os @@ -6,7 +7,6 @@ pub const version = '0.0.0' const singleton = false const default = true - pub fn heroscript_default(args DefaultConfigArgs) !string { mail_from := os.getenv_opt('MAIL_FROM') or { 'info@example.com' } mail_password := os.getenv_opt('MAIL_PASSWORD') or { 'secretpassword' } @@ -23,7 +23,7 @@ pub fn heroscript_default(args DefaultConfigArgs) !string { mail_username: '${mail_username}' " - return heroscript + return heroscript } @[heap] @@ -40,22 +40,18 @@ pub mut: } fn cfg_play(p paramsparser.Params) ! { - mut mycfg := MailClient{ + mut mycfg := MailClient{ name: p.get_default('name', 'default')! mail_from: p.get('mail_from')! mail_password: p.get('mail_password')! mail_port: p.get_int_default('mail_port', 465)! mail_server: p.get('mail_server')! mail_username: p.get('mail_username')! - } - set(mycfg)! -} - - -fn obj_init(obj_ MailClient)!MailClient{ - mut obj:=obj_ - return obj + } + set(mycfg)! } - - +fn obj_init(obj_ MailClient) !MailClient { + mut obj := obj_ + return obj +} diff --git a/lib/core/base/context.v b/lib/core/base/context.v index f0de79cc..2d22d583 100644 --- a/lib/core/base/context.v +++ b/lib/core/base/context.v @@ -144,7 +144,6 @@ pub fn (mut self Context) hero_config_delete(cat string, name string) ! { config_file.delete()! } - pub fn (mut self Context) hero_config_exists(cat string, name string) bool { path := '${os.home_dir()}/hero/context/${self.config.name}/${cat}__${name}.yaml' return os.exists(path) diff --git a/lib/core/herocmds/docusaurus.v b/lib/core/herocmds/docusaurus.v index c3449411..85aab58a 100644 --- a/lib/core/herocmds/docusaurus.v +++ b/lib/core/herocmds/docusaurus.v @@ -53,7 +53,6 @@ pub fn cmd_docusaurus(mut cmdroot Command) { description: 'update your environment the template and the repo you are working on (git pull).' }) - cmd_run.add_flag(Flag{ flag: .bool required: false @@ -84,29 +83,29 @@ fn cmd_docusaurus_execute(cmd Command) ! { // exit(1) // } - mut docs := docusaurus.new(update:update)! + mut docs := docusaurus.new(update: update)! if build { // Create a new docusaurus site _ := docs.build( - url: url - update:update + url: url + update: update )! } if builddev { // Create a new docusaurus site _ := docs.build_dev( - url: url - update:update + url: url + update: update )! } if dev { // Create a new docusaurus site _ := docs.dev( - url: url - update:update + url: url + update: update )! } } diff --git a/lib/data/location/db.v b/lib/data/location/db.v index 9569eddb..cb879c84 100644 --- a/lib/data/location/db.v +++ b/lib/data/location/db.v @@ -10,16 +10,16 @@ import freeflowuniverse.herolib.clients.postgresql_client // LocationDB handles all database operations for locations pub struct LocationDB { pub mut: - db pg.DB + db pg.DB db_client postgresql_client.PostgresClient - tmp_dir pathlib.Path - db_dir pathlib.Path + tmp_dir pathlib.Path + db_dir pathlib.Path } // new_location_db creates a new LocationDB instance pub fn new_location_db(mut db_client postgresql_client.PostgresClient, reset bool) !LocationDB { - mut db_dir := pathlib.get_dir(path:'${os.home_dir()}/hero/var/db/location.db',create: true)! - + mut db_dir := pathlib.get_dir(path: '${os.home_dir()}/hero/var/db/location.db', create: true)! + // Create locations database if it doesn't exist if !db_client.db_exists('locations')! { db_client.db_create('locations')! @@ -27,15 +27,15 @@ pub fn new_location_db(mut db_client postgresql_client.PostgresClient, reset boo // Switch to locations database db_client.dbname = 'locations' - + // Get the underlying pg.DB connection db := db_client.db()! - + mut loc_db := LocationDB{ - db: db + db: db db_client: db_client - tmp_dir: pathlib.get_dir(path: '/tmp/location/',create: true)! - db_dir: db_dir + tmp_dir: pathlib.get_dir(path: '/tmp/location/', create: true)! + db_dir: db_dir } loc_db.init_tables(reset)! return loc_db @@ -50,7 +50,7 @@ fn (mut l LocationDB) init_tables(reset bool) ! { drop table Country }! } - + sql l.db { create table Country create table City diff --git a/lib/data/location/factory.v b/lib/data/location/factory.v index afe2139f..eb8d9766 100644 --- a/lib/data/location/factory.v +++ b/lib/data/location/factory.v @@ -5,7 +5,7 @@ import freeflowuniverse.herolib.clients.postgresql_client // Location represents the main API for location operations pub struct Location { mut: - db LocationDB + db LocationDB db_client postgresql_client.PostgresClient } @@ -13,7 +13,7 @@ mut: pub fn new(mut db_client postgresql_client.PostgresClient, reset bool) !Location { db := new_location_db(mut db_client, reset)! return Location{ - db: db + db: db db_client: db_client } } @@ -28,7 +28,7 @@ pub fn (mut l Location) download_and_import(redownload bool) ! { fn main() ! { // Configure and get PostgreSQL client heroscript := " - !!postgresql_client.configure + !!postgresql_client.configure name:'test' user: 'postgres' port: 5432 diff --git a/lib/data/location/geonames.v b/lib/data/location/geonames.v index d722e5a0..00406873 100644 --- a/lib/data/location/geonames.v +++ b/lib/data/location/geonames.v @@ -1,4 +1,3 @@ module location -//https://www.geonames.org/export/codes.html - +// https://www.geonames.org/export/codes.html diff --git a/lib/data/location/importer.v b/lib/data/location/importer.v index 2af18738..98104d59 100644 --- a/lib/data/location/importer.v +++ b/lib/data/location/importer.v @@ -7,27 +7,24 @@ import freeflowuniverse.herolib.osal import freeflowuniverse.herolib.ui.console import freeflowuniverse.herolib.core.texttools -const ( - geonames_url = 'https://download.geonames.org/export/dump' -) +const geonames_url = 'https://download.geonames.org/export/dump' // download_and_import_data downloads and imports GeoNames data pub fn (mut l LocationDB) download_and_import_data(redownload bool) ! { // Download country info - if redownload{ + if redownload { l.reset_import_dates()! } country_file := osal.download( - url: '${geonames_url}/countryInfo.txt' - dest: '${l.tmp_dir.path}/country.txt' + url: '${geonames_url}/countryInfo.txt' + dest: '${l.tmp_dir.path}/country.txt' minsize_kb: 10 )! l.import_country_data(country_file.path)! l.import_cities()! - } // reset_import_dates sets all country import_dates to 0 @@ -41,9 +38,9 @@ pub fn (mut l LocationDB) reset_import_dates() ! { // should_import_cities checks if a city should be imported based on its last import date on country level fn (mut l LocationDB) should_import_cities(iso2 string) !bool { console.print_debug('Checking if should import country: ${iso2}') - + country := sql l.db { - select from Country where iso2 == "${iso2}" limit 1 + select from Country where iso2 == '${iso2}' limit 1 } or { []Country{} } console.print_debug('SQL query result: ${country.len} records found') @@ -58,11 +55,11 @@ fn (mut l LocationDB) should_import_cities(iso2 string) !bool { one_month := i64(30 * 24 * 60 * 60) // 30 days in seconds last_import := country[0].import_date time_since_import := now - last_import - - console.print_debug('Last import: ${last_import}, Time since import: ${time_since_import} seconds (${time_since_import/86400} days)') - should_import := (time_since_import > one_month) || (last_import == 0) + + console.print_debug('Last import: ${last_import}, Time since import: ${time_since_import} seconds (${time_since_import / 86400} days)') + should_import := time_since_import > one_month || last_import == 0 console.print_debug('Should import ${iso2}: ${should_import}') - + return should_import } @@ -70,10 +67,10 @@ fn (mut l LocationDB) should_import_cities(iso2 string) !bool { fn (mut l LocationDB) import_country_data(filepath string) ! { console.print_header('Starting import from: ${filepath}') l.db.exec('BEGIN TRANSACTION')! - - mut file := os.open(filepath) or { + + mut file := os.open(filepath) or { console.print_stderr('Failed to open country file: ${err}') - return err + return err } defer { file.close() } @@ -98,39 +95,34 @@ fn (mut l LocationDB) import_country_data(filepath string) ! { } or { []Country{} } country := Country{ - iso2: iso2 - iso3: fields[1] - name: fields[4] - continent: fields[8] + iso2: iso2 + iso3: fields[1] + name: fields[4] + continent: fields[8] population: fields[7].i64() - timezone: fields[17] + timezone: fields[17] } - + if existing_country.len > 0 { // Update existing country sql l.db { - update Country set - iso3 = country.iso3, - name = country.name, - continent = country.continent, - population = country.population, - timezone = country.timezone - where iso2 == iso2 + update Country set iso3 = country.iso3, name = country.name, continent = country.continent, + population = country.population, timezone = country.timezone where iso2 == iso2 }! - //console.print_debug("Updated country: ${country}") + // console.print_debug("Updated country: ${country}") } else { // Insert new country sql l.db { insert country into Country }! - //console.print_debug("Inserted country: ${country}") + // console.print_debug("Inserted country: ${country}") } count++ if count % 10 == 0 { console.print_header('Processed ${count} countries') } } - + l.db.exec('COMMIT')! console.print_header('Finished importing countries. Total records: ${count}') } @@ -158,13 +150,13 @@ fn (mut l LocationDB) import_cities() ! { // Download and process cities for this country cities_file := osal.download( - url: '${geonames_url}/${iso2}.zip' - dest: '${l.tmp_dir.path}/${iso2}.zip' + url: '${geonames_url}/${iso2}.zip' + dest: '${l.tmp_dir.path}/${iso2}.zip' expand_file: '${l.tmp_dir.path}/${iso2}' - minsize_kb: 2 + minsize_kb: 2 )! - l.import_city_data("${l.tmp_dir.path}/${iso2}/${iso2}.txt")! + l.import_city_data('${l.tmp_dir.path}/${iso2}/${iso2}.txt')! // Update the country's import date after successful city import now := time.now().unix() @@ -193,36 +185,34 @@ fn (mut l LocationDB) import_city_data(filepath string) ! { // country code : ISO-3166 2-letter country code, 2 characters // cc2 : alternate country codes, comma separated, ISO-3166 2-letter country code, 200 characters // admin1 code : fipscode (subject to change to iso code), see exceptions below, see file admin1Codes.txt for display names of this code; varchar(20) - // admin2 code : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) + // admin2 code : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) // admin3 code : code for third level administrative division, varchar(20) // admin4 code : code for fourth level administrative division, varchar(20) - // population : bigint (8 byte int) + // population : bigint (8 byte int) // elevation : in meters, integer // dem : digital elevation model, srtm3 or gtopo30, average elevation of 3''x3'' (ca 90mx90m) or 30''x30'' (ca 900mx900m) area in meters, integer. srtm processed by cgiar/ciat. // timezone : the iana timezone id (see file timeZone.txt) varchar(40) // modification date : date of last modification in yyyy-MM-dd format - - l.db.exec('BEGIN TRANSACTION')! - mut file := os.open(filepath) or { + mut file := os.open(filepath) or { console.print_stderr('Failed to open city file: ${err}') - return err + return err } defer { file.close() } - mut reader := io.new_buffered_reader(reader:file) + mut reader := io.new_buffered_reader(reader: file) defer { reader.free() } mut count := 0 console.print_header('Start import ${filepath}') for { - line := reader.read_line() or { - //console.print_debug('End of file reached') - break + line := reader.read_line() or { + // console.print_debug('End of file reached') + break } - //console.print_debug(line) + // console.print_debug(line) fields := line.split('\t') if fields.len < 12 { // Need at least 12 fields for required data console.print_stderr('fields < 12: ${line}') @@ -234,65 +224,52 @@ fn (mut l LocationDB) import_city_data(filepath string) ! { name := fields[1] ascii_name := texttools.name_fix(fields[2]) country_iso2 := fields[8].to_upper() - + // Check if city exists existing_city := sql l.db { select from City where id == geoname_id } or { []City{} } city := City{ - id: geoname_id - name: name - ascii_name: ascii_name - country_iso2: country_iso2 - postal_code: '' // Not provided in this format - state_name: '' // Will need separate admin codes file - state_code: fields[10] - county_name: '' - county_code: fields[11] - community_name: '' - community_code: '' - latitude: fields[4].f64() - longitude: fields[5].f64() - accuracy: 4 // Using geonameid, so accuracy is 4 - population: fields[14].i64() - timezone: fields[17] - feature_class: fields[6] - feature_code: fields[7] + id: geoname_id + name: name + ascii_name: ascii_name + country_iso2: country_iso2 + postal_code: '' // Not provided in this format + state_name: '' // Will need separate admin codes file + state_code: fields[10] + county_name: '' + county_code: fields[11] + community_name: '' + community_code: '' + latitude: fields[4].f64() + longitude: fields[5].f64() + accuracy: 4 // Using geonameid, so accuracy is 4 + population: fields[14].i64() + timezone: fields[17] + feature_class: fields[6] + feature_code: fields[7] search_priority: 0 // Default priority } if existing_city.len > 0 { // Update existing city sql l.db { - update City set - name = city.name, - ascii_name = city.ascii_name, - country_iso2 = city.country_iso2, - postal_code = city.postal_code, - state_name = city.state_name, - state_code = city.state_code, - county_name = city.county_name, - county_code = city.county_code, - community_name = city.community_name, - community_code = city.community_code, - latitude = city.latitude, - longitude = city.longitude, - accuracy = city.accuracy, - population = city.population, - timezone = city.timezone, - feature_class = city.feature_class, - feature_code = city.feature_code, - search_priority = city.search_priority - where id == geoname_id + update City set name = city.name, ascii_name = city.ascii_name, country_iso2 = city.country_iso2, + postal_code = city.postal_code, state_name = city.state_name, state_code = city.state_code, + county_name = city.county_name, county_code = city.county_code, community_name = city.community_name, + community_code = city.community_code, latitude = city.latitude, longitude = city.longitude, + accuracy = city.accuracy, population = city.population, timezone = city.timezone, + feature_class = city.feature_class, feature_code = city.feature_code, + search_priority = city.search_priority where id == geoname_id }! - //console.print_debug("Updated city: ${city}") + // console.print_debug("Updated city: ${city}") } else { // Insert new city sql l.db { insert city into City }! - //console.print_debug("Inserted city: ${city}") + // console.print_debug("Inserted city: ${city}") } count++ // if count % 1000 == 0 { @@ -300,8 +277,8 @@ fn (mut l LocationDB) import_city_data(filepath string) ! { // } } - console.print_debug( 'Processed ${count} cities') - + console.print_debug('Processed ${count} cities') + l.db.exec('COMMIT')! console.print_header('Finished importing cities for ${filepath}. Total records: ${count}') } diff --git a/lib/data/location/models.v b/lib/data/location/models.v index c5b921a4..107920ef 100644 --- a/lib/data/location/models.v +++ b/lib/data/location/models.v @@ -2,44 +2,44 @@ module location pub struct Country { pub: - iso2 string @[primary; sql: 'iso2'; max_len: 2; unique; index] - name string @[required; unique; index] - iso3 string @[required; sql: 'iso3'; max_len: 3; unique; index] + iso2 string @[index; max_len: 2; primary; sql: 'iso2'; unique] + name string @[index; required; unique] + iso3 string @[index; max_len: 3; required; sql: 'iso3'; unique] continent string @[max_len: 2] population i64 timezone string @[max_len: 40] - import_date i64 // Epoch timestamp of last import + import_date i64 // Epoch timestamp of last import } pub struct City { pub: - id int @[unique; index] - name string @[required; max_len: 200; index] - ascii_name string @[required; max_len: 200; index] // Normalized name without special characters - country_iso2 string @[required; fkey: 'Country.iso2'] - postal_code string @[max_len: 20; index ] //postal code - state_name string @[max_len: 100] // State/Province name - state_code string @[max_len: 20] // State/Province code - county_name string @[max_len: 100] - county_code string @[max_len: 20] - community_name string @[max_len: 100] - community_code string @[max_len: 20] - latitude f64 @[index: 'idx_coords'] - longitude f64 @[index: 'idx_coords'] - population i64 - timezone string @[max_len: 40] - feature_class string @[max_len: 1] // For filtering (P for populated places) - feature_code string @[max_len: 10] // Detailed type (PPL, PPLA, etc.) + id int @[index; unique] + name string @[index; max_len: 200; required] + ascii_name string @[index; max_len: 200; required] // Normalized name without special characters + country_iso2 string @[fkey: 'Country.iso2'; required] + postal_code string @[index; max_len: 20] // postal code + state_name string @[max_len: 100] // State/Province name + state_code string @[max_len: 20] // State/Province code + county_name string @[max_len: 100] + county_code string @[max_len: 20] + community_name string @[max_len: 100] + community_code string @[max_len: 20] + latitude f64 @[index: 'idx_coords'] + longitude f64 @[index: 'idx_coords'] + population i64 + timezone string @[max_len: 40] + feature_class string @[max_len: 1] // For filtering (P for populated places) + feature_code string @[max_len: 10] // Detailed type (PPL, PPLA, etc.) search_priority int - accuracy i16 = 1 //1=estimated, 4=geonameid, 6=centroid of addresses or shape + accuracy i16 = 1 // 1=estimated, 4=geonameid, 6=centroid of addresses or shape } pub struct AlternateName { pub: - id int @[primary; sql: serial] - city_id int @[required; fkey: 'City.id'] - name string @[required; max_len: 200; index] - language_code string @[max_len: 2] + id int @[primary; sql: serial] + city_id int @[fkey: 'City.id'; required] + name string @[index; max_len: 200; required] + language_code string @[max_len: 2] is_preferred bool is_short bool } @@ -47,9 +47,9 @@ pub: // SearchResult represents a location search result with combined city and country info pub struct SearchResult { pub: - city City - country Country - similarity f64 // Search similarity score + city City + country Country + similarity f64 // Search similarity score } // Coordinates represents a geographic point diff --git a/lib/data/location/search.v b/lib/data/location/search.v index 4c276427..cfb604ed 100644 --- a/lib/data/location/search.v +++ b/lib/data/location/search.v @@ -51,11 +51,11 @@ import db.pg // where_clause := if query_conditions.len > 0 { 'WHERE ' + query_conditions.join(' AND ') } else { '' } // query := ' -// SELECT c.*, co.* +// SELECT c.*, co.* // FROM City c // JOIN Country co ON c.country_iso2 = co.iso2 // ${where_clause} -// ORDER BY c.search_priority DESC, c.population DESC +// ORDER BY c.search_priority DESC, c.population DESC // LIMIT ${opts.limit} // ' @@ -111,8 +111,8 @@ import db.pg // query := " // WITH distances AS ( // SELECT c.*, co.*, -// (6371 * acos(cos(radians($1)) * cos(radians(latitude)) * -// cos(radians(longitude) - radians($2)) + sin(radians($1)) * +// (6371 * acos(cos(radians($1)) * cos(radians(latitude)) * +// cos(radians(longitude) - radians($2)) + sin(radians($1)) * // sin(radians(latitude)))) AS distance // FROM City c // JOIN Country co ON c.country_iso2 = co.iso2 @@ -122,7 +122,7 @@ import db.pg // ORDER BY distance // LIMIT $4 // " - + // params := [ // opts.coordinates.latitude.str(), // opts.coordinates.longitude.str(), diff --git a/lib/develop/gittools/repository_load.v b/lib/develop/gittools/repository_load.v index 051d57ec..5d561af9 100644 --- a/lib/develop/gittools/repository_load.v +++ b/lib/develop/gittools/repository_load.v @@ -97,13 +97,13 @@ fn (mut repo GitRepo) load_tags() ! { tags_result := repo.exec('git tag --list') or { return error('Failed to list tags: ${err}. Please ensure git is installed and repository is accessible.') } - //println(tags_result) + // println(tags_result) for line in tags_result.split('\n') { line_trimmed := line.trim_space() if line_trimmed != '' { parts := line_trimmed.split(' ') if parts.len < 2 { - //console.print_debug('Skipping malformed tag line: ${line_trimmed}') + // console.print_debug('Skipping malformed tag line: ${line_trimmed}') continue } commit_hash := parts[0].trim_space() diff --git a/lib/installers/infra/gitea/gitea_actions.v b/lib/installers/infra/gitea/gitea_actions.v index e9525605..6e06eab3 100644 --- a/lib/installers/infra/gitea/gitea_actions.v +++ b/lib/installers/infra/gitea/gitea_actions.v @@ -25,22 +25,21 @@ fn installed() !bool { } fn install() ! { - console.print_header('install gitea') - baseurl:="https://github.com/go-gitea/gitea/releases/download/v${version}/gitea-${version}" + baseurl := 'https://github.com/go-gitea/gitea/releases/download/v${version}/gitea-${version}' mut url := '' - if core.is_linux_arm()! { - //https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-linux-arm64.xz + if core.is_linux_arm()! { + // https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-linux-arm64.xz url = '${baseurl}-linux-arm64.xz' } else if core.is_linux_intel()! { // https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-linux-amd64.xz url = '${baseurl}-linux-amd64.xz' } else if core.is_osx_arm()! { - //https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-arm64.xz + // https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-arm64.xz url = '${baseurl}-darwin-10.12-arm64.xz' } else if core.is_osx_intel()! { - //https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-amd64.xz + // https://github.com/go-gitea/gitea/releases/download/v1.23.2/gitea-1.23.2-darwin-10.12-amd64.xz url = '${baseurl}-darwin-10.12-amd64.xz' } else { return error('unsported platform') @@ -104,68 +103,66 @@ fn startupcmd() ![]zinit.ZProcessNewArgs { } return res + // mut res := []zinit.ZProcessNewArgs{} + // cfg := get()! + // res << zinit.ZProcessNewArgs{ + // name: 'gitea' + // // cmd: 'GITEA_WORK_DIR=${cfg.path} sudo -u git /var/lib/git/gitea web -c /etc/gitea_app.ini' + // cmd: ' + // # Variables + // GITEA_USER="${cfg.run_user}" + // GITEA_HOME="${cfg.path}" + // GITEA_BINARY="/usr/local/bin/gitea" + // GITEA_CONFIG="/etc/gitea_app.ini" + // GITEA_DATA_PATH="\$GITEA_HOME/data" + // GITEA_CUSTOM_PATH="\$GITEA_HOME/custom" + // GITEA_LOG_PATH="\$GITEA_HOME/log" -// mut res := []zinit.ZProcessNewArgs{} -// cfg := get()! -// res << zinit.ZProcessNewArgs{ -// name: 'gitea' -// // cmd: 'GITEA_WORK_DIR=${cfg.path} sudo -u git /var/lib/git/gitea web -c /etc/gitea_app.ini' -// cmd: ' + // # Ensure the script is run as root + // if [[ \$EUID -ne 0 ]]; then + // echo "This script must be run as root." + // exit 1 + // fi -// # Variables -// GITEA_USER="${cfg.run_user}" -// GITEA_HOME="${cfg.path}" -// GITEA_BINARY="/usr/local/bin/gitea" -// GITEA_CONFIG="/etc/gitea_app.ini" -// GITEA_DATA_PATH="\$GITEA_HOME/data" -// GITEA_CUSTOM_PATH="\$GITEA_HOME/custom" -// GITEA_LOG_PATH="\$GITEA_HOME/log" + // echo "Setting up Gitea..." -// # Ensure the script is run as root -// if [[ \$EUID -ne 0 ]]; then -// echo "This script must be run as root." -// exit 1 -// fi + // # Create Gitea user if it doesn\'t exist + // if id -u "\$GITEA_USER" &>/dev/null; then + // echo "User \$GITEA_USER already exists." + // else + // echo "Creating Gitea user..." + // if ! sudo adduser --system --shell /bin/bash --group --disabled-password --home "/var/lib/\$GITEA_USER" "\$GITEA_USER"; then + // echo "Failed to create user \$GITEA_USER." + // exit 1 + // fi + // fi -// echo "Setting up Gitea..." + // # Create necessary directories + // echo "Creating directories..." + // mkdir -p "\$GITEA_DATA_PATH" "\$GITEA_CUSTOM_PATH" "\$GITEA_LOG_PATH" + // chown -R "\$GITEA_USER:\$GITEA_USER" "\$GITEA_HOME" + // chmod -R 750 "\$GITEA_HOME" -// # Create Gitea user if it doesn\'t exist -// if id -u "\$GITEA_USER" &>/dev/null; then -// echo "User \$GITEA_USER already exists." -// else -// echo "Creating Gitea user..." -// if ! sudo adduser --system --shell /bin/bash --group --disabled-password --home "/var/lib/\$GITEA_USER" "\$GITEA_USER"; then -// echo "Failed to create user \$GITEA_USER." -// exit 1 -// fi -// fi + // chown "\$GITEA_USER:\$GITEA_USER" "\$GITEA_CONFIG" + // chmod 640 "\$GITEA_CONFIG" -// # Create necessary directories -// echo "Creating directories..." -// mkdir -p "\$GITEA_DATA_PATH" "\$GITEA_CUSTOM_PATH" "\$GITEA_LOG_PATH" -// chown -R "\$GITEA_USER:\$GITEA_USER" "\$GITEA_HOME" -// chmod -R 750 "\$GITEA_HOME" - -// chown "\$GITEA_USER:\$GITEA_USER" "\$GITEA_CONFIG" -// chmod 640 "\$GITEA_CONFIG" - -// GITEA_WORK_DIR=\$GITEA_HOME sudo -u git gitea web -c \$GITEA_CONFIG -// ' -// workdir: cfg.path -// } -// res << zinit.ZProcessNewArgs{ -// name: 'restart_gitea' -// cmd: 'sleep 30 && zinit restart gitea && exit 1' -// after: ['gitea'] -// oneshot: true -// workdir: cfg.path -// } -// return res + // GITEA_WORK_DIR=\$GITEA_HOME sudo -u git gitea web -c \$GITEA_CONFIG + // ' + // workdir: cfg.path + // } + // res << zinit.ZProcessNewArgs{ + // name: 'restart_gitea' + // cmd: 'sleep 30 && zinit restart gitea && exit 1' + // after: ['gitea'] + // oneshot: true + // workdir: cfg.path + // } + // return res } fn running() !bool { - //TODO: extend with proper gitea client + // TODO: extend with proper gitea client res := os.execute('curl -fsSL http://localhost:3000 || exit 1') return res.exit_code == 0 } diff --git a/lib/installers/infra/gitea/gitea_factory_.v b/lib/installers/infra/gitea/gitea_factory_.v index 5254bb21..c0fd64d5 100644 --- a/lib/installers/infra/gitea/gitea_factory_.v +++ b/lib/installers/infra/gitea/gitea_factory_.v @@ -4,287 +4,277 @@ import freeflowuniverse.herolib.core.base import freeflowuniverse.herolib.core.playbook import freeflowuniverse.herolib.ui.console import freeflowuniverse.herolib.data.paramsparser - import freeflowuniverse.herolib.sysadmin.startupmanager import freeflowuniverse.herolib.osal.zinit import time __global ( - gitea_global map[string]&GiteaServer - gitea_default string + gitea_global map[string]&GiteaServer + gitea_default string ) /////////FACTORY @[params] -pub struct ArgsGet{ +pub struct ArgsGet { pub mut: - name string + name string } -fn args_get (args_ ArgsGet) ArgsGet { - mut args:=args_ - if args.name == ""{ - args.name = "default" - } - return args +fn args_get(args_ ArgsGet) ArgsGet { + mut args := args_ + if args.name == '' { + args.name = 'default' + } + return args } -pub fn get(args_ ArgsGet) !&GiteaServer { - mut context:=base.context()! - mut args := args_get(args_) - mut obj := GiteaServer{} - if !(args.name in gitea_global) { - if ! exists(args)!{ - set(obj)! - }else{ - heroscript := context.hero_config_get("gitea",args.name)! - mut obj2:=heroscript_loads(heroscript)! - set_in_mem(obj2)! - } - } - return gitea_global[args.name] or { - println(gitea_global) - //bug if we get here because should be in globals - panic("could not get config for gitea with name, is bug:${args.name}") - } +pub fn get(args_ ArgsGet) !&GiteaServer { + mut context := base.context()! + mut args := args_get(args_) + mut obj := GiteaServer{} + if args.name !in gitea_global { + if !exists(args)! { + set(obj)! + } else { + heroscript := context.hero_config_get('gitea', args.name)! + mut obj2 := heroscript_loads(heroscript)! + set_in_mem(obj2)! + } + } + return gitea_global[args.name] or { + println(gitea_global) + // bug if we get here because should be in globals + panic('could not get config for gitea with name, is bug:${args.name}') + } } -//register the config for the future -pub fn set(o GiteaServer)! { - set_in_mem(o)! - mut context := base.context()! - heroscript := heroscript_dumps(o)! - context.hero_config_set("gitea", o.name, heroscript)! +// register the config for the future +pub fn set(o GiteaServer) ! { + set_in_mem(o)! + mut context := base.context()! + heroscript := heroscript_dumps(o)! + context.hero_config_set('gitea', o.name, heroscript)! } -//does the config exists? +// does the config exists? pub fn exists(args_ ArgsGet) !bool { - mut context := base.context()! - mut args := args_get(args_) - return context.hero_config_exists("gitea", args.name) + mut context := base.context()! + mut args := args_get(args_) + return context.hero_config_exists('gitea', args.name) } -pub fn delete(args_ ArgsGet)! { - mut args := args_get(args_) - mut context:=base.context()! - context.hero_config_delete("gitea",args.name)! - if args.name in gitea_global { - //del gitea_global[args.name] - } +pub fn delete(args_ ArgsGet) ! { + mut args := args_get(args_) + mut context := base.context()! + context.hero_config_delete('gitea', args.name)! + if args.name in gitea_global { + // del gitea_global[args.name] + } } -//only sets in mem, does not set as config -fn set_in_mem(o GiteaServer)! { - mut o2:=obj_init(o)! - gitea_global[o.name] = &o2 - gitea_default = o.name +// only sets in mem, does not set as config +fn set_in_mem(o GiteaServer) ! { + mut o2 := obj_init(o)! + gitea_global[o.name] = &o2 + gitea_default = o.name } - @[params] pub struct PlayArgs { pub mut: - heroscript string //if filled in then plbook will be made out of it - plbook ?playbook.PlayBook - reset bool + heroscript string // if filled in then plbook will be made out of it + plbook ?playbook.PlayBook + reset bool } pub fn play(args_ PlayArgs) ! { - - mut args:=args_ + mut args := args_ - mut plbook := args.plbook or { - playbook.new(text: args.heroscript)! - } - - mut install_actions := plbook.find(filter: 'gitea.configure')! - if install_actions.len > 0 { - for install_action in install_actions { - heroscript:=install_action.heroscript() - mut obj:=heroscript_loads(heroscript)! - set(obj)! - } - } + mut plbook := args.plbook or { playbook.new(text: args.heroscript)! } - mut other_actions := plbook.find(filter: 'gitea.')! - for other_action in other_actions { - if other_action.name in ["destroy","install","build"]{ - mut p := other_action.params - reset:=p.get_default_false("reset") - if other_action.name == "destroy" || reset{ - console.print_debug("install action gitea.destroy") - destroy()! - } - if other_action.name == "install"{ - console.print_debug("install action gitea.install") - install()! - } - } - if other_action.name in ["start","stop","restart"]{ - mut p := other_action.params - name := p.get('name')! - mut gitea_obj:=get(name:name)! - console.print_debug("action object:\n${gitea_obj}") - if other_action.name == "start"{ - console.print_debug("install action gitea.${other_action.name}") - gitea_obj.start()! - } + mut install_actions := plbook.find(filter: 'gitea.configure')! + if install_actions.len > 0 { + for install_action in install_actions { + heroscript := install_action.heroscript() + mut obj := heroscript_loads(heroscript)! + set(obj)! + } + } - if other_action.name == "stop"{ - console.print_debug("install action gitea.${other_action.name}") - gitea_obj.stop()! - } - if other_action.name == "restart"{ - console.print_debug("install action gitea.${other_action.name}") - gitea_obj.restart()! - } - } - } + mut other_actions := plbook.find(filter: 'gitea.')! + for other_action in other_actions { + if other_action.name in ['destroy', 'install', 'build'] { + mut p := other_action.params + reset := p.get_default_false('reset') + if other_action.name == 'destroy' || reset { + console.print_debug('install action gitea.destroy') + destroy()! + } + if other_action.name == 'install' { + console.print_debug('install action gitea.install') + install()! + } + } + if other_action.name in ['start', 'stop', 'restart'] { + mut p := other_action.params + name := p.get('name')! + mut gitea_obj := get(name: name)! + console.print_debug('action object:\n${gitea_obj}') + if other_action.name == 'start' { + console.print_debug('install action gitea.${other_action.name}') + gitea_obj.start()! + } + if other_action.name == 'stop' { + console.print_debug('install action gitea.${other_action.name}') + gitea_obj.stop()! + } + if other_action.name == 'restart' { + console.print_debug('install action gitea.${other_action.name}') + gitea_obj.restart()! + } + } + } } - //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS /////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager { - // unknown - // screen - // zinit - // tmux - // systemd - match cat{ - .zinit{ - console.print_debug("startupmanager: zinit") - return startupmanager.get(cat:.zinit)! - } - .systemd{ - console.print_debug("startupmanager: systemd") - return startupmanager.get(cat:.systemd)! - }else{ - console.print_debug("startupmanager: auto") - return startupmanager.get()! - } - } + // unknown + // screen + // zinit + // tmux + // systemd + match cat { + .zinit { + console.print_debug('startupmanager: zinit') + return startupmanager.get(cat: .zinit)! + } + .systemd { + console.print_debug('startupmanager: systemd') + return startupmanager.get(cat: .systemd)! + } + else { + console.print_debug('startupmanager: auto') + return startupmanager.get()! + } + } } -//load from disk and make sure is properly intialized +// load from disk and make sure is properly intialized pub fn (mut self GiteaServer) reload() ! { - switch(self.name) - self=obj_init(self)! + switch(self.name) + self = obj_init(self)! } pub fn (mut self GiteaServer) start() ! { - switch(self.name) - if self.running()!{ - return - } + switch(self.name) + if self.running()! { + return + } - console.print_header('gitea start') + console.print_header('gitea start') - if ! installed()!{ - install()! - } + if !installed()! { + install()! + } - configure()! + configure()! - start_pre()! + start_pre()! - for zprocess in startupcmd()!{ - mut sm:=startupmanager_get(zprocess.startuptype)! + for zprocess in startupcmd()! { + mut sm := startupmanager_get(zprocess.startuptype)! - console.print_debug('starting gitea with ${zprocess.startuptype}...') + console.print_debug('starting gitea with ${zprocess.startuptype}...') - sm.new(zprocess)! + sm.new(zprocess)! - sm.start(zprocess.name)! - } + sm.start(zprocess.name)! + } - start_post()! - - for _ in 0 .. 50 { - if self.running()! { - return - } - time.sleep(100 * time.millisecond) - } - return error('gitea did not install properly.') + start_post()! + for _ in 0 .. 50 { + if self.running()! { + return + } + time.sleep(100 * time.millisecond) + } + return error('gitea did not install properly.') } pub fn (mut self GiteaServer) install_start(args InstallArgs) ! { - switch(self.name) - self.install(args)! - self.start()! + switch(self.name) + self.install(args)! + self.start()! } pub fn (mut self GiteaServer) stop() ! { - switch(self.name) - stop_pre()! - for zprocess in startupcmd()!{ - mut sm:=startupmanager_get(zprocess.startuptype)! - sm.stop(zprocess.name)! - } - stop_post()! + switch(self.name) + stop_pre()! + for zprocess in startupcmd()! { + mut sm := startupmanager_get(zprocess.startuptype)! + sm.stop(zprocess.name)! + } + stop_post()! } pub fn (mut self GiteaServer) restart() ! { - switch(self.name) - self.stop()! - self.start()! + switch(self.name) + self.stop()! + self.start()! } pub fn (mut self GiteaServer) running() !bool { - switch(self.name) + switch(self.name) - //walk over the generic processes, if not running return - for zprocess in startupcmd()!{ - mut sm:=startupmanager_get(zprocess.startuptype)! - r:=sm.running(zprocess.name)! - if r==false{ - return false - } - } - return running()! + // walk over the generic processes, if not running return + for zprocess in startupcmd()! { + mut sm := startupmanager_get(zprocess.startuptype)! + r := sm.running(zprocess.name)! + if r == false { + return false + } + } + return running()! } @[params] -pub struct InstallArgs{ +pub struct InstallArgs { pub mut: - reset bool + reset bool } pub fn (mut self GiteaServer) install(args InstallArgs) ! { - switch(self.name) - if args.reset || (!installed()!) { - install()! - } + switch(self.name) + if args.reset || (!installed()!) { + install()! + } } pub fn (mut self GiteaServer) build() ! { - switch(self.name) - build()! + switch(self.name) + build()! } pub fn (mut self GiteaServer) destroy() ! { - switch(self.name) - self.stop() or {} - destroy()! + switch(self.name) + self.stop() or {} + destroy()! } - - -//switch instance to be used for gitea +// switch instance to be used for gitea pub fn switch(name string) { - gitea_default = name + gitea_default = name } - -//helpers +// helpers @[params] -pub struct DefaultConfigArgs{ - instance string = 'default' +pub struct DefaultConfigArgs { + instance string = 'default' } diff --git a/lib/installers/infra/gitea/gitea_model.v b/lib/installers/infra/gitea/gitea_model.v index dccaebe5..e26f97ec 100644 --- a/lib/installers/infra/gitea/gitea_model.v +++ b/lib/installers/infra/gitea/gitea_model.v @@ -1,4 +1,5 @@ module gitea + import freeflowuniverse.herolib.data.paramsparser import freeflowuniverse.herolib.data.encoderhero import freeflowuniverse.herolib.core.pathlib @@ -16,30 +17,29 @@ const default = false @[heap] pub struct GiteaServer { pub mut: - name string = 'default' - path string = '${os.home_dir()}/hero/var/gitea' - passwd string - domain string = "git.test.com" - jwt_secret string = rand.hex(12) - lfs_jwt_secret string - internal_token string - secret_key string - postgresql_client_name string = "default" - mail_client_name string = "default" + name string = 'default' + path string = '${os.home_dir()}/hero/var/gitea' + passwd string + domain string = 'git.test.com' + jwt_secret string = rand.hex(12) + lfs_jwt_secret string + internal_token string + secret_key string + postgresql_client_name string = 'default' + mail_client_name string = 'default' } - pub fn (obj GiteaServer) config_path() string { - return '${obj.path}/config.ini' + return '${obj.path}/config.ini' } -//your checking & initialization code if needed -fn obj_init(mycfg_ GiteaServer)!GiteaServer{ - mut mycfg:=mycfg_ - return mycfg +// your checking & initialization code if needed +fn obj_init(mycfg_ GiteaServer) !GiteaServer { + mut mycfg := mycfg_ + return mycfg } -//called before start if done +// called before start if done fn configure() ! { mut server := get()! @@ -68,7 +68,7 @@ fn configure() ! { return error('Failed to initialize mail client "${server.mail_client_name}": ${err}') } - //TODO: check database exists + // TODO: check database exists if !db_client.db_exists('gitea_${server.name}')! { console.print_header('Creating database gitea_${server.name} for gitea.') db_client.db_create('gitea_${server.name}')! @@ -85,10 +85,10 @@ fn configure() ! { /////////////NORMALLY NO NEED TO TOUCH pub fn heroscript_dumps(obj GiteaServer) !string { - return encoderhero.encode[GiteaServer ](obj)! + return encoderhero.encode[GiteaServer](obj)! } pub fn heroscript_loads(heroscript string) !GiteaServer { - mut obj := encoderhero.decode[GiteaServer](heroscript)! - return obj + mut obj := encoderhero.decode[GiteaServer](heroscript)! + return obj } diff --git a/lib/osal/tmux/tmux_window_test.v b/lib/osal/tmux/tmux_window_test.v index 5bb228d0..ccf6582c 100644 --- a/lib/osal/tmux/tmux_window_test.v +++ b/lib/osal/tmux/tmux_window_test.v @@ -10,9 +10,9 @@ fn testsuite_begin() { muttmux := new() or { panic('Cannot create tmux: ${err}') } // reset tmux for tests - is_running := tmux.is_running() or { panic('cannot check if tmux is running: ${err}') } + is_running := is_running() or { panic('cannot check if tmux is running: ${err}') } if is_running { - tmux.stop() or { panic('Cannot stop tmux: ${err}') } + stop() or { panic('Cannot stop tmux: ${err}') } } } @@ -41,27 +41,21 @@ fn test_window_new() ! { // tests creating duplicate windows fn test_window_new0() { + installer := get_install()! - - installer := tmux.get_install( - - mut tmux := Tmux { + mut tmux := Tmux{ node: node_ssh } - window_args := WindowArgs { + window_args := WindowArgs{ name: 'TestWindow0' } // console.print_debug(tmux) - mut window := tmux.window_new(window_args) or { - panic("Can't create new window: $err") - } + mut window := tmux.window_new(window_args) or { panic("Can't create new window: ${err}") } assert tmux.sessions.keys().contains('main') - mut window_dup := tmux.window_new(window_args) or { - panic("Can't create new window: $err") - } - console.print_debug(node_ssh.exec('tmux ls') or { panic("fail:$err")}) - window.delete() or { panic("Cant delete window") } + mut window_dup := tmux.window_new(window_args) or { panic("Can't create new window: ${err}") } + console.print_debug(node_ssh.exec('tmux ls') or { panic('fail:${err}') }) + window.delete() or { panic('Cant delete window') } // console.print_debug(tmux) } diff --git a/lib/web/docusaurus/dsite.v b/lib/web/docusaurus/dsite.v index 91ea5a60..b7624ddc 100644 --- a/lib/web/docusaurus/dsite.v +++ b/lib/web/docusaurus/dsite.v @@ -13,58 +13,58 @@ import freeflowuniverse.herolib.ui.console @[heap] pub struct DocSite { pub mut: - name string - url string - path_src pathlib.Path - path_build pathlib.Path + name string + url string + path_src pathlib.Path + path_build pathlib.Path // path_publish pathlib.Path - args DSiteNewArgs - errors []SiteError + args DSiteNewArgs + errors []SiteError config Config } @[params] pub struct DSiteNewArgs { pub mut: - name string - nameshort string - path string - url string + name string + nameshort string + path string + url string // publish_path string - build_path string - production bool + build_path string + production bool watch_changes bool = true - update bool + update bool } pub fn (mut f DocusaurusFactory) build_dev(args_ DSiteNewArgs) !&DocSite { - mut s:=f.add(args_)! + mut s := f.add(args_)! s.generate()! osal.exec( - cmd: ' + cmd: ' cd ${s.path_build.path} bash build_dev.sh ' retry: 0 - )! + )! return s } pub fn (mut f DocusaurusFactory) build(args_ DSiteNewArgs) !&DocSite { - mut s:=f.add(args_)! + mut s := f.add(args_)! s.generate()! osal.exec( - cmd: ' + cmd: ' cd ${s.path_build.path} bash build.sh ' retry: 0 - )! + )! return s } pub fn (mut f DocusaurusFactory) dev(args_ DSiteNewArgs) !&DocSite { - mut s:=f.add(args_)! + mut s := f.add(args_)! s.clean()! s.generate()! @@ -72,14 +72,14 @@ pub fn (mut f DocusaurusFactory) dev(args_ DSiteNewArgs) !&DocSite { // Create screen session for docusaurus development server mut screen_name := 'docusaurus' mut sf := screen.new()! - + // Add and start a new screen session mut scr := sf.add( - name: screen_name - cmd: '/bin/bash' - start: true + name: screen_name + cmd: '/bin/bash' + start: true attach: false - reset: true + reset: true )! // Send commands to the screen session @@ -93,33 +93,29 @@ pub fn (mut f DocusaurusFactory) dev(args_ DSiteNewArgs) !&DocSite { console.print_item(' 1. Attach to screen: screen -r ${screen_name}') console.print_item(' 2. To detach from screen: Press Ctrl+A then D') console.print_item(' 3. To list all screens: screen -ls') - console.print_item('The site content is on::') + console.print_item('The site content is on::') console.print_item(' 1. location of documents: ${s.path_src.path}/docs') - if osal.cmd_exists("code"){ + if osal.cmd_exists('code') { console.print_item(' 2. We opened above dir in vscode.') - osal.exec(cmd:'code ${s.path_src.path}/docs')! + osal.exec(cmd: 'code ${s.path_src.path}/docs')! } - // Start the watcher in a separate thread - //mut tf:=spawn watch_docs(docs_path, s.path_src.path, s.path_build.path) - //tf.wait()! - println("\n") + // mut tf:=spawn watch_docs(docs_path, s.path_src.path, s.path_build.path) + // tf.wait()! + println('\n') if args_.watch_changes { docs_path := '${s.path_src.path}/docs' watch_docs(docs_path, s.path_src.path, s.path_build.path)! - } - + } return s } - ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// - pub fn (mut f DocusaurusFactory) add(args_ DSiteNewArgs) !&DocSite { console.print_header(' Docusaurus: ${args_.name}') mut args := args_ @@ -129,62 +125,57 @@ pub fn (mut f DocusaurusFactory) add(args_ DSiteNewArgs) !&DocSite { } // if args.publish_path.len == 0 { // args.publish_path = '${f.path_publish.path}/${args.name}' - - - if args.url.len>0{ + if args.url.len > 0 { mut gs := gittools.new()! args.path = gs.get_path(url: args.url)! - } - if args.path.len==0{ + if args.path.len == 0 { return error("Can't get path from docusaurus site, its not specified.") - } mut gs := gittools.new()! - mut r := gs.get_repo(url: 'https://github.com/freeflowuniverse/docusaurus_template.git',pull:args.update)! + mut r := gs.get_repo( + url: 'https://github.com/freeflowuniverse/docusaurus_template.git' + pull: args.update + )! mut template_path := r.patho()! // First ensure cfg directory exists in src, if not copy from template - if !os.exists("${args.path}/cfg") { - mut template_cfg := template_path.dir_get("cfg")! - template_cfg.copy(dest:"${args.path}/cfg")! + if !os.exists('${args.path}/cfg') { + mut template_cfg := template_path.dir_get('cfg')! + template_cfg.copy(dest: '${args.path}/cfg')! } - if !os.exists("${args.path}/docs") { - mut template_cfg := template_path.dir_get("docs")! - template_cfg.copy(dest:"${args.path}/docs")! + if !os.exists('${args.path}/docs') { + mut template_cfg := template_path.dir_get('docs')! + template_cfg.copy(dest: '${args.path}/docs')! } + mut myconfig := load_config('${args.path}/cfg')! - mut myconfig:=load_config("${args.path}/cfg")! - - if myconfig.main.name.len==0{ - myconfig.main.name = myconfig.main.base_url.trim_space().trim("/").trim_space() + if myconfig.main.name.len == 0 { + myconfig.main.name = myconfig.main.base_url.trim_space().trim('/').trim_space() } - if args.name == '' { args.name = myconfig.main.name - } + } if args.nameshort.len == 0 { args.nameshort = args.name - } + } args.nameshort = texttools.name_fix(args.nameshort) - - mut ds := DocSite{ - name: args.name - url: args.url - path_src: pathlib.get_dir(path: args.path, create: false)! + name: args.name + url: args.url + path_src: pathlib.get_dir(path: args.path, create: false)! path_build: f.path_build // path_publish: pathlib.get_dir(path: args.publish_path, create: true)! - args: args - config:myconfig + args: args + config: myconfig } f.sites << &ds @@ -201,9 +192,9 @@ pub mut: } pub fn (mut site DocSite) error(args ErrorArgs) { - // path2 := pathlib.get(args.path) - e := SiteError{ - path: args.path + // path2 := pathlib.get(args.path) + e := SiteError{ + path: args.path msg: args.msg cat: args.cat } @@ -222,21 +213,19 @@ pub fn (mut site DocSite) generate() ! { // retry: 0 // )! - // Now copy all directories that exist in src to build - for item in ["src","static","cfg"]{ - if os.exists("${site.path_src.path}/${item}"){ - mut aa:= site.path_src.dir_get(item)! - aa.copy(dest:"${site.path_build.path}/${item}")! + for item in ['src', 'static', 'cfg'] { + if os.exists('${site.path_src.path}/${item}') { + mut aa := site.path_src.dir_get(item)! + aa.copy(dest: '${site.path_build.path}/${item}')! } } - for item in ["docs"]{ - if os.exists("${site.path_src.path}/${item}"){ - mut aa:= site.path_src.dir_get(item)! - aa.copy(dest:"${site.path_build.path}/${item}",delete:true)! + for item in ['docs'] { + if os.exists('${site.path_src.path}/${item}') { + mut aa := site.path_src.dir_get(item)! + aa.copy(dest: '${site.path_build.path}/${item}', delete: true)! } } - } fn (mut site DocSite) template_install() ! { @@ -245,22 +234,26 @@ fn (mut site DocSite) template_install() ! { mut r := gs.get_repo(url: 'https://github.com/freeflowuniverse/docusaurus_template.git')! mut template_path := r.patho()! - //always start from template first - for item in ["src","static","cfg"]{ - mut aa:= template_path.dir_get(item)! - aa.copy(dest:"${site.path_build.path}/${item}",delete:true)! + // always start from template first + for item in ['src', 'static', 'cfg'] { + mut aa := template_path.dir_get(item)! + aa.copy(dest: '${site.path_build.path}/${item}', delete: true)! } - for item in ['package.json', 'sidebars.ts', 'tsconfig.json','docusaurus.config.ts'] { + for item in ['package.json', 'sidebars.ts', 'tsconfig.json', 'docusaurus.config.ts'] { src_path := os.join_path(template_path.path, item) dest_path := os.join_path(site.path_build.path, item) - os.cp(src_path, dest_path) or { return error('Failed to copy ${item} to build path: ${err}') } + os.cp(src_path, dest_path) or { + return error('Failed to copy ${item} to build path: ${err}') + } } for item in ['.gitignore'] { src_path := os.join_path(template_path.path, item) dest_path := os.join_path(site.path_src.path, item) - os.cp(src_path, dest_path) or { return error('Failed to copy ${item} to source path: ${err}') } + os.cp(src_path, dest_path) or { + return error('Failed to copy ${item} to source path: ${err}') + } } cfg := site.config @@ -269,30 +262,27 @@ fn (mut site DocSite) template_install() ! { build := $tmpl('templates/build.sh') build_dev := $tmpl('templates/build_dev.sh') - mut develop_ := site.path_build.file_get_new("develop.sh")! - develop_.template_write(develop,true)! + mut develop_ := site.path_build.file_get_new('develop.sh')! + develop_.template_write(develop, true)! develop_.chmod(0o700)! - mut build_ := site.path_build.file_get_new("build.sh")! - build_.template_write(build,true)! + mut build_ := site.path_build.file_get_new('build.sh')! + build_.template_write(build, true)! build_.chmod(0o700)! - mut build_dev_ := site.path_build.file_get_new("build_dev.sh")! - build_dev_.template_write(build_dev,true)! + mut build_dev_ := site.path_build.file_get_new('build_dev.sh')! + build_dev_.template_write(build_dev, true)! build_dev_.chmod(0o700)! - mut develop2_ := site.path_src.file_get_new("develop.sh")! - develop2_.template_write(develop,true)! + mut develop2_ := site.path_src.file_get_new('develop.sh')! + develop2_.template_write(develop, true)! develop2_.chmod(0o700)! - mut build2_ := site.path_src.file_get_new("build.sh")! - build2_.template_write(build,true)! + mut build2_ := site.path_src.file_get_new('build.sh')! + build2_.template_write(build, true)! build2_.chmod(0o700)! - mut build_dev2_ := site.path_src.file_get_new("build_dev.sh")! - build_dev2_.template_write(build_dev,true)! - build_dev2_.chmod(0o700)! - - - + mut build_dev2_ := site.path_src.file_get_new('build_dev.sh')! + build_dev2_.template_write(build_dev, true)! + build_dev2_.chmod(0o700)! } diff --git a/lib/web/docusaurus/factory.v b/lib/web/docusaurus/factory.v index 785438ac..fe119cf2 100644 --- a/lib/web/docusaurus/factory.v +++ b/lib/web/docusaurus/factory.v @@ -22,7 +22,7 @@ pub mut: // publish_path string build_path string production bool - update bool + update bool } pub fn new(args_ DocusaurusArgs) !&DocusaurusFactory { diff --git a/lib/web/docusaurus/template.v b/lib/web/docusaurus/template.v index 262f3f9f..e2196c4b 100644 --- a/lib/web/docusaurus/template.v +++ b/lib/web/docusaurus/template.v @@ -7,7 +7,10 @@ import freeflowuniverse.herolib.installers.web.bun fn (mut site DocusaurusFactory) template_install(update bool) ! { mut gs := gittools.new()! - mut r := gs.get_repo(url: 'https://github.com/freeflowuniverse/docusaurus_template.git',pull:update)! + mut r := gs.get_repo( + url: 'https://github.com/freeflowuniverse/docusaurus_template.git' + pull: update + )! mut template_path := r.patho()! for item in ['package.json', 'sidebars.ts', 'tsconfig.json'] { diff --git a/manual/create_tag.md b/manual/create_tag.md new file mode 100644 index 00000000..d334d584 --- /dev/null +++ b/manual/create_tag.md @@ -0,0 +1,8 @@ + +## how to tag a version and push + +```bash +cd ~/Users/despiegk~/code/github/freeflowuniverse/herolib/README.md +git tag -a v1.0.2 -m "some message" +git add . -A ; git commit -m ... ; git pull ; git push origin v1.0.2 +``` \ No newline at end of file