Files
shadowsocks-libev/scripts/source_archive.py
Max Lv bdc77408cb Rename to shadowsocks-c with libuv, async DNS and CI lint (#3051)
Rename the project to shadowsocks-c while retaining ss-* commands, the embedding ABI, and legacy library/package lookup compatibility.

Replace libev with bundled libuv for IOCP/kqueue event backends, expand asynchronous runtime DNS coverage, and add actionlint/Ruff with strict clang-tidy failure handling. Validate native platforms, static builds, packaging, interoperability, sanitizers, and canonical/legacy consumers.

All 22 hosted checks pass at reviewed head a8493250eb.
2026-09-11 14:18:37 +08:00

55 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python3
"""Create an offline source archive from Git's tracked working-tree files.
Maintainer-only tool; building the resulting archive needs neither Git nor
Python (unless integration tests or generated documentation are requested).
"""
import argparse
import gzip
import io
import os
from pathlib import Path
import subprocess
import tarfile
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("output", type=Path)
parser.add_argument("--prefix", default="shadowsocks-c-3.3.6")
args = parser.parse_args()
root = Path(__file__).resolve().parents[1]
if "/" in args.prefix or args.prefix in ("", ".", ".."):
parser.error("prefix must be a single directory name")
epoch = int(os.environ.get("SOURCE_DATE_EPOCH") or subprocess.check_output(
["git", "show", "-s", "--format=%ct", "HEAD"], cwd=root, text=True).strip())
entries = subprocess.check_output(["git", "ls-files", "--stage", "-z"], cwd=root).split(b"\0")
args.output.parent.mkdir(parents=True, exist_ok=True)
with args.output.open("wb") as raw, gzip.GzipFile(filename="", mode="wb", fileobj=raw, mtime=epoch) as compressed:
with tarfile.open(fileobj=compressed, mode="w|") as archive:
for entry in entries:
if not entry:
continue
metadata, encoded = entry.split(b"\t", 1)
mode, _, stage = metadata.split()
if stage != b"0" or mode == b"160000":
raise RuntimeError("Unmerged entry or submodule in source archive")
relative = os.fsdecode(encoded)
path = root / relative
info = tarfile.TarInfo(args.prefix + "/" + relative)
info.mtime = epoch
info.mode = int(mode, 8) & 0o777
if path.is_symlink():
info.type = tarfile.SYMTYPE
info.linkname = os.readlink(path)
archive.addfile(info)
else:
content = path.read_bytes()
info.size = len(content)
archive.addfile(info, io.BytesIO(content))
print(args.output)
if __name__ == "__main__":
main()