diff --git a/lib/clients/giteaclient/giteaclient_factory_.v b/lib/clients/giteaclient/giteaclient_factory_.v index d0edd9aa..45a7c56f 100644 --- a/lib/clients/giteaclient/giteaclient_factory_.v +++ b/lib/clients/giteaclient/giteaclient_factory_.v @@ -71,6 +71,22 @@ pub fn delete(args_ ArgsGet) ! { } } +@[params] +pub struct ArgsList { +pub mut: + fromdb bool //will load from filesystem +} + + +pub fn list(args ArgsList) ![]&GiteaClient { + + mut res := []&GiteaClient{} + if args.name in giteaclient_global { + res << giteaclient_global[o.name] + } + return res +} + // only sets in mem, does not set as config fn set_in_mem(o GiteaClient) ! { mut o2 := obj_init(o)! diff --git a/lib/clients/giteaclient/readme.md b/lib/clients/giteaclient/readme.md index 4622d9d7..9c8654db 100644 --- a/lib/clients/giteaclient/readme.md +++ b/lib/clients/giteaclient/readme.md @@ -14,8 +14,6 @@ You can configure the client using a HeroScript file: secret: 'your-gitea-api-token' ``` -Save this content in your project's configuration (e.g., `~/.config/hero/config.hcl`) or pass it to a playbook. - ## Usage Example Here's how to get the client and use its methods. diff --git a/lib/core/generator/generic/templates/objname_factory_.vtemplate b/lib/core/generator/generic/templates/objname_factory_.vtemplate index 37e1ca5e..88a52673 100644 --- a/lib/core/generator/generic/templates/objname_factory_.vtemplate +++ b/lib/core/generator/generic/templates/objname_factory_.vtemplate @@ -80,6 +80,16 @@ pub fn delete(args_ ArgsGet)! { } } +pub fn list()![]&${args.classname} { + mut args := args_get(args_) + mut res:=[]&${args.classname} + if args.name in ${args.name}_global { + res << ${args.name}_global[o.name] + } + return res +} + + //only sets in mem, does not set as config fn set_in_mem(o ${args.classname})! { mut o2:=obj_init(o)! diff --git a/lib/core/generator/installer_client_OLD/ask.v b/lib/core/generator/installer_client_OLD/ask.v deleted file mode 100644 index ff0d6bde..00000000 --- a/lib/core/generator/installer_client_OLD/ask.v +++ /dev/null @@ -1,69 +0,0 @@ -module installer_client - -import freeflowuniverse.herolib.ui.console -import os -import freeflowuniverse.herolib.core.pathlib - -// will ask questions & create the .heroscript -pub fn ask(path string) ! { - mut myconsole := console.new() - - mut model := gen_model_get(path, false)! - - console.clear() - console.print_header('Configure generation of code for a module on path:') - console.print_green('Path: ${path}') - console.lf() - - model.classname = myconsole.ask_question( - description: 'Class name of the ${model.cat}' - question: 'What is the class name of the generator e.g. MyClass ?' - warning: 'Please provide a valid class name for the generator' - default: model.classname - minlen: 4 - )! - - model.title = myconsole.ask_question( - description: 'Title of the ${model.cat} (optional)' - default: model.title - )! - - model.hasconfig = !myconsole.ask_yesno( - description: 'Is there a config (normally yes)?' - default: model.hasconfig - )! - - if model.hasconfig { - model.singleton = !myconsole.ask_yesno( - description: 'Can there be multiple instances (normally yes)?' - default: !model.singleton - )! - if model.cat == .installer { - model.templates = myconsole.ask_yesno( - description: 'Will there be templates available for your installer?' - default: model.templates - )! - } - } else { - model.singleton = true - } - - if model.cat == .installer { - model.startupmanager = myconsole.ask_yesno( - description: 'Is this an installer which will be managed by a startup mananger?' - default: model.startupmanager - )! - - model.build = myconsole.ask_yesno( - description: 'Are there builders for the installers (compilation)' - default: model.build - )! - } - - // if true{ - // println(model) - // panic("Sdsd") - // } - - gen_model_set(GenerateArgs{ model: model, path: path })! -} diff --git a/lib/core/generator/installer_client_OLD/factory.v b/lib/core/generator/installer_client_OLD/factory.v deleted file mode 100644 index db7c2a08..00000000 --- a/lib/core/generator/installer_client_OLD/factory.v +++ /dev/null @@ -1,85 +0,0 @@ -module installer_client - -import freeflowuniverse.herolib.ui.console -import os - -@[params] -pub struct GenerateArgs { -pub mut: - reset bool // regenerate all, dangerous !!! - interactive bool // if we want to ask - path string - playonly bool - model ?GenModel - cat ?Cat -} - -pub struct PlayArgs { -pub mut: - name string - modulepath string -} - -// the default to start with -// -// reset bool // regenerate all, dangerous !!! -// interactive bool //if we want to ask -// path string -// model ?GenModel -// cat ?Cat -// -// will return the module path where we need to execute a play command as well as the name of -pub fn do(args_ GenerateArgs) !PlayArgs { - mut args := args_ - - console.print_header('Generate code for path: ${args.path} (reset:${args.reset}, interactive:${args.interactive})') - - mut create := true // to create .heroscript - - mut model := args.model or { - create = false // we cannot create because model not given - if args.path == '' { - args.path = os.getwd() - } - mut m := gen_model_get(args.path, false)! - m - } - - if model.classname == '' { - args.interactive = true - } - - if create { - if args.path == '' { - return error('need to specify path fo ${args_} because we asked to create .heroscript ') - } - gen_model_set(args)! // persist it on disk - } else { - if args.path == '' { - args.path = os.getwd() - } - } - - // if model.cat == .unknown { - // model.cat = args.cat or { return error('cat needs to be specified for generator.') } - // } - - if args.interactive { - ask(args.path)! - args.model = gen_model_get(args.path, false)! - } else { - args.model = model - } - - console.print_debug(args) - - // only generate if playonly is false and there is a classname - if !args.playonly && model.classname.len > 0 { - generate(args)! - } - - return PlayArgs{ - name: model.play_name - modulepath: model.module_path - } -} diff --git a/lib/core/generator/installer_client_OLD/generate.v b/lib/core/generator/installer_client_OLD/generate.v deleted file mode 100644 index 102e692f..00000000 --- a/lib/core/generator/installer_client_OLD/generate.v +++ /dev/null @@ -1,77 +0,0 @@ -module installer_client - -import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.core.pathlib - -// generate based on filled in args, ask has to be done before -fn generate(args GenerateArgs) ! { - console.print_debug('generate code for path: ${args.path}') - - // as used in the templates - model := args.model or { panic('bug no model specified in generate') } - - mut path_actions := pathlib.get(args.path + '/${model.name}_actions.v') - if args.reset { - path_actions.delete()! - } - if !path_actions.exists() && model.cat == .installer { - console.print_debug('write installer actions') - mut templ_1 := $tmpl('templates/objname_actions.vtemplate') - pathlib.template_write(templ_1, '${args.path}/${model.name}_actions.v', true)! - } - - mut templ_2 := $tmpl('templates/objname_factory_.vtemplate') - - pathlib.template_write(templ_2, '${args.path}/${model.name}_factory_.v', true)! - - mut path_model := pathlib.get(args.path + '/${model.name}_model.v') - if args.reset || !path_model.exists() { - console.print_debug('write model.') - mut templ_3 := $tmpl('templates/objname_model.vtemplate') - pathlib.template_write(templ_3, '${args.path}/${model.name}_model.v', true)! - } - - // TODO: check case sensistivity for delete - mut path_readme := pathlib.get(args.path + '/readme.md') - if args.reset || !path_readme.exists() { - mut templ_readme := $tmpl('templates/readme.md') - pathlib.template_write(templ_readme, '${args.path}/readme.md', true)! - } - - mut path_templ_dir := pathlib.get_dir(path: args.path + '/templates', create: false)! - if args.reset { - path_templ_dir.delete()! - } - if (args.model or { panic('bug') }).templates { - if !path_templ_dir.exists() { - mut templ_6 := $tmpl('templates/atemplate.yaml') - pathlib.template_write(templ_6, '${args.path}/templates/atemplate.yaml', true)! - } - } -} - -// fn platform_check(args GenModel) ! { -// ok := 'osx,ubuntu,arch' -// ok2 := ok.split(',') -// for i in args.supported_platforms { -// if i !in ok2 { -// return error('cannot find ${i} in choices for supported_platforms. Valid ones are ${ok}') -// } -// } -// } - -// pub fn (args GenModel) platform_check_str() string { -// mut out := '' - -// if 'osx' in args.supported_platforms { -// out += 'myplatform == .osx || ' -// } -// if 'ubuntu' in args.supported_platforms { -// out += 'myplatform == .ubuntu ||' -// } -// if 'arch' in args.supported_platforms { -// out += 'myplatform == .arch ||' -// } -// out = out.trim_right('|') -// return out -// } diff --git a/lib/core/generator/installer_client_OLD/model.v b/lib/core/generator/installer_client_OLD/model.v deleted file mode 100644 index 623c92d0..00000000 --- a/lib/core/generator/installer_client_OLD/model.v +++ /dev/null @@ -1,136 +0,0 @@ -module installer_client - -import os -import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.core.playbook -import freeflowuniverse.herolib.ui.console - -pub struct GenModel { -pub mut: - name string - classname string - default bool = true // means user can just get the object and a default will be created - title string - // supported_platforms []string // only relevant for installers for now - singleton bool // means there can only be one - templates bool // means we will use templates in the installer, client doesn't do this' - reset bool // regenerate all, dangerous !!! - interactive bool // if we want to ask - startupmanager bool = true - build bool = true - hasconfig bool = true - cat Cat // dont' set default - play_name string // e.g. docusaurus is what we look for - module_path string // e.g.freeflowuniverse.herolib.web.docusaurus -} - -pub enum Cat { - unknown - client - installer -} - -// creates the heroscript from the GenModel as part of GenerateArgs -pub fn gen_model_set(args GenerateArgs) ! { - console.print_debug('Code generator set: ${args}') - model := args.model or { return error('model is none') } - heroscript_templ := match model.cat { - .client { $tmpl('templates/heroscript_client') } - .installer { $tmpl('templates/heroscript_installer') } - else { return error('Invalid category: ${model.cat}') } - } - pathlib.template_write(heroscript_templ, '${args.path}/.heroscript', true)! -} - -// loads the heroscript and return the model -pub fn gen_model_get(path string, create bool) !GenModel { - console.print_debug('play installer code for path: ${path}') - - mut config_path := pathlib.get_file(path: '${path}/.heroscript', create: create)! - - mut plbook := playbook.new(text: config_path.read()!)! - - mut model := GenModel{} - mut found := false - - mut install_actions := plbook.find(filter: 'hero_code.generate_installer')! - if install_actions.len > 0 { - for install_action in install_actions { - if found { - return error('cannot find more than one her_code.generate_installer ... in ${path}') - } - found = true - mut p := install_action.params - model = GenModel{ - name: p.get_default('name', '')! - classname: p.get_default('classname', '')! - title: p.get_default('title', '')! - default: p.get_default_true('default') - // supported_platforms: p.get_list('supported_platforms')! - singleton: p.get_default_false('singleton') - templates: p.get_default_false('templates') - startupmanager: p.get_default_true('startupmanager') - build: p.get_default_true('build') - hasconfig: p.get_default_true('hasconfig') - cat: .installer - } - } - } - - mut client_actions := plbook.find(filter: 'hero_code.generate_client')! - if client_actions.len > 0 { - for client_action in client_actions { - if found { - return error('cannot find more than one her_code.generate_client ... in ${path}') - } - found = true - mut p := client_action.params - model = GenModel{ - name: p.get_default('name', '')! - classname: p.get_default('classname', '')! - title: p.get_default('title', '')! - default: p.get_default_true('default') - singleton: p.get_default_false('singleton') - hasconfig: p.get_default_true('hasconfig') - cat: .client - } - } - } - - if model.cat == .unknown { - if path.contains('clients') { - model.cat = .client - } else { - model.cat = .installer - } - } - - if model.name == '' { - model.name = os.base(path).to_lower() - } - - model.play_name = model.name - - pathsub := path.replace('${os.home_dir()}/code/github/', '') - model.module_path = pathsub.replace('/', '.').replace('.lib.', '.') - - // !!hero_code.play - // name:'docusaurus' - - mut play_actions := plbook.find(filter: 'hero_code.play')! - if play_actions.len > 1 { - return error('should have max 1 hero_code.play action in ${config_path.path}') - } - if play_actions.len == 1 { - mut p := play_actions[0].params - model.play_name = p.get_default('name', model.name)! - } - - if model.module_path.contains('docusaurus') { - println(model) - println('4567ujhjk') - exit(0) - } - - return model -} diff --git a/lib/core/generator/installer_client_OLD/readme.md b/lib/core/generator/installer_client_OLD/readme.md deleted file mode 100644 index cf259770..00000000 --- a/lib/core/generator/installer_client_OLD/readme.md +++ /dev/null @@ -1,71 +0,0 @@ -# generation framework for clients & installers - -```bash -#generate all play commands -hero generate -playonly -#will ask questions if .heroscript is not there yet -hero generate -p thepath_is_optional -# to generate without questions -hero generate -p thepath_is_optional -t client -#if installer, default is a client -hero generate -p thepath_is_optional -t installer - -#when you want to scan over multiple directories -hero generate -p thepath_is_optional -t installer -s - -``` - -there will be a ```.heroscript``` in the director you want to generate for, the format is as follows: - -```hero -//for a server -!!hero_code.generate_installer - name:'daguserver' - classname:'DaguServer' - singleton:1 //there can only be 1 object in the globals, is called 'default' - templates:1 //are there templates for the installer - title:'' - startupmanager:1 //managed by a startup manager, default true - build:1 //will we also build the component - -//or for a client - -!!hero_code.generate_client - name:'mail' - classname:'MailClient' - singleton:0 //default is 0 - -``` - -needs to be put as .heroscript in the directories which we want to generate - - -## templates remarks - -in templates: - -- ^^ or @@ > gets replaced to @ -- ?? > gets replaced to $ - -this is to make distinction between processing at compile time (pre-compile) or at runtime. - -## call by code - -to call in code - -```v -#!/usr/bin/env -S v -gc none -cc tcc -d use_openssl -enable-globals run - -import freeflowuniverse.herolib.code.generator.generic - -generic.scan(path:"~/code/github/freeflowuniverse/herolib/herolib/installers",force:true)! - - -``` - -to run from bash - -```bash -~/code/github/freeflowuniverse/herolib/scripts/fix_installers.vsh -``` - diff --git a/lib/core/generator/installer_client_OLD/scanner.v b/lib/core/generator/installer_client_OLD/scanner.v deleted file mode 100644 index 642135fe..00000000 --- a/lib/core/generator/installer_client_OLD/scanner.v +++ /dev/null @@ -1,49 +0,0 @@ -module installer_client - -import os -import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.ui.console - -@[params] -pub struct ScannerArgs { -pub mut: - reset bool // regenerate all, dangerous !!! - interactive bool // if we want to ask - path string - playonly bool -} - -// scan over a set of directories call the play where -pub fn scan(args ScannerArgs) ! { - console.print_debug('Code generator scan: ${args.path}') - - if args.path == '' { - scan(path: '${os.home_dir()}/code/github/freeflowuniverse/herolib/lib/installers')! - scan(path: '${os.home_dir()}/code/github/freeflowuniverse/herolib/lib/clients')! - scan(path: '${os.home_dir()}/code/github/freeflowuniverse/herolib/lib/web')! - return - } - - console.print_header('Scan for generation of code for ${args.path}') - - // now walk over all directories, find .heroscript - mut pathroot := pathlib.get_dir(path: args.path, create: false)! - mut plist := pathroot.list( - recursive: true - ignoredefault: false - regex: ['.heroscript'] - )! - - for mut p in plist.paths { - pparent := p.parent()! - path_module := pparent.path - if os.exists('${path_module}/.heroscript') { - do( - interactive: args.interactive - path: path_module - reset: args.reset - playonly: args.playonly - )! - } - } -} diff --git a/lib/core/generator/installer_client_OLD/templates/atemplate.yaml b/lib/core/generator/installer_client_OLD/templates/atemplate.yaml deleted file mode 100644 index 07ae0536..00000000 --- a/lib/core/generator/installer_client_OLD/templates/atemplate.yaml +++ /dev/null @@ -1,5 +0,0 @@ - - -name: ??{model.name} - - diff --git a/lib/core/generator/installer_client_OLD/templates/heroscript_client b/lib/core/generator/installer_client_OLD/templates/heroscript_client deleted file mode 100644 index 4b55af3d..00000000 --- a/lib/core/generator/installer_client_OLD/templates/heroscript_client +++ /dev/null @@ -1,7 +0,0 @@ -!!hero_code.generate_client - name: "${model.name}" - classname: "${model.classname}" - hasconfig: ${model.hasconfig} - singleton: ${model.singleton} - default: ${model.default} - title: "${model.title}" diff --git a/lib/core/generator/installer_client_OLD/templates/heroscript_installer b/lib/core/generator/installer_client_OLD/templates/heroscript_installer deleted file mode 100644 index 25bb3472..00000000 --- a/lib/core/generator/installer_client_OLD/templates/heroscript_installer +++ /dev/null @@ -1,11 +0,0 @@ -!!hero_code.generate_installer - name: "${model.name}" - classname: "${model.classname}" - hasconfig: ${model.hasconfig} - singleton: ${model.singleton} - default: ${model.default} - title: "${model.title}" - templates: ${model.templates} - build: ${model.build} - startupmanager: ${model.startupmanager} - diff --git a/lib/core/generator/installer_client_OLD/templates/objname_actions.vtemplate b/lib/core/generator/installer_client_OLD/templates/objname_actions.vtemplate deleted file mode 100644 index 1b900c97..00000000 --- a/lib/core/generator/installer_client_OLD/templates/objname_actions.vtemplate +++ /dev/null @@ -1,219 +0,0 @@ -module ${model.name} - -import freeflowuniverse.herolib.osal.core as osal -import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.core.texttools -import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.core -import freeflowuniverse.herolib.installers.ulist -import freeflowuniverse.herolib.installers.base - -@if model.startupmanager -import freeflowuniverse.herolib.osal.systemd -import freeflowuniverse.herolib.osal.zinit -@end - -@if model.build -import freeflowuniverse.herolib.installers.lang.golang -import freeflowuniverse.herolib.installers.lang.rust -import freeflowuniverse.herolib.installers.lang.python -@end - -import os - -@if model.startupmanager -fn startupcmd () ![]zinit.ZProcessNewArgs{ - mut installer := get()! - mut res := []zinit.ZProcessNewArgs{} - //THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED - // res << zinit.ZProcessNewArgs{ - // name: '${model.name}' - // cmd: '${model.name} server' - // env: { - // 'HOME': '/root' - // } - // } - - return res - -} - -fn running_() !bool { - mut installer := get()! - //THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED - // this checks health of ${model.name} - // curl http://localhost:3333/api/v1/s --oauth2-bearer 1234 works - // url:='http://127.0.0.1:??{cfg.port}/api/v1' - // mut conn := httpconnection.new(name: '${model.name}', url: url)! - - // if cfg.secret.len > 0 { - // conn.default_header.add(.authorization, 'Bearer ??{cfg.secret}') - // } - // conn.default_header.add(.content_type, 'application/json') - // console.print_debug("curl -X 'GET' '??{url}'/tags --oauth2-bearer ??{cfg.secret}") - // r := conn.get_json_dict(prefix: 'tags', debug: false) or {return false} - // println(r) - // if true{panic("ssss")} - // tags := r['Tags'] or { return false } - // console.print_debug(tags) - // console.print_debug('${model.name} is answering.') - return false -} - -fn start_pre()!{ - -} - -fn start_post()!{ - -} - -fn stop_pre()!{ - -} - -fn stop_post()!{ - -} - -@end - -//////////////////// following actions are not specific to instance of the object - -@if model.cat == .installer -// checks if a certain version or above is installed -fn installed_() !bool { - //THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED - // res := os.execute('??{osal.profile_path_source_and()!} ${model.name} version') - // if res.exit_code != 0 { - // return false - // } - // r := res.output.split_into_lines().filter(it.trim_space().len > 0) - // if r.len != 1 { - // return error("couldn't parse ${model.name} version.\n??{res.output}") - // } - // if texttools.version(version) == texttools.version(r[0]) { - // return true - // } - return false -} - -//get the Upload List of the files -fn ulist_get() !ulist.UList { - //optionally build a UList which is all paths which are result of building, is then used e.g. in upload - return ulist.UList{} -} - -//uploads to S3 server if configured -fn upload_() ! { - // installers.upload( - // cmdname: '${model.name}' - // source: '??{gitpath}/target/x86_64-unknown-linux-musl/release/${model.name}' - // )! - -} - -fn install_() ! { - console.print_header('install ${model.name}') - //THIS IS EXAMPLE CODEAND NEEDS TO BE CHANGED - // mut url := '' - // if core.is_linux_arm()! { - // url = 'https://github.com/${model.name}-dev/${model.name}/releases/download/v??{version}/${model.name}_??{version}_linux_arm64.tar.gz' - // } else if core.is_linux_intel()! { - // url = 'https://github.com/${model.name}-dev/${model.name}/releases/download/v??{version}/${model.name}_??{version}_linux_amd64.tar.gz' - // } else if core.is_osx_arm()! { - // url = 'https://github.com/${model.name}-dev/${model.name}/releases/download/v??{version}/${model.name}_??{version}_darwin_arm64.tar.gz' - // } else if core.is_osx_intel()! { - // url = 'https://github.com/${model.name}-dev/${model.name}/releases/download/v??{version}/${model.name}_??{version}_darwin_amd64.tar.gz' - // } else { - // return error('unsported platform') - // } - - // mut dest := osal.download( - // url: url - // minsize_kb: 9000 - // expand_dir: '/tmp/${model.name}' - // )! - - // //dest.moveup_single_subdir()! - - // mut binpath := dest.file_get('${model.name}')! - // osal.cmd_add( - // cmdname: '${model.name}' - // source: binpath.path - // )! -} - -@if model.build -fn build_() ! { - //url := 'https://github.com/threefoldtech/${model.name}' - - // make sure we install base on the node - // if core.platform()!= .ubuntu { - // return error('only support ubuntu for now') - // } - - //mut g:=golang.get()! - //g.install()! - - //console.print_header('build coredns') - - //mut gs := gittools.new(coderoot: '~/code')! - // console.print_header('build ${model.name}') - - // gitpath := gittools.get_repo(url: url, reset: true, pull: true)! - - // cmd := ' - // cd ??{gitpath} - // source ~/.cargo/env - // exit 1 #todo - // ' - // osal.execute_stdout(cmd)! - // - // //now copy to the default bin path - // mut binpath := dest.file_get('...')! - // adds it to path - // osal.cmd_add( - // cmdname: 'griddriver2' - // source: binpath.path - // )! - -} -@end - -fn destroy_() ! { - - // mut systemdfactory := systemd.new()! - // systemdfactory.destroy("zinit")! - - // osal.process_kill_recursive(name:'zinit')! - // osal.cmd_delete('zinit')! - - // osal.package_remove(' - // podman - // conmon - // buildah - // skopeo - // runc - // ')! - - // //will remove all paths where go/bin is found - // osal.profile_path_add_remove(paths2delete:"go/bin")! - - // osal.rm(" - // podman - // conmon - // buildah - // skopeo - // runc - // /var/lib/containers - // /var/lib/podman - // /var/lib/buildah - // /tmp/podman - // /tmp/conmon - // ")! - - -} - -@end \ No newline at end of file diff --git a/lib/core/generator/installer_client_OLD/templates/objname_factory_.vtemplate b/lib/core/generator/installer_client_OLD/templates/objname_factory_.vtemplate deleted file mode 100644 index 3f7721b6..00000000 --- a/lib/core/generator/installer_client_OLD/templates/objname_factory_.vtemplate +++ /dev/null @@ -1,338 +0,0 @@ - -module ${model.name} - -import freeflowuniverse.herolib.core.base -import freeflowuniverse.herolib.core.playbook -import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.core -@if model.hasconfig -import freeflowuniverse.herolib.data.encoderhero -@end - -@if model.cat == .installer -import freeflowuniverse.herolib.osal.startupmanager -import freeflowuniverse.herolib.osal.zinit -import time -@end - -__global ( - ${model.name}_global map[string]&${model.classname} - ${model.name}_default string -) - -/////////FACTORY - - -@if model.singleton == false - -^^[params] -pub struct ArgsGet{ -pub mut: - name string -} - -fn args_get (args_ ArgsGet) ArgsGet { - mut model:=args_ - if model.name == ""{ - model.name = ${model.name}_default - } - if model.name == ""{ - model.name = "default" - } - return model -} - -pub fn get(args_ ArgsGet) !&${model.classname} { - mut args := args_get(args_) - if !(args.name in ${model.name}_global) { - if args.name=="default"{ - if ! exists(args)!{ - if default{ - mut context:=base.context() or { panic("bug") } - context.hero_config_set("${model.name}",args.name,heroscript_default()!)! - } - } - load(args)! - } - } - return ${model.name}_global[args.name] or { - println(${model.name}_global) - panic("could not get config for ??{args.name}.") - } -} - -@end - -@if model.hasconfig - -//set the model in mem and the config on the filesystem -pub fn set(o ${model.classname})! { - mut o2:=obj_init(o)! - ${model.name}_global[o.name] = &o2 - ${model.name}_default = o.name -} - -//check we find the config on the filesystem -pub fn exists(args_ ArgsGet)!bool { - mut model := args_get(args_) - mut context:=base.context()! - return context.hero_config_exists("${model.name}",model.name) -} - -//load the config error if it doesn't exist -pub fn load(args_ ArgsGet) ! { - mut model := args_get(args_) - mut context:=base.context()! - mut heroscript := context.hero_config_get("${model.name}",model.name)! - play(heroscript:heroscript)! -} - -//save the config to the filesystem in the context -pub fn save(o ${model.classname})! { - mut context:=base.context()! - heroscript := encoderhero.encode[${model.classname}](o)! - context.hero_config_set("${model.name}",o.name,heroscript)! -} - - -pub fn play(mut plbook PlayBook) ! { - - mut plbook := model.plbook or { - playbook.new(text: model.heroscript)! - } - - @if model.hasconfig - mut configure_actions := plbook.find(filter: '${model.name}.configure')! - if configure_actions.len > 0 { - for config_action in configure_actions { - mut p := config_action.params - mycfg:=cfg_play(p)! - console.print_debug("install action ${model.name}.configure\n??{mycfg}") - set(mycfg)! - save(mycfg)! - } - } - @end - - @if model.cat == .installer - mut other_actions := plbook.find(filter: '${model.name}.')! - 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 ${model.name}.destroy") - destroy_()! - } - if other_action.name == "install"{ - console.print_debug("install action ${model.name}.install") - install_()! - } - } - @if model.startupmanager - if other_action.name in ["start","stop","restart"]{ - mut p := other_action.params - name := p.get('name')! - mut ${model.name}_obj:=get(name:name)! - console.print_debug("action object:\n??{${model.name}_obj}") - if other_action.name == "start"{ - console.print_debug("install action ${model.name}.??{other_action.name}") - ${model.name}_obj.start()! - } - - if other_action.name == "stop"{ - console.print_debug("install action ${model.name}.??{other_action.name}") - ${model.name}_obj.stop()! - } - if other_action.name == "restart"{ - console.print_debug("install action ${model.name}.??{other_action.name}") - ${model.name}_obj.restart()! - } - } - @end - } - @end - -} - -@end - -@if model.cat == .installer - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS /////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - -@if model.hasconfig -//load from disk and make sure is properly intialized -pub fn (mut self ${model.classname}) reload() ! { - switch(self.name) - self=obj_init(self)! -} -@end - -@if model.startupmanager - -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()! - } - } -} - -pub fn (mut self ${model.classname}) start() ! { - switch(self.name) - if self.running()!{ - return - } - - console.print_header('${model.name} start') - - if ! installed_()!{ - install_()! - } - - configure()! - - start_pre()! - - for zprocess in startupcmd()!{ - mut sm:=startupmanager_get(zprocess.startuptype)! - - console.print_debug('starting ${model.name} with ??{zprocess.startuptype}...') - - sm.new(zprocess)! - - sm.start(zprocess.name)! - } - - start_post()! - - for _ in 0 .. 50 { - if self.running()! { - return - } - time.sleep(100 * time.millisecond) - } - return error('${model.name} did not install properly.') - -} - -pub fn (mut self ${model.classname}) install_start(model InstallArgs) ! { - switch(self.name) - self.install(model)! - self.start()! -} - -pub fn (mut self ${model.classname}) stop() ! { - 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 ${model.classname}) restart() ! { - switch(self.name) - self.stop()! - self.start()! -} - -pub fn (mut self ${model.classname}) running() !bool { - 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_()! -} -@end - -@@[params] -pub struct InstallArgs{ -pub mut: - reset bool -} - -@if model.singleton - -pub fn install(args InstallArgs) ! { - if args.reset { - destroy()! - } - if ! (installed_()!){ - install_()! - } -} - -pub fn destroy() ! { - destroy_()! -} - -@if model.build -pub fn build() ! { - build_()! -} -@end - - -@else - -//switch instance to be used for ${model.name} -pub fn switch(name string) { - ${model.name}_default = name -} - - -pub fn (mut self ${model.classname}) install(args InstallArgs) ! { - switch(self.name) - if args.reset { - destroy_()! - } - if ! (installed_()!){ - install_()! - } -} - -@if model.build -pub fn (mut self ${model.classname}) build() ! { - switch(self.name) - build_()! -} -@end - -pub fn (mut self ${model.classname}) destroy() ! { - switch(self.name) -@if model.startupmanager - self.stop() or {} -@end - destroy_()! -} - -@end - -@end - - diff --git a/lib/core/generator/installer_client_OLD/templates/objname_model.vtemplate b/lib/core/generator/installer_client_OLD/templates/objname_model.vtemplate deleted file mode 100644 index 623599b3..00000000 --- a/lib/core/generator/installer_client_OLD/templates/objname_model.vtemplate +++ /dev/null @@ -1,155 +0,0 @@ -module ${model.name} -import freeflowuniverse.herolib.data.paramsparser -import os - -pub const version = '0.0.0' -const singleton = ${model.singleton} -const default = ${model.default} - -@if model.hasconfig -//TODO: THIS IS EXAMPLE CODE AND NEEDS TO BE CHANGED IN LINE TO STRUCT BELOW, IS STRUCTURED AS HEROSCRIPT -pub fn heroscript_default() !string { -@if model.cat == .installer - heroscript:=" - !!${model.name}.configure - name:'${model.name}' - homedir: '{HOME}/hero/var/${model.name}' - configpath: '{HOME}/.config/${model.name}/admin.yaml' - username: 'admin' - password: 'secretpassword' - secret: '' - title: 'My Hero DAG' - host: 'localhost' - port: 8888 - - " -@else - heroscript:=" - !!${model.name}.configure - name:'${model.name}' - mail_from: 'info@@example.com' - mail_password: 'secretpassword' - mail_port: 587 - mail_server: 'smtp-relay.brevo.com' - mail_username: 'kristof@@incubaid.com' - - " - -// mail_from := os.getenv_opt('MAIL_FROM') or {'info@@example.com'} -// mail_password := os.getenv_opt('MAIL_PASSWORD') or {'secretpassword'} -// mail_port := (os.getenv_opt('MAIL_PORT') or {"587"}).int() -// mail_server := os.getenv_opt('MAIL_SERVER') or {'smtp-relay.brevo.com'} -// mail_username := os.getenv_opt('MAIL_USERNAME') or {'kristof@@incubaid.com'} -// -// heroscript:=" -// !!mailclient.configure name:'default' -// mail_from: '??{mail_from}' -// mail_password: '??{mail_password}' -// mail_port: ??{mail_port} -// mail_server: '??{mail_server}' -// mail_username: '??{mail_username}' -// -// " -// - -@end - - return heroscript - -} -@end - -//THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED -@if model.cat == .installer -^^[heap] -pub struct ${model.classname} { -pub mut: - name string = 'default' -@if model.hasconfig - homedir string - configpath string - username string - password string @@[secret] - secret string @@[secret] - title string - host string - port int -@end -} -@if model.hasconfig -fn cfg_play(p paramsparser.Params) !${model.classname} { - //THIS IS EXAMPLE CODE AND NEEDS TO BE CHANGED IN LINE WITH struct above - mut mycfg := ${model.classname}{ - name: p.get_default('name', 'default')! - homedir: p.get_default('homedir', '{HOME}/hero/var/${model.name}')! - configpath: p.get_default('configpath', '{HOME}/hero/var/${model.name}/admin.yaml')! - username: p.get_default('username', 'admin')! - password: p.get_default('password', '')! - secret: p.get_default('secret', '')! - title: p.get_default('title', 'HERO DAG')! - host: p.get_default('host', 'localhost')! - port: p.get_int_default('port', 8888)! - } - - if mycfg.password == '' && mycfg.secret == '' { - return error('password or secret needs to be filled in for ${model.name}') - } - return mycfg -} -@end - -@else - -^^[heap] -pub struct ${model.classname} { -pub mut: - name string = 'default' - mail_from string - mail_password string @@[secret] - mail_port int - mail_server string - mail_username string -} - -@if model.hasconfig -fn cfg_play(p paramsparser.Params) !${model.classname} { - //THIS IS EXAMPLE CODE AND NEEDS TO BE CHANGED IN LINE WITH struct above - mut mycfg := ${model.classname}{ - 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', 8888)! - mail_server: p.get('mail_server')! - mail_username: p.get('mail_username')! - } - set(mycfg)! - return mycfg -} -@end - -@end - -fn obj_init(obj_ ${model.classname})!${model.classname}{ - //never call get here, only thing we can do here is work on object itself - mut obj:=obj_ - return obj -} - -@if model.cat == .installer -//called before start if done -fn configure() ! { - @if model.cat == .installer - //mut installer := get()! - @else - //mut client := get()! - @end -@if model.templates - // mut mycode := ??tmpl('templates/atemplate.yaml') - // mut path := pathlib.get_file(path: cfg.configpath, create: true)! - // path.write(mycode)! - // console.print_debug(mycode) -@end -} -@end - - diff --git a/lib/core/generator/installer_client_OLD/templates/readme.md b/lib/core/generator/installer_client_OLD/templates/readme.md deleted file mode 100644 index f11f1905..00000000 --- a/lib/core/generator/installer_client_OLD/templates/readme.md +++ /dev/null @@ -1,63 +0,0 @@ -# ${model.name} - -${model.title} - -To get started - -```vlang - -@if model.cat == .installer - -import freeflowuniverse.herolib.installers.something.${model.name} as ${model.name}_installer - -heroscript:=" -!!${model.name}.configure name:'test' - password: '1234' - port: 7701 - -!!${model.name}.start name:'test' reset:1 -" - -${model.name}_installer.play(heroscript=heroscript)! - -//or we can call the default and do a start with reset -//mut installer:= ${model.name}_installer.get()! -//installer.start(reset:true)! - -@else - -import freeflowuniverse.herolib.clients. ${model.name} - -mut client:= ${model.name}.get()! - -client... - -@end - - - -``` - -## example heroscript - -@if model.cat == .installer -```hero -!!${model.name}.configure - homedir: '/home/user/${model.name}' - username: 'admin' - password: 'secretpassword' - title: 'Some Title' - host: 'localhost' - port: 8888 - -``` -@else -```hero -!!${model.name}.configure - secret: '...' - host: 'localhost' - port: 8888 -``` -@end - - diff --git a/lib/core/herocmds/git.v b/lib/core/herocmds/git.v index 8a8a6850..d5b47b74 100644 --- a/lib/core/herocmds/git.v +++ b/lib/core/herocmds/git.v @@ -8,7 +8,7 @@ import os pub fn cmd_git(mut cmdroot Command) { mut cmd_run := Command{ name: 'git' - description: 'Work with your repos, list, commit, pull, reload, ...' + description: 'Work with your repos, list, commit, pull, reload, ...\narg is url or path, or nothing if for all repos. \nCheck -f for filter. ' // required_args: 1 usage: 'sub commands of git are ' execute: cmd_git_execute @@ -61,7 +61,7 @@ pub fn cmd_git(mut cmdroot Command) { sort_flags: true name: 'list' execute: cmd_git_execute - description: 'list all repos.' + description: 'list all repos.\nThe Argument is url or path, otherwise use -f filter.' } mut sourcetree_command := Command{ diff --git a/lib/develop/gittools/repository.v b/lib/develop/gittools/repository.v index 5fb1b4ce..62093726 100644 --- a/lib/develop/gittools/repository.v +++ b/lib/develop/gittools/repository.v @@ -16,8 +16,8 @@ pub fn (mut repo GitRepo) commit(msg string) ! { if msg == '' { return error('Commit message cannot be empty.') } - repo.exec('git add . -A')! - repo.exec('git commit -m "${msg}"') or { + repo.exec('add . -A')! + repo.exec('commit -m "${msg}"') or { // A common case for failure is when changes are only whitespace changes and git is configured to ignore them. console.print_debug('Could not commit in ${repo.path()}. Maybe nothing to commit? Error: ${err}') return @@ -38,7 +38,7 @@ pub fn (mut repo GitRepo) push() ! { console.print_header('Pushing changes to ${url}') // This will push the current branch to its upstream counterpart. // --set-upstream is useful for new branches. - repo.exec('git push --set-upstream origin ${repo.status.branch}')! + repo.exec('push --set-upstream origin ${repo.status.branch}')! console.print_green('Changes pushed successfully.') repo.cache_last_load_clear()! } @@ -62,7 +62,7 @@ pub fn (mut repo GitRepo) pull(args PullArgs) ! { return error('Cannot pull in ${repo.path()} due to uncommitted changes. Either commit them or use the reset:true option.') } - repo.exec('git pull')! + repo.exec('pull')! if args.submodules { repo.update_submodules()! @@ -74,7 +74,7 @@ pub fn (mut repo GitRepo) pull(args PullArgs) ! { // branch_create creates a new branch. pub fn (mut repo GitRepo) branch_create(branchname string) ! { - repo.exec('git branch ${branchname}')! + repo.exec('branch ${branchname}')! repo.cache_last_load_clear()! console.print_green('Branch ${branchname} created successfully in ${repo.path()}.') } @@ -84,7 +84,7 @@ pub fn (mut repo GitRepo) branch_switch(branchname string) ! { if repo.need_commit()! { return error('Cannot switch branch in ${repo.path()} due to uncommitted changes.') } - repo.exec('git switch ${branchname}')! + repo.exec('switch ${branchname}')! console.print_green('Switched to branch ${branchname} in ${repo.path()}.') repo.status.branch = branchname repo.status.tag = '' @@ -93,7 +93,7 @@ pub fn (mut repo GitRepo) branch_switch(branchname string) ! { // tag_create creates a new tag. pub fn (mut repo GitRepo) tag_create(tagname string) ! { - repo.exec('git tag ${tagname}')! + repo.exec('tag ${tagname}')! console.print_green('Tag ${tagname} created successfully in ${repo.path()}.') repo.cache_last_load_clear()! } @@ -103,7 +103,7 @@ pub fn (mut repo GitRepo) tag_switch(tagname string) ! { if repo.need_commit()! { return error('Cannot switch to tag in ${repo.path()} due to uncommitted changes.') } - repo.exec('git checkout tags/${tagname}')! + repo.exec('checkout tags/${tagname}')! console.print_green('Switched to tag ${tagname} in ${repo.path()}.') repo.status.branch = '' repo.status.tag = tagname @@ -177,7 +177,7 @@ fn (mut repo GitRepo) set_sshkey(key_name string) ! { return error('SSH Key with name ${key_name} not found.') } private_key_path := key.private_key_path()! - repo.exec('git config core.sshCommand "ssh -i ${private_key_path}"')! + repo.exec('config core.sshCommand "ssh -i ${private_key_path}"')! repo.deploysshkey = key_name } @@ -186,7 +186,7 @@ pub fn (mut repo GitRepo) remove_changes() ! { repo.status_update()! if repo.status.has_changes { console.print_header('Removing all local changes in ${repo.path()}') - repo.exec('git reset --hard HEAD && git clean -fdx')! + repo.exec('reset --hard HEAD && git clean -fdx')! repo.cache_last_load_clear()! } } @@ -198,14 +198,20 @@ pub fn (mut repo GitRepo) reset() ! { // update_submodules initializes and updates all submodules. fn (mut repo GitRepo) update_submodules() ! { - repo.exec('git submodule update --init --recursive')! + repo.exec('submodule update --init --recursive')! } // exec executes a command within the repository's directory. // This is the designated wrapper for all git commands for this repo. fn (repo GitRepo) exec(cmd_ string) !string { repo_path := repo.path() - cmd := 'cd ${repo_path} && ${cmd_}' + + if cmd_.starts_with("pull ") || cmd_.starts_with("push ") || cmd_.starts_with("fetch "){ + //means we need to be able to fetch from remote repo, check we have a key registered e.g. for gitea + $dbg; + + } + cmd := 'cd ${repo_path} && git ${cmd_}' // console.print_debug(cmd) r := os.execute(cmd) if r.exit_code != 0 { diff --git a/lib/develop/gittools/repository_load.v b/lib/develop/gittools/repository_load.v index 954e5edd..6f898642 100644 --- a/lib/develop/gittools/repository_load.v +++ b/lib/develop/gittools/repository_load.v @@ -49,7 +49,7 @@ fn (mut repo GitRepo) load_internal() ! { console.print_debug('load ${repo.print_key()}') repo.init()! - repo.exec('git fetch --all') or { + repo.exec('fetch --all') or { repo.status.error = 'Failed to fetch updates: ${err}' return error('Failed to fetch updates for ${repo.name} at ${repo.path()}: ${err}. Please check network connection and repository access.') } @@ -61,7 +61,7 @@ fn (mut repo GitRepo) load_internal() ! { repo.status.behind = 0 // Get ahead/behind information for the current branch - status_res := repo.exec('git status --porcelain=v2 --branch')! + status_res := repo.exec('status --porcelain=v2 --branch')! for line in status_res.split_into_lines() { if line.starts_with('# branch.ab') { parts := line.split(' ') @@ -92,7 +92,7 @@ fn (mut repo GitRepo) load_internal() ! { // Helper to load remote tags fn (mut repo GitRepo) load_branches() ! { - tags_result := repo.exec("git for-each-ref --format='%(objectname) %(refname:short)' refs/heads refs/remotes/origin") or { + tags_result := repo.exec("for-each-ref --format='%(objectname) %(refname:short)' refs/heads refs/remotes/origin") or { return error('Failed to get branch references: ${err}. Command: git for-each-ref') } for line in tags_result.split('\n') { @@ -120,7 +120,7 @@ fn (mut repo GitRepo) load_branches() ! { } } - mybranch := repo.exec('git branch --show-current') or { + mybranch := repo.exec('branch --show-current') or { return error('Failed to get current branch: ${err}') }.split_into_lines().filter(it.trim_space() != '') if mybranch.len == 1 { @@ -133,7 +133,7 @@ fn (mut repo GitRepo) load_branches() ! { // Helper to load remote tags fn (mut repo GitRepo) load_tags() ! { // CORRECTED: Use for-each-ref to get commit hashes for tags. - tags_result := repo.exec("git for-each-ref --format='%(objectname) %(refname:short)' refs/tags") or { + tags_result := repo.exec("for-each-ref --format='%(objectname) %(refname:short)' refs/tags") or { return error('Failed to list tags: ${err}. Please ensure git is installed and repository is accessible.') } @@ -162,7 +162,7 @@ fn (mut repo GitRepo) load_tags() ! { // - An array of strings representing file paths of unstaged changes. // - Throws an error if the command execution fails. pub fn (repo GitRepo) get_changes_unstaged() ![]string { - unstaged_result := repo.exec('git ls-files --other --modified --exclude-standard') or { + unstaged_result := repo.exec('ls-files --other --modified --exclude-standard') or { return error('Failed to check for unstaged changes: ${repo.path()}\n${err}') } @@ -178,7 +178,7 @@ pub fn (repo GitRepo) get_changes_unstaged() ![]string { // - An array of strings representing file paths of staged changes. // - Throws an error if the command execution fails. pub fn (repo GitRepo) get_changes_staged() ![]string { - staged_result := repo.exec('git diff --name-only --staged') or { + staged_result := repo.exec('diff --name-only --staged') or { return error('Failed to check for staged changes: ${repo.path()}\n${err}') } // Filter out any empty lines from the result.