Spaces:
Sleeping
Sleeping
File size: 4,931 Bytes
76684fa |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#!/usr/bin/env python3
import importlib.metadata
import re
import os
# 解析包的版本规范
def parse_package_spec(spec):
"""
解析包名和版本规范。
返回 (name, operator, version)。
"""
match = re.match(r'^([^=<>!~]+)\s*([=<>!~]+)\s*(.+)$', spec)
if match:
name, op, version = match.groups()
return name.strip(), op.strip(), version.strip()
else:
return spec.strip(), None, None
# 获取已安装包的版本
def get_installed_versions(packages):
installed_versions = {}
for pkg in packages:
name, _, _ = parse_package_spec(pkg)
try:
installed_version = importlib.metadata.version(name)
installed_versions[name] = installed_version
except importlib.metadata.PackageNotFoundError:
print(f"包 {name} 未安装。")
continue
return installed_versions
# 读取现有的 requirements.txt
def read_requirements(file_path='requirements.txt'):
req_versions = {}
if os.path.exists(file_path):
with open(file_path, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
name, op, version_spec = parse_package_spec(line)
if op and version_spec:
req_versions[name] = f"{op}{version_spec}"
else:
req_versions[name] = None # 未指定版本
return req_versions
# 合并包信息
def merge_requirements(installed_versions, req_versions):
merged_requirements = []
conflict_detected = False
processed_packages = set()
for name, installed_version in installed_versions.items():
if name in req_versions:
req_version_spec = req_versions[name]
if req_version_spec:
# 检查版本是否匹配
version_match = False
# 支持多种版本操作符
ops = ['==', '>=', '<=', '>', '<', '!=', '~=']
for op in ops:
if req_version_spec.startswith(op):
req_op = op
req_ver = req_version_spec[len(op):]
break
else:
req_op = None
req_ver = None
if req_op == '==':
if req_ver == installed_version:
merged_requirements.append(f"{name}=={installed_version}")
else:
# 版本冲突
merged_requirements.append(f"<<<<<<< HEAD")
merged_requirements.append(f"{name}{req_version_spec}")
merged_requirements.append(f"=======")
merged_requirements.append(f"{name}=={installed_version}")
merged_requirements.append(f">>>>>>> Merged version")
conflict_detected = True
else:
# 如果 requirements.txt 中有版本规范但不是 '=='
# 可以根据需要调整此逻辑
# 这里假设只在 '==' 时进行严格匹配
# 其他情况下认为没有冲突
merged_requirements.append(f"{name}{req_version_spec}")
else:
# requirements.txt 未指定版本,直接覆盖为已安装版本
merged_requirements.append(f"{name}=={installed_version}")
processed_packages.add(name)
else:
# 包不在 requirements.txt 中,添加已安装版本
merged_requirements.append(f"{name}=={installed_version}")
processed_packages.add(name)
# 添加 requirements.txt 中未处理的包
for name, version_spec in req_versions.items():
if name not in processed_packages:
if version_spec:
merged_requirements.append(f"{name}{version_spec}")
else:
merged_requirements.append(f"{name}")
return merged_requirements, conflict_detected
def main():
# 读取现有的 requirements.txt 获取包列表
req_versions = read_requirements('requirements.txt')
packages = list(req_versions.keys())
# 获取已安装包的版本
installed_versions = get_installed_versions(packages)
# 合并包信息
merged_requirements, conflict_detected = merge_requirements(installed_versions, req_versions)
# 将合并结果写回 requirements.txt
with open('requirements.txt', 'w') as f:
for line in merged_requirements:
f.write(line + '\n')
if conflict_detected:
print("requirements.txt 已更新,存在版本冲突。请手动解决冲突标记。")
else:
print("requirements.txt 已更新,无版本冲突。")
if __name__ == "__main__":
main() |