LLMChat / modules /repo.py
JohnSmith9982's picture
Upload 98 files
0cc999a
raw
history blame
11.5 kB
# -*- coding:utf-8 -*-
import os
import sys
import subprocess
from functools import lru_cache
import logging
import gradio as gr
import datetime
import platform
# This file is mainly used to describe repo version info, execute the git command, python pip command, shell command, etc.
# Part of the code in this file is referenced from stable-diffusion-webui/modules/launch_utils.py
python = sys.executable
pip = os.environ.get("PIP", "pip")
git = os.environ.get("GIT", "git")
# Pypi index url
index_url = os.environ.get("INDEX_URL", "")
# Whether to default to printing command output
default_command_live = True
def run(
command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live
) -> str:
if desc is not None:
print(desc)
run_kwargs = {
"args": command,
"shell": True,
"env": os.environ if custom_env is None else custom_env,
"encoding": "utf8",
"errors": "ignore",
}
if not live:
run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
result = subprocess.run(**run_kwargs)
if result.returncode != 0:
error_bits = [
f"{errdesc or 'Error running command'}.",
f"Command: {command}",
f"Error code: {result.returncode}",
]
if result.stdout:
error_bits.append(f"stdout: {result.stdout}")
if result.stderr:
error_bits.append(f"stderr: {result.stderr}")
raise RuntimeError("\n".join(error_bits))
return result.stdout or ""
def run_pip(command, desc=None, pref=None, live=default_command_live):
# if args.skip_install:
# return
index_url_line = f" --index-url {index_url}" if index_url != "" else ""
return run(
f'"{python}" -m pip {command} --prefer-binary{index_url_line}',
desc=f"{pref} Installing {desc}...",
errdesc=f"Couldn't install {desc}",
live=live,
)
@lru_cache()
def commit_hash():
try:
return subprocess.check_output(
[git, "rev-parse", "HEAD"], shell=False, encoding="utf8"
).strip()
except Exception:
return "<none>"
def commit_html():
commit = commit_hash()
if commit != "<none>":
short_commit = commit[0:7]
commit_info = f'<a style="text-decoration:none;color:inherit" href="https://github.com/GaiZhenbiao/ChuanhuChatGPT/commit/{short_commit}">{short_commit}</a>'
else:
commit_info = "unknown \U0001F615"
return commit_info
@lru_cache()
def tag_html():
try:
latest_tag = run(f"{git} describe --tags --abbrev=0", live=False).strip()
try:
# tag = subprocess.check_output([git, "describe", "--tags", "--exact-match"], shell=False, encoding='utf8').strip()
tag = run(f"{git} describe --tags --exact-match", live=False).strip()
except Exception:
tag = "<edited>"
except Exception:
tag = "<none>"
if tag == "<none>":
tag_info = "unknown \U0001F615"
elif tag == "<edited>":
tag_info = f'<a style="text-decoration:none;color:inherit" href="https://github.com/GaiZhenbiao/ChuanhuChatGPT/releases/tag/{latest_tag}">{latest_tag}</a><span style="font-size:smaller">*</span>'
else:
tag_info = f'<a style="text-decoration:none;color:inherit" href="https://github.com/GaiZhenbiao/ChuanhuChatGPT/releases/tag/{tag}">{tag}</a>'
return tag_info
def repo_tag_html():
commit_version = commit_html()
tag_version = tag_html()
return tag_version if tag_version != "unknown \U0001F615" else commit_version
def versions_html():
python_version = ".".join([str(x) for x in sys.version_info[0:3]])
repo_version = repo_tag_html()
return f"""
Python: <span title="{sys.version}">{python_version}</span>
 • 
Gradio: {gr.__version__}
 • 
<a style="text-decoration:none;color:inherit" href="https://github.com/GaiZhenbiao/ChuanhuChatGPT">ChuanhuChat</a>: {repo_version}
"""
def version_time():
git = "git"
cmd = f"{git} log -1 --format=%cd --date=iso-strict"
commit_time = "unknown"
try:
if platform.system() == "Windows":
# For Windows
env = dict(os.environ) # copy the current environment
env["TZ"] = "UTC" # set timezone to UTC
raw_commit_time = subprocess.check_output(
cmd, shell=True, encoding="utf8", env=env
).strip()
else:
# For Unix systems
cmd = f"TZ=UTC {cmd}"
raw_commit_time = subprocess.check_output(
cmd, shell=True, encoding="utf8"
).strip()
# Convert the date-time to the desired format
commit_datetime = datetime.datetime.strptime(
raw_commit_time, "%Y-%m-%dT%H:%M:%S%z"
)
commit_time = commit_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")
# logging.info(f"commit time: {commit_time}")
except Exception:
commit_time = "unknown"
return commit_time
def get_current_branch():
try:
# branch = run(f"{git} rev-parse --abbrev-ref HEAD").strip()
branch = subprocess.check_output(
[git, "rev-parse", "--abbrev-ref", "HEAD"], shell=False, encoding="utf8"
).strip()
except Exception:
branch = "<none>"
return branch
def get_latest_release():
try:
import requests
release = requests.get(
"https://api.github.com/repos/GaiZhenbiao/ChuanhuChatGPT/releases/latest"
).json()
tag = release["tag_name"]
release_note = release["body"]
need_pip = release_note.find("requirements reinstall needed") != -1
except Exception:
tag = "<none>"
release_note = ""
need_pip = False
return {"tag": tag, "release_note": release_note, "need_pip": need_pip}
def get_tag_commit_hash(tag):
try:
import requests
tags = requests.get(
"https://api.github.com/repos/GaiZhenbiao/ChuanhuChatGPT/tags"
).json()
commit_hash = [x["commit"]["sha"] for x in tags if x["name"] == tag][0]
except Exception:
commit_hash = "<none>"
return commit_hash
def repo_need_stash():
try:
return (
subprocess.check_output(
[git, "diff-index", "--quiet", "HEAD", "--"],
shell=False,
encoding="utf8",
).strip()
!= ""
)
except Exception:
return True
def background_update():
# {git} fetch --all && ({git} pull https://github.com/GaiZhenbiao/ChuanhuChatGPT.git main -f || ({git} stash && {git} pull https://github.com/GaiZhenbiao/ChuanhuChatGPT.git main -f && {git} stash pop)) && {pip} install -r requirements.txt")
try:
latest_release = get_latest_release()
latest_release_tag = latest_release["tag"]
latest_release_hash = get_tag_commit_hash(latest_release_tag)
need_pip = latest_release["need_pip"]
need_stash = repo_need_stash()
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
current_branch = get_current_branch()
updater_branch = f"tmp_{timestamp}"
backup_branch = f"backup_{timestamp}"
track_repo = "https://github.com/GaiZhenbiao/ChuanhuChatGPT.git"
try:
try:
run(
f"{git} fetch {track_repo}",
desc="[Updater] Fetching from github...",
live=False,
)
except Exception:
logging.error(
f"Update failed in fetching, check your network connection"
)
return "failed"
run(
f'{git} stash push --include-untracked -m "updater-{timestamp}"',
desc=f"[Updater] Restoring you local changes on stash updater-{timestamp}",
live=False,
) if need_stash else None
run(f"{git} checkout -b {backup_branch}", live=False)
run(f"{git} checkout -b {updater_branch}", live=False)
run(f"{git} reset --hard FETCH_HEAD", live=False)
run(
f"{git} reset --hard {latest_release_hash}",
desc=f"[Updater] Checking out {latest_release_tag}...",
live=False,
)
run(f"{git} checkout {current_branch}", live=False)
try:
run(
f"{git} merge --no-edit {updater_branch} -q",
desc=f"[Updater] Trying to apply latest update on version {latest_release_tag}...",
)
except Exception:
logging.error(f"Update failed in merging")
try:
run(
f"{git} merge --abort",
desc="[Updater] Conflict detected, canceling update...",
)
run(f"{git} reset --hard {backup_branch}", live=False)
run(f"{git} branch -D -f {updater_branch}", live=False)
run(f"{git} branch -D -f {backup_branch}", live=False)
run(f"{git} stash pop", live=False) if need_stash else None
logging.error(
f"Update failed, but your file was safely reset to the state before the update."
)
return "failed"
except Exception as e:
logging.error(
f"!!!Update failed in resetting, try to reset your files manually. {e}"
)
return "failed"
if need_stash:
try:
run(
f"{git} stash apply",
desc="[Updater] Trying to restore your local modifications...",
live=False,
)
except Exception:
run(
f"{git} reset --hard {backup_branch}",
desc="[Updater] Conflict detected, canceling update...",
live=False,
)
run(f"{git} branch -D -f {updater_branch}", live=False)
run(f"{git} branch -D -f {backup_branch}", live=False)
run(f"{git} stash pop", live=False)
logging.error(
f"Update failed in applying your local changes, but your file was safely reset to the state before the update."
)
return "failed"
run(f"{git} stash drop", live=False)
run(f"{git} branch -D -f {updater_branch}", live=False)
run(f"{git} branch -D -f {backup_branch}", live=False)
except Exception as e:
logging.error(f"Update failed: {e}")
return "failed"
if need_pip:
try:
run_pip(
f"install -r requirements.txt",
pref="[Updater]",
desc="requirements",
live=False,
)
except Exception:
logging.error(f"Update failed in pip install")
return "failed"
return "success"
except Exception as e:
logging.error(f"Update failed: {e}")
return "failed"