Browse Source

Fix nonworking local (~/git/<repo>), branch, stopgap install_mod options.

master
Poikilos 1 week ago
parent
commit
9f9b8be845
  1. 2
      build-enliven.py
  2. 60
      pyenliven/gamebuilder.py

2
build-enliven.py

@ -39,7 +39,7 @@ logger = logging.getLogger(os.path.split(__file__)[1])
# 'name': folder name expected in mods/ or mods_stopgap/ # 'name': folder name expected in mods/ or mods_stopgap/
# 'repo': git URL (str or list[str] — first = highest priority) # 'repo': git URL (str or list[str] — first = highest priority)
# 'branch': optional branch name # 'branch': optional branch name
# 'stopgap_only': True → only use from MODS_STOPGAP_DIR, ignore repo # 'stopgap': True → only use from MODS_STOPGAP_DIR, ignore repo
def main(): def main():
parser = argparse.ArgumentParser(description="Build ENLIVEN subgame from minetest_game") parser = argparse.ArgumentParser(description="Build ENLIVEN subgame from minetest_game")

60
pyenliven/gamebuilder.py

@ -67,9 +67,9 @@ class GameBuilder:
def install_mod(self, entry: Dict[str, any], remove_git=True): def install_mod(self, entry: Dict[str, any], remove_git=True):
name = entry.get('name') name = entry.get('name')
repo = entry.get('repo') url = entry.get('repo')
branch = entry.get('branch') branch = entry.get('branch')
stopgap_only = entry.get('stopgap_only', False) stopgap = entry.get('stopgap', False)
settings = entry.get('settings') settings = entry.get('settings')
if settings: if settings:
for k, v in settings.items(): for k, v in settings.items():
@ -84,6 +84,7 @@ class GameBuilder:
# 1. Prefer stopgap if exists # 1. Prefer stopgap if exists
stopgap_src = os.path.join(MODS_STOPGAP_DIR, name) stopgap_src = os.path.join(MODS_STOPGAP_DIR, name)
if stopgap:
if os.path.isdir(stopgap_src): if os.path.isdir(stopgap_src):
echo0(f" [stopgap] {name}") echo0(f" [stopgap] {name}")
if os.path.exists(dest): if os.path.exists(dest):
@ -94,43 +95,66 @@ class GameBuilder:
shutil.copytree(stopgap_src, dest) shutil.copytree(stopgap_src, dest)
self.meta['mods'][name] = entry self.meta['mods'][name] = entry
return return
raise FileNotFoundError(
f"stopgap={stopgap} but there is no {stopgap_src}")
# 2. Git clone if we have repo URL(s) # 2. Git clone if we have repo URL(s)
if not repo: if not url:
raise ValueError(f"Missing 'repo' for {entry}") raise ValueError(f"Missing 'repo' for {entry}")
urls = [repo] if isinstance(repo, str) else repo urls = [url] if isinstance(url, str) else url
url = urls[-1] # prefer last one url = urls[-1] # prefer last one
del urls del urls
distributor = entry.get('distributor') user = entry.get('distributor')
if not distributor: if not user:
distributor = url.split("/")[-2] user = url.split("/")[-2]
repo_name = url.split("/")[-1].replace(".git", "") repo_name = url.split("/")[-1].replace(".git", "")
source_path = os.path.expanduser(f"~/{repo_name}") source_path = os.path.expanduser(f"~/git/{repo_name}")
symlink = False symlink = False
if os.path.isdir(source_path): if os.path.isdir(source_path):
# Use the development copy on the computer # Use the development copy on the computer
logger.warning( logger.warning(
f"Using local git repo without update: {source_path}") " [local] using local git repo without update:"
f" {source_path}")
symlink = True symlink = True
else: else:
source_path = os.path.expanduser( source_path = os.path.expanduser(
f"~/Downloads/git/{distributor}/{repo_name}") f"~/Downloads/git/{user}/{repo_name}")
if os.path.isdir(source_path): if os.path.isdir(source_path):
if not self.offline: if not self.offline:
repo = Repo(source_path)
if self.pull: if self.pull:
echo0(f" pulling {source_path}") if branch:
git_repo = Repo(source_path) if hasattr(repo, 'switch'):
git_repo.remotes.origin.pull() echo0(f" [{branch} branch] {source_path}")
repo.git.switch(branch)
else:
echo0(f" [{branch} branch] Updating remotes for {source_path}")
repo.remotes.origin.fetch()
# remote_ref = f"origin/{branch}"
if branch in repo.heads:
# Just switch to existing local branch
repo.heads[branch].checkout()
echo0(f" Switched to existing local branch '{branch}'")
else:
# Create local branch tracking the remote one + switch to it
remote_head = repo.remotes.origin.refs[branch] # origin/feature-xyz
new_local = repo.create_head(branch, remote_head.commit)
new_local.set_tracking_branch(remote_head) # optional but recommended
new_local.checkout()
echo0(f" Created and checked out local branch '{branch}' ← origin/{branch}")
echo0(f" [git] pulling {source_path}")
repo.remotes.origin.pull()
else: else:
echo0(f" using existing {source_path}") echo0(f" [--no-pull] using existing {source_path}")
else: else:
if self.offline: if self.offline:
raise FileNotFoundError( raise FileNotFoundError(
f"Mod {name} not found in offline mode:" f"Mod {name} not found in offline mode:"
f" {source_path}") f" {source_path}")
else: else:
echo0(f" cloning {url}{source_path}") echo0(f" [git] cloning {url}{source_path}")
Repo.clone_from(url, source_path) Repo.clone_from(url, source_path)
if os.path.exists(dest): if os.path.exists(dest):
raise FileExistsError(f"Remove {dest} first.") raise FileExistsError(f"Remove {dest} first.")
@ -147,10 +171,10 @@ class GameBuilder:
for sub in exclude: for sub in exclude:
subPath = os.path.join(dest, sub) subPath = os.path.join(dest, sub)
if os.path.isfile(subPath): if os.path.isfile(subPath):
print(f"rm {repr(subPath)}") print(f" rm {repr(subPath)}")
os.remove(subPath) os.remove(subPath)
elif os.path.isdir(subPath): elif os.path.isdir(subPath):
print(f"rm -r {repr(subPath)}") print(f" rm -r {repr(subPath)}")
shutil.rmtree(subPath) shutil.rmtree(subPath)
else: else:
logger.warning( logger.warning(
@ -163,7 +187,7 @@ class GameBuilder:
if remove_git: if remove_git:
destGit = os.path.join(dest, ".git") destGit = os.path.join(dest, ".git")
if os.path.isdir(destGit): if os.path.isdir(destGit):
print(f"rm -rf {repr(destGit)}") print(f" rm -rf {repr(destGit)}")
shutil.rmtree(destGit) shutil.rmtree(destGit)
def remove_mod(self, name: str): def remove_mod(self, name: str):

Loading…
Cancel
Save