Merge pull request #7407 from hugovk/ci-appveyor-depends

AppVeyor: don't download huge pillow-depends.zip
This commit is contained in:
Andrew Murray 2023-09-24 14:36:04 +10:00 committed by GitHub
commit b723e9e62e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 48 deletions

View File

@ -21,13 +21,11 @@ environment:
install: install:
- '%PYTHON%\%EXECUTABLE% --version' - '%PYTHON%\%EXECUTABLE% --version'
- '%PYTHON%\%EXECUTABLE% -m pip install --upgrade pip' - '%PYTHON%\%EXECUTABLE% -m pip install --upgrade pip'
- curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/main.zip
- curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip - curl -fsSL -o pillow-test-images.zip https://github.com/python-pillow/test-images/archive/main.zip
- 7z x pillow-depends.zip -oc:\
- 7z x pillow-test-images.zip -oc:\ - 7z x pillow-test-images.zip -oc:\
- mv c:\pillow-depends-main c:\pillow-depends
- xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images - xcopy /S /Y c:\test-images-main\* c:\pillow\tests\images
- 7z x ..\pillow-depends\nasm-2.16.01-win64.zip -oc:\ - curl -fsSL -o nasm-win64.zip https://raw.githubusercontent.com/python-pillow/pillow-depends/main/nasm-2.16.01-win64.zip
- 7z x nasm-win64.zip -oc:\
- choco install ghostscript --version=10.0.0.20230317 - choco install ghostscript --version=10.0.0.20230317
- path c:\nasm-2.16.01;C:\Program Files\gs\gs10.00.0\bin;%PATH% - path c:\nasm-2.16.01;C:\Program Files\gs\gs10.00.0\bin;%PATH%
- cd c:\pillow\winbuild\ - cd c:\pillow\winbuild\

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import argparse import argparse
import os import os
import platform import platform
@ -7,42 +9,41 @@ import struct
import subprocess import subprocess
def cmd_cd(path): def cmd_cd(path: str) -> str:
return f"cd /D {path}" return f"cd /D {path}"
def cmd_set(name, value): def cmd_set(name: str, value: str) -> str:
return f"set {name}={value}" return f"set {name}={value}"
def cmd_append(name, value): def cmd_append(name: str, value: str) -> str:
op = "path " if name == "PATH" else f"set {name}=" op = "path " if name == "PATH" else f"set {name}="
return op + f"%{name}%;{value}" return op + f"%{name}%;{value}"
def cmd_copy(src, tgt): def cmd_copy(src: str, tgt: str) -> str:
return f'copy /Y /B "{src}" "{tgt}"' return f'copy /Y /B "{src}" "{tgt}"'
def cmd_xcopy(src, tgt): def cmd_xcopy(src: str, tgt: str) -> str:
return f'xcopy /Y /E "{src}" "{tgt}"' return f'xcopy /Y /E "{src}" "{tgt}"'
def cmd_mkdir(path): def cmd_mkdir(path: str) -> str:
return f'mkdir "{path}"' return f'mkdir "{path}"'
def cmd_rmdir(path): def cmd_rmdir(path: str) -> str:
return f'rmdir /S /Q "{path}"' return f'rmdir /S /Q "{path}"'
def cmd_nmake(makefile=None, target="", params=None): def cmd_nmake(
if params is None: makefile: str | None = None,
params = "" target: str = "",
elif isinstance(params, (list, tuple)): params: list[str] | None = None,
params = " ".join(params) ) -> str:
else: params = "" if params is None else " ".join(params)
params = str(params)
return " ".join( return " ".join(
[ [
@ -55,7 +56,7 @@ def cmd_nmake(makefile=None, target="", params=None):
) )
def cmds_cmake(target, *params): def cmds_cmake(target: str | tuple[str, ...] | list[str], *params) -> list[str]:
if not isinstance(target, str): if not isinstance(target, str):
target = " ".join(target) target = " ".join(target)
@ -80,8 +81,11 @@ def cmds_cmake(target, *params):
def cmd_msbuild( def cmd_msbuild(
file, configuration="Release", target="Build", platform="{msbuild_arch}" file: str,
): configuration: str = "Release",
target: str = "Build",
platform: str = "{msbuild_arch}",
) -> str:
return " ".join( return " ".join(
[ [
"{msbuild}", "{msbuild}",
@ -96,14 +100,14 @@ def cmd_msbuild(
SF_PROJECTS = "https://sourceforge.net/projects" SF_PROJECTS = "https://sourceforge.net/projects"
architectures = { ARCHITECTURES = {
"x86": {"vcvars_arch": "x86", "msbuild_arch": "Win32"}, "x86": {"vcvars_arch": "x86", "msbuild_arch": "Win32"},
"x64": {"vcvars_arch": "x86_amd64", "msbuild_arch": "x64"}, "x64": {"vcvars_arch": "x86_amd64", "msbuild_arch": "x64"},
"ARM64": {"vcvars_arch": "x86_arm64", "msbuild_arch": "ARM64"}, "ARM64": {"vcvars_arch": "x86_arm64", "msbuild_arch": "ARM64"},
} }
# dependencies, listed in order of compilation # dependencies, listed in order of compilation
deps = { DEPS = {
"libjpeg": { "libjpeg": {
"url": SF_PROJECTS "url": SF_PROJECTS
+ "/libjpeg-turbo/files/3.0.0/libjpeg-turbo-3.0.0.tar.gz/download", + "/libjpeg-turbo/files/3.0.0/libjpeg-turbo-3.0.0.tar.gz/download",
@ -365,7 +369,7 @@ deps = {
# based on distutils._msvccompiler from CPython 3.7.4 # based on distutils._msvccompiler from CPython 3.7.4
def find_msvs(): def find_msvs() -> dict[str, str] | None:
root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles")
if not root: if not root:
print("Program Files not found") print("Program Files not found")
@ -421,17 +425,13 @@ def find_msvs():
} }
def extract_dep(url, filename): def download_dep(url: str, file: str) -> None:
import tarfile
import urllib.request import urllib.request
import zipfile
file = os.path.join(args.depends_dir, filename)
if not os.path.exists(file):
ex = None ex = None
for i in range(3): for i in range(3):
try: try:
print("Fetching %s (attempt %d)..." % (url, i + 1)) print(f"Fetching {url} (attempt {i + 1})...")
content = urllib.request.urlopen(url).read() content = urllib.request.urlopen(url).read()
with open(file, "wb") as f: with open(file, "wb") as f:
f.write(content) f.write(content)
@ -441,6 +441,25 @@ def extract_dep(url, filename):
else: else:
raise RuntimeError(ex) raise RuntimeError(ex)
def extract_dep(url: str, filename: str) -> None:
import tarfile
import zipfile
file = os.path.join(args.depends_dir, filename)
if not os.path.exists(file):
# First try our mirror
mirror_url = (
f"https://raw.githubusercontent.com/"
f"python-pillow/pillow-depends/main/{filename}"
)
try:
download_dep(mirror_url, file)
except RuntimeError as exc:
# Otherwise try upstream
print(exc)
download_dep(url, file)
print("Extracting " + filename) print("Extracting " + filename)
sources_dir_abs = os.path.abspath(sources_dir) sources_dir_abs = os.path.abspath(sources_dir)
if filename.endswith(".zip"): if filename.endswith(".zip"):
@ -466,7 +485,7 @@ def extract_dep(url, filename):
raise RuntimeError(msg) raise RuntimeError(msg)
def write_script(name, lines): def write_script(name: str, lines: list[str]) -> None:
name = os.path.join(args.build_dir, name) name = os.path.join(args.build_dir, name)
lines = [line.format(**prefs) for line in lines] lines = [line.format(**prefs) for line in lines]
print("Writing " + name) print("Writing " + name)
@ -477,7 +496,7 @@ def write_script(name, lines):
print(" " + line) print(" " + line)
def get_footer(dep): def get_footer(dep: dict) -> list[str]:
lines = [] lines = []
for out in dep.get("headers", []): for out in dep.get("headers", []):
lines.append(cmd_copy(out, "{inc_dir}")) lines.append(cmd_copy(out, "{inc_dir}"))
@ -488,7 +507,7 @@ def get_footer(dep):
return lines return lines
def build_env(): def build_env() -> None:
lines = [ lines = [
"if defined DISTUTILS_USE_SDK goto end", "if defined DISTUTILS_USE_SDK goto end",
cmd_set("INCLUDE", "{inc_dir}"), cmd_set("INCLUDE", "{inc_dir}"),
@ -504,8 +523,8 @@ def build_env():
write_script("build_env.cmd", lines) write_script("build_env.cmd", lines)
def build_dep(name): def build_dep(name: str) -> str:
dep = deps[name] dep = DEPS[name]
dir = dep["dir"] dir = dep["dir"]
file = f"build_dep_{name}.cmd" file = f"build_dep_{name}.cmd"
@ -554,9 +573,9 @@ def build_dep(name):
return file return file
def build_dep_all(): def build_dep_all() -> None:
lines = [r'call "{build_dir}\build_env.cmd"'] lines = [r'call "{build_dir}\build_env.cmd"']
for dep_name in deps: for dep_name in DEPS:
print() print()
if dep_name in disabled: if dep_name in disabled:
print(f"Skipping disabled dependency {dep_name}") print(f"Skipping disabled dependency {dep_name}")
@ -602,7 +621,7 @@ if __name__ == "__main__":
) )
parser.add_argument( parser.add_argument(
"--architecture", "--architecture",
choices=architectures, choices=ARCHITECTURES,
default=os.environ.get( default=os.environ.get(
"ARCHITECTURE", "ARCHITECTURE",
( (
@ -634,7 +653,7 @@ if __name__ == "__main__":
) )
args = parser.parse_args() args = parser.parse_args()
arch_prefs = architectures[args.architecture] arch_prefs = ARCHITECTURES[args.architecture]
print("Target architecture:", args.architecture) print("Target architecture:", args.architecture)
msvs = find_msvs() msvs = find_msvs()
@ -693,7 +712,7 @@ if __name__ == "__main__":
# TODO find NASM automatically # TODO find NASM automatically
} }
for k, v in deps.items(): for k, v in DEPS.items():
prefs[f"dir_{k}"] = os.path.join(sources_dir, v["dir"]) prefs[f"dir_{k}"] = os.path.join(sources_dir, v["dir"])
print() print()