mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-09-24 17:13:57 +00:00
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.
55 lines
2.2 KiB
Python
Executable File
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()
|