forked from rosa/hakurei
Despite the lack of standards, pytest seems somewhat widely agreed upon. Signed-off-by: Ophestra <cat@gensokyo.uk>
578 lines
14 KiB
Go
578 lines
14 KiB
Go
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() {
|
|
artifactsM[PythonMako] = newPypi(
|
|
"mako", 3915,
|
|
"a template library written in Python",
|
|
"1.3.11", "py3", "none", "any",
|
|
"WJ_hxYI-nNiuDiM6QhfAG84uO5U-M2aneB0JS9AQ2J2Oi6YXAbBxIdOeOEng6CoS",
|
|
PythonMarkupSafe,
|
|
)
|
|
|
|
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(),
|
|
)
|
|
}
|