This commit is contained in:
2025-07-21 13:35:30 +02:00
parent 02c4229116
commit bb3dd2dbf9
8 changed files with 94 additions and 30 deletions

View File

@@ -22,6 +22,7 @@ pub mut:
ssh_key_name string // name of ssh key to be used when loading the gitstructure
ssh_key_path string
reload bool
offline bool = false
}
// Retrieve or create a new GitStructure instance with the given configuration.
@@ -37,6 +38,7 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
debug: args.debug
ssh_key_name: args.ssh_key_name
ssh_key_path: args.ssh_key_path
offline: args.offline
}
return get(coderoot: args.coderoot, reload: args.reload, cfg: cfg)

View File

@@ -15,6 +15,7 @@ pub mut:
debug bool = true
ssh_key_name string
ssh_key_path string
offline bool = false
}
// GitStructure holds information about repositories within a specific code root.
@@ -53,13 +54,13 @@ pub fn (mut gitstructure GitStructure) load(reload bool) ! {
redisclient.checkempty()
for _, mut repo in gitstructure.repos {
// mut myfunction := fn (mut repo GitRepo) ! {
// }
// ths << spawn myfunction(mut repo_)
repo.status_update(reload: reload) or {
msg := 'Error in git repo: ${repo.path()}\n${err}'
console.print_stderr(msg)
return error(msg)
// If status_update fails, the error is already captured within the repo object.
// We log it here and continue to process other repositories.
console.print_stderr('Error updating status for repo ${repo.path()}: ${err}')
// Ensure last_load is reset to 0 if there was an error, so it's re-checked next time.
repo.last_load = 0
repo.cache_set()! // Persist the updated last_load and error state
}
}
}

View File

