package rosa import ( "path" "slices" "strings" "hakurei.app/internal/pkg" ) func (t Toolchain) newPython() (pkg.Artifact, string) { const ( version = "3.14.4" checksum = "X0VRAAGOlCVldh4J9tRAE-YrJtDvqfQTJaqxKPXNX6YTPlwpR9GwA5WRIZDO-63s" ) 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-" + linuxArch() + ".so.1", }, }, &MakeHelper{ Check: []string{"test"}, }, Zlib, Bzip2, Libffi, OpenSSL, PkgConfig, XZ, ), version } func init() { artifactsM[Python] = Metadata{ f: Toolchain.newPython, 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. Append []string // Whether to omit --no-build-isolation. BuildIsolation bool // Whether to enter source after install. EnterSource bool // Whether to install to build environment after install. Install bool // Whether to skip running tests. SkipCheck bool // Replaces pytest if non-empty. Check string // Runs after install. Script string } var _ Helper = new(PipHelper) // extra returns python, or pytest if defaults are assumed. func (attr *PipHelper) extra(int) P { if attr == nil || (!attr.SkipCheck && attr.Check == "") { return P{PythonPyTest} } return P{Python} } // wantsChmod returns true. func (*PipHelper) wantsChmod() bool { return true } // wantsWrite is equivalent to wantsChmod. func (attr *PipHelper) wantsWrite() bool { return attr.wantsChmod() } // scriptEarly is a noop. func (*PipHelper) scriptEarly() string { return "" } // createDir returns false. func (*PipHelper) createDir() bool { return false } // wantsDir requests a new directory in TMPDIR. func (*PipHelper) wantsDir() string { return `"$(mktemp -d)"` } // script generates the pip3 install command. func (attr *PipHelper) script(name string) string { if attr == nil { attr = new(PipHelper) } sourcePath := AbsUsrSrc.Append(name).Append(attr.Append...) var extra string if !attr.BuildIsolation { extra += ` --no-build-isolation \` } var script string if attr.Install { script += `pip3 install \ --no-index \ --prefix=/system \ --no-build-isolation \ '` + sourcePath.String() + `' ` } if attr.EnterSource { script += "cd '/usr/src/" + name + "'\n" } if !attr.SkipCheck { if attr.Check == "" { // some test suites fall apart when ran out-of-tree script += "(cd '" + sourcePath.String() + "' && pytest)\n" } else { script += attr.Check } } script += attr.Script return ` pip3 install \ --no-index \ --prefix=/system \ --root=/work \` + extra + ` '` + sourcePath.String() + `' ` + script } // newPythonPackage creates [Metadata] for a [Python] package. func newPythonPackage( name string, id int, description, website, version string, source pkg.Artifact, attrP *PackageAttr, attr *PipHelper, build P, extra ...PArtifact, ) Metadata { name = "python-" + name return Metadata{ f: func(t Toolchain) (pkg.Artifact, string) { return t.NewPackage(name, version, source, attrP, attr, slices.Concat( P{Python}, extra, build, )...), version }, Name: name, Description: description, Website: website, Dependencies: slices.Concat(P{Python}, extra), ID: id, } } // newViaPip installs a pip wheel from a url. func (t Toolchain) newViaPip( name, version, url, checksum string, extra ...PArtifact, ) pkg.Artifact { return t.New(name+"-"+version, 0, t.AppendPresets(nil, slices.Concat(P{Python}, extra)..., ), nil, nil, ` pip3 install \ --no-index \ --prefix=/system \ --root=/work \ '/usr/src/`+path.Base(url)+`' `, pkg.Path(AbsUsrSrc.Append(path.Base(url)), false, pkg.NewHTTPGet( nil, url, mustDecode(checksum), ))) } // newPypi creates [Metadata] for a [pypi] package. // // [pypi]: https://pypi.org/ func newPypi( name string, id int, description, version, interpreter, abi, platform, checksum string, extra ...PArtifact, ) Metadata { return Metadata{ f: func(t Toolchain) (pkg.Artifact, string) { return t.newViaPip(name, version, "https://files.pythonhosted.org/"+path.Join( "packages", interpreter, string(name[0]), name, name+"-"+version+"-"+interpreter+"-"+abi+"-"+platform+".whl", ), checksum, extra...), version }, Name: "python-" + name, Description: description, Website: "https://pypi.org/project/" + name + "/", Dependencies: slices.Concat(P{Python}, extra), ID: id, } } func init() { const ( version = "82.0.1" checksum = "nznP46Tj539yqswtOrIM4nQgwLA1h-ApKX7z7ghazROCpyF5swtQGwsZoI93wkhc" ) artifactsM[PythonSetuptools] = newPythonPackage( "setuptools", 4021, "the autotools of the Python ecosystem", "https://pypi.org/project/setuptools/", version, newFromGitHub( "pypa/setuptools", "v"+version, checksum, ), nil, &PipHelper{ // error: invalid command 'dist_info' BuildIsolation: true, // pytest circular dependency SkipCheck: true, }, nil) } func init() { const ( version = "1.1.1" checksum = "rXZixTsZcRcIoUC1LvWrjySsiXSv5uhW6ng2P-yXZrbdj7FrSrDeJLCfC2b-ladV" ) artifactsM[PythonVCSVersioning] = newPythonPackage( "vcs-versioning", 389421, "core VCS versioning functionality extracted as a standalone library", "https://setuptools-scm.readthedocs.io/en/latest/", version, newFromGitHub( "pypa/setuptools-scm", "vcs-versioning-v"+version, checksum, ), &PackageAttr{ Env: []string{ "SETUPTOOLS_SCM_PRETEND_VERSION=" + version, }, }, &PipHelper{ // upstream is monorepo of two packages (setuptools-scm) Append: []string{"vcs-versioning"}, // pytest circular dependency SkipCheck: true, }, nil, PythonSetuptools, PythonPackaging, ) } func init() { const ( version = "10.0.5" checksum = "vTN_TPd-b4Wbsw5WmAcsWjrs-FNXXznOeVTDnb54NtXve9Oy-eb2HPy-RG3FzNqp" ) artifactsM[PythonSetuptoolsSCM] = newPythonPackage( "setuptools-scm", 7874, "extracts Python package versions from Git or Mercurial metadata", "https://setuptools-scm.readthedocs.io/en/latest/", version, newFromGitHub( "pypa/setuptools-scm", "setuptools-scm-v"+version, checksum, ), &PackageAttr{ Env: []string{ "SETUPTOOLS_SCM_PRETEND_VERSION=" + version, }, }, &PipHelper{ // upstream is monorepo of two packages Append: []string{"setuptools-scm"}, // pytest circular dependency SkipCheck: true, }, nil, PythonSetuptools, PythonVCSVersioning, ) } func init() { const ( version = "3.12.0" checksum = "VcTsiGiDU1aPLbjSPe38f9OjJDCLcxFz9loObJqUI1ZxDHXAaQMxBpNyLz_G1Rff" ) artifactsM[PythonFlitCore] = newPythonPackage( "flit-core", 44841, "a PEP 517 build backend for packages using Flit", "https://flit.pypa.io/", version, newFromGitHub( "pypa/flit", version, checksum, ), nil, &PipHelper{ // upstream has other unused packages with many dependencies Append: []string{"flit_core"}, // pytest circular dependency SkipCheck: true, }, nil, ) } func init() { const ( version = "26.1" checksum = "AOX4RBYPCMs2-vv8zSxQWANCK4XUbACRZWuR0ZHSiZ-fz_43IUXpMs_1-SZl8AVP" ) artifactsM[PythonPackaging] = newPythonPackage( "packaging", 60461, "reusable core utilities for various Python Packaging interoperability specifications", "https://packaging.pypa.io/", version, newFromGitHub( "pypa/packaging", version, checksum, ), nil, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonFlitCore}, ) } func init() { const ( version = "1.0.4" checksum = "zAZbcIO-JnNhb-xMg76W2j0tn5b2MtavWjUpGpPjBmbrcRZDLoXBn8o8yJ3DUgCT" ) artifactsM[PythonPathspec] = newPythonPackage( "pathspec", 23424, "utility library for gitignore style pattern matching of file paths", "https://github.com/cpburnz/python-pathspec", version, newFromGitHub( "cpburnz/python-pathspec", "v"+version, checksum, ), nil, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonFlitCore}, ) } func init() { const ( version = "2026.1.14.14" checksum = "ADfyOvGq7wfOhW10xTVvTmcuY7ZXw8Xlqhz7AM6KULOEm42rpk_45hfcO2PgxOIe" ) artifactsM[PythonTroveClassifiers] = newPythonPackage( "trove-classifiers", 88298, "canonical source for classifiers on PyPI", "https://pypi.org/p/trove-classifiers/", version, newFromGitHub( "pypa/trove-classifiers", version, checksum, ), nil, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonSetuptools}, ) } func init() { const ( version = "1.6.0" checksum = "GiUgDkKjF8Xn1cmq6iMhTGXzcPIYeaJrvQpHBSAJapNVx4UyuiTXqd5eVlxSClJu" ) artifactsM[PythonPluggy] = newPythonPackage( "pluggy", 7500, "the core framework used by the pytest, tox, and devpi projects", "https://pluggy.readthedocs.io/en/latest/", version, newFromGitHub( "pytest-dev/pluggy", version, checksum, ), &PackageAttr{ Env: []string{ "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PLUGGY=" + version, }, }, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonSetuptoolsSCM}, ) } func init() { const ( version = "1.16.5" checksum = "V2eREtqZLZeV85yb4O-bfAJCUluHcQP76Qfs0QH5s7RF_Oc8xIP8jD0jl85qFyWk" ) artifactsM[PythonHatchling] = newPythonPackage( "hatchling", 16137, "the extensible, standards compliant build backend used by Hatch", "https://hatch.pypa.io/latest/", version, newFromGitHub( "pypa/hatch", "hatch-v"+version, checksum, ), nil, &PipHelper{ // upstream has other unused packages with many dependencies Append: []string{"backend"}, // pytest circular dependency SkipCheck: true, }, nil, PythonPackaging, PythonPathspec, PythonTroveClassifiers, PythonPluggy, ) } func init() { const ( version = "2.20.0" checksum = "L-2P6vn7c_CNZYliE5CJAWLxO1ziDQVVkf8bnZbHj8aSCQ43oWv11wC9KzU9MeCa" ) artifactsM[PythonPygments] = newPythonPackage( "pygments", 3986, "a syntax highlighting package written in Python", "https://pygments.org/", version, newFromGitHub( "pygments/pygments", version, checksum, ), nil, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonHatchling}, ) } func init() { const ( version = "2.3.0" checksum = "mH7VBZaXcYatBPE3RQQZvSzz_Ay8IPPek60NpPHZulPq4ReAFUUsA4EPWfiyMknZ" ) artifactsM[PythonIniConfig] = newPythonPackage( "iniconfig", 114778, "a small and simple INI-file parser module", "https://github.com/pytest-dev/iniconfig", version, newFromGitHub( "pytest-dev/iniconfig", "v"+version, checksum, ), &PackageAttr{ Env: []string{ "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_INICONFIG=" + version, }, }, &PipHelper{ // pytest circular dependency SkipCheck: true, }, P{PythonSetuptoolsSCM}, ) } func init() { const ( version = "9.0.3" checksum = "qfLL_znWhbJCDbNJvrx9H3-orJ86z4ifhaW0bIn21jl2sDP-FVoX_1yieOypArQe" ) artifactsM[PythonPyTest] = newPythonPackage( "pytest", 3765, "the pytest framework", "https://pytest.org", version, newFromGitHub( "pytest-dev/pytest", version, checksum, ), &PackageAttr{ Env: []string{ "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST=" + version, }, }, &PipHelper{ // many dependencies SkipCheck: true, }, P{PythonSetuptoolsSCM}, PythonIniConfig, PythonPackaging, PythonPluggy, PythonPygments, ) } func init() { const ( version = "3.0.3" checksum = "txRGYdWE3his1lHHRI-lZADw0-ILvUg2l5OGdFHtFXIb_QowGxwdxHCUSJIgmjQs" ) artifactsM[PythonMarkupSafe] = newPythonPackage( "markupsafe", 3918, "implements a text object that escapes characters so it is safe to use in HTML and XML", "https://markupsafe.palletsprojects.com/", version, newFromGitHub( "pallets/markupsafe", version, checksum, ), nil, &PipHelper{ // ModuleNotFoundError: No module named 'markupsafe' Install: true, }, P{PythonSetuptools}, ) } func init() { const ( version = "1.3.11" checksum = "HbNreFhqmvmplmIa6h5TVnkwYYlPnsxBzkTXEA-esyx04GzybjTb7OU8Go07Kfyz" ) artifactsM[PythonMako] = newPythonPackage( "mako", 3915, "a template library written in Python", "https://www.makotemplates.org/", version, newFromGitHub( "sqlalchemy/mako", "rel_"+strings.Join(strings.SplitN(version, ".", 3), "_"), checksum, ), nil, nil, P{PythonSetuptools}, PythonMarkupSafe, ) } func init() { artifactsM[PythonPyYAML] = newPypi( "pyyaml", 4123, "a YAML parser and emitter for Python", "6.0.3", "cp314", "cp314", "musllinux_1_2_"+linuxArch(), perArch[string]{ "amd64": "4_jhCFpUNtyrFp2HOMqUisR005u90MHId53eS7rkUbcGXkoaJ7JRsY21dREHEfGN", "arm64": "sQ818ZYSmC7Vj9prIPx3sEYqSDhZlWvLbgHV9w4GjxsfQ63ZSzappctKM7Lb0Whw", }.unwrap(), ) }