Files
herolib/lib/develop/gittools/gittools_do.v
2025-01-23 14:09:20 +01:00

275 lines
6.7 KiB
V

module gittools
import freeflowuniverse.herolib.ui as gui
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.ui.generic
import freeflowuniverse.herolib.core.redisclient
import os
pub const gitcmds = 'clone,commit,pull,push,delete,reload,list,edit,sourcetree,cd'
@[params]
pub struct ReposActionsArgs {
pub mut:
cmd string // clone,commit,pull,push,delete,reload,list,edit,sourcetree
filter string // if used will only show the repo's which have the filter string inside
repo string
account string
provider string
msg string
url string
branch string
recursive bool
pull bool
script bool = true // run non interactive
reset bool = true // means we will lose changes (only relevant for clone, pull)
}
// do group actions on repo
// args
//```
// cmd string // clone,commit,pull,push,delete,reload,list,edit,sourcetree,cd
// filter string // if used will only show the repo's which have the filter string inside
// repo string
// account string
// provider string
// msg string
// url string
// pull bool
// script bool = true // run non interactive
// reset bool = true // means we will lose changes (only relevant for clone, pull)
//```
pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
mut args := args_
console.print_debug('git do ${args.cmd}')
if args.repo == '' && args.account == '' && args.provider == '' && args.filter == '' {
curdir := os.getwd()
mut curdiro := pathlib.get_dir(path: curdir, create: false)!
mut parentpath := curdiro.parent_find('.git') or { pathlib.Path{} }
if parentpath.path != '' {
r0 := gs.repo_init_from_path_(parentpath.path)!
args.repo = r0.name
args.account = r0.account
args.provider = r0.provider
}
}
args.cmd = args.cmd.trim_space().to_lower()
mut ui := gui.new()!
if args.cmd == 'reload' {
console.print_header(' - reload gitstructure ${gs.config()!.coderoot}')
gs.load(true)!
return ''
}
if args.cmd == 'list' {
gs.repos_print(
filter: args.filter
name: args.repo
account: args.account
provider: args.provider
)!
return ''
}
mut repos := gs.get_repos(
filter: args.filter
name: args.repo
account: args.account
provider: args.provider
)!
if args.url.len > 0 {
mut g := gs.get_repo(url: args.url)!
g.load()!
if args.cmd == 'cd' {
return g.path()
}
if args.reset {
g.remove_changes()!
}
if args.cmd == 'pull' || args.pull {
g.pull()!
}
if args.cmd == 'push' {
if g.need_commit()! {
if args.msg.len == 0 {
return error('please specify message with -m ...')
}
g.commit(args.msg)!
}
g.push()!
}
if args.cmd == 'pull' || args.cmd == 'clone' || args.cmd == 'push' {
gpath := g.path()
console.print_debug('git do ok, on path ${gpath}')
return gpath
}
repos = [g]
}
if args.cmd in 'sourcetree,edit'.split(',') {
if repos.len == 0 {
return error('please specify at least 1 repo for cmd:${args.cmd}')
}
if repos.len > 4 {
return error('more than 4 repo found for cmd:${args.cmd}')
}
for mut r in repos {
if args.cmd == 'edit' {
r.open_vscode()!
}
if args.cmd == 'sourcetree' {
r.sourcetree()!
}
}
return ''
}
if args.cmd in 'pull,push,commit,delete'.split(',') {
gs.repos_print(
filter: args.filter
name: args.repo
account: args.account
provider: args.provider
)!
mut need_commit := false
mut need_pull := false
mut need_push := false
if repos.len == 0 {
console.print_header(' - nothing to do.')
return ''
}
// check on repos who needs what
for mut g in repos {
g.load()!
// console.print_debug(st)
need_commit = g.need_commit()! || need_commit
if args.cmd == 'push' && need_commit {
need_push = true
}
need_pull = args.cmd in 'pull,push'.split(',') // always do pull when push and pull
need_push = args.cmd == 'push' && (g.need_push_or_pull()! || need_push)
}
mut ok := false
if need_commit || need_pull || need_push {
mut out := '\n ** NEED TO '
if need_commit {
out += 'COMMIT '
}
if need_pull {
out += 'PULL '
}
if need_push {
out += 'PUSH '
}
if args.reset {
out += ' (changes will be lost!)'
}
console.print_debug(out + ' ** \n')
if args.script {
ok = true
} else {
ok = ui.ask_yesno(question: 'Is above ok?')!
}
}
if args.cmd == 'delete' {
if args.script {
ok = true
} else {
ok = ui.ask_yesno(question: 'Is it ok to delete above repos? (DANGEROUS)')!
}
}
if ok == false {
return error('cannot continue with action, you asked me to stop.\n${args}')
}
// mut changed := false
mut ths := []thread !bool{}
for mut g in repos {
ths << spawn fn (mut g GitRepo, args ReposActionsArgs, need_commit bool, need_push bool, shared ui generic.UserInterface) !bool {
redisclient.reset()!
redisclient.checkempty()
mut has_changed := false
need_commit_repo := (g.need_commit()! || need_commit)
&& args.cmd in 'commit,pull,push'.split(',')
need_pull_repo := args.cmd in 'pull,push'.split(',') // always do pull when push and pull
need_push_repo := args.cmd in 'push'.split(',')
&& (g.need_push_or_pull()! || need_push)
// console.print_debug(" --- git_do ${g.addr.name} ${st.need_commit} ${st.need_pull} ${st.need_push}")
if need_commit_repo {
mut msg := args.msg
if msg.len == 0 {
if args.script {
return error('message needs to be specified for commit.')
}
lock ui {
msg = ui.ask_question(
question: 'commit message for repo: ${g.account}/${g.name} '
)!
}
}
console.print_header(' - commit ${g.account}/${g.name}')
g.commit(msg)!
has_changed = true
}
if need_pull_repo {
if args.reset {
console.print_header(' - remove changes ${g.account}/${g.name}')
g.remove_changes()!
}
console.print_header(' - pull ${g.account}/${g.name}')
g.pull()!
has_changed = true
}
if need_push_repo {
console.print_header(' - push ${g.account}/${g.name}')
g.push()!
has_changed = true
}
if args.cmd == 'delete' {
g.delete()!
has_changed = true
}
return has_changed
}(mut g, args, need_commit, need_push, shared &ui)
}
for th in ths {
has_changed := th.wait()!
if has_changed {
// console.clear()
console.print_header('\nCompleted required actions.\n')
gs.repos_print(
filter: args.filter
name: args.repo
account: args.account
provider: args.provider
)!
}
}
return ''
}
// end for the commit, pull, push, delete
$if debug {
print_backtrace()
}
return error('did not find cmd: ${args.cmd}')
}