@styx-api/core 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +30 -19
- package/dist/index.mjs +30 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/backend/python/packaging.ts +24 -9
- package/src/backend/python/python.ts +26 -14
package/dist/index.cjs
CHANGED
|
@@ -4461,17 +4461,19 @@ function licenseField(proj) {
|
|
|
4461
4461
|
return `{ text = "${tomlStr(proj.license?.description ?? "unknown")}" }`;
|
|
4462
4462
|
}
|
|
4463
4463
|
/**
|
|
4464
|
-
* Per-suite `pyproject.toml`. The
|
|
4465
|
-
*
|
|
4466
|
-
* import
|
|
4464
|
+
* Per-suite `pyproject.toml`. The suite source stays in a flat directory
|
|
4465
|
+
* (`python/<pkg>/bet.py`), but setuptools' `package-dir` maps that directory onto
|
|
4466
|
+
* the dotted import package `<project>.<pkg>`, so every suite nests under the
|
|
4467
|
+
* metapackage's `<project>/` namespace. That restores `from <project> import
|
|
4468
|
+
* <pkg>` while keeping each suite a separately-installable distribution (and
|
|
4469
|
+
* leaves no top-level `<pkg>` polluting the global namespace). With no project
|
|
4470
|
+
* name the import name is the bare `<pkg>` (top-level fallback). The styxdefs
|
|
4467
4471
|
* floor is the only runtime dependency.
|
|
4468
4472
|
*
|
|
4469
|
-
* Precondition: `
|
|
4470
|
-
*
|
|
4471
|
-
* it verbatim as the directory name, so this stays consistent with that.
|
|
4473
|
+
* Precondition: `importName` is a valid (possibly dotted) Python package path -
|
|
4474
|
+
* the caller scrubs the project + package names into identifiers accordingly.
|
|
4472
4475
|
*/
|
|
4473
|
-
function generateSubPyproject(proj, pkg) {
|
|
4474
|
-
const importName = pkgDir(pkg);
|
|
4476
|
+
function generateSubPyproject(proj, pkg, importName) {
|
|
4475
4477
|
const cb = new CodeBuilder(" ");
|
|
4476
4478
|
cb.line("[project]");
|
|
4477
4479
|
cb.line(`name = "${tomlStr(pyDistName(proj, pkg))}"`);
|
|
@@ -4510,9 +4512,14 @@ function generateRootInitPy() {
|
|
|
4510
4512
|
* Root `pyproject.toml`: a metapackage depending on `styxkit[all]` (the runner
|
|
4511
4513
|
* stack it re-exports) plus each per-suite distribution. `packages` lists only
|
|
4512
4514
|
* the metapackage's own module so setuptools ships the styxkit re-export without
|
|
4513
|
-
* sweeping the sibling suite directories into this distribution.
|
|
4515
|
+
* sweeping the sibling suite directories into this distribution. The module is
|
|
4516
|
+
* the `<project>/` namespace package the suites nest into, so installing the
|
|
4517
|
+
* metapackage makes `<project>.use_docker()` reachable alongside the suites'
|
|
4518
|
+
* `from <project> import <pkg>`. `moduleDir` is the on-disk source directory; it
|
|
4519
|
+
* differs from the import `moduleName` only when a suite is named after the
|
|
4520
|
+
* project, in which case a `package-dir` remap keeps the import name intact.
|
|
4514
4521
|
*/
|
|
4515
|
-
function generateRootPyproject(proj, distNames, moduleName) {
|
|
4522
|
+
function generateRootPyproject(proj, distNames, moduleName, moduleDir) {
|
|
4516
4523
|
const cb = new CodeBuilder(" ");
|
|
4517
4524
|
cb.line("[project]");
|
|
4518
4525
|
cb.line(`name = "${tomlStr(proj.name ?? "project")}"`);
|
|
@@ -4529,6 +4536,7 @@ function generateRootPyproject(proj, distNames, moduleName) {
|
|
|
4529
4536
|
cb.blank();
|
|
4530
4537
|
cb.line("[tool.setuptools]");
|
|
4531
4538
|
cb.line(`packages = ["${moduleName}"]`);
|
|
4539
|
+
if (moduleDir !== moduleName) cb.line(`package-dir = { "${moduleName}" = "${moduleDir}" }`);
|
|
4532
4540
|
cb.blank();
|
|
4533
4541
|
cb.line("[tool.setuptools.package-data]");
|
|
4534
4542
|
cb.line(`"${moduleName}" = ["py.typed"]`);
|
|
@@ -5548,23 +5556,26 @@ var PythonBackend = class {
|
|
|
5548
5556
|
const distNames = [];
|
|
5549
5557
|
const pkgDirs = [];
|
|
5550
5558
|
const warnings = [];
|
|
5559
|
+
const nsName = proj.name && proj.name.trim() ? pyScrubIdent(proj.name, PY_RESERVED) : void 0;
|
|
5551
5560
|
for (const p of packages) {
|
|
5552
5561
|
const pkg = p.meta ?? {};
|
|
5553
5562
|
const dir = pkg.name ?? "package";
|
|
5554
5563
|
pkgDirs.push(dir);
|
|
5555
5564
|
distNames.push(pyDistName(proj, pkg));
|
|
5556
|
-
|
|
5565
|
+
const importPkg = nsName ? `${nsName}.${dir}` : dir;
|
|
5566
|
+
files.set(`${dir}/pyproject.toml`, generateSubPyproject(proj, pkg, importPkg));
|
|
5557
5567
|
files.set(`${dir}/README.md`, generateSubReadme(proj, pkg));
|
|
5558
5568
|
}
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5569
|
+
const metaImport = nsName ?? "project";
|
|
5570
|
+
let metaDir = metaImport;
|
|
5571
|
+
if (pkgDirs.includes(metaDir)) {
|
|
5572
|
+
const collided = metaDir;
|
|
5573
|
+
while (pkgDirs.includes(metaDir)) metaDir += "_";
|
|
5574
|
+
warnings.push({ message: `metapackage directory "${collided}" collides with a suite directory; emitting its sources in "${metaDir}" instead (import name stays "${metaImport}")` });
|
|
5564
5575
|
}
|
|
5565
|
-
files.set(`${
|
|
5566
|
-
files.set(`${
|
|
5567
|
-
files.set("pyproject.toml", generateRootPyproject(proj, distNames,
|
|
5576
|
+
files.set(`${metaDir}/__init__.py`, generateRootInitPy());
|
|
5577
|
+
files.set(`${metaDir}/py.typed`, "");
|
|
5578
|
+
files.set("pyproject.toml", generateRootPyproject(proj, distNames, metaImport, metaDir));
|
|
5568
5579
|
files.set("README.md", generateRootReadme(proj, distNames));
|
|
5569
5580
|
files.set("requirements.txt", generateRequirementsTxt(pkgDirs));
|
|
5570
5581
|
return {
|
package/dist/index.mjs
CHANGED
|
@@ -4460,17 +4460,19 @@ function licenseField(proj) {
|
|
|
4460
4460
|
return `{ text = "${tomlStr(proj.license?.description ?? "unknown")}" }`;
|
|
4461
4461
|
}
|
|
4462
4462
|
/**
|
|
4463
|
-
* Per-suite `pyproject.toml`. The
|
|
4464
|
-
*
|
|
4465
|
-
* import
|
|
4463
|
+
* Per-suite `pyproject.toml`. The suite source stays in a flat directory
|
|
4464
|
+
* (`python/<pkg>/bet.py`), but setuptools' `package-dir` maps that directory onto
|
|
4465
|
+
* the dotted import package `<project>.<pkg>`, so every suite nests under the
|
|
4466
|
+
* metapackage's `<project>/` namespace. That restores `from <project> import
|
|
4467
|
+
* <pkg>` while keeping each suite a separately-installable distribution (and
|
|
4468
|
+
* leaves no top-level `<pkg>` polluting the global namespace). With no project
|
|
4469
|
+
* name the import name is the bare `<pkg>` (top-level fallback). The styxdefs
|
|
4466
4470
|
* floor is the only runtime dependency.
|
|
4467
4471
|
*
|
|
4468
|
-
* Precondition: `
|
|
4469
|
-
*
|
|
4470
|
-
* it verbatim as the directory name, so this stays consistent with that.
|
|
4472
|
+
* Precondition: `importName` is a valid (possibly dotted) Python package path -
|
|
4473
|
+
* the caller scrubs the project + package names into identifiers accordingly.
|
|
4471
4474
|
*/
|
|
4472
|
-
function generateSubPyproject(proj, pkg) {
|
|
4473
|
-
const importName = pkgDir(pkg);
|
|
4475
|
+
function generateSubPyproject(proj, pkg, importName) {
|
|
4474
4476
|
const cb = new CodeBuilder(" ");
|
|
4475
4477
|
cb.line("[project]");
|
|
4476
4478
|
cb.line(`name = "${tomlStr(pyDistName(proj, pkg))}"`);
|
|
@@ -4509,9 +4511,14 @@ function generateRootInitPy() {
|
|
|
4509
4511
|
* Root `pyproject.toml`: a metapackage depending on `styxkit[all]` (the runner
|
|
4510
4512
|
* stack it re-exports) plus each per-suite distribution. `packages` lists only
|
|
4511
4513
|
* the metapackage's own module so setuptools ships the styxkit re-export without
|
|
4512
|
-
* sweeping the sibling suite directories into this distribution.
|
|
4514
|
+
* sweeping the sibling suite directories into this distribution. The module is
|
|
4515
|
+
* the `<project>/` namespace package the suites nest into, so installing the
|
|
4516
|
+
* metapackage makes `<project>.use_docker()` reachable alongside the suites'
|
|
4517
|
+
* `from <project> import <pkg>`. `moduleDir` is the on-disk source directory; it
|
|
4518
|
+
* differs from the import `moduleName` only when a suite is named after the
|
|
4519
|
+
* project, in which case a `package-dir` remap keeps the import name intact.
|
|
4513
4520
|
*/
|
|
4514
|
-
function generateRootPyproject(proj, distNames, moduleName) {
|
|
4521
|
+
function generateRootPyproject(proj, distNames, moduleName, moduleDir) {
|
|
4515
4522
|
const cb = new CodeBuilder(" ");
|
|
4516
4523
|
cb.line("[project]");
|
|
4517
4524
|
cb.line(`name = "${tomlStr(proj.name ?? "project")}"`);
|
|
@@ -4528,6 +4535,7 @@ function generateRootPyproject(proj, distNames, moduleName) {
|
|
|
4528
4535
|
cb.blank();
|
|
4529
4536
|
cb.line("[tool.setuptools]");
|
|
4530
4537
|
cb.line(`packages = ["${moduleName}"]`);
|
|
4538
|
+
if (moduleDir !== moduleName) cb.line(`package-dir = { "${moduleName}" = "${moduleDir}" }`);
|
|
4531
4539
|
cb.blank();
|
|
4532
4540
|
cb.line("[tool.setuptools.package-data]");
|
|
4533
4541
|
cb.line(`"${moduleName}" = ["py.typed"]`);
|
|
@@ -5547,23 +5555,26 @@ var PythonBackend = class {
|
|
|
5547
5555
|
const distNames = [];
|
|
5548
5556
|
const pkgDirs = [];
|
|
5549
5557
|
const warnings = [];
|
|
5558
|
+
const nsName = proj.name && proj.name.trim() ? pyScrubIdent(proj.name, PY_RESERVED) : void 0;
|
|
5550
5559
|
for (const p of packages) {
|
|
5551
5560
|
const pkg = p.meta ?? {};
|
|
5552
5561
|
const dir = pkg.name ?? "package";
|
|
5553
5562
|
pkgDirs.push(dir);
|
|
5554
5563
|
distNames.push(pyDistName(proj, pkg));
|
|
5555
|
-
|
|
5564
|
+
const importPkg = nsName ? `${nsName}.${dir}` : dir;
|
|
5565
|
+
files.set(`${dir}/pyproject.toml`, generateSubPyproject(proj, pkg, importPkg));
|
|
5556
5566
|
files.set(`${dir}/README.md`, generateSubReadme(proj, pkg));
|
|
5557
5567
|
}
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5568
|
+
const metaImport = nsName ?? "project";
|
|
5569
|
+
let metaDir = metaImport;
|
|
5570
|
+
if (pkgDirs.includes(metaDir)) {
|
|
5571
|
+
const collided = metaDir;
|
|
5572
|
+
while (pkgDirs.includes(metaDir)) metaDir += "_";
|
|
5573
|
+
warnings.push({ message: `metapackage directory "${collided}" collides with a suite directory; emitting its sources in "${metaDir}" instead (import name stays "${metaImport}")` });
|
|
5563
5574
|
}
|
|
5564
|
-
files.set(`${
|
|
5565
|
-
files.set(`${
|
|
5566
|
-
files.set("pyproject.toml", generateRootPyproject(proj, distNames,
|
|
5575
|
+
files.set(`${metaDir}/__init__.py`, generateRootInitPy());
|
|
5576
|
+
files.set(`${metaDir}/py.typed`, "");
|
|
5577
|
+
files.set("pyproject.toml", generateRootPyproject(proj, distNames, metaImport, metaDir));
|
|
5567
5578
|
files.set("README.md", generateRootReadme(proj, distNames));
|
|
5568
5579
|
files.set("requirements.txt", generateRequirementsTxt(pkgDirs));
|
|
5569
5580
|
return {
|