This commit is contained in:
2025-08-15 08:52:46 +02:00
parent 71298a9704
commit 43ffedfad8
36 changed files with 517 additions and 550 deletions

View File

@@ -1,7 +1,6 @@
module gittools
import os
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
@@ -16,11 +15,11 @@ pub fn reset() {
@[params]
pub struct GitStructureArgsNew {
pub mut:
coderoot string
log bool = true // If true, logs git commands/statements
debug bool = true
reload bool
offline bool
coderoot string
log bool = true // If true, logs git commands/statements
debug bool = true
reload bool
offline bool
}
// Retrieve or create a new GitStructure instance with the given configuration.
@@ -38,8 +37,8 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
panic('Unexpected error: key not found in gsinstances')
}
return gs
}else{
console.print_debug("Loading GitStructure for ${args.coderoot}")
} else {
console.print_debug('Loading GitStructure for ${args.coderoot}')
}
// Create and load the GitStructure instance.
@@ -47,8 +46,8 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
key: rediskey_
coderoot: pathlib.get_dir(path: args.coderoot, create: true)!
log: args.log
debug: args.debug
offline: args.offline
debug: args.debug
offline: args.offline
}
if 'OFFLINE' in os.environ() {
@@ -59,14 +58,13 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
if args.reload {
gs.load(true)!
}else{
} else {
gs.load(false)!
}
gsinstances[rediskey_] = &gs
return gsinstances[rediskey_] or { panic('bug') }
}
@[params]
@@ -90,15 +88,15 @@ pub mut:
pub fn path(args_ GitPathGetArgs) !pathlib.Path {
mut args := args_
if args.path!=""{
if args.path != '' {
if os.exists(args.path) {
return pathlib.get(args.path)
}else{
if args.git_url == "" {
} else {
if args.git_url == '' {
return error("can't resolve git repo path without url or existing path, ${args.path} does not exist.")
}
}
}
}
if args.git_url.len > 0 {
mut gs := new(coderoot: args.git_root)!
@@ -114,4 +112,3 @@ pub fn path(args_ GitPathGetArgs) !pathlib.Path {
}
return pathlib.get(args.path)
}

View File

@@ -32,7 +32,7 @@ pub fn (mut gs GitStructure) gitlocation_from_path(path string) !GitLocation {
provider := parts[0]
account := parts[1]
name := parts[2]
mut repo_path := if parts.len > 3 { parts[3..].join('/') } else { "" } //this is for relative path in repo
mut repo_path := if parts.len > 3 { parts[3..].join('/') } else { '' } // this is for relative path in repo
return GitLocation{
provider: provider

View File

@@ -6,7 +6,6 @@ import freeflowuniverse.herolib.ui.console
import os
import json
// GitStructure holds information about repositories within a specific code root.
// This structure keeps track of loaded repositories, their configurations, and their status.
@[heap]
@@ -17,9 +16,9 @@ pub mut:
key string // Unique key representing the git structure (default is hash of $home/code).
repos map[string]&GitRepo // Map of repositories
coderoot pathlib.Path
log bool = true // If true, logs git commands/statements
debug bool = true
offline bool
log bool = true // If true, logs git commands/statements
debug bool = true
offline bool
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -52,8 +51,6 @@ pub fn (mut gitstructure GitStructure) load(reset bool) ! {
// - path (string): The path to search for repositories.
// - processed_paths ([]string): List of already processed paths to avoid duplication.
fn (mut gitstructure GitStructure) load_recursive(path string, mut processed_paths []string) ! {
path_object := pathlib.get(path)
relpath := path_object.path_relative(gitstructure.coderoot.path)!
@@ -72,7 +69,8 @@ fn (mut gitstructure GitStructure) load_recursive(path string, mut processed_pat
current_path := os.join_path(path, item)
if os.is_dir(current_path) {
excluded_dirs := ['node_modules', 'vendor', 'dist', 'build', 'bin', 'obj', 'target', 'tmp', 'temp']
excluded_dirs := ['node_modules', 'vendor', 'dist', 'build', 'bin', 'obj', 'target',
'tmp', 'temp']
if item.starts_with('.') || item.starts_with('_') || excluded_dirs.contains(item) {
continue
}
@@ -131,13 +129,13 @@ fn (mut gitstructure GitStructure) repo_init_from_path_(path string, params Repo
// console.print_debug("Initializing GitRepo from path: ${mypath.path}")
// Initialize and return a GitRepo struct.
mut r := GitRepo{
gs: &gitstructure
status: GitStatus{}
config: GitRepoConfig{}
provider: gl.provider
account: gl.account
name: gl.name
deploysshkey: params.ssh_key_name
gs: &gitstructure
status: GitStatus{}
config: GitRepoConfig{}
provider: gl.provider
account: gl.account
name: gl.name
deploysshkey: params.ssh_key_name
}
return r

View File

@@ -2,7 +2,6 @@ module gittools
import json
@[params]
pub struct GitStructureConfig {
pub mut:
@@ -11,8 +10,6 @@ pub mut:
ssh_key_path string
}
// Load config from redis
pub fn (mut self GitStructure) config() !GitStructureConfig {
mut config := self.config_ or {
@@ -24,10 +21,10 @@ pub fn (mut self GitStructure) config() !GitStructureConfig {
}
c
}
return config
}
pub fn (mut self GitStructure) config_set(args GitStructureConfig) ! {
mut redis := redis_get()
redis.set('${self.cache_key()}:config', json.encode(args))!

View File

@@ -44,17 +44,44 @@ pub mut:
pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
mut args := args_
console.print_debug('git do ${args.cmd}')
// println(args)
// $dbg;
// if args.path == '' && args.url == '' && args.repo == '' && args.account == ''
// && args.provider == '' && args.filter == '' {
// args.path = os.getwd()
// }
if args.path.len > 0 && args.url.len > 0 {
panic('bug')
}
if args.path.len > 0 && args.filter.len > 0 {
panic('bug')
}
if args.url.len > 0 && args.filter.len > 0 {
panic('bug')
}
if args.path != '' {
mut curdiro := pathlib.get_dir(path: args.path, create: false)!
mut parentpath := curdiro.parent_find('.git') or { pathlib.Path{} }
if parentpath.path != '' {
r0 := gs.repo_init_from_path_(parentpath.path)!
if args.path.contains('*') {
panic('bug')
}
if args.path == '.' {
// means current dir
args.path = os.getwd()
mut curdiro := pathlib.get_dir(path: args.path, create: false)!
mut parentpath := curdiro.parent_find('.git') or { pathlib.Path{} }
args.path = curdiro.path
}
if !os.exists(args.path) {
return error('Path does not exist: ${args.path}')
}
r0 := gs.repo_init_from_path_(args.path)!
args.repo = r0.name
args.account = r0.account
args.provider = r0.provider
} else {
if args.url.len > 0 {
if !(args.repo == '' && args.account == '' && args.provider == '' && args.filter == '') {
return error('when specify url cannot specify repo, account, profider or filter')
}
mut r0 := gs.get_repo(url: args.url)!
args.repo = r0.name
args.account = r0.account
args.provider = r0.provider
@@ -72,15 +99,6 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
provider: args.provider
)!
// MODIFIED: Remove the global reload.
// The reload flag will now be handled inside the loop.
// if args.reload || args.cmd == 'reload' {
// for mut repo in repos {
// repo.cache_last_load_clear()!
// }
// gs.load(true)! // <-- REMOVED
// }
for mut repo in repos {
repo.status_update(reset: args.reload || args.cmd == 'reload')!
}
@@ -122,18 +140,6 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
return ''
}
// see if a url was used means we are in 1 repo
if args.url.len > 0 {
if !(args.repo == '' && args.account == '' && args.provider == '' && args.filter == '') {
return error('when specify url cannot specify repo, account, profider or filter')
}
mut r0 := gs.get_repo(url: args.url)!
args.repo = r0.name
args.account = r0.account
args.provider = r0.provider
}
if args.cmd in 'pull,push,commit,delete'.split(',') {
gs.repos_print(
filter: args.filter
@@ -166,10 +172,9 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
}
console.print_debug(" --- status repo ${g.name}'s\n need_commit0:${need_commit0} \n need_pull0:${need_pull0} \n need_push0:${need_push0}")
}
console.print_debug(" --- status all repo's\n need_commit0:${need_commit0} \n need_pull0:${need_pull0} \n need_push0:${need_push0}")
console.print_debug(" --- status all repo's\n need_commit0:${need_commit0} \n need_pull0:${need_pull0} \n need_push0:${need_push0}")
mut ok := false
if need_commit0 || need_pull0 || need_push0 {

View File

@@ -119,7 +119,7 @@ pub fn (mut gitstructure GitStructure) get_repo(args_ ReposGetArgs) !&GitRepo {
// repos := repositories.map('- ${it.account}.${it.name}').join_lines()
$if debug {
print_backtrace()
}
}
return error('Found more than one repository for \n${args}')
}

View File

@@ -5,8 +5,6 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal.core as osal
import os
// commit stages all changes and commits them with the provided message.
pub fn (mut repo GitRepo) commit(msg string) ! {
repo.status_update()!

View File

@@ -26,13 +26,13 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo {
// Initialize a new GitRepo instance
mut repo := GitRepo{
gs: &gitstructure
provider: git_location.provider
account: git_location.account
name: git_location.name
deploysshkey: args.sshkey // Use the sshkey from args
config: GitRepoConfig{} // Initialize with default config
status: GitStatus{} // Initialize with default status
gs: &gitstructure
provider: git_location.provider
account: git_location.account
name: git_location.name
deploysshkey: args.sshkey // Use the sshkey from args
config: GitRepoConfig{} // Initialize with default config
status: GitStatus{} // Initialize with default status
}
// Add the new repo to the gitstructure's repos map
@@ -70,7 +70,7 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo {
if result.exit_code != 0 {
return error('Cannot clone the repository due to: \n${result.output}')
}
// The repo is now cloned. Load its initial status.
repo.load_internal()!

View File

@@ -30,7 +30,6 @@ pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
// Decide if a full load is needed.
if args.reset || repo.last_load == 0
|| current_time - repo.last_load >= repo.config.remote_check_period {
$dbg;
repo.load_internal() or {
// Persist the error state to the cache
console.print_stderr('Failed to load repository ${repo.name} at ${repo.path()}: ${err}')
@@ -55,7 +54,7 @@ fn (mut repo GitRepo) load_internal() ! {
return error('Failed to fetch updates for ${repo.name} at ${repo.path()}: ${err}. Please check network connection and repository access.')
}
repo.load_branches()!
repo.load_tags()!
repo.load_tags()!
// Reset ahead/behind counts before recalculating
repo.status.ahead = 0
@@ -89,7 +88,6 @@ fn (mut repo GitRepo) load_internal() ! {
// Persist the newly loaded state to the cache.
repo.cache_set()!
}
// Helper to load remote tags
@@ -195,4 +193,4 @@ pub fn (mut repo GitRepo) detect_changes() !bool {
return true
}
return false
}
}

View File

@@ -1,12 +1,11 @@
module gittools
// GitRepo represents a single git repository.
@[heap]
pub struct GitRepo {
// a git repo is always part of a git structure
mut:
gs &GitStructure @[skip; str: skip]
gs &GitStructure @[skip; str: skip]
last_load int // epoch when last loaded
pub mut:
provider string // e.g., github.com
@@ -26,10 +25,10 @@ pub mut:
tags map[string]string // All tag names -> commit hash
// Current local state
branch string // The current checked-out branch.
tag string // The current checked-out tag (if any).
ahead int // Commits ahead of remote.
behind int // Commits behind remote.
branch string // The current checked-out branch.
tag string // The current checked-out tag (if any).
ahead int // Commits ahead of remote.
behind int // Commits behind remote.
// Combined status
has_changes bool // True if there are uncommitted local changes.