This commit is contained in:
2025-01-23 14:09:20 +01:00
parent f2b9b73528
commit 6637756088
16 changed files with 233 additions and 214 deletions

View File

@@ -45,7 +45,7 @@ repo.branch_create('feature-branch')!
repo.branch_switch('feature-branch')!
// Check status and commit changes
if repo.has_changes() {
if repo.has_changes {
repo.commit('feat: Add new feature')!
repo.push()!
}
@@ -114,7 +114,7 @@ if repo.need_checkout() {
```v
// Check for changes
if repo.has_changes() {
if repo.has_changes {
// Handle changes
}

View File

@@ -36,13 +36,8 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
debug: args.debug
ssh_key_name: args.ssh_key_name
}
// Retrieve the configuration from Redis.
rediskey_ := rediskey(args.coderoot)
mut redis := redis_get()
datajson := json.encode(cfg)
redis.set(rediskey_, datajson)!
return get(coderoot: args.coderoot, reload: args.reload)
return get(coderoot: args.coderoot,reload:args.reload,cfg:cfg)
}
@[params]
@@ -50,6 +45,7 @@ pub struct GitStructureArgGet {
pub mut:
coderoot string
reload bool
cfg ?GitStructureConfig
}
// Retrieve a GitStructure instance based on the given arguments.
@@ -58,44 +54,29 @@ pub fn get(args_ GitStructureArgGet) !&GitStructure {
if args.coderoot == '' {
args.coderoot = '${os.home_dir()}/code'
}
if args.reload {
cachereset()!
}
rediskey_ := rediskey(args.coderoot)
rediskey_ := cache_key(args.coderoot)
// Return existing instance if already created.
if rediskey_ in gsinstances {
mut gs := gsinstances[rediskey_] or {
panic('Unexpected error: key not found in gsinstances')
}
if args.reload {
gs.load()!
}
gs.load(args.reload)!
return gs
}
mut redis := redis_get()
mut datajson := redis.get(rediskey_) or { '' }
if datajson == '' {
if args_.coderoot == '' {
return new()!
}
return error("can't find repostructure for coderoot: ${args.coderoot}")
}
mut config := json.decode(GitStructureConfig, datajson) or { GitStructureConfig{} }
// Create and load the GitStructure instance.
mut gs := GitStructure{
key: rediskey_
config: config
coderoot: pathlib.get_dir(path: args.coderoot, create: true)!
}
// TODO: should we load repos here disregarding the reload flag?
gs.config()! //will load the config, don't remove
gs.load(false)!
if gs.repos.keys().len == 0 || args.reload {
gs.load()!
gs.load(true)!
}
gsinstances[rediskey_] = &gs
@@ -103,25 +84,3 @@ pub fn get(args_ GitStructureArgGet) !&GitStructure {
return gsinstances[rediskey_] or { panic('bug') }
}
// Reset the configuration cache for Git structures.
pub fn configreset() ! {
mut redis := redis_get()
key_check := 'git:config:*'
keys := redis.keys(key_check)!
for key in keys {
redis.del(key)!
}
}
// Reset all caches and configurations for all Git repositories.
pub fn cachereset() ! {
key_check := 'git:repos:**'
mut redis := redis_get()
keys := redis.keys(key_check)!
for key in keys {
redis.del(key)!
}
configreset()!
}

View File

@@ -103,7 +103,7 @@ pub fn (mut gs GitStructure) gitlocation_from_url(url string) !GitLocation {
}
// Return a herolib path object on the filesystem pointing to the locator
pub fn (mut l GitLocation) patho() !pathlib.Path {
pub fn (l GitLocation) patho() !pathlib.Path {
mut addrpath := pathlib.get_dir(path: '${l.provider}/${l.account}/${l.name}', create: false)!
if l.path.len > 0 {
return pathlib.get('${addrpath.path}/${l.path}')

View File

@@ -5,33 +5,31 @@ import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.redisclient
import os
import freeflowuniverse.herolib.ui.console
import json
pub struct GitStructureConfig {
pub mut:
coderoot string
coderoot string //just to be informative, its not used
light bool = true // If true, clones only the last history for all branches (clone with only 1 level deep)
log bool = true // If true, logs git commands/statements
debug bool = true
ssh_key_name string
}
fn rediskey(coderoot string) string {
key := md5.hexhash(coderoot)
return 'git:config:${key}'
}
// GitStructure holds information about repositories within a specific code root.
// This structure keeps track of loaded repositories, their configurations, and their status.
@[heap]
pub struct GitStructure {
mut:
config_ ?GitStructureConfig // Configuration settings for the git structure.
pub mut:
key string // Unique key representing the git structure (default is hash of $home/code).
config GitStructureConfig // Configuration settings for the git structure.
coderoot pathlib.Path // Root directory where repositories are located.
repos map[string]&GitRepo // Map of repositories, keyed by their unique names.
loaded bool // Indicates if the repositories have been loaded into memory.
key string // Unique key representing the git structure (default is hash of $home/code).
repos map[string]&GitRepo // Map of repositories
coderoot pathlib.Path
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
@@ -39,45 +37,57 @@ pub mut:
// Use the reload argument to force reloading from the disk.
//
// Args:
// - args (StatusUpdateArgs): Arguments controlling the reload behavior.
pub fn (mut gitstructure GitStructure) load(args StatusUpdateArgs) ! {
// - args (StatusUpdateArgs): Arguments controlling the reload behavior. (is just a reload:bool)
pub fn (mut gitstructure GitStructure) load(reload bool) ! {
mut processed_paths := []string{}
if reload{
gitstructure.repos=map[string]&GitRepo{}
}
gitstructure.load_recursive(gitstructure.coderoot.path, mut processed_paths)!
if args.reload {
mut ths := []thread !{}
redisclient.reset()! // make sure redis is empty, we don't want to reuse
for _, mut repo_ in gitstructure.repos {
mut myfunction := fn (mut repo GitRepo) ! {
// println("reload repo ${repo.name} on ${repo.get_path()!}")
redisclient.reset()!
redisclient.checkempty()
repo.status_update(reload: true)!
}
ths << spawn myfunction(mut repo_)
}
console.print_debug('loaded all threads for git on ${gitstructure.coderoot.path}')
for th in ths {
th.wait()!
}
// console.print_debug("threads finished")
// exit(0)
if reload{
gitstructure.cache_reset()!
}
// mut ths := []thread !{}
//need to make sure redis is empty before doing the threads
redisclient.reset()!
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)
}
}
// pp.work_on_items(todo)
//console.print_debug('loaded all threads for git on ${gitstructure.coderoot}')
// for th in ths {
// th.wait()!
// }
// for x in pp.get_results[SResult]() {
// println('result: ${x.s}')
// }
// console.print_debug("threads finished")
//now we need to load them back in our memory because these were done in sub process
// for _, mut r in gitstructure.repos {
// r.cache_get()!
// }
// gitstructure.init()!
}
// // just some initialization mechanism
// pub fn (mut gitstructure GitStructure) init() ! {
// if gitstructure.repos.keys().len == 0 {
// println('Before loading keys.')
// gitstructure.load()!
// }
// }
// Recursively loads repositories from the provided path, updating their statuses.
// Recursively loads repositories from the provided path, updating their statuses, does not check the status
//
// Args:
// - path (string): The path to search for repositories.
@@ -104,8 +114,8 @@ fn (mut gitstructure GitStructure) load_recursive(path string, mut processed_pat
mut repo := gitstructure.repo_init_from_path_(current_path)!
// repo.status_update()!
key_ := repo.get_key()
path_ := repo.get_path()!
key_ := repo.cache_key()
path_ := repo.path()
if processed_paths.contains(key_) || processed_paths.contains(path_) {
return error('Duplicate repository detected.\nPath: ${path_}\nKey: ${key_}')
@@ -126,15 +136,6 @@ fn (mut gitstructure GitStructure) load_recursive(path string, mut processed_pat
}
}
// Resets the cache for the current Git structure, removing cached data from Redis.
pub fn (mut gitstructure GitStructure) cachereset() ! {
mut redis := redis_get()
keys := redis.keys('git:repos:${gitstructure.key}:**')!
for key in keys {
redis.del(key)!
}
}
@[params]
pub struct RepoInitParams {
@@ -190,3 +191,77 @@ pub fn (mut gitstructure GitStructure) get_working_repo() ?GitRepo {
curdir := pathlib.get_wd()
return gitstructure.repo_init_from_path_(curdir.path) or { return none }
}
//key in redis used to store all config info
fn cache_key(coderoot string) string {
key := md5.hexhash(coderoot)
return 'git:${key}'
}
//key in redis used to store all config info
pub fn (mut self GitStructure) cache_key() string {
return cache_key(self.coderoot.path)
}
//load from cache
pub fn (mut self GitStructure) cache_load() ! {
// Retrieve the configuration from Redis.
mut redis := redis_get()
keys := redis.keys("${self.cache_key()}:repos")!
self.repos = map[string]&GitRepo{} //reset
for key in keys {
data:=redis.get(key)!
mut r:=json.decode(GitRepo,data)!
self.repos[key] = &r
}
}
// Reset all caches and configurations for all Git repositories.
pub fn (mut self GitStructure) cache_reset() ! {
mut redis := redis_get()
keys := redis.keys("${self.cache_key()}:**")!
for key in keys {
redis.del(key)!
}
}
// Load config from redis
fn (mut self GitStructure) coderoot() !pathlib.Path {
mut coderoot := pathlib.get_dir(path:self.coderoot.path,create:true)!
return coderoot
}
////// CONFIG
// Load config from redis
fn (mut self GitStructure) config() !GitStructureConfig {
mut config := self.config_ or {
mut redis := redis_get()
data:=redis.get("${self.cache_key()}:config")!
mut c:= GitStructureConfig{}
if data.len>0{
c = json.decode(GitStructureConfig,data)!
}
c
}
return config
}
// Reset the configuration cache for Git structures.
pub fn (mut self GitStructure) config_reset() ! {
mut redis := redis_get()
redis.del("${self.cache_key()}:config")!
}
//save to the cache
pub fn (mut self GitStructure) config_save() ! {
// Retrieve the configuration from Redis.
mut redis := redis_get()
datajson := json.encode(self.config)
redis.set("${self.cache_key()}:config", datajson)!
}

View File

@@ -61,8 +61,8 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
mut ui := gui.new()!
if args.cmd == 'reload' {
console.print_header(' - reload gitstructure ${gs.config.coderoot}')
gs.load(reload: true)!
console.print_header(' - reload gitstructure ${gs.config()!.coderoot}')
gs.load(true)!
return ''
}
@@ -87,7 +87,7 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
mut g := gs.get_repo(url: args.url)!
g.load()!
if args.cmd == 'cd' {
return g.get_path()!
return g.path()
}
if args.reset {
g.remove_changes()!
@@ -105,7 +105,7 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
g.push()!
}
if args.cmd == 'pull' || args.cmd == 'clone' || args.cmd == 'push' {
gpath := g.get_path()!
gpath := g.path()
console.print_debug('git do ok, on path ${gpath}')
return gpath
}
@@ -119,7 +119,7 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
if repos.len > 4 {
return error('more than 4 repo found for cmd:${args.cmd}')
}
for r in repos {
for mut r in repos {
if args.cmd == 'edit' {
r.open_vscode()!
}

View File

@@ -7,13 +7,14 @@ fn get_repo_status(gr GitRepo) !string {
mut repo := gr
mut statuses := []string{}
if repo.need_commit()! {
if repo.has_changes {
statuses << 'COMMIT'
}
if repo.need_push_or_pull()! {
statuses << 'PULL'
statuses << 'PUSH'
}
return statuses.join(', ')
}
@@ -33,8 +34,8 @@ 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('')
// console.print_debug('#### Overview of repositories:')
// console.print_debug('')
mut repo_data := [][]string{}
@@ -49,11 +50,11 @@ pub fn (mut gitstructure GitStructure) repos_print(args ReposGetArgs) ! {
// Display header with optional argument filtering information
// header := if args.str().len > 0 {
// 'Repositories: ${gitstructure.config.coderoot} [${args.str()}]'
// 'Repositories: ${gitstructure.config()!.coderoot} [${args.str()}]'
// } else {
// 'Repositories: ${gitstructure.config.coderoot}'
// 'Repositories: ${gitstructure.config()!.coderoot}'
// }
header:='Repositories: ${gitstructure.config.coderoot}'
header:='Repositories: ${gitstructure.config()!.coderoot}'
console.print_header(header)
// Print the repository information in a formatted array

View File

@@ -18,6 +18,7 @@ pub mut:
config GitRepoConfig // Repository-specific configuration
last_load int // Epoch timestamp of the last load from reality
deploysshkey string // to use with git
has_changes bool
}
// this is the status we want, we need to work towards off
@@ -77,7 +78,7 @@ pub fn (mut repo GitRepo) commit(msg string) ! {
if msg == '' {
return error('Commit message is empty.')
}
repo_path := repo.get_path()!
repo_path := repo.path()
repo.exec('git add . -A') or {
return error('Cannot add to repo: ${repo_path}. Error: ${err}')
}
@@ -121,7 +122,7 @@ pub fn (mut repo GitRepo) pull(args_ PullCheckoutArgs) ! {
}
repo.exec('git pull') or {
return error('Cannot pull repo: ${repo.get_path()!}. Error: ${err}')
return error('Cannot pull repo: ${repo.path()}. Error: ${err}')
}
if args_.submodules {
@@ -139,7 +140,7 @@ pub fn (mut repo GitRepo) checkout() ! {
repo.reset()!
}
if repo.need_commit()! {
return error('Cannot checkout branch due to uncommitted changes in ${repo.get_path()!}.')
return error('Cannot checkout branch due to uncommitted changes in ${repo.path()}.')
}
if repo.status_wanted.tag.len > 0 {
repo.exec('git checkout tags/${repo.status_wanted.tag}')!
@@ -152,14 +153,14 @@ pub fn (mut repo GitRepo) checkout() ! {
// Create a new branch in the repository.
pub fn (mut repo GitRepo) branch_create(branchname string) ! {
repo.exec('git branch -c ${branchname}') or {
return error('Cannot Create branch: ${repo.get_path()!} to ${branchname}\nError: ${err}')
return error('Cannot Create branch: ${repo.path()} to ${branchname}\nError: ${err}')
}
console.print_green('Branch ${branchname} created successfully.')
}
pub fn (mut repo GitRepo) branch_switch(branchname string) ! {
repo.exec('git switch ${branchname}') or {
return error('Cannot switch branch: ${repo.get_path()!} to ${branchname}\nError: ${err}')
return error('Cannot switch branch: ${repo.path()} to ${branchname}\nError: ${err}')
}
console.print_green('Branch ${branchname} switched successfully.')
repo.status_local.branch = branchname
@@ -169,7 +170,7 @@ pub fn (mut repo GitRepo) branch_switch(branchname string) ! {
// Create a new branch in the repository.
pub fn (mut repo GitRepo) tag_create(tagname string) ! {
repo_path := repo.get_path()!
repo_path := repo.path()
repo.exec('git tag ${tagname}') or {
return error('Cannot create tag: ${repo_path}. Error: ${err}')
}
@@ -194,7 +195,7 @@ pub fn (mut repo GitRepo) tag_exists(tag string) !bool {
// Deletes the Git repository
pub fn (mut repo GitRepo) delete() ! {
repo_path := repo.get_path()!
repo_path := repo.path()
repo.cache_delete()!
osal.rm(repo_path)!
repo.load()!
@@ -230,10 +231,7 @@ pub fn (mut gs GitRepo) gitlocation_from_path(path string) !GitLocation {
// Check if repo path exists and validate fields
pub fn (mut repo GitRepo) init() ! {
path_string := repo.get_path()!
if repo.gs.coderoot.path == '' {
return error('Coderoot cannot be empty')
}
path_string := repo.path()
if repo.provider == '' {
return error('Provider cannot be empty')
}
@@ -272,12 +270,12 @@ fn (mut repo GitRepo) set_sshkey(key_name string) ! {
// Removes all changes from the repo; be cautious
pub fn (mut repo GitRepo) remove_changes() ! {
repo.status_update()!
if repo.has_changes()! {
console.print_header('Removing changes in ${repo.get_path()!}')
if repo.has_changes {
console.print_header('Removing changes in ${repo.path()}')
repo.exec('git reset HEAD --hard && git clean -xfd') or {
return error("can't remove changes on repo: ${repo.get_path()!}.\n${err}")
return error("can't remove changes on repo: ${repo.path()}.\n${err}")
// TODO: we can do this fall back later
// console.print_header('Could not remove changes; will re-clone ${repo.get_path()!}')
// console.print_header('Could not remove changes; will re-clone ${repo.path()}')
// mut p := repo.patho()!
// p.delete()! // remove path, this will re-clone the full thing
// repo.load_from_url()!
@@ -294,16 +292,14 @@ pub fn (mut repo GitRepo) reset() ! {
// Update submodules
fn (mut repo GitRepo) update_submodules() ! {
repo.exec('git submodule update --init --recursive') or {
return error('Cannot update submodules for repo: ${repo.get_path()!}. Error: ${err}')
return error('Cannot update submodules for repo: ${repo.path()}. Error: ${err}')
}
}
fn (repo GitRepo) exec(cmd_ string) !string {
repo_path := repo.get_path()!
repo_path := repo.path()
cmd := 'cd ${repo_path} && ${cmd_}'
if repo.gs.config.log {
console.print_green(cmd)
}
//console.print_debug(cmd)
r := os.execute(cmd)
if r.exit_code != 0 {
return error('Repo failed to exec cmd: ${cmd}\n${r.output})')

View File

@@ -12,7 +12,7 @@ fn redis_get() &redisclient.Redis {
fn (mut repo GitRepo) cache_set() ! {
mut redis_client := redis_get()
repo_json := json.encode(repo)
cache_key := repo.get_cache_key()
cache_key := repo.cache_key()
redis_client.set(cache_key, repo_json)!
}
@@ -20,9 +20,9 @@ fn (mut repo GitRepo) cache_set() ! {
fn (mut repo GitRepo) cache_get() ! {
mut repo_json := ''
mut redis_client := redis_get()
cache_key := repo.get_cache_key()
cache_key := repo.cache_key()
repo_json = redis_client.get(cache_key) or {
return error('Failed to get redis key ${cache_key}\n${err}')
return
}
if repo_json.len > 0 {
@@ -33,9 +33,9 @@ fn (mut repo GitRepo) cache_get() ! {
}
// Remove cache
fn (repo GitRepo) cache_delete() ! {
fn (mut repo GitRepo) cache_delete() ! {
mut redis_client := redis_get()
cache_key := repo.get_cache_key()
cache_key := repo.cache_key()
redis_client.del(cache_key) or { return error('Cannot delete the repo cache due to: ${err}') }
// TODO: report v bug, function should work without return as well
return

View File

@@ -1,7 +1,7 @@
module gittools
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.osal
import os
@[params]
@@ -31,7 +31,7 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo {
parent_dir := repo.get_parent_dir(create: true)!
mut extra := ''
if gitstructure.config.light {
if gitstructure.config()!.light {
extra = '--depth 1 --no-single-branch '
}

View File

@@ -34,7 +34,7 @@ pub fn (repo GitRepo) get_changes_staged() ![]string {
}
// Check if there are any unstaged or untracked changes in the repository.
pub fn (mut repo GitRepo) has_changes() !bool {
pub fn (mut repo GitRepo) detect_changes() !bool {
repo.status_update()!
r0 := repo.get_changes_unstaged()!
r1 := repo.get_changes_staged()!
@@ -46,10 +46,10 @@ pub fn (mut repo GitRepo) has_changes() !bool {
// Check if there are staged changes to commit.
pub fn (mut repo GitRepo) need_commit() !bool {
return repo.has_changes()!
return repo.has_changes
}
// Check if the repository has changes that need to be pushed.
// Check if the repository has changes that need to be pushed (is against the cached info).
pub fn (mut repo GitRepo) need_push_or_pull() !bool {
repo.status_update()!
last_remote_commit := repo.get_last_remote_commit() or {
@@ -58,8 +58,7 @@ pub fn (mut repo GitRepo) need_push_or_pull() !bool {
last_local_commit := repo.get_last_local_commit() or {
return error('Failed to get last local commit: ${err}')
}
println('last_local_commit: ${last_local_commit}')
println('last_remote_commit: ${last_remote_commit}')
println('commit status: ${repo.name} ${last_local_commit} ${last_remote_commit}')
return last_local_commit != last_remote_commit
}
@@ -92,19 +91,19 @@ fn (mut repo GitRepo) get_remote_default_branchname() !string {
}
// is always the commit for the branch as known remotely, if not known will return ""
pub fn (repo GitRepo) get_last_remote_commit() !string {
if repo.status_local.branch in repo.status_remote.branches {
return repo.status_local.branches[repo.status_local.branch]
pub fn (self GitRepo) get_last_remote_commit() !string {
if self.status_local.branch in self.status_remote.branches {
return self.status_remote.branches[self.status_local.branch]
}
return ''
}
// get commit for branch, will return '' if local branch doesn't exist remotely
pub fn (repo GitRepo) get_last_local_commit() !string {
if repo.status_local.branch in repo.status_local.branches {
return repo.status_local.branches[repo.status_local.branch]
pub fn (self GitRepo) get_last_local_commit() !string {
if self.status_local.branch in self.status_local.branches {
return self.status_local.branches[self.status_local.branch]
}
return error("can't find branch: ${repo.status_local.branch} in local branches:\n${repo.status_local.branches}")
return error("can't find branch: ${self.status_local.branch} in local branches:\n${self.status_local.branches}")
}

View File

@@ -2,11 +2,10 @@ module gittools
import time
import freeflowuniverse.herolib.ui.console
import os
@[params]
pub struct StatusUpdateArgs {
reload bool
ssh_key_name string // name of ssh key to be used when loading
}
pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
@@ -27,14 +26,18 @@ pub fn (mut repo GitRepo) status_update(args StatusUpdateArgs) ! {
// Load repo information
// Does not check cache, it is the callers responsibility to check cache and load accordingly.
fn (mut repo GitRepo) load() ! {
console.print_debug('load ${repo.get_key()}')
console.print_debug('load ${repo.cache_key()}')
repo.init()!
if os.exists("${repo.path()}/.git") == false{
return error("Can't find git in repo ${repo.path()}")
}
repo.exec('git fetch --all') or {
return error('Cannot fetch repo: ${repo.get_path()!}. Error: ${err}')
return error('Cannot fetch repo: ${repo.path()}. Error: ${err}')
}
repo.load_branches()!
repo.load_tags()!
repo.last_load = int(time.now().unix())
repo.has_changes = repo.detect_changes()!
repo.cache_set()!
}

View File

@@ -1,6 +1,5 @@
module gittools
import freeflowuniverse.herolib.osal
import freeflowuniverse.herolib.osal.sshagent
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
@@ -14,22 +13,28 @@ pub mut:
create bool
}
fn (repo GitRepo) get_key() string {
return '${repo.gs.key}:${repo.provider}:${repo.account}:${repo.name}'
//get the key in redis where json cached info is
pub fn (mut repo GitRepo) cache_key() string {
return '${repo.gs.cache_key()}:${repo.provider}:${repo.account}:${repo.name}'
}
fn (repo GitRepo) get_cache_key() string {
return 'git:repos:${repo.gs.key}:${repo.provider}:${repo.account}:${repo.name}'
//get path where the repo is on the fs
pub fn (repo GitRepo) path() string {
mut repo_:=repo
mypath:=repo_.gs.coderoot.path
return '${mypath}/${repo.provider}/${repo.account}/${repo.name}'
}
pub fn (repo GitRepo) get_path() !string {
return '${repo.gs.coderoot.path}/${repo.provider}/${repo.account}/${repo.name}'
//get herolib path object
pub fn (repo GitRepo) patho() !pathlib.Path {
return pathlib.get_dir(path: repo.path(), create: false)!
}
// gets the path of a given url within a repo
// ex: 'https://git.ourworld.tf/ourworld_holding/info_ourworld/src/branch/main/books/cocreation/SUMMARY.md'
// returns <repo_path>/books/cocreation/SUMMARY.md
pub fn (repo GitRepo) get_path_of_url(url string) !string {
fn (mut repo GitRepo) get_path_of_url(url string) !string {
// Split the URL into components
url_parts := url.split('/')
@@ -41,9 +46,7 @@ pub fn (repo GitRepo) get_path_of_url(url string) !string {
if repo_root_idx == -1 {
// maybe default repo url (without src and blob)
return repo.get_path() or {
return error('Invalid URL format: Cannot find repository path')
}
return repo.path()
}
// Ensure that the repository path starts after the branch
@@ -55,17 +58,18 @@ pub fn (repo GitRepo) get_path_of_url(url string) !string {
path_in_repo := url_parts[repo_root_idx + 3..].join('/')
// Construct the full path
return '${repo.get_path()!}/${path_in_repo}'
return '${repo.path()}/${path_in_repo}'
}
// Relative path inside the gitstructure, pointing to the repo
pub fn (repo GitRepo) get_relative_path() !string {
mut mypath := repo.patho()!
return mypath.path_relative(repo.gs.coderoot.path) or { panic("couldn't get relative path") }
mut repo_:=repo
return mypath.path_relative(repo_.gs.coderoot.path) or { panic("couldn't get relative path") }
}
pub fn (repo GitRepo) get_parent_dir(args GetParentDir) !string {
repo_path := repo.get_path()!
pub fn (mut repo GitRepo) get_parent_dir(args GetParentDir) !string {
repo_path := repo.path()
parent_dir := os.dir(repo_path)
if !os.exists(parent_dir) && !args.create {
return error('Parent directory does not exist: ${parent_dir}')
@@ -114,9 +118,6 @@ fn (self GitRepo) get_http_url() !string {
}
// Return rich path object from our library hero lib
pub fn (repo GitRepo) patho() !pathlib.Path {
return pathlib.get_dir(path: repo.get_path()!, create: false)!
}
pub fn (mut repo GitRepo) display_current_status() ! {
staged_changes := repo.get_changes_staged()!
@@ -139,13 +140,13 @@ pub fn (mut repo GitRepo) display_current_status() ! {
}
// Opens SourceTree for the Git repo
pub fn (repo GitRepo) sourcetree() ! {
sourcetree.open(path: repo.get_path()!)!
pub fn (mut repo GitRepo) sourcetree() ! {
sourcetree.open(path: repo.path())!
}
// Opens Visual Studio Code for the repo
pub fn (repo GitRepo) open_vscode() ! {
path := repo.get_path()!
pub fn (mut repo GitRepo) open_vscode() ! {
path := repo.path()
mut vs_code := vscode.new(path)
vs_code.open()!
}

View File

@@ -42,7 +42,7 @@ fn test_clone_repo() {
repo_setup_tests = setup_repo()!
mut gs := gittools.new(coderoot: repo_setup_tests.coderoot)!
repo_tests = gs.get_repo(url: repo_setup_tests.repo_url)!
repo_path_tests = repo_tests.get_path()!
repo_path_tests = repo_tests.path()
assert os.exists(repo_path_tests) == true
}
@@ -91,7 +91,7 @@ fn test_tag_create() {
@[test]
fn test_has_changes_add_changes_commit_changes() {
file_name := create_new_file(repo_path_tests)!
assert repo_tests.has_changes()! == true
assert repo_tests.has_changes == true
mut unstaged_changes := repo_tests.get_changes_unstaged()!
assert unstaged_changes.len == 1
mut staged_changes := repo_tests.get_changes_staged()!
@@ -113,7 +113,7 @@ fn test_has_changes_add_changes_commit_changes() {
@[test]
fn test_push_changes() {
file_name := create_new_file(repo_path_tests)!
assert repo_tests.has_changes()! == true
assert repo_tests.has_changes == true
mut unstaged_changes := repo_tests.get_changes_unstaged()!
assert unstaged_changes.len == 1
mut staged_changes := repo_tests.get_changes_staged()!
@@ -142,7 +142,7 @@ fn test_multiple_commits_and_push() {
repo_tests.commit('feat: Added ${file_name_2} file.')!
repo_tests.push()!
assert repo_tests.has_changes()! == false
assert repo_tests.has_changes == false
}
// Test committing with valid changes.
@@ -165,7 +165,7 @@ fn test_commit_with_valid_changes() {
// - Attempts to commit and expects a failure.
@[test]
fn test_commit_without_changes() {
assert repo_tests.has_changes()! == false
assert repo_tests.has_changes == false
assert repo_tests.need_commit()! == false
repo_tests.commit('Initial commit') or {
assert false, 'Commit should be done with some changes'
@@ -223,7 +223,7 @@ fn test_remove_changes() {
assert staged_changes.len == 0
file_name := create_new_file(repo_path_tests)!
assert repo_tests.has_changes()! == true
assert repo_tests.has_changes == true
unstaged_changes = repo_tests.get_changes_unstaged()!
assert unstaged_changes.len == 1