scons-plus-plus/addons/gitbranch.py

49 lines
1.9 KiB
Python

from git import Repo
from git.exc import GitError
import hashlib
import os
from SCons.Script import *
Import('env')
def _clone(env: Environment, repo_name: str, remote_url: str):
repo_dir = os.path.join(env['CLONE_DIR'], 'git', repo_name, '_bare')
try:
repo = Repo(repo_dir)
origin = repo.remotes['origin']
except GitError:
print(f'Initializing git repository at {repo_dir}.')
repo = Repo.init(repo_dir, bare=True)
origin = repo.create_remote('origin', remote_url)
return repo, origin
def _gitbranch(env: Environment, repo_name: str, remote_url: str, git_ref: str = 'main') -> dict:
repo, origin = _clone(env, repo_name, remote_url)
worktree_dir = os.path.join(env['CLONE_DIR'], 'git', repo_name, hashlib.shake_128(git_ref.encode('utf-8')).hexdigest(6)) # TODO: commit hash would be better, right? -> not if it's a branch!
if not os.path.exists(worktree_dir):
print(f'Checking out into {worktree_dir}.')
origin.fetch(tags=True)
os.makedirs(worktree_dir)
repo.git.worktree('add', worktree_dir, git_ref)
elif env['UPDATE_REPOSITORIES']:
worktree_repo = Repo(worktree_dir)
if not worktree_repo.head.is_detached:
print(f'Updating git repository at {worktree_dir}')
worktree_origin = worktree_repo.remotes['origin']
worktree_origin.pull()
else:
print(f'Not updating git repository {worktree_dir} as it is not on a branch.')
return {
'checkout_root': worktree_dir
}
def _gittags(env: Environment, repo_name: str, remote_url: str, force_fetch: bool = False) -> 'list[str]':
repo, origin = _clone(env, repo_name, remote_url)
if force_fetch or env['UPDATE_REPOSITORIES']:
origin.fetch(tags=True)
return [t.name for t in repo.tags]
env.AddMethod(_gitbranch, 'GitBranch')
env.AddMethod(_gittags, 'GitTags')
Return('env')