mirror of
https://git.datalinker.icu/ltdrdata/ComfyUI-Manager
synced 2025-12-13 16:14:26 +08:00
Merge branch 'feat/pip-snapshot'
This commit is contained in:
commit
83d7ec697c
13
cm-cli.py
13
cm-cli.py
@ -24,7 +24,7 @@ if not (len(sys.argv) == 2 and sys.argv[1] in ['save-snapshot', 'restore-depende
|
|||||||
f" [update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
f" [update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
||||||
f" [simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
f" [simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
||||||
f" save-snapshot ?[--output <snapshot .json/.yaml>]\n"
|
f" save-snapshot ?[--output <snapshot .json/.yaml>]\n"
|
||||||
f" restore-snapshot <snapshot .json/.yaml>\n"
|
f" restore-snapshot <snapshot .json/.yaml> ?[--pip-non-url] ?[--pip-non-local-url] ?[--pip-local-url]\n"
|
||||||
f" cli-only-mode [enable|disable]\n"
|
f" cli-only-mode [enable|disable]\n"
|
||||||
f" restore-dependencies\n"
|
f" restore-dependencies\n"
|
||||||
f" deps-in-workflow --workflow <workflow .json/.png> --output <output .json>\n"
|
f" deps-in-workflow --workflow <workflow .json/.png> --output <output .json>\n"
|
||||||
@ -126,9 +126,14 @@ def install_deps():
|
|||||||
print("Dependency installation and activation complete.")
|
print("Dependency installation and activation complete.")
|
||||||
|
|
||||||
|
|
||||||
def restore_snapshot(snapshot_name):
|
def restore_snapshot():
|
||||||
global processed_install
|
global processed_install
|
||||||
|
|
||||||
|
snapshot_name = sys.argv[2]
|
||||||
|
extras = [x for x in sys.argv if x in ['--pip-non-url', '--pip-local-url', '--pip-non-local-url']]
|
||||||
|
|
||||||
|
print(f"pips restore mode: {extras}")
|
||||||
|
|
||||||
if os.path.exists(snapshot_name):
|
if os.path.exists(snapshot_name):
|
||||||
snapshot_path = os.path.abspath(snapshot_name)
|
snapshot_path = os.path.abspath(snapshot_name)
|
||||||
else:
|
else:
|
||||||
@ -163,7 +168,7 @@ def restore_snapshot(snapshot_name):
|
|||||||
is_failed = True
|
is_failed = True
|
||||||
|
|
||||||
print(f"Restore snapshot.")
|
print(f"Restore snapshot.")
|
||||||
cmd_str = [sys.executable, git_script_path, '--apply-snapshot', snapshot_path]
|
cmd_str = [sys.executable, git_script_path, '--apply-snapshot', snapshot_path] + extras
|
||||||
output = subprocess.check_output(cmd_str, cwd=custom_nodes_path, text=True)
|
output = subprocess.check_output(cmd_str, cwd=custom_nodes_path, text=True)
|
||||||
msg_lines = output.split('\n')
|
msg_lines = output.split('\n')
|
||||||
extract_infos(msg_lines)
|
extract_infos(msg_lines)
|
||||||
@ -647,7 +652,7 @@ elif op == 'save-snapshot':
|
|||||||
print(f"Current snapshot is saved as `{path}`")
|
print(f"Current snapshot is saved as `{path}`")
|
||||||
|
|
||||||
elif op == 'restore-snapshot':
|
elif op == 'restore-snapshot':
|
||||||
restore_snapshot(sys.argv[2])
|
restore_snapshot()
|
||||||
|
|
||||||
elif op == 'restore-dependencies':
|
elif op == 'restore-dependencies':
|
||||||
restore_dependencies()
|
restore_dependencies()
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import traceback
|
||||||
|
|
||||||
import git
|
import git
|
||||||
import configparser
|
import configparser
|
||||||
import re
|
import re
|
||||||
@ -13,6 +16,10 @@ config_path = os.path.join(os.path.dirname(__file__), "config.ini")
|
|||||||
nodelist_path = os.path.join(os.path.dirname(__file__), "custom-node-list.json")
|
nodelist_path = os.path.join(os.path.dirname(__file__), "custom-node-list.json")
|
||||||
working_directory = os.getcwd()
|
working_directory = os.getcwd()
|
||||||
|
|
||||||
|
if os.path.basename(working_directory) != 'custom_nodes':
|
||||||
|
print(f"ERROR: This script should be executed in custom_nodes dir")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
class GitProgress(RemoteProgress):
|
class GitProgress(RemoteProgress):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -133,7 +140,7 @@ def gitpull(path):
|
|||||||
|
|
||||||
|
|
||||||
def checkout_comfyui_hash(target_hash):
|
def checkout_comfyui_hash(target_hash):
|
||||||
repo_path = os.path.join(working_directory, '..') # ComfyUI dir
|
repo_path = os.path.abspath(os.path.join(working_directory, '..')) # ComfyUI dir
|
||||||
|
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
commit_hash = repo.head.commit.hexsha
|
commit_hash = repo.head.commit.hexsha
|
||||||
@ -282,7 +289,7 @@ def apply_snapshot(target):
|
|||||||
if not target.endswith('.json') and not target.endswith('.yaml'):
|
if not target.endswith('.json') and not target.endswith('.yaml'):
|
||||||
print(f"Snapshot file not found: `{path}`")
|
print(f"Snapshot file not found: `{path}`")
|
||||||
print("APPLY SNAPSHOT: False")
|
print("APPLY SNAPSHOT: False")
|
||||||
return
|
return None
|
||||||
|
|
||||||
with open(path, 'r', encoding="UTF-8") as snapshot_file:
|
with open(path, 'r', encoding="UTF-8") as snapshot_file:
|
||||||
if target.endswith('.json'):
|
if target.endswith('.json'):
|
||||||
@ -293,7 +300,7 @@ def apply_snapshot(target):
|
|||||||
else:
|
else:
|
||||||
# impossible case
|
# impossible case
|
||||||
print("APPLY SNAPSHOT: False")
|
print("APPLY SNAPSHOT: False")
|
||||||
return
|
return None
|
||||||
|
|
||||||
comfyui_hash = info['comfyui']
|
comfyui_hash = info['comfyui']
|
||||||
git_custom_node_infos = info['git_custom_nodes']
|
git_custom_node_infos = info['git_custom_nodes']
|
||||||
@ -304,14 +311,81 @@ def apply_snapshot(target):
|
|||||||
invalidate_custom_node_file(file_custom_node_infos)
|
invalidate_custom_node_file(file_custom_node_infos)
|
||||||
|
|
||||||
print("APPLY SNAPSHOT: True")
|
print("APPLY SNAPSHOT: True")
|
||||||
return
|
if 'pips' in info:
|
||||||
|
return info['pips']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
print(f"Snapshot file not found: `{path}`")
|
print(f"Snapshot file not found: `{path}`")
|
||||||
print("APPLY SNAPSHOT: False")
|
print("APPLY SNAPSHOT: False")
|
||||||
|
|
||||||
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
traceback.print_exc()
|
||||||
print("APPLY SNAPSHOT: False")
|
print("APPLY SNAPSHOT: False")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def restore_pip_snapshot(pips, options):
|
||||||
|
non_url = []
|
||||||
|
local_url = []
|
||||||
|
non_local_url = []
|
||||||
|
for k, v in pips.items():
|
||||||
|
if v == "":
|
||||||
|
non_url.append(v)
|
||||||
|
else:
|
||||||
|
if v.startswith('file:'):
|
||||||
|
local_url.append(v)
|
||||||
|
else:
|
||||||
|
non_local_url.append(v)
|
||||||
|
|
||||||
|
failed = []
|
||||||
|
if '--pip-non-url' in options:
|
||||||
|
# try all at once
|
||||||
|
res = 1
|
||||||
|
try:
|
||||||
|
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + non_url)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# fallback
|
||||||
|
if res != 0:
|
||||||
|
for x in non_url:
|
||||||
|
res = 1
|
||||||
|
try:
|
||||||
|
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if res != 0:
|
||||||
|
failed.append(x)
|
||||||
|
|
||||||
|
if '--pip-non-local-url' in options:
|
||||||
|
for x in non_local_url:
|
||||||
|
res = 1
|
||||||
|
try:
|
||||||
|
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if res != 0:
|
||||||
|
failed.append(x)
|
||||||
|
|
||||||
|
if '--pip-local-url' in options:
|
||||||
|
for x in local_url:
|
||||||
|
res = 1
|
||||||
|
try:
|
||||||
|
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if res != 0:
|
||||||
|
failed.append(x)
|
||||||
|
|
||||||
|
print(f"Installation failed for pip packages: {failed}")
|
||||||
|
|
||||||
|
|
||||||
def setup_environment():
|
def setup_environment():
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@ -333,7 +407,15 @@ try:
|
|||||||
elif sys.argv[1] == "--pull":
|
elif sys.argv[1] == "--pull":
|
||||||
gitpull(sys.argv[2])
|
gitpull(sys.argv[2])
|
||||||
elif sys.argv[1] == "--apply-snapshot":
|
elif sys.argv[1] == "--apply-snapshot":
|
||||||
apply_snapshot(sys.argv[2])
|
options = set()
|
||||||
|
for x in sys.argv:
|
||||||
|
if x in ['--pip-non-url', '--pip-local-url', '--pip-non-local-url']:
|
||||||
|
options.add(x)
|
||||||
|
|
||||||
|
pips = apply_snapshot(sys.argv[2])
|
||||||
|
|
||||||
|
if pips and len(options) > 0:
|
||||||
|
restore_pip_snapshot(pips, options)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|||||||
@ -22,7 +22,7 @@ sys.path.append(glob_path)
|
|||||||
import cm_global
|
import cm_global
|
||||||
from manager_util import *
|
from manager_util import *
|
||||||
|
|
||||||
version = [2, 26]
|
version = [2, 27]
|
||||||
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
||||||
|
|
||||||
comfyui_manager_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
comfyui_manager_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
@ -312,7 +312,7 @@ def __win_check_git_update(path, do_fetch=False, do_update=False):
|
|||||||
else:
|
else:
|
||||||
command = [sys.executable, git_script_path, "--check", path]
|
command = [sys.executable, git_script_path, "--check", path]
|
||||||
|
|
||||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=custom_nodes_path)
|
||||||
output, _ = process.communicate()
|
output, _ = process.communicate()
|
||||||
output = output.decode('utf-8').strip()
|
output = output.decode('utf-8').strip()
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ def __win_check_git_update(path, do_fetch=False, do_update=False):
|
|||||||
|
|
||||||
def __win_check_git_pull(path):
|
def __win_check_git_pull(path):
|
||||||
command = [sys.executable, git_script_path, "--pull", path]
|
command = [sys.executable, git_script_path, "--pull", path]
|
||||||
process = subprocess.Popen(command)
|
process = subprocess.Popen(command, cwd=custom_nodes_path)
|
||||||
process.wait()
|
process.wait()
|
||||||
|
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ def gitclone_install(files, instant_execution=False, msg_prefix=''):
|
|||||||
|
|
||||||
# Clone the repository from the remote URL
|
# Clone the repository from the remote URL
|
||||||
if not instant_execution and platform.system() == 'Windows':
|
if not instant_execution and platform.system() == 'Windows':
|
||||||
res = manager_funcs.run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url])
|
res = manager_funcs.run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url], cwd=custom_nodes_path)
|
||||||
if res != 0:
|
if res != 0:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
@ -941,6 +941,24 @@ def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do
|
|||||||
item['installed'] = 'False'
|
item['installed'] = 'False'
|
||||||
|
|
||||||
|
|
||||||
|
def get_installed_pip_packages():
|
||||||
|
# extract pip package infos
|
||||||
|
pips = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'], text=True).split('\n')
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
for x in pips:
|
||||||
|
if x.strip() == "":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ' @ ' in x:
|
||||||
|
spec_url = x.split(' @ ')
|
||||||
|
res[spec_url[0]] = spec_url[1]
|
||||||
|
else:
|
||||||
|
res[x] = ""
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
def get_current_snapshot():
|
def get_current_snapshot():
|
||||||
# Get ComfyUI hash
|
# Get ComfyUI hash
|
||||||
repo_path = comfy_path
|
repo_path = comfy_path
|
||||||
@ -990,10 +1008,13 @@ def get_current_snapshot():
|
|||||||
|
|
||||||
file_custom_nodes.append(item)
|
file_custom_nodes.append(item)
|
||||||
|
|
||||||
|
pip_packages = get_installed_pip_packages()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'comfyui': comfyui_commit_hash,
|
'comfyui': comfyui_commit_hash,
|
||||||
'git_custom_nodes': git_custom_nodes,
|
'git_custom_nodes': git_custom_nodes,
|
||||||
'file_custom_nodes': file_custom_nodes,
|
'file_custom_nodes': file_custom_nodes,
|
||||||
|
'pips': pip_packages,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1133,6 +1154,5 @@ async def extract_nodes_from_workflow(filepath, mode='local', channel_url='defau
|
|||||||
else:
|
else:
|
||||||
unknown_nodes.add(node_name)
|
unknown_nodes.add(node_name)
|
||||||
|
|
||||||
|
|
||||||
return used_exts, unknown_nodes
|
return used_exts, unknown_nodes
|
||||||
|
|
||||||
|
|||||||
@ -872,7 +872,6 @@ async def update_comfyui(request):
|
|||||||
return web.Response(status=200)
|
return web.Response(status=200)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"ComfyUI update fail: {e}", file=sys.stderr)
|
print(f"ComfyUI update fail: {e}", file=sys.stderr)
|
||||||
pass
|
|
||||||
|
|
||||||
return web.Response(status=400)
|
return web.Response(status=400)
|
||||||
|
|
||||||
|
|||||||
@ -615,7 +615,7 @@ async function updateAll(update_check_checkbox, manager_dialog) {
|
|||||||
const response1 = await api.fetchApi('/comfyui_manager/update_comfyui');
|
const response1 = await api.fetchApi('/comfyui_manager/update_comfyui');
|
||||||
const response2 = await api.fetchApi(`/customnode/update_all?mode=${mode}`);
|
const response2 = await api.fetchApi(`/customnode/update_all?mode=${mode}`);
|
||||||
|
|
||||||
if (response1.status != 200 && response2.status != 201) {
|
if (response1.status == 400 || response2.status == 400) {
|
||||||
app.ui.dialog.show('Failed to update ComfyUI or several extensions.<BR><BR>See terminal log.<BR>');
|
app.ui.dialog.show('Failed to update ComfyUI or several extensions.<BR><BR>See terminal log.<BR>');
|
||||||
app.ui.dialog.element.style.zIndex = 10010;
|
app.ui.dialog.element.style.zIndex = 10010;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user