@@ -1,6 +1,7 @@
module gittools
import freeflowuniverse.herolib.core.redisclient
import freeflowuniverse.herolib.ui.console
import time
// ReposGetArgs defines arguments to retrieve repositories from the git structure.
@@ -61,7 +62,13 @@ pub fn (mut gitstructure GitStructure) get_repos(args_ ReposGetArgs) ![]&GitRepo
repo.cache_last_load_clear()!
}
if args.status_update {
repo.status_update()!
repo.status_update() or {
// Log the error but continue processing other repositories
console.print_stderr('Error updating status for repo ${repo.path()}: ${err}')
// Ensure last_load is reset to 0 if there was an error, so it's re-checked next time.
repo.last_load = 0
repo.cache_set()! // Persist the updated last_load and error state
}
}
if args.reset {
repo.reset()!

View File

@@ -7,6 +7,21 @@ fn get_repo_status(gr GitRepo) !string {
mut repo := gr
mut statuses := []string{}
if repo.status_local.error.len > 0 {
mut err_msg := repo.status_local.error
if err_msg.len > 40 {
err_msg = err_msg[0..40] + '...'
}
statuses << 'ERROR (Local): ${err_msg}'
}
if repo.status_remote.error.len > 0 {
mut err_msg := repo.status_remote.error
if err_msg.len > 40 {
err_msg = err_msg[0..40] + '...'
}
statuses << 'ERROR (Remote): ${err_msg}'
}
if repo.has_changes {
statuses << 'COMMIT'
}
@@ -38,32 +53,22 @@ fn format_repo_info(repo GitRepo) ![]string {
// Print repositories based on the provided criteria, showing their statuses
pub fn (mut gitstructure GitStructure) repos_print(args ReposGetArgs) ! {
// console.print_debug('#### Overview of repositories:')
// console.print_debug('')
mut repo_data := [][]string{}
// Collect repository information based on the provided criteria
for _, repo in gitstructure.get_repos(args)! {
// repo.status_update()!
repo_data << format_repo_info(repo)!
}
// Clear the console and start printing the formatted repository information
console.clear()
console.print_lf(1)
// console.print_lf(1) // Removed to reduce newlines
// Display header with optional argument filtering information
// header := if args.str().len > 0 {
// 'Repositories: ${gitstructure.config()!.coderoot} [${args.str()}]'
// } else {
// 'Repositories: ${gitstructure.config()!.coderoot}'
// }
header := 'Repositories: ${gitstructure.config()!.coderoot}'
console.print_header(header)
console.print_lf(1) // Keep one newline after header
// Print the repository information in a formatted array
console.print_lf(1)
console.print_array(repo_data, ' ', true) // true -> aligned for better readability
console.print_lf(5)
// console.print_lf(5) // Removed to reduce newlines
}

View File

@@ -36,6 +36,7 @@ pub mut:
ref_default string // is the default branch hash
branches map[string]string // Branch name -> commit hash
tags map[string]string // Tag name -> commit hash
error string // Error message if remote status update fails
}
// GitRepoStatusLocal holds local status information for a repository.
@@ -44,6 +45,7 @@ pub mut:
branches map[string]string // Branch name -> commit hash
branch string // the current branch
tag string // If the local branch is not set, the tag may be set
error string // Error message if local status update fails
}
// GitRepoConfig holds repository-specific configuration options.

View File

@@ -7,13 +7,33 @@ import os
@[params]
pub struct StatusUpdateArgs {
reload bool
force bool // Add force flag to bypass cache when callers need it.
}
pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
// Clear previous errors
repo.status_local.error = ''
repo.status_remote.error = ''
// Check current time vs last check, if needed (check period) then load
repo.cache_get() or { return error('Failed to get cache for repo ${repo.name}: ${err}') } // Ensure we have the situation from redis
repo.init() or { return error('Failed to initialize repo ${repo.name}: ${err}') }
if 'OFFLINE' !in os.environ() {
repo.cache_get() or {
repo.status_local.error = 'Failed to get cache: ${err}'
return error('Failed to get cache for repo ${repo.name}: ${err}')
} // Ensure we have the situation from redis
repo.init() or {
repo.status_local.error = 'Failed to initialize: ${err}'
return error('Failed to initialize repo ${repo.name}: ${err}')
}
// If there's an existing error, skip loading and just return.
// This prevents repeated attempts to load a problematic repo.
if repo.status_local.error.len > 0 || repo.status_remote.error.len > 0 {
console.print_debug('Skipping load for ${repo.name} due to existing error.')
return
}
if 'OFFLINE' in os.environ() || (repo.gs.config()!.offline) {
console.print_debug('fetch skipped (offline)')
return
}
current_time := int(time.now().unix())
@@ -21,7 +41,10 @@ pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
|| current_time - repo.last_load >= repo.config.remote_check_period {
// console.print_debug('${repo.name} ${current_time}-${repo.last_load} (${current_time - repo.last_load >= repo.config.remote_check_period}): ${repo.config.remote_check_period} +++')
// if true{exit(0)}
repo.load() or { return error('Failed to load repository ${repo.name}: ${err}') }
repo.load() or {
repo.status_remote.error = 'Failed to load repository: ${err}'
return error('Failed to load repository ${repo.name}: ${err}')
}
}
}
@@ -29,27 +52,40 @@ pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
// Does not check cache, it is the callers responsibility to check cache and load accordingly.
fn (mut repo GitRepo) load() ! {
console.print_header('load ${repo.print_key()}')
repo.init() or { return error('Failed to initialize repo during load operation: ${err}') }
repo.init() or {
repo.status_local.error = 'Failed to initialize repo during load operation: ${err}'
return error('Failed to initialize repo during load operation: ${err}')
}
git_path := '${repo.path()}/.git'
if os.exists(git_path) == false {
repo.status_local.error = 'Repository not found: missing .git directory'
return error('Repository not found: ${repo.path()} is not a valid git repository (missing .git directory)')
}
repo.exec('git fetch --all') or {
repo.status_remote.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.')
}
repo.load_branches() or { return error('Failed to load branches for ${repo.name}: ${err}') }
repo.load_branches() or {
repo.status_remote.error = 'Failed to load branches: ${err}'
return error('Failed to load branches for ${repo.name}: ${err}')
}
repo.load_tags() or { return error('Failed to load tags for ${repo.name}: ${err}') }
repo.load_tags() or {
repo.status_remote.error = 'Failed to load tags: ${err}'
return error('Failed to load tags for ${repo.name}: ${err}')
}
repo.last_load = int(time.now().unix())
repo.has_changes = repo.detect_changes() or {
repo.status_local.error = 'Failed to detect changes: ${err}'
return error('Failed to detect changes in repository ${repo.name}: ${err}')
}
repo.cache_set() or {
repo.status_local.error = 'Failed to update cache: ${err}'
return error('Failed to update cache for repository ${repo.name}: ${err}')
}
}