@mnci/nx-python-pip 0.1.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/README.md +120 -0
- package/dist/executors/build/executor.d.ts +25 -0
- package/dist/executors/build/executor.d.ts.map +1 -0
- package/dist/executors/build/executor.js +81 -0
- package/dist/executors/build/executor.js.map +1 -0
- package/dist/executors/build/schema.json +10 -0
- package/dist/executors/lint/executor.d.ts +20 -0
- package/dist/executors/lint/executor.d.ts.map +1 -0
- package/dist/executors/lint/executor.js +26 -0
- package/dist/executors/lint/executor.js.map +1 -0
- package/dist/executors/lint/schema.json +9 -0
- package/dist/executors/publish/executor.d.ts +30 -0
- package/dist/executors/publish/executor.d.ts.map +1 -0
- package/dist/executors/publish/executor.js +42 -0
- package/dist/executors/publish/executor.js.map +1 -0
- package/dist/executors/publish/schema.json +16 -0
- package/dist/executors/test/executor.d.ts +26 -0
- package/dist/executors/test/executor.d.ts.map +1 -0
- package/dist/executors/test/executor.js +38 -0
- package/dist/executors/test/executor.js.map +1 -0
- package/dist/executors/test/schema.json +15 -0
- package/dist/generators/application/generator.d.ts +20 -0
- package/dist/generators/application/generator.d.ts.map +1 -0
- package/dist/generators/application/generator.js +29 -0
- package/dist/generators/application/generator.js.map +1 -0
- package/dist/generators/application/schema.json +22 -0
- package/dist/generators/functionApplication/generator.d.ts +21 -0
- package/dist/generators/functionApplication/generator.d.ts.map +1 -0
- package/dist/generators/functionApplication/generator.js +43 -0
- package/dist/generators/functionApplication/generator.js.map +1 -0
- package/dist/generators/functionApplication/schema.json +22 -0
- package/dist/generators/internalLibrary/generator.d.ts +20 -0
- package/dist/generators/internalLibrary/generator.d.ts.map +1 -0
- package/dist/generators/internalLibrary/generator.js +39 -0
- package/dist/generators/internalLibrary/generator.js.map +1 -0
- package/dist/generators/internalLibrary/schema.json +22 -0
- package/dist/generators/library/generator.d.ts +23 -0
- package/dist/generators/library/generator.d.ts.map +1 -0
- package/dist/generators/library/generator.js +33 -0
- package/dist/generators/library/generator.js.map +1 -0
- package/dist/generators/library/schema.json +22 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/azureFunctionApp.d.ts +53 -0
- package/dist/internal/azureFunctionApp.d.ts.map +1 -0
- package/dist/internal/azureFunctionApp.js +89 -0
- package/dist/internal/azureFunctionApp.js.map +1 -0
- package/dist/internal/executorContext.d.ts +17 -0
- package/dist/internal/executorContext.d.ts.map +1 -0
- package/dist/internal/executorContext.js +26 -0
- package/dist/internal/executorContext.js.map +1 -0
- package/dist/internal/generateProject.d.ts +43 -0
- package/dist/internal/generateProject.d.ts.map +1 -0
- package/dist/internal/generateProject.js +58 -0
- package/dist/internal/generateProject.js.map +1 -0
- package/dist/internal/pythonProject.d.ts +57 -0
- package/dist/internal/pythonProject.d.ts.map +1 -0
- package/dist/internal/pythonProject.js +94 -0
- package/dist/internal/pythonProject.js.map +1 -0
- package/dist/internal/vendor.d.ts +42 -0
- package/dist/internal/vendor.d.ts.map +1 -0
- package/dist/internal/vendor.js +64 -0
- package/dist/internal/vendor.js.map +1 -0
- package/dist/release/versionActions.d.ts +107 -0
- package/dist/release/versionActions.d.ts.map +1 -0
- package/dist/release/versionActions.js +136 -0
- package/dist/release/versionActions.js.map +1 -0
- package/executors.json +25 -0
- package/generators.json +25 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @mnci/nx-python-pip
|
|
2
|
+
|
|
3
|
+
An Nx plugin for **pip-native** Python projects — plain `pip`, Ruff, pytest
|
|
4
|
+
and the standard PyPA `build`/`twine` tools. No uv, no Poetry, no lock file.
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
No maintained, Nx-23-compatible Python plugin supports pip: the closest
|
|
9
|
+
existing option, [`@nxlv/python`](https://github.com/lucasvieirasilva/nx-plugins),
|
|
10
|
+
ships only `uv` and Poetry providers, and every alternative found on npm is
|
|
11
|
+
either the same uv/Poetry architecture or years stale. If your organization
|
|
12
|
+
standardizes on plain pip (no uv, no Poetry), this plugin fills that gap.
|
|
13
|
+
|
|
14
|
+
It was built for and is used by [`@mnci/cli`](../cli)'s `mnci2 add python-*`
|
|
15
|
+
commands, but has no dependency on `@mnci/cli` — any Nx 21+ workspace can
|
|
16
|
+
install and use it directly.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install --save-dev @mnci/nx-python-pip
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
No `nx.json` `plugins` registration needed — its generators and executors
|
|
25
|
+
are explicit (resolved via `generators.json`/`executors.json`, plain Node
|
|
26
|
+
module lookup), not inference-based.
|
|
27
|
+
|
|
28
|
+
You will also need the actual Python tools this plugin's executors shell out
|
|
29
|
+
to: `python3 -m pip install build twine ruff pytest` (or pin them in your own
|
|
30
|
+
`requirements-dev.txt` / `requirements-dev.in`). The plugin has no opinion on
|
|
31
|
+
*how* those land on a machine — same way `@nx/js`'s executors assume `node`
|
|
32
|
+
is already there.
|
|
33
|
+
|
|
34
|
+
## Generators
|
|
35
|
+
|
|
36
|
+
| Generator | Location default | Writes |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `application` | `apps/<name>` | `pyproject.toml` (hatchling) + `project.json` (`lint`/`test`/`build`) + a sample module and pytest |
|
|
39
|
+
| `library` | `libs/<name>` | Same as `application`, plus `nx-release-publish` (twine) and a project-level `release.version.versionActions` override |
|
|
40
|
+
| `internal-library` | `libs/<name>` | `lint`/`test` only — no `build`/publish; meant to be **vendored** into a consumer's wheel, not built or released on its own |
|
|
41
|
+
| `function-application` | `apps/<name>` | Azure Functions **v2** programming model (`function_app.py` + `host.json` + `requirements.txt` + a tested pure helper) — no `pyproject.toml`/build target, since the deployable is source, not a wheel |
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
nx g @mnci/nx-python-pip:application my-app
|
|
45
|
+
nx g @mnci/nx-python-pip:library my-lib --directory=packages/my-lib
|
|
46
|
+
nx g @mnci/nx-python-pip:internal-library my-shared-lib
|
|
47
|
+
nx g @mnci/nx-python-pip:function-application my-function-app
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Executors
|
|
51
|
+
|
|
52
|
+
| Executor | Runs |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `build` | `python -m build` — vendoring-aware (see below) |
|
|
55
|
+
| `test` | `python -m pip install -e .` (unless `installEditable: false`) then `python -m pytest` |
|
|
56
|
+
| `lint` | `python -m ruff check .` |
|
|
57
|
+
| `publish` | `python -m twine upload --skip-existing dist/*`, reading `TWINE_USERNAME`/`TWINE_PASSWORD`/`TWINE_REPOSITORY_URL` from the environment |
|
|
58
|
+
|
|
59
|
+
Every command is invoked as `python3 -m <tool>`, never a hard-coded venv
|
|
60
|
+
path, so the exact same command works whether or not you've activated a
|
|
61
|
+
virtualenv — this plugin never creates or manages one itself.
|
|
62
|
+
|
|
63
|
+
`publish` accepts a real, typed `dryRun` option — `nx release publish
|
|
64
|
+
--dry-run` sets it automatically on every `nx-release-publish` executor, so
|
|
65
|
+
a dry run cleanly previews the twine command instead of running it.
|
|
66
|
+
|
|
67
|
+
## Internal-lib vendoring
|
|
68
|
+
|
|
69
|
+
Plain pip has no bundled-local-dependency feature (the equivalent of
|
|
70
|
+
`@nxlv/python`'s `bundleLocalDependencies`). To have a project's built wheel
|
|
71
|
+
bundle an internal library's module as a real top-level package, hand-add a
|
|
72
|
+
`vendor` entry to the consuming project's `pyproject.toml`:
|
|
73
|
+
|
|
74
|
+
```toml
|
|
75
|
+
[tool.mnci-python-pip]
|
|
76
|
+
vendor = ["my-shared-lib"]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The `build` executor resolves `my-shared-lib`'s root via the **real Nx
|
|
80
|
+
project graph** (not a hard-coded path), copies its module directory into a
|
|
81
|
+
staged copy of the project being built, patches the staged
|
|
82
|
+
`pyproject.toml`'s `[tool.hatch.build.targets.wheel] packages` list to
|
|
83
|
+
include it, and builds from there. No cross-project dependency is ever wired
|
|
84
|
+
automatically — you always add this entry by hand, mirroring how you'd wire
|
|
85
|
+
any other cross-project dependency.
|
|
86
|
+
|
|
87
|
+
Verified empirically that vendoring an internal lib and declaring a real
|
|
88
|
+
external PyPI dependency on the *same* project works correctly together —
|
|
89
|
+
the combination that silently dropped the external dependency's metadata
|
|
90
|
+
under `@nxlv/python`'s `bundleLocalDependencies` does not reproduce here.
|
|
91
|
+
|
|
92
|
+
## Versioning (`nx release`)
|
|
93
|
+
|
|
94
|
+
The `library` generator sets:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
"release": { "version": { "versionActions": "@mnci/nx-python-pip/release/version-actions" } }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
on the generated project. This is a hand-written implementation of Nx's
|
|
101
|
+
`VersionActions` interface that reads/writes the `version = "..."` line
|
|
102
|
+
under `pyproject.toml`'s `[project]` table — verified empirically against a
|
|
103
|
+
real `nx release version --dry-run`, both the disk-fallback and
|
|
104
|
+
git-tag-based resolution paths. Internal-lib dependencies are vendored, not
|
|
105
|
+
registry references, so dependency-version tracking is a no-op (the same
|
|
106
|
+
branch `@nxlv/python`'s own reference implementation takes for bundled
|
|
107
|
+
dependencies).
|
|
108
|
+
|
|
109
|
+
## Known gaps
|
|
110
|
+
|
|
111
|
+
- No lock file — plain pip has none. A published wheel's `Requires-Dist`
|
|
112
|
+
mirrors whatever specifier `pyproject.toml` declares (e.g. `tomli>=2.0.0`)
|
|
113
|
+
verbatim, not a resolved/pinned version.
|
|
114
|
+
- Vendored internal-lib imports are only resolvable inside the **built**
|
|
115
|
+
wheel — not from a plain `pip install -e .` dev environment, since
|
|
116
|
+
vendoring happens at `build` time only. A project whose pytest-covered
|
|
117
|
+
code imports a vendored internal lib needs its own test-isolation
|
|
118
|
+
strategy; the `test` executor makes no attempt to solve this.
|
|
119
|
+
- venv management is left to the user — same spirit as never managing
|
|
120
|
+
`node_modules` beyond `npm install`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import type { BuildExecutorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a Python project's wheel/sdist via `python -m build`.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* When the project's `pyproject.toml` declares a `vendor` entry (see
|
|
8
|
+
* `parseVendorEntries`), each named project's module directory is copied
|
|
9
|
+
* into a staged copy of the project before building, and the staged
|
|
10
|
+
* `pyproject.toml`'s wheel `packages` list is patched to include it — so the
|
|
11
|
+
* built wheel contains the vendored module as a real top-level package, with
|
|
12
|
+
* no separate install needed by whoever installs the published wheel.
|
|
13
|
+
* Projects with no `vendor` entry build straight from their own directory,
|
|
14
|
+
* no staging.
|
|
15
|
+
*
|
|
16
|
+
* @param _options - Unused (vendoring is driven by `pyproject.toml`, not options).
|
|
17
|
+
* @param context - The Nx executor context.
|
|
18
|
+
* @returns `{ success: true }` when `python -m build` exits 0.
|
|
19
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
20
|
+
* @typeParam None - this function has no generic type parameters.
|
|
21
|
+
*/
|
|
22
|
+
export default function buildExecutor(_options: BuildExecutorSchema, context: ExecutorContext): Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/executors/build/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAQjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAoBrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAA8B,aAAa,CAAE,QAAQ,EAAE,mBAAmB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqCnI"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = buildExecutor;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const executorContext_1 = require("../../internal/executorContext");
|
|
9
|
+
const pythonProject_1 = require("../../internal/pythonProject");
|
|
10
|
+
const vendor_1 = require("../../internal/vendor");
|
|
11
|
+
/**
|
|
12
|
+
* Resolves a vendored project's workspace-relative root via the Nx project
|
|
13
|
+
* graph (not a hard-coded `libs/<name>` path) — the same lookup
|
|
14
|
+
* {@link projectRootFrom} uses for the project under build itself.
|
|
15
|
+
*
|
|
16
|
+
* @param name - The vendored project's Nx project name.
|
|
17
|
+
* @param context - The Nx executor context.
|
|
18
|
+
* @returns The workspace-relative root, or `undefined` when no project with
|
|
19
|
+
* that name is registered.
|
|
20
|
+
* @throws Never - an unresolvable name yields `undefined`, not a throw; the
|
|
21
|
+
* caller surfaces it as a normal `python -m build` failure (a missing
|
|
22
|
+
* source directory), not a confusing internal error.
|
|
23
|
+
* @typeParam None - this function has no generic type parameters.
|
|
24
|
+
*/
|
|
25
|
+
function vendoredProjectRoot(name, context) {
|
|
26
|
+
return context.projectsConfigurations?.projects[name]?.root;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds a Python project's wheel/sdist via `python -m build`.
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
* When the project's `pyproject.toml` declares a `vendor` entry (see
|
|
33
|
+
* `parseVendorEntries`), each named project's module directory is copied
|
|
34
|
+
* into a staged copy of the project before building, and the staged
|
|
35
|
+
* `pyproject.toml`'s wheel `packages` list is patched to include it — so the
|
|
36
|
+
* built wheel contains the vendored module as a real top-level package, with
|
|
37
|
+
* no separate install needed by whoever installs the published wheel.
|
|
38
|
+
* Projects with no `vendor` entry build straight from their own directory,
|
|
39
|
+
* no staging.
|
|
40
|
+
*
|
|
41
|
+
* @param _options - Unused (vendoring is driven by `pyproject.toml`, not options).
|
|
42
|
+
* @param context - The Nx executor context.
|
|
43
|
+
* @returns `{ success: true }` when `python -m build` exits 0.
|
|
44
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
45
|
+
* @typeParam None - this function has no generic type parameters.
|
|
46
|
+
*/
|
|
47
|
+
async function buildExecutor(_options, context) {
|
|
48
|
+
const projectRoot = (0, executorContext_1.projectRootFrom)(context);
|
|
49
|
+
const absoluteProjectRoot = (0, node_path_1.join)(context.root, projectRoot);
|
|
50
|
+
const outDirectory = (0, node_path_1.join)(absoluteProjectRoot, 'dist');
|
|
51
|
+
const pyprojectPath = (0, node_path_1.join)(absoluteProjectRoot, 'pyproject.toml');
|
|
52
|
+
const pyprojectToml = (0, node_fs_1.readFileSync)(pyprojectPath, 'utf8');
|
|
53
|
+
const vendorNames = (0, vendor_1.parseVendorEntries)(pyprojectToml);
|
|
54
|
+
if (vendorNames.length === 0) {
|
|
55
|
+
const result = (0, node_child_process_1.spawnSync)('python3', ['-m', 'build', '--outdir', outDirectory, absoluteProjectRoot], { stdio: 'inherit' });
|
|
56
|
+
return { success: result.status === 0 };
|
|
57
|
+
}
|
|
58
|
+
const stagingRoot = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'nx-python-pip-build-'));
|
|
59
|
+
try {
|
|
60
|
+
(0, node_fs_1.cpSync)(absoluteProjectRoot, stagingRoot, { recursive: true });
|
|
61
|
+
const moduleDirectories = [];
|
|
62
|
+
for (const name of vendorNames) {
|
|
63
|
+
const vendoredRoot = vendoredProjectRoot(name, context);
|
|
64
|
+
if (!vendoredRoot) {
|
|
65
|
+
console.error(`nx-python-pip build: vendored project "${name}" is not registered in this workspace.`);
|
|
66
|
+
return { success: false };
|
|
67
|
+
}
|
|
68
|
+
const moduleDirectory = (0, pythonProject_1.pythonModuleDirectory)(name);
|
|
69
|
+
(0, node_fs_1.cpSync)((0, node_path_1.join)(context.root, vendoredRoot, moduleDirectory), (0, node_path_1.join)(stagingRoot, moduleDirectory), { recursive: true });
|
|
70
|
+
moduleDirectories.push(moduleDirectory);
|
|
71
|
+
}
|
|
72
|
+
const stagedPyprojectPath = (0, node_path_1.join)(stagingRoot, 'pyproject.toml');
|
|
73
|
+
(0, node_fs_1.writeFileSync)(stagedPyprojectPath, (0, vendor_1.addPackagesToWheelTarget)((0, node_fs_1.readFileSync)(stagedPyprojectPath, 'utf8'), moduleDirectories));
|
|
74
|
+
const result = (0, node_child_process_1.spawnSync)('python3', ['-m', 'build', '--outdir', outDirectory, stagingRoot], { stdio: 'inherit' });
|
|
75
|
+
return { success: result.status === 0 };
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
(0, node_fs_1.rmSync)(stagingRoot, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/executors/build/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "MnciNxPythonPipBuild",
|
|
5
|
+
"title": "Build a Python wheel/sdist with python -m build",
|
|
6
|
+
"description": "Runs `python -m build`. When the project's pyproject.toml declares [tool.mnci-python-pip] vendor = [...], the named libs/<name> modules are copied into a staged copy of the project first, so the built wheel bundles them as real top-level packages.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {},
|
|
9
|
+
"required": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import type { LintExecutorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Runs `python3 -m ruff check .` in the project's own directory.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* `python3 -m ruff` (not a bare `ruff`) so it resolves whatever `python3`
|
|
8
|
+
* the caller has active — no hard-coded venv path, matching every other
|
|
9
|
+
* executor in this package.
|
|
10
|
+
*
|
|
11
|
+
* @param _options - Unused (ruff needs no per-project configuration here).
|
|
12
|
+
* @param context - The Nx executor context.
|
|
13
|
+
* @returns `{ success: true }` when ruff exits 0.
|
|
14
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
15
|
+
* @typeParam None - this function has no generic type parameters.
|
|
16
|
+
*/
|
|
17
|
+
export default function lintExecutor(_options: LintExecutorSchema, context: ExecutorContext): Promise<{
|
|
18
|
+
success: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/executors/lint/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;GAaG;AACH,wBAA8B,YAAY,CAAE,QAAQ,EAAE,kBAAkB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAIjI"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = lintExecutor;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const executorContext_1 = require("../../internal/executorContext");
|
|
7
|
+
/**
|
|
8
|
+
* Runs `python3 -m ruff check .` in the project's own directory.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* `python3 -m ruff` (not a bare `ruff`) so it resolves whatever `python3`
|
|
12
|
+
* the caller has active — no hard-coded venv path, matching every other
|
|
13
|
+
* executor in this package.
|
|
14
|
+
*
|
|
15
|
+
* @param _options - Unused (ruff needs no per-project configuration here).
|
|
16
|
+
* @param context - The Nx executor context.
|
|
17
|
+
* @returns `{ success: true }` when ruff exits 0.
|
|
18
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
19
|
+
* @typeParam None - this function has no generic type parameters.
|
|
20
|
+
*/
|
|
21
|
+
async function lintExecutor(_options, context) {
|
|
22
|
+
const cwd = (0, node_path_1.join)(context.root, (0, executorContext_1.projectRootFrom)(context));
|
|
23
|
+
const result = (0, node_child_process_1.spawnSync)('python3', ['-m', 'ruff', 'check', '.'], { cwd, stdio: 'inherit' });
|
|
24
|
+
return { success: result.status === 0 };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/executors/lint/executor.ts"],"names":[],"mappings":";;;AACA,2DAA8C;AAC9C,yCAAgC;AAChC,oEAAgE;AAGhE;;;;;;;;;;;;;GAaG;AACY,KAAK,uBAAwB,QAA4B,EAAE,OAAwB;IAChG,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,OAAO,CAAC,IAAI,EAAE,IAAA,iCAAe,EAAC,OAAO,CAAC,CAAC,CAAA;IACxD,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import type { PublishExecutorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Runs `python -m twine upload --skip-existing dist/*`.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* `--skip-existing` mirrors npm's own idempotent-publish behaviour (Nx's
|
|
8
|
+
* `@nx/js:release-publish` also tolerates a version already on the
|
|
9
|
+
* registry), so a re-run after a partial release failure does not
|
|
10
|
+
* hard-error on the packages that already made it. Credentials
|
|
11
|
+
* (`TWINE_USERNAME`/`TWINE_PASSWORD`/`TWINE_REPOSITORY_URL`) are read from
|
|
12
|
+
* the environment by twine itself — never written to disk here.
|
|
13
|
+
*
|
|
14
|
+
* `dryRun` is a real, typed executor option (unlike a plain
|
|
15
|
+
* `nx:run-commands` target, which would only see the `--dry-run` flag as an
|
|
16
|
+
* opaque, appended `--dryRun=true` string on the shell command line).
|
|
17
|
+
* `nx release publish` sets `dryRun` automatically for every
|
|
18
|
+
* `nx-release-publish` executor, custom or not, so no argv-parsing trick is
|
|
19
|
+
* needed to preview instead of uploading for real.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Whether to preview instead of actually uploading.
|
|
22
|
+
* @param context - The Nx executor context.
|
|
23
|
+
* @returns `{ success: true }` on a successful (real or previewed) publish.
|
|
24
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
25
|
+
* @typeParam None - this function has no generic type parameters.
|
|
26
|
+
*/
|
|
27
|
+
export default function publishExecutor(options: PublishExecutorSchema, context: ExecutorContext): Promise<{
|
|
28
|
+
success: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/executors/publish/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAA8B,eAAe,CAAE,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAWtI"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = publishExecutor;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const executorContext_1 = require("../../internal/executorContext");
|
|
7
|
+
/**
|
|
8
|
+
* Runs `python -m twine upload --skip-existing dist/*`.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* `--skip-existing` mirrors npm's own idempotent-publish behaviour (Nx's
|
|
12
|
+
* `@nx/js:release-publish` also tolerates a version already on the
|
|
13
|
+
* registry), so a re-run after a partial release failure does not
|
|
14
|
+
* hard-error on the packages that already made it. Credentials
|
|
15
|
+
* (`TWINE_USERNAME`/`TWINE_PASSWORD`/`TWINE_REPOSITORY_URL`) are read from
|
|
16
|
+
* the environment by twine itself — never written to disk here.
|
|
17
|
+
*
|
|
18
|
+
* `dryRun` is a real, typed executor option (unlike a plain
|
|
19
|
+
* `nx:run-commands` target, which would only see the `--dry-run` flag as an
|
|
20
|
+
* opaque, appended `--dryRun=true` string on the shell command line).
|
|
21
|
+
* `nx release publish` sets `dryRun` automatically for every
|
|
22
|
+
* `nx-release-publish` executor, custom or not, so no argv-parsing trick is
|
|
23
|
+
* needed to preview instead of uploading for real.
|
|
24
|
+
*
|
|
25
|
+
* @param options - Whether to preview instead of actually uploading.
|
|
26
|
+
* @param context - The Nx executor context.
|
|
27
|
+
* @returns `{ success: true }` on a successful (real or previewed) publish.
|
|
28
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
29
|
+
* @typeParam None - this function has no generic type parameters.
|
|
30
|
+
*/
|
|
31
|
+
async function publishExecutor(options, context) {
|
|
32
|
+
if (options.dryRun) {
|
|
33
|
+
console.log('[dry-run] would run: python3 -m twine upload --skip-existing dist/*');
|
|
34
|
+
return { success: true };
|
|
35
|
+
}
|
|
36
|
+
const cwd = (0, node_path_1.join)(context.root, (0, executorContext_1.projectRootFrom)(context));
|
|
37
|
+
// No shell: true needed for the dist/* glob — twine globs its own path
|
|
38
|
+
// arguments internally, so this stays free of a shell-injection surface.
|
|
39
|
+
const result = (0, node_child_process_1.spawnSync)('python3', ['-m', 'twine', 'upload', '--skip-existing', 'dist/*'], { cwd, stdio: 'inherit' });
|
|
40
|
+
return { success: result.status === 0 };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/executors/publish/executor.ts"],"names":[],"mappings":";;;AACA,2DAA8C;AAC9C,yCAAgC;AAChC,oEAAgE;AAGhE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACY,KAAK,0BAA2B,OAA8B,EAAE,OAAwB;IACrG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAA;QAClF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,OAAO,CAAC,IAAI,EAAE,IAAA,iCAAe,EAAC,OAAO,CAAC,CAAC,CAAA;IACxD,uEAAuE;IACvE,yEAAyE;IACzE,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IACtH,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "MnciNxPythonPipPublish",
|
|
5
|
+
"title": "Publish a Python wheel/sdist with twine",
|
|
6
|
+
"description": "Runs `python -m twine upload --skip-existing dist/*`. Credentials (TWINE_USERNAME/TWINE_PASSWORD/TWINE_REPOSITORY_URL) are read from the environment by twine itself. Detects the --dryRun flag `nx release publish --dry-run` appends and previews instead of uploading for real.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"dryRun": {
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"description": "Preview instead of actually uploading. Set automatically by `nx release publish --dry-run`.",
|
|
12
|
+
"default": false
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"required": []
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import type { TestExecutorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Runs pytest for a Python project, optionally installing it in editable
|
|
5
|
+
* mode first so its own declared dependencies are importable.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* `pip install -e .` (when `installEditable` is not `false`) makes the
|
|
9
|
+
* project's `pyproject.toml` `dependencies` (real external PyPI packages)
|
|
10
|
+
* importable at test time. It does **not** make vendored internal-lib
|
|
11
|
+
* imports importable — those are woven in only at `build` time (see the
|
|
12
|
+
* `build` executor's remarks) — so a project whose pytest-covered code
|
|
13
|
+
* imports a vendored internal lib needs its own test isolation strategy;
|
|
14
|
+
* this executor makes no attempt to solve that.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Whether to `pip install -e .` before pytest.
|
|
17
|
+
* @param context - The Nx executor context.
|
|
18
|
+
* @returns `{ success: true }` when pytest exits 0 (and, when requested, the
|
|
19
|
+
* editable install also succeeded).
|
|
20
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
21
|
+
* @typeParam None - this function has no generic type parameters.
|
|
22
|
+
*/
|
|
23
|
+
export default function testExecutor(options: TestExecutorSchema, context: ExecutorContext): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/executors/test/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAA8B,YAAY,CAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAYhI"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = testExecutor;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const executorContext_1 = require("../../internal/executorContext");
|
|
7
|
+
/**
|
|
8
|
+
* Runs pytest for a Python project, optionally installing it in editable
|
|
9
|
+
* mode first so its own declared dependencies are importable.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* `pip install -e .` (when `installEditable` is not `false`) makes the
|
|
13
|
+
* project's `pyproject.toml` `dependencies` (real external PyPI packages)
|
|
14
|
+
* importable at test time. It does **not** make vendored internal-lib
|
|
15
|
+
* imports importable — those are woven in only at `build` time (see the
|
|
16
|
+
* `build` executor's remarks) — so a project whose pytest-covered code
|
|
17
|
+
* imports a vendored internal lib needs its own test isolation strategy;
|
|
18
|
+
* this executor makes no attempt to solve that.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Whether to `pip install -e .` before pytest.
|
|
21
|
+
* @param context - The Nx executor context.
|
|
22
|
+
* @returns `{ success: true }` when pytest exits 0 (and, when requested, the
|
|
23
|
+
* editable install also succeeded).
|
|
24
|
+
* @throws Never - failures surface through the returned `success: false`.
|
|
25
|
+
* @typeParam None - this function has no generic type parameters.
|
|
26
|
+
*/
|
|
27
|
+
async function testExecutor(options, context) {
|
|
28
|
+
const cwd = (0, node_path_1.join)(context.root, (0, executorContext_1.projectRootFrom)(context));
|
|
29
|
+
if (options.installEditable !== false) {
|
|
30
|
+
const install = (0, node_child_process_1.spawnSync)('python3', ['-m', 'pip', 'install', '--quiet', '-e', '.'], { cwd, stdio: 'inherit' });
|
|
31
|
+
if (install.status !== 0) {
|
|
32
|
+
return { success: false };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const result = (0, node_child_process_1.spawnSync)('python3', ['-m', 'pytest'], { cwd, stdio: 'inherit' });
|
|
36
|
+
return { success: result.status === 0 };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/executors/test/executor.ts"],"names":[],"mappings":";;;AACA,2DAA8C;AAC9C,yCAAgC;AAChC,oEAAgE;AAGhE;;;;;;;;;;;;;;;;;;;GAmBG;AACY,KAAK,uBAAwB,OAA2B,EAAE,OAAwB;IAC/F,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,OAAO,CAAC,IAAI,EAAE,IAAA,iCAAe,EAAC,OAAO,CAAC,CAAC,CAAA;IAExD,IAAI,OAAO,CAAC,eAAe,KAAK,KAAK,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAA,8BAAS,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QAC/G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAChF,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "MnciNxPythonPipTest",
|
|
5
|
+
"title": "Test a Python project with pytest",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"installEditable": {
|
|
9
|
+
"type": "boolean",
|
|
10
|
+
"description": "Run `pip install -e .` before pytest, so the project's own declared dependencies are importable. Set to false for projects with no pyproject.toml (e.g. an Azure Function app, which deploys as source, not a wheel).",
|
|
11
|
+
"default": true
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": []
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Tree } from '@nx/devkit';
|
|
2
|
+
import type { AppGeneratorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a pip-native Python application: `pyproject.toml` + `project.json`
|
|
5
|
+
* (lint/test/build) + a sample module and pytest.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* No `nx-release-publish` target and no `release.version.versionActions`
|
|
9
|
+
* override — apps are never released by `nx release` (packed into a deploy
|
|
10
|
+
* artifact instead, by whatever `package`-style target the calling workspace
|
|
11
|
+
* layers on top).
|
|
12
|
+
*
|
|
13
|
+
* @param tree - The Nx virtual file system.
|
|
14
|
+
* @param options - The project name and directory.
|
|
15
|
+
* @returns A promise that resolves once generated files are formatted.
|
|
16
|
+
* @throws Never - pure Tree writes.
|
|
17
|
+
* @typeParam None - this function has no generic type parameters.
|
|
18
|
+
*/
|
|
19
|
+
export default function appGenerator(tree: Tree, options: AppGeneratorSchema): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/generators/application/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;;;GAeG;AACH,wBAA8B,YAAY,CAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = appGenerator;
|
|
4
|
+
const generateProject_1 = require("../../internal/generateProject");
|
|
5
|
+
/**
|
|
6
|
+
* Generates a pip-native Python application: `pyproject.toml` + `project.json`
|
|
7
|
+
* (lint/test/build) + a sample module and pytest.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* No `nx-release-publish` target and no `release.version.versionActions`
|
|
11
|
+
* override — apps are never released by `nx release` (packed into a deploy
|
|
12
|
+
* artifact instead, by whatever `package`-style target the calling workspace
|
|
13
|
+
* layers on top).
|
|
14
|
+
*
|
|
15
|
+
* @param tree - The Nx virtual file system.
|
|
16
|
+
* @param options - The project name and directory.
|
|
17
|
+
* @returns A promise that resolves once generated files are formatted.
|
|
18
|
+
* @throws Never - pure Tree writes.
|
|
19
|
+
* @typeParam None - this function has no generic type parameters.
|
|
20
|
+
*/
|
|
21
|
+
async function appGenerator(tree, options) {
|
|
22
|
+
(0, generateProject_1.generateBuildableProject)(tree, {
|
|
23
|
+
name: options.name,
|
|
24
|
+
directory: options.directory ?? `apps/${options.name}`,
|
|
25
|
+
projectType: 'application',
|
|
26
|
+
});
|
|
27
|
+
await (0, generateProject_1.formatFiles)(tree);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/generators/application/generator.ts"],"names":[],"mappings":";;;AACA,oEAAsF;AAGtF;;;;;;;;;;;;;;;GAeG;AACY,KAAK,uBAAwB,IAAU,EAAE,OAA2B;IACjF,IAAA,0CAAwB,EAAC,IAAI,EAAE;QAC7B,IAAI,EAAS,OAAO,CAAC,IAAI;QACzB,SAAS,EAAI,OAAO,CAAC,SAAS,IAAI,QAAQ,OAAO,CAAC,IAAI,EAAE;QACxD,WAAW,EAAE,aAAa;KAC3B,CAAC,CAAA;IACF,MAAM,IAAA,6BAAW,EAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "MnciNxPythonPipApplication",
|
|
5
|
+
"title": "Create a Python application",
|
|
6
|
+
"description": "Hand-authors a pip-native Python app: pyproject.toml (hatchling) + project.json (lint/test/build targets) + a sample module and pytest.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"name": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "The project name.",
|
|
12
|
+
"$default": { "$source": "argv", "index": 0 },
|
|
13
|
+
"x-prompt": "What name would you like to use?",
|
|
14
|
+
"pattern": "^[a-zA-Z][^:]*$"
|
|
15
|
+
},
|
|
16
|
+
"directory": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Workspace-relative directory for the project (defaults to apps/<name>)."
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["name"]
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
import type { FunctionAppGeneratorSchema } from './schema.d';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a Python Azure Function app (v2 programming model): `function_app.py`
|
|
5
|
+
* + `host.json` + `requirements.txt` + a tested pure helper module.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* No `pyproject.toml`/`build` target: the deployable is the **source tree**
|
|
9
|
+
* (Azure's Python worker installs `requirements.txt` and runs
|
|
10
|
+
* `function_app.py` directly — Oryx build at deploy time, no wheel), so this
|
|
11
|
+
* generator writes no build system at all. `func` CLI is not needed to
|
|
12
|
+
* generate — only for local `func start`.
|
|
13
|
+
*
|
|
14
|
+
* @param tree - The Nx virtual file system.
|
|
15
|
+
* @param options - The project name and directory.
|
|
16
|
+
* @returns A promise that resolves once generated files are formatted.
|
|
17
|
+
* @throws Never - pure Tree writes.
|
|
18
|
+
* @typeParam None - this function has no generic type parameters.
|
|
19
|
+
*/
|
|
20
|
+
export default function functionAppGenerator(tree: Tree, options: FunctionAppGeneratorSchema): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/generators/functionApplication/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAS5E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAA8B,oBAAoB,CAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBlH"}
|