vscode-dotnet-runtime/dependency-verifier.py

89 строки
4.7 KiB
Python
Исходник Обычный вид История

2022-10-06 20:23:43 +03:00
import sys
2022-10-06 20:41:31 +03:00
import subprocess
2022-10-06 22:16:15 +03:00
import os
2022-10-07 01:00:26 +03:00
from pathlib import Path
2022-10-06 20:23:43 +03:00
2022-10-06 21:26:57 +03:00
def main():
"""Check if the dependency updates in package-lock are also updated in yarn.locks"""
targetBranch = sys.argv[1] # Script is called with PR Target Branch Name, Fulfilled by AzDo
2022-10-06 21:26:57 +03:00
subprocess.getoutput(f"git fetch --all")
2022-10-06 22:16:15 +03:00
subprocess.getoutput(f"git pull origin {targetBranch}")
2022-10-06 21:26:57 +03:00
VerifyDependencies(targetBranch)
sys.exit(0)
def VerifyDependencies(targetBranch):
"""Enumerate through all changed files to check diffs."""
# origin/ requires origin/ to be up to date.
2022-10-07 01:00:26 +03:00
changedFiles = [Path(path) for path in subprocess.getoutput(f"git diff --name-only origin/{targetBranch}..").splitlines()]
2022-10-06 21:26:57 +03:00
npmLockFile = "package-lock.json"
2022-10-06 21:26:57 +03:00
for file in changedFiles:
fileName = os.path.basename(os.path.realpath(file))
if fileName == npmLockFile:
NpmChangesMirrorYarnChanges(changedFiles, file, targetBranch)
2022-10-07 01:00:26 +03:00
def GetNpmDependencyUpdates(packageLockDiffLines):
2022-10-06 22:06:10 +03:00
"""Returns a dictionary of [dependency -> [] (can be changed to version in later implementations)] changes found in diff string of package-lock.json"""
# Assumes dependency line starts with "node_modules/DEPENDENCYNAME". Version may or may not come after
dependencies = {}
2022-10-07 01:00:26 +03:00
for line in packageLockDiffLines:
line = line.strip()
line = line.lstrip("\t")
if line.startswith('"node_modules/'):
dependencies[line.split('"node_modules/', 1)[1].split('"', 1)[0]] = [] # will be "node_modules/dep further" content, need to cull
2022-10-06 22:06:10 +03:00
return dependencies
2022-10-07 01:00:26 +03:00
def GetYarnDependencyUpdates(yarnLockDiffLines):
2022-10-06 22:06:10 +03:00
"""Returns a dictionary of [dependency -> [] (can be changed to version in later implementations)] changes found in diff string of yarn.lock"""
2022-10-07 01:00:26 +03:00
# Assumes dependency line starts with DEPEDENCY@Version without whitespace
2022-10-06 22:06:10 +03:00
dependencies = {}
2022-10-07 01:00:26 +03:00
for line in yarnLockDiffLines:
if line == line.lstrip() and "@" in line:
depsAtVers = line.lstrip('"').split(",") # multiple dependencies are possible with diff versions, sep by ,
for dependencyAtVers in depsAtVers:
dep = dependencyAtVers.rsplit("@", 1)[0]
vers = dependencyAtVers.rsplit("@", 1)[1]
dependencies[dep] = [] # Could add version here later. That will probably not happen
2022-10-06 22:06:10 +03:00
return dependencies
2022-10-07 01:00:26 +03:00
def GetUnmatchedDiffs(yarnDiff, npmDiff):
"""Returns [] if dependency updates are reflected in both diffs, else the dependencies out of sync."""
2022-10-07 01:00:26 +03:00
# v Remove + or - from diff and additional git diff context lines
yarnDeps = GetYarnDependencyUpdates([line[1:] for line in yarnDiff.splitlines() if line.startswith("+") or line.startswith("-")])
npmDeps = GetNpmDependencyUpdates([line[1:] for line in npmDiff.splitlines() if line.startswith("+") or line.startswith("-")])
outOfSyncDependencies = []
2022-10-06 22:06:10 +03:00
for dep in npmDeps:
if dep in yarnDeps and yarnDeps[dep] == npmDeps[dep]: # version changes match
continue
else:
2022-10-07 01:00:26 +03:00
outOfSyncDependencies.append(dep)
return outOfSyncDependencies
2022-10-06 22:06:10 +03:00
2022-10-06 21:26:57 +03:00
def NpmChangesMirrorYarnChanges(changedFiles, packageLockPath, targetBranch):
"""Returns successfully if yarn.lock matches package lock changes, if not, throws exit code"""
2022-10-06 21:26:57 +03:00
yarnLockFile = "yarn.lock"
2022-10-07 01:00:26 +03:00
yarnLockPath = Path(os.path.join(os.path.dirname(packageLockPath), yarnLockFile))
2022-10-06 21:30:36 +03:00
outOfDateYarnLocks = []
2022-10-06 21:30:36 +03:00
if yarnLockPath in changedFiles:
2022-10-07 01:00:26 +03:00
yarnDiff = subprocess.getoutput(f"git diff origin/{targetBranch}.. -- {str(yarnLockPath)}")
npmDiff = subprocess.getoutput(f"git diff origin/{targetBranch}.. -- {packageLockPath}")
diffSetComplement = GetUnmatchedDiffs(yarnDiff, npmDiff)
if diffSetComplement == []:
2022-10-06 22:06:10 +03:00
pass
2022-10-06 21:39:55 +03:00
else:
2022-10-07 01:00:26 +03:00
outOfDateYarnLocks.append((str(yarnLockPath), diffSetComplement))
2022-10-06 21:30:36 +03:00
else:
2022-10-07 01:00:26 +03:00
outOfDateYarnLocks.append(yarnLockPath)
2022-10-06 21:39:55 +03:00
if(outOfDateYarnLocks != []):
sys.exit(f"""{outOfDateYarnLocks} may be out of sync with node.
The yarn.lock and package-lock appear to be out of sync with the changes made after {targetBranch}.
Update by first using npm to push to the registry, doing npm install package@version. Then, do yarn add package@version for each primary package. During the yarn add process, you may need to npm install specific dependencies that yarn will flag to allow yarn to proceed. You may consider (yarn import). Note this tool will list dependencies of packages, but you should try adding just the main package first.
If you can confirm the new changes are in sync, then you may ignore this failure.""")
2022-10-06 21:39:55 +03:00
else:
return 0 # OK, status here is not used
2022-10-06 22:16:15 +03:00
if __name__ == "__main__":
2022-10-07 01:00:26 +03:00
main()