* scripts/make_distribution_archives.py: New file. This standalone Python script should be equivalent to running `make dist` with the Make-based build system, with the following minor differences: - Since `make distclean` doesn't always clean up `objs/` properly, `make dist` archives may contain some stale binaries like `objs/.libs/libfreetype.so.6` or others. - `config.guess` and `config.sub` are not updated unless option `--gnu-config-dir=DIR` is used to specify the location of these files. - Some bits of the auto-generated reference documentation may appear in slightly different order, probably due to issues related to mkdocs and docwriter. As an example, the call scripts/make_distribution_archives.py /tmp/freetype2-dist creates the following files under `/tmp/freetype2-dist`: freetype-<version>.tar.gz freetype-<version>.tar.xz ft<winversion>.zipwl/meson-logging
parent
46417607e6
commit
d686f2ff9c
2 changed files with 240 additions and 0 deletions
@ -0,0 +1,208 @@ |
||||
#!/usr/bin/env python3 |
||||
"""Generate distribution archives for a given FreeType 2 release.""" |
||||
|
||||
from __future__ import print_function |
||||
|
||||
import argparse |
||||
import atexit |
||||
import os |
||||
import shutil |
||||
import subprocess |
||||
import sys |
||||
import tempfile |
||||
|
||||
_SCRIPT_DIR = os.path.dirname(__file__) |
||||
_TOP_DIR = os.path.abspath(os.path.join(_SCRIPT_DIR, "..")) |
||||
|
||||
|
||||
def get_cmd_output(cmd, cwd=None): |
||||
"""Run a command and return its output as a string.""" |
||||
if cwd is not None: |
||||
out = subprocess.check_output(cmd, cwd=cwd) |
||||
else: |
||||
out = subprocess.check_output(cmd) |
||||
return out.decode("utf-8").rstrip() |
||||
|
||||
|
||||
def is_git_dir_clean(git_dir): |
||||
"""Return True iff |git_dir| is a git directory in clean state.""" |
||||
out = get_cmd_output(["git", "status", "--porcelain"], cwd=git_dir) |
||||
return len(out) == 0 |
||||
|
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
||||
parser.add_argument( |
||||
"--source_dir", default=_TOP_DIR, help="Source directory path." |
||||
) |
||||
|
||||
parser.add_argument( |
||||
"--version", |
||||
help=( |
||||
"Specify alternate FreeType version (it is otherwise extracted" |
||||
" from current sources by default)." |
||||
), |
||||
) |
||||
|
||||
parser.add_argument( |
||||
"--gnu-config-dir", |
||||
help=( |
||||
"Path of input directory containing recent `config.guess` and" |
||||
" `config.sub` files from GNU config." |
||||
), |
||||
) |
||||
|
||||
parser.add_argument( |
||||
"--build-dir", |
||||
help="Specify build directory. Only used for debugging this script.", |
||||
) |
||||
|
||||
parser.add_argument( |
||||
"--ignore-clean-check", |
||||
action="store_true", |
||||
help=( |
||||
"Do not check for a clean source git repository. Only used for" |
||||
" debugging this script." |
||||
), |
||||
) |
||||
|
||||
parser.add_argument( |
||||
"output_dir", help="Output directory for generated archives." |
||||
) |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
git_dir = args.source_dir if args.source_dir else _TOP_DIR |
||||
if not args.ignore_clean_check and not is_git_dir_clean(git_dir): |
||||
sys.stderr.write( |
||||
"ERROR: Your git repository is not in a clean state: %s\n" |
||||
% git_dir |
||||
) |
||||
return 1 |
||||
|
||||
if args.version: |
||||
version = args.version |
||||
else: |
||||
# Extract FreeType version from sources. |
||||
version = get_cmd_output( |
||||
[ |
||||
sys.executable, |
||||
os.path.join(_SCRIPT_DIR, "extract_freetype_version.py"), |
||||
os.path.join(_TOP_DIR, "include", "freetype", "freetype.h"), |
||||
] |
||||
) |
||||
|
||||
# Determine the build directory. This will be a temporary file that is |
||||
# cleaned up on script exit by default, unless --build-dir=DIR is used, |
||||
# in which case we only create and empty the directory, but never remove |
||||
# its content on exit. |
||||
if args.build_dir: |
||||
build_dir = args.build_dir |
||||
if not os.path.exists(build_dir): |
||||
os.makedirs(build_dir) |
||||
else: |
||||
# Remove anything from the build directory, if any. |
||||
for item in os.listdir(build_dir): |
||||
file_path = os.path.join(build_dir, item) |
||||
if os.path.isdir(file_path): |
||||
shutil.rmtree(file_path) |
||||
else: |
||||
os.unlink(file_path) |
||||
else: |
||||
# Create a temporary directory, and ensure it is removed on exit. |
||||
build_dir = tempfile.mkdtemp(prefix="freetype-dist-") |
||||
|
||||
def clean_build_dir(): |
||||
shutil.rmtree(build_dir) |
||||
|
||||
atexit.register(clean_build_dir) |
||||
|
||||
# Copy all source files known to git into $BUILD_DIR/freetype-$VERSION |
||||
# with the exception of .gitignore and .mailmap files. |
||||
source_files = [ |
||||
f |
||||
for f in get_cmd_output(["git", "ls-files"], cwd=git_dir).split("\n") |
||||
if os.path.basename(f) not in (".gitignore", ".mailmap") |
||||
] |
||||
|
||||
freetype_dir = "freetype-" + version |
||||
tmp_src_dir = os.path.join(build_dir, freetype_dir) |
||||
os.makedirs(tmp_src_dir) |
||||
|
||||
for src in source_files: |
||||
dst = os.path.join(tmp_src_dir, src) |
||||
dst_dir = os.path.dirname(dst) |
||||
if not os.path.exists(dst_dir): |
||||
os.makedirs(dst_dir) |
||||
shutil.copyfile(src, dst) |
||||
|
||||
# Run autogen.sh in directory. |
||||
subprocess.check_call(["/bin/sh", "autogen.sh"], cwd=tmp_src_dir) |
||||
shutil.rmtree( |
||||
os.path.join(tmp_src_dir, "builds", "unix", "autom4te.cache") |
||||
) |
||||
|
||||
# Copy config.guess and config.sub if possible! |
||||
if args.gnu_config_dir: |
||||
for f in ("config.guess", "config.sub"): |
||||
shutil.copyfile( |
||||
os.path.join(args.gnu_config_dir, f), |
||||
os.path.join(tmp_src_dir, "builds", "unix", f), |
||||
) |
||||
|
||||
# Generate reference documentation under docs/ |
||||
subprocess.check_call( |
||||
[ |
||||
sys.executable, |
||||
os.path.join(_SCRIPT_DIR, "generate_reference_docs.py"), |
||||
"--input-dir", |
||||
tmp_src_dir, |
||||
"--version", |
||||
version, |
||||
"--output-dir", |
||||
os.path.join(tmp_src_dir, "docs"), |
||||
] |
||||
) |
||||
|
||||
shutil.rmtree(os.path.join(tmp_src_dir, "docs", "markdown")) |
||||
os.unlink(os.path.join(tmp_src_dir, "docs", "mkdocs.yml")) |
||||
|
||||
# Generate our archives |
||||
freetype_tar = freetype_dir + ".tar" |
||||
|
||||
subprocess.check_call( |
||||
["tar", "-H", "ustar", "-chf", freetype_tar, freetype_dir], |
||||
cwd=build_dir, |
||||
) |
||||
|
||||
subprocess.check_call( |
||||
["gzip", "-9", "--keep", freetype_tar], cwd=build_dir |
||||
) |
||||
|
||||
subprocess.check_call(["xz", "--keep", freetype_tar], cwd=build_dir) |
||||
|
||||
ftwinversion = "ft" + "".join(version.split(".")) |
||||
subprocess.check_call( |
||||
["zip", "-qlr9", ftwinversion + ".zip", freetype_dir], cwd=build_dir |
||||
) |
||||
|
||||
# Copy file to output directory now. |
||||
if not os.path.exists(args.output_dir): |
||||
os.makedirs(args.output_dir) |
||||
|
||||
for f in ( |
||||
freetype_tar + ".gz", |
||||
freetype_tar + ".xz", |
||||
ftwinversion + ".zip", |
||||
): |
||||
shutil.copyfile( |
||||
os.path.join(build_dir, f), os.path.join(args.output_dir, f) |
||||
) |
||||
|
||||
# Done! |
||||
return 0 |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
sys.exit(main()) |
Loading…
Reference in new issue