Files
herolib/lib/develop/gittools/repository_clone.v
2025-08-29 10:17:34 +02:00

90 lines
2.7 KiB
V

module gittools
import freeflowuniverse.herolib.ui.console
import os
import freeflowuniverse.herolib.core.pathlib
@[params]
pub struct GitCloneArgs {
pub mut:
// only url needed because is a clone
url string
sshkey string
recursive bool // If true, also clone submodules
light bool // If true, clones only the last history for all branches (clone with only 1 level deep)
}
// Clones a new repository into the git structure based on the provided arguments.
pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo {
if args.url.len == 0 {
return error('url needs to be specified when doing a clone.')
}
console.print_header('Git clone from the URL: ${args.url}.')
// gitlocatin comes just from the url, not from fs of whats already there
git_location := gitstructure.gitlocation_from_url(args.url)!
// 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
}
// Add the new repo to the gitstructure's repos map
key_ := repo.cache_key()
gitstructure.repos[key_] = &repo
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 {
repo.set_sshkey(args.sshkey)!
}
parent_dir := repo.get_parent_dir(create: true)!
mut extra := ''
if args.light {
extra = '--depth 1 --no-single-branch '
}
// the url needs to be http if no agent, otherwise its ssh, the following code will do this
mut cmd := 'cd ${parent_dir} && git clone ${extra} ${repo.get_repo_url_for_clone()!} ${repo.name}'
mut sshkey_include := ''
cfg := gitstructure.config()!
if cfg.ssh_key_path.len > 0 {
sshkey_include = "GIT_SSH_COMMAND=\"ssh -i ${cfg.ssh_key_path}\" "
cmd = 'cd ${parent_dir} && ${sshkey_include}git clone ${extra} ${repo.get_ssh_url()!} ${repo.name}'
}
console.print_debug(cmd)
result := os.execute(cmd)
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()!
console.print_green("The repository '${repo.name}' cloned into ${parent_dir}.")
return &repo // Return the initialized repo
}