diff --git a/internal/rosa/package/python/package.az b/internal/rosa/package/python/package.az new file mode 100644 index 00000000..70699250 --- /dev/null +++ b/internal/rosa/package/python/package.az @@ -0,0 +1,70 @@ +package python { + description = "the Python programming language interpreter"; + website = "https://www.python.org"; + anitya = 13254; + + version* = "3.14.5"; + source = remoteTar { + url = "https://www.python.org/ftp/python/"+version+ + "/Python-"+version+".tgz"; + checksum = "zYIpDlk2ftZ-UVGCQS1rthle2OHoyXV653ztWiopKV1NhmIJf1K2hHbkwM4DozQ9"; + compress = gzip; + }; + patches = [ "zipfile-no-default-strict_timestamps.patch" ]; + + // test_synopsis_sourceless assumes this is writable and checks __pycache__ + writable = true; + chmod = true; + + env = [ + "EXTRATESTOPTS=-j0 -x " + join { + elems = [ + // requires internet access (http://www.pythontest.net/) + "test_asyncio", + "test_socket", + "test_urllib2", + "test_urllibnet", + "test_urllib2net", + + // makes assumptions about uid_map/gid_map + "test_os", + "test_subprocess", + + // patched out insane strict_timestamps default + "test_zipfile", + + // requires gcc + "test_ctypes", + + // breaks on llvm + "test_dbm_gnu", + ]; + sep = " -x "; + }, + + // _ctypes appears to infer something from the linker name + "LDFLAGS=-Wl,--dynamic-linker=/system/lib/" + + "ld-musl-" + linuxArch + ".so.1", + ]; + + exec = make { + check = [ "test" ]; + }; + + inputs = [ + zlib, + bzip2, + libffi, + openssl, + + pkg-config, + xz, + ]; + + runtime = [ + zlib, + bzip2, + libffi, + openssl, + ]; +} diff --git a/internal/rosa/package/python/zipfile-no-default-strict_timestamps.patch b/internal/rosa/package/python/zipfile-no-default-strict_timestamps.patch new file mode 100644 index 00000000..5effb75f --- /dev/null +++ b/internal/rosa/package/python/zipfile-no-default-strict_timestamps.patch @@ -0,0 +1,22 @@ +diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py +index 19aea290b58..51603ba9510 100644 +--- a/Lib/zipfile/__init__.py ++++ b/Lib/zipfile/__init__.py +@@ -617,7 +617,7 @@ def _decodeExtra(self, filename_crc): + extra = extra[ln+4:] + + @classmethod +- def from_file(cls, filename, arcname=None, *, strict_timestamps=True): ++ def from_file(cls, filename, arcname=None, *, strict_timestamps=False): + """Construct an appropriate ZipInfo for a file on the filesystem. + + filename should be the path to a file or directory on the filesystem. +@@ -1412,7 +1412,7 @@ class ZipFile: + _windows_illegal_name_trans_table = None + + def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, +- compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): ++ compresslevel=None, *, strict_timestamps=False, metadata_encoding=None): + """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x', + or append 'a'.""" + if mode not in ('r', 'w', 'x', 'a'): diff --git a/internal/rosa/python.go b/internal/rosa/python.go index 2258a7f6..1e4cbca8 100644 --- a/internal/rosa/python.go +++ b/internal/rosa/python.go @@ -7,103 +7,6 @@ import ( "hakurei.app/internal/pkg" ) -func (t Toolchain) newPython() (pkg.Artifact, string) { - const ( - version = "3.14.5" - checksum = "zYIpDlk2ftZ-UVGCQS1rthle2OHoyXV653ztWiopKV1NhmIJf1K2hHbkwM4DozQ9" - ) - return t.NewPackage("python", version, newTar( - "https://www.python.org/ftp/python/"+version+ - "/Python-"+version+".tgz", - checksum, - pkg.TarGzip, - ), &PackageAttr{ - // test_synopsis_sourceless assumes this is writable and checks __pycache__ - Writable: true, - Chmod: true, - - Patches: []KV{ - {"zipfile-no-default-strict_timestamps", `diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py -index 19aea290b58..51603ba9510 100644 ---- a/Lib/zipfile/__init__.py -+++ b/Lib/zipfile/__init__.py -@@ -617,7 +617,7 @@ def _decodeExtra(self, filename_crc): - extra = extra[ln+4:] - - @classmethod -- def from_file(cls, filename, arcname=None, *, strict_timestamps=True): -+ def from_file(cls, filename, arcname=None, *, strict_timestamps=False): - """Construct an appropriate ZipInfo for a file on the filesystem. - - filename should be the path to a file or directory on the filesystem. -@@ -1412,7 +1412,7 @@ class ZipFile: - _windows_illegal_name_trans_table = None - - def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, -- compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): -+ compresslevel=None, *, strict_timestamps=False, metadata_encoding=None): - """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x', - or append 'a'.""" - if mode not in ('r', 'w', 'x', 'a'): -`}, - }, - - Env: []string{ - "EXTRATESTOPTS=-j0 -x " + strings.Join([]string{ - // requires internet access (http://www.pythontest.net/) - "test_asyncio", - "test_socket", - "test_urllib2", - "test_urllibnet", - "test_urllib2net", - - // makes assumptions about uid_map/gid_map - "test_os", - "test_subprocess", - - // patched out insane strict_timestamps default - "test_zipfile", - - // requires gcc - "test_ctypes", - - // breaks on llvm - "test_dbm_gnu", - }, " -x "), - - // _ctypes appears to infer something from the linker name - "LDFLAGS=-Wl,--dynamic-linker=/system/lib/" + - "ld-musl-" + t.linuxArch() + ".so.1", - }, - }, &MakeHelper{ - Check: []string{"test"}, - }, - Zlib, - Bzip2, - Libffi, - OpenSSL, - - PkgConfig, - XZ, - ), version -} -func init() { - native.mustRegister(Toolchain.newPython, &Metadata{ - Name: "python", - Description: "the Python programming language interpreter", - Website: "https://www.python.org/", - - Dependencies: P{ - Zlib, - Bzip2, - Libffi, - OpenSSL, - }, - - ID: 13254, - }) -} - // PipHelper is the [Python] pip packaging helper. type PipHelper struct { // Path elements joined with source. diff --git a/internal/rosa/state.go b/internal/rosa/state.go index c4c4519a..6a0f4553 100644 --- a/internal/rosa/state.go +++ b/internal/rosa/state.go @@ -424,6 +424,8 @@ func (s *S) getFrame() azalea.Frame { ) s.frame.Val = map[unique.Handle[azalea.Ident]]any{ + k("linuxArch"): s.linuxArch(), + k("jobsE"): jobsE, k("jobsFlagE"): jobsFlagE, k("jobsLE"): jobsLE, @@ -431,6 +433,24 @@ func (s *S) getFrame() azalea.Frame { } s.frame.Func = map[unique.Handle[azalea.Ident]]azalea.F{ + // library functions + + k("join"): {F: func( + args azalea.FArgs, + ) (v any, set bool, err error) { + var elems []string + var sep string + if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ + k("elems"): &elems, + k("sep"): &sep, + }); err != nil { + return + } + v = strings.Join(elems, sep) + set = true + return + }}, + // intenral/pkg built-ins k("remoteTar"): {F: func(