chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
import * as fs from "node:fs";
|
||||
import { execSync } from "child_process";
|
||||
import * as url from "url";
|
||||
import * as toml from "@iarna/toml";
|
||||
import * as tar from "tar";
|
||||
import * as path from "path";
|
||||
import "zx/globals";
|
||||
|
||||
const __dirname = url.fileURLToPath(new URL(".", import.meta.url)).slice(0, -1);
|
||||
const pkg = JSON.parse(
|
||||
fs.readFileSync(__dirname + "/package.json", { encoding: "utf-8" }),
|
||||
);
|
||||
|
||||
let flags = "--release";
|
||||
let features = [];
|
||||
if (!!process.env.PSP_DEBUG) {
|
||||
flags = "";
|
||||
}
|
||||
|
||||
const is_pyodide = !!process.env.PSP_PYODIDE;
|
||||
|
||||
const python_version =
|
||||
process.env.PSP_PYTHON_VERSION || (is_pyodide ? "3.13" : "3.12");
|
||||
|
||||
const version = pkg.version;
|
||||
|
||||
fs.mkdirSync(`./perspective_python-${version}.data`, { recursive: true });
|
||||
fs.copyFileSync("../../LICENSE.md", "./LICENSE.md");
|
||||
|
||||
const cwd = process.cwd();
|
||||
const env = { ...process.env };
|
||||
|
||||
let emsdk_prefix = "";
|
||||
if (is_pyodide) {
|
||||
const emsdkdir = path.resolve(__dirname, "../../.emsdk");
|
||||
const { emscripten } = JSON.parse(
|
||||
fs.readFileSync(path.resolve(__dirname, "../../package.json")),
|
||||
);
|
||||
emsdk_prefix = `cd ${emsdkdir} && . ./emsdk_env.sh && ./emsdk activate ${emscripten} && cd ${cwd} && `;
|
||||
env.MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION =
|
||||
process.env.MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION || "2025_0";
|
||||
}
|
||||
|
||||
// if not windows
|
||||
if (process.platform !== "win32") {
|
||||
env.PSP_ROOT_DIR = "../..";
|
||||
}
|
||||
|
||||
const build_wheel = !!process.env.PSP_BUILD_WHEEL || is_pyodide;
|
||||
const build_sdist = !!process.env.PSP_BUILD_SDIST;
|
||||
|
||||
let target = "";
|
||||
if (is_pyodide) {
|
||||
target = `--target=wasm32-unknown-emscripten -i${python_version}`;
|
||||
} else if (process.env.PSP_ARCH === "x86_64" && process.platform === "darwin") {
|
||||
target = "--target=x86_64-apple-darwin";
|
||||
} else if (
|
||||
process.env.PSP_ARCH === "aarch64" &&
|
||||
process.platform === "darwin"
|
||||
) {
|
||||
target = "--target=aarch64-apple-darwin";
|
||||
} else if (process.env.PSP_ARCH === "x86_64" && process.platform === "linux") {
|
||||
target = "--target=x86_64-unknown-linux-gnu --compatibility manylinux_2_28";
|
||||
} else if (process.env.PSP_ARCH === "aarch64" && process.platform === "linux") {
|
||||
target = "--target=aarch64-unknown-linux-gnu";
|
||||
}
|
||||
|
||||
if (build_wheel) {
|
||||
if (!!process.env.PSP_BUILD_VERBOSE) {
|
||||
flags += " -vv";
|
||||
}
|
||||
|
||||
if (process.env.CONDA_BUILD === "1") {
|
||||
console.log("Building with Conda flags and features");
|
||||
if (process.env.PYTHON) {
|
||||
console.log(`interpreter: ${process.env.PYTHON}`);
|
||||
flags += ` --interpreter=${process.env.PYTHON}`;
|
||||
} else {
|
||||
console.warn(
|
||||
"Expected PYTHON to be set in CONDA_BUILD environment, but it isn't. maturin will likely detect the wrong Python.",
|
||||
);
|
||||
}
|
||||
// we need to generate proto.rs using conda's protoc, which is set in
|
||||
// the environment. we use the unstable "versioned" python abi
|
||||
features.push(["generate-proto"]);
|
||||
} else {
|
||||
// standard for in-repo builds. a different set will be standard in the sdist
|
||||
const standard_features = ["abi3", "generate-proto", "protobuf-src"];
|
||||
|
||||
console.log("Building with standard flags and features");
|
||||
features.push(...standard_features);
|
||||
}
|
||||
|
||||
execSync(`${emsdk_prefix}maturin build ${flags} --features=${features.join(",")} ${target}`, { stdio: "inherit", env });
|
||||
}
|
||||
|
||||
if (build_sdist) {
|
||||
// `maturin sdist` has some issues with Cargo workspaces, so we assemble the sdist by hand here
|
||||
// Note that the resulting sdist is _not_ a Cargo workspace, it is rooted in this package.
|
||||
const cargo_toml = fs.readFileSync("./Cargo.toml").toString("utf-8");
|
||||
const pyproject_toml = fs
|
||||
.readFileSync("./pyproject.toml")
|
||||
.toString("utf-8");
|
||||
const cargo = toml.parse(cargo_toml);
|
||||
const pyproject = toml.parse(pyproject_toml);
|
||||
|
||||
const version = cargo["package"]["version"];
|
||||
const data_dir = `perspective_python-${version}.data`;
|
||||
const testfile = path.join(
|
||||
data_dir,
|
||||
"data/share/jupyter/labextensions/@perspective-dev/jupyterlab/package.json",
|
||||
);
|
||||
if (!fs.existsSync(testfile)) {
|
||||
throw new Error(
|
||||
"labextension is not present in data directory, please build `perspective-jupyterlab`",
|
||||
);
|
||||
}
|
||||
const readme_md = fs.readFileSync("./README.md");
|
||||
const pkg_info = generatePkgInfo(pyproject, cargo, readme_md);
|
||||
fs.writeFileSync("./PKG-INFO", pkg_info);
|
||||
|
||||
// Maturin finds extra license files in the root of the source directory,
|
||||
// then packages them into .dist-info in the wheel. As of Nov 2024,
|
||||
// Maturin does not yet support explicitly declaring `license-files` in
|
||||
// pyproject.toml. See https://github.com/PyO3/maturin/pull/862
|
||||
// https://github.com/PyO3/maturin/issues/861
|
||||
const crate_files = glob.sync(Array.from(cargo["package"]["include"]));
|
||||
const wheel_dir = `../target/wheels`;
|
||||
fs.mkdirSync(wheel_dir, { recursive: true });
|
||||
await tar.create(
|
||||
{
|
||||
gzip: true,
|
||||
file: path.join(wheel_dir, `perspective_python-${version}.tar.gz`),
|
||||
prefix: `perspective_python-${version}`,
|
||||
strict: true,
|
||||
},
|
||||
crate_files.concat(["PKG-INFO", data_dir]),
|
||||
);
|
||||
}
|
||||
|
||||
if (process.env["PSP_UV"] === "1") {
|
||||
flags += " --uv";
|
||||
}
|
||||
|
||||
if (!build_wheel && !build_sdist) {
|
||||
const dev_features = ["abi3"];
|
||||
execSync(
|
||||
`${emsdk_prefix}maturin develop --features=${dev_features.join(",")} ${flags} ${target}`,
|
||||
{ stdio: "inherit", env },
|
||||
);
|
||||
}
|
||||
|
||||
// Generates version 2.3 according to https://packaging.python.org/en/latest/specifications/core-metadata/
|
||||
// Takes parsed pyproject.toml, Cargo.toml, and contents of README.md.
|
||||
function generatePkgInfo(pyproject, cargo, readme_md) {
|
||||
const project = pyproject["project"];
|
||||
const field = (name, value) => {
|
||||
if (typeof value !== "string") {
|
||||
throw new Error(
|
||||
`PKG-INFO value for field ${name} was not a string:\n${value}`,
|
||||
);
|
||||
}
|
||||
return `${name}: ${value}`;
|
||||
};
|
||||
const lines = [];
|
||||
const addField = (key, value) => lines.push(field(key, value));
|
||||
addField("Metadata-Version", "2.3");
|
||||
addField("Name", project.name);
|
||||
addField("Version", cargo.package.version);
|
||||
for (const c of project["classifiers"]) {
|
||||
addField("Classifier", c);
|
||||
}
|
||||
for (const [extra, deps] of Object.entries(
|
||||
project["optional-dependencies"],
|
||||
)) {
|
||||
for (const dep of deps) {
|
||||
addField("Requires-Dist", `${dep} ; extra == '${extra}'`);
|
||||
}
|
||||
}
|
||||
for (const extra of Object.keys(project["optional-dependencies"])) {
|
||||
addField("Provides-Extra", extra);
|
||||
}
|
||||
addField("Summary", cargo.package.description);
|
||||
addField("Home-page", cargo.package.homepage);
|
||||
addField("Author", cargo.package.authors[0]);
|
||||
addField("Author-email", cargo.package.authors[0]);
|
||||
addField("License", cargo.package.license);
|
||||
addField("Requires-Python", project["requires-python"]);
|
||||
addField(
|
||||
"Description-Content-Type",
|
||||
"text/markdown; charset=UTF-8; variant=GFM",
|
||||
);
|
||||
addField("Project-URL", `Source Code, ${cargo.package.repository}`);
|
||||
lines.push("");
|
||||
lines.push(readme_md);
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
Reference in New Issue
Block a user