From 3d86ec7cf510d1aef6b53923682a093ee9e8fa5f Mon Sep 17 00:00:00 2001 From: Timur Gordon <31495328+timurgordon@users.noreply.github.com> Date: Fri, 29 Aug 2025 10:17:34 +0200 Subject: [PATCH] git herocmd improvements --- lib/core/herocmds/git.v | 28 +++++++++++++------- lib/core/herocmds/playbook_lib.v | 35 ++++++++++++++++++------- lib/develop/gittools/gittools_do.v | 16 ++++++++++- lib/develop/gittools/repository_clone.v | 15 ++++++++--- lib/develop/gittools/repository_utils.v | 34 ++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 24 deletions(-) diff --git a/lib/core/herocmds/git.v b/lib/core/herocmds/git.v index d5b47b74..6027f36a 100644 --- a/lib/core/herocmds/git.v +++ b/lib/core/herocmds/git.v @@ -78,23 +78,30 @@ pub fn cmd_git(mut cmdroot Command) { description: 'Open visual studio code on found repos, will do for max 5.' } - mut cmd_cd := Command{ + mut exists_command := Command{ sort_flags: true - name: 'cd' + name: 'exists' execute: cmd_git_execute - description: 'cd to a git repo, use e.g. eval $(git cd -u https://github.com/threefoldfoundation/www_threefold_io)' + description: 'Check if git repository exists. Returns exit code 0 if exists, 1 if not.' } - cmd_cd.add_flag(Flag{ + mut cmd_path := Command{ + sort_flags: true + name: 'path' + execute: cmd_git_execute + description: 'Get the path to a git repository. Use with cd $(hero git path )' + } + + cmd_path.add_flag(Flag{ flag: .string required: false name: 'url' abbrev: 'u' - description: 'url for git cd operation, so we know where to cd to' + description: 'url for git path operation, so we know which repo path to get' }) mut allcmdsref := [&list_command, &clone_command, &push_command, &pull_command, &commit_command, - &reload_command, &delete_command, &sourcetree_command, &editor_command] + &reload_command, &delete_command, &sourcetree_command, &editor_command, &exists_command] for mut c in allcmdsref { c.add_flag(Flag{ @@ -181,7 +188,7 @@ pub fn cmd_git(mut cmdroot Command) { }) cmd_run.add_command(c) } - cmd_run.add_command(cmd_cd) + cmd_run.add_command(cmd_path) cmdroot.add_command(cmd_run) } @@ -189,7 +196,8 @@ fn cmd_git_execute(cmd Command) ! { mut is_silent := cmd.flags.get_bool('silent') or { false } mut reload := cmd.flags.get_bool('load') or { false } - if is_silent || cmd.name == 'cd' { + // path command is silent so it just outputs repo path + if is_silent || cmd.name == 'path' { console.silent_set() } mut coderoot := cmd.flags.get_string('coderoot') or { '' } @@ -235,8 +243,8 @@ fn cmd_git_execute(cmd Command) ! { url: url path: path )! - if cmd.name == 'cd' { - print('cd ${mypath}\n') + if cmd.name == 'path' { + print('${mypath}\n') } return } else { diff --git a/lib/core/herocmds/playbook_lib.v b/lib/core/herocmds/playbook_lib.v index 90f03c2c..518274d5 100644 --- a/lib/core/herocmds/playbook_lib.v +++ b/lib/core/herocmds/playbook_lib.v @@ -72,6 +72,13 @@ pub fn cmd_run_add_flags(mut cmd_run Command) { description: 'runs non interactive!' }) + cmd_run.add_flag(Flag{ + flag: .string + name: 'heroscript' + abbrev: 'h' + description: 'runs non interactive!' + }) + cmd_run.add_flag(Flag{ flag: .bool name: 'reset' @@ -143,14 +150,21 @@ pub fn plbook_code_get(cmd Command) !string { // same as session_run_get but will also run the plbook pub fn plbook_run(cmd Command) !(&playbook.PlayBook, string) { - path := plbook_code_get(cmd)! - if path.len == 0 { - return error(cmd.help_message()) + heroscript := cmd.flags.get_string('heroscript') or { '' } + mut path := '' + + mut plbook := if heroscript.len > 0 { + playbook.new(text: heroscript)! + } else { + path + = plbook_code_get(cmd)! + if path.len == 0 { + return error(cmd.help_message()) + } + // add all actions inside to the plbook + playbook.new(path: path)! } - - // add all actions inside to the plbook - mut plbook := playbook.new(path: path)! - + dagu := cmd.flags.get_bool('dagu') or { false } playcmds.run(plbook: plbook)! @@ -160,14 +174,15 @@ pub fn plbook_run(cmd Command) !(&playbook.PlayBook, string) { return &plbook, path } -fn plbook_edit_sourcetree(cmd Command) !(&playbook.PlayBook, string) { +fn plbook_edit_sourcetree(cmd Command) !&playbook.PlayBook { edit := cmd.flags.get_bool('edit') or { false } treedo := cmd.flags.get_bool('sourcetree') or { false } mut plbook, path := plbook_run(cmd)! if path.len == 0 { - return error('path or url needs to be specified') + // THIS CAN HAPPEN IF RUNNING HEROSCRIPT STRAIGHT FROM STRING + // return error('path or url needs to be specified') } if treedo { @@ -179,5 +194,5 @@ fn plbook_edit_sourcetree(cmd Command) !(&playbook.PlayBook, string) { vscode_.open()! } - return plbook, path + return plbook } diff --git a/lib/develop/gittools/gittools_do.v b/lib/develop/gittools/gittools_do.v index 863d75d2..ab1f5523 100644 --- a/lib/develop/gittools/gittools_do.v +++ b/lib/develop/gittools/gittools_do.v @@ -5,7 +5,7 @@ import freeflowuniverse.herolib.core.pathlib import freeflowuniverse.herolib.ui.console import os -pub const gitcmds = 'clone,commit,pull,push,delete,reload,list,edit,sourcetree,cd' +pub const gitcmds = 'clone,commit,pull,push,delete,reload,list,edit,sourcetree,path,exists' @[params] pub struct ReposActionsArgs { @@ -117,6 +117,20 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string { return '' } + if args.cmd == 'exists' { + return gs.check_repos_exist(args) + } + + if args.cmd == 'path' { + if repos.len == 0 { + return error('No repository found for path command') + } + if repos.len > 1 { + return error('Multiple repositories found for path command, please be more specific') + } + return repos[0].path() + } + // means we are on 1 repo if args.cmd in 'sourcetree,edit'.split(',') { if repos.len == 0 { diff --git a/lib/develop/gittools/repository_clone.v b/lib/develop/gittools/repository_clone.v index bea49343..96df8142 100644 --- a/lib/develop/gittools/repository_clone.v +++ b/lib/develop/gittools/repository_clone.v @@ -39,9 +39,18 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo { key_ := repo.cache_key() gitstructure.repos[key_] = &repo - mut repopath := repo.patho()! - if repopath.exists() { - return error("can't clone on existing path, came from url, path found is ${repopath.path}.\n") + if repo.exists() { + console.print_green("Repository already exists at ${repo.path()}") + // Load the existing repository status + repo.load_internal() or { + console.print_debug('Could not load existing repository status: ${err}') + } + return &repo + } + + // Check if path exists but is not a git repository + if os.exists(repo.path()) { + return error("Path exists but is not a git repository: ${repo.path()}") } if args.sshkey.len > 0 { diff --git a/lib/develop/gittools/repository_utils.v b/lib/develop/gittools/repository_utils.v index dd30f56d..ae0dd97d 100644 --- a/lib/develop/gittools/repository_utils.v +++ b/lib/develop/gittools/repository_utils.v @@ -163,3 +163,37 @@ pub fn (mut repo GitRepo) open_vscode() ! { mut vs_code := vscode.new(path) vs_code.open()! } + +// Check if repository exists at its expected path +pub fn (repo GitRepo) exists() bool { + repo_path := repo.path() + if !os.exists(repo_path) { + return false + } + git_dir := os.join_path(repo_path, '.git') + return os.exists(git_dir) +} + +// Check if any repositories exist based on filter criteria and return result for exists command +pub fn (mut gs GitStructure) check_repos_exist(args ReposActionsArgs) !string { + repos := gs.get_repos( + filter: args.filter + name: args.repo + account: args.account + provider: args.provider + )! + + if repos.len > 0 { + // Repository exists - print path and return success + if !args.script { + console.print_green('Repository exists: ${repos[0].path()}') + } + return repos[0].path() + } else { + // Repository doesn't exist - return error for exit code 1 + if !args.script { + console.print_stderr('Repository not found') + } + return error('Repository not found') + } +}