@mgwilt/nx-uv 0.1.0

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.
Files changed (34) hide show
  1. package/README.md +30 -0
  2. package/executors.json +19 -0
  3. package/generators.json +9 -0
  4. package/package.json +58 -0
  5. package/src/executors/add/add.d.ts +4 -0
  6. package/src/executors/add/add.js +28 -0
  7. package/src/executors/add/add.js.map +1 -0
  8. package/src/executors/add/schema.d.ts +8 -0
  9. package/src/executors/add/schema.json +43 -0
  10. package/src/executors/run/run.d.ts +4 -0
  11. package/src/executors/run/run.js +30 -0
  12. package/src/executors/run/run.js.map +1 -0
  13. package/src/executors/run/schema.d.ts +9 -0
  14. package/src/executors/run/schema.json +48 -0
  15. package/src/executors/shared/run-uv.d.ts +9 -0
  16. package/src/executors/shared/run-uv.js +35 -0
  17. package/src/executors/shared/run-uv.js.map +1 -0
  18. package/src/executors/sync/schema.d.ts +6 -0
  19. package/src/executors/sync/schema.json +30 -0
  20. package/src/executors/sync/sync.d.ts +4 -0
  21. package/src/executors/sync/sync.js +19 -0
  22. package/src/executors/sync/sync.js.map +1 -0
  23. package/src/generators/python-package/files/package/README.md.template +3 -0
  24. package/src/generators/python-package/files/package/pyproject.toml.template +14 -0
  25. package/src/generators/python-package/files/package/src/__moduleName__/__init__.py.template +5 -0
  26. package/src/generators/python-package/files/package/tests/test_smoke.py.template +5 -0
  27. package/src/generators/python-package/python-package.d.ts +4 -0
  28. package/src/generators/python-package/python-package.js +98 -0
  29. package/src/generators/python-package/python-package.js.map +1 -0
  30. package/src/generators/python-package/schema.d.ts +7 -0
  31. package/src/generators/python-package/schema.json +36 -0
  32. package/src/index.d.ts +8 -0
  33. package/src/index.js +12 -0
  34. package/src/index.js.map +1 -0
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @mgwilt/nx-uv
2
+
3
+ Nx plugin for integrating [uv](https://docs.astral.sh/uv/) workflows into an Nx monorepo.
4
+
5
+ ## Executors
6
+
7
+ - `@mgwilt/nx-uv:sync` runs `uv sync`
8
+ - `@mgwilt/nx-uv:run` runs `uv run`
9
+ - `@mgwilt/nx-uv:add` runs `uv add`
10
+
11
+ ## Generator
12
+
13
+ - `@mgwilt/nx-uv:python-package`
14
+ - Creates a Python package in `packages/py/<name>` by default.
15
+ - Generates `pyproject.toml`, `src/<module>/__init__.py`, and optional tests.
16
+ - Adds Nx targets: `sync`, `add`, `run`, `test`, `lint`.
17
+
18
+ ## Local Usage
19
+
20
+ ```bash
21
+ pnpm nx g @mgwilt/nx-uv:python-package shared
22
+ pnpm nx run shared:sync
23
+ pnpm nx run shared:test
24
+ ```
25
+
26
+ ## Releasing
27
+
28
+ - Releases are done with `.github/workflows/release.yml` using npm Trusted Publishing (OIDC).
29
+ - One-time npm setup is required: add this repository/workflow as a trusted publisher for `@mgwilt/nx-uv` in npm settings.
30
+ - `NPM_ACCESS_TOKEN` is not required.
package/executors.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "executors": {
3
+ "sync": {
4
+ "implementation": "./src/executors/sync/sync",
5
+ "schema": "./src/executors/sync/schema.json",
6
+ "description": "Run uv sync for a Python package."
7
+ },
8
+ "run": {
9
+ "implementation": "./src/executors/run/run",
10
+ "schema": "./src/executors/run/schema.json",
11
+ "description": "Run arbitrary commands through uv run."
12
+ },
13
+ "add": {
14
+ "implementation": "./src/executors/add/add",
15
+ "schema": "./src/executors/add/schema.json",
16
+ "description": "Add dependencies through uv add."
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "generators": {
3
+ "python-package": {
4
+ "factory": "./src/generators/python-package/python-package",
5
+ "schema": "./src/generators/python-package/schema.json",
6
+ "description": "Generate a Python package with uv and Nx targets."
7
+ }
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@mgwilt/nx-uv",
3
+ "version": "0.1.0",
4
+ "description": "Nx plugin for uv workflows in Nx monorepos",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "main": "./src/index.js",
8
+ "types": "./src/index.d.ts",
9
+ "private": false,
10
+ "scripts": {
11
+ "build": "nx run nx-uv:build",
12
+ "lint": "nx run nx-uv:lint",
13
+ "test": "nx run nx-uv:test",
14
+ "release:version": "nx release version",
15
+ "release:publish": "nx release publish",
16
+ "commitlint": "commitlint --from=HEAD~1 --to=HEAD"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/mgwilt/nx-uv.git"
21
+ },
22
+ "keywords": [
23
+ "nx",
24
+ "plugin",
25
+ "uv",
26
+ "python"
27
+ ],
28
+ "dependencies": {
29
+ "@nx/devkit": "22.5.3",
30
+ "@nx/vite": "22.5.3",
31
+ "tslib": "^2.3.0",
32
+ "vitest": "^4.0.18"
33
+ },
34
+ "devDependencies": {
35
+ "@commitlint/cli": "^20.4.2",
36
+ "@commitlint/config-conventional": "^20.4.2",
37
+ "@eslint/js": "^9.39.0",
38
+ "@nx/eslint": "22.5.3",
39
+ "@nx/eslint-plugin": "22.5.3",
40
+ "@nx/js": "22.5.3",
41
+ "@nx/vitest": "22.5.3",
42
+ "@swc-node/register": "^1.11.1",
43
+ "@swc/core": "^1.15.18",
44
+ "@types/node": "^20.19.9",
45
+ "@vitest/coverage-v8": "^4.0.8",
46
+ "eslint": "^9.39.0",
47
+ "eslint-config-prettier": "^10.1.8",
48
+ "jsdom": "^27.1.0",
49
+ "jsonc-eslint-parser": "^2.4.0",
50
+ "nx": "22.5.3",
51
+ "prettier": "^3.6.2",
52
+ "typescript": "~5.9.2",
53
+ "typescript-eslint": "^8.56.0",
54
+ "vite": "^7.3.1"
55
+ },
56
+ "executors": "./executors.json",
57
+ "generators": "./generators.json"
58
+ }
@@ -0,0 +1,4 @@
1
+ import { PromiseExecutor } from '@nx/devkit';
2
+ import { AddExecutorSchema } from './schema';
3
+ declare const addExecutor: PromiseExecutor<AddExecutorSchema>;
4
+ export default addExecutor;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const run_uv_1 = require("../shared/run-uv");
5
+ const addExecutor = async (options, context) => {
6
+ var _a, _b;
7
+ if (!((_a = options.dependencies) === null || _a === void 0 ? void 0 : _a.length)) {
8
+ devkit_1.logger.error('Provide at least one dependency for the uv add executor.');
9
+ return { success: false };
10
+ }
11
+ const args = ['add'];
12
+ if (options.package) {
13
+ args.push('--package', options.package);
14
+ }
15
+ if (options.dev) {
16
+ args.push('--dev');
17
+ }
18
+ if (options.group) {
19
+ args.push('--group', options.group);
20
+ }
21
+ if ((_b = options.extraArgs) === null || _b === void 0 ? void 0 : _b.length) {
22
+ args.push(...options.extraArgs);
23
+ }
24
+ args.push(...options.dependencies);
25
+ return (0, run_uv_1.runUvCommand)(args, options, context);
26
+ };
27
+ exports.default = addExecutor;
28
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../../src/executors/add/add.ts"],"names":[],"mappings":";;AAAA,uCAAqD;AAErD,6CAAgD;AAEhD,MAAM,WAAW,GAAuC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;;IACjF,IAAI,CAAC,CAAA,MAAA,OAAO,CAAC,YAAY,0CAAE,MAAM,CAAA,EAAE,CAAC;QAClC,eAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QACzE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,IAAI,GAAa,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,MAAA,OAAO,CAAC,SAAS,0CAAE,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEnC,OAAO,IAAA,qBAAY,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface AddExecutorSchema {
2
+ cwd?: string;
3
+ package?: string;
4
+ dev?: boolean;
5
+ group?: string;
6
+ dependencies: string[];
7
+ extraArgs?: string[];
8
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "version": 2,
4
+ "title": "uv add executor",
5
+ "description": "Add dependencies with uv add in the selected project directory.",
6
+ "type": "object",
7
+ "properties": {
8
+ "cwd": {
9
+ "type": "string",
10
+ "description": "Working directory relative to the workspace root."
11
+ },
12
+ "package": {
13
+ "type": "string",
14
+ "description": "Workspace package passed through as --package."
15
+ },
16
+ "dev": {
17
+ "type": "boolean",
18
+ "description": "Pass --dev to uv add.",
19
+ "default": false
20
+ },
21
+ "group": {
22
+ "type": "string",
23
+ "description": "Dependency group passed through as --group."
24
+ },
25
+ "dependencies": {
26
+ "type": "array",
27
+ "description": "Dependencies to add.",
28
+ "items": {
29
+ "type": "string"
30
+ },
31
+ "minItems": 1
32
+ },
33
+ "extraArgs": {
34
+ "type": "array",
35
+ "description": "Additional arguments appended before dependencies.",
36
+ "items": {
37
+ "type": "string"
38
+ }
39
+ }
40
+ },
41
+ "required": ["dependencies"],
42
+ "additionalProperties": false
43
+ }
@@ -0,0 +1,4 @@
1
+ import { PromiseExecutor } from '@nx/devkit';
2
+ import { RunExecutorSchema } from './schema';
3
+ declare const runExecutor: PromiseExecutor<RunExecutorSchema>;
4
+ export default runExecutor;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const run_uv_1 = require("../shared/run-uv");
5
+ const runExecutor = async (options, context) => {
6
+ var _a, _b, _c;
7
+ if (!options.command) {
8
+ devkit_1.logger.error('The "command" option is required for the uv run executor.');
9
+ return { success: false };
10
+ }
11
+ const args = ['run'];
12
+ if (options.package) {
13
+ args.push('--package', options.package);
14
+ }
15
+ if (options.python) {
16
+ args.push('--python', options.python);
17
+ }
18
+ if ((_a = options.with) === null || _a === void 0 ? void 0 : _a.length) {
19
+ for (const dependency of options.with) {
20
+ args.push('--with', dependency);
21
+ }
22
+ }
23
+ if ((_b = options.extraArgs) === null || _b === void 0 ? void 0 : _b.length) {
24
+ args.push(...options.extraArgs);
25
+ }
26
+ args.push('--', options.command, ...((_c = options.args) !== null && _c !== void 0 ? _c : []));
27
+ return (0, run_uv_1.runUvCommand)(args, options, context);
28
+ };
29
+ exports.default = runExecutor;
30
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../src/executors/run/run.ts"],"names":[],"mappings":";;AAAA,uCAAqD;AAErD,6CAAgD;AAEhD,MAAM,WAAW,GAAuC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,eAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC1E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,IAAI,GAAa,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,MAAA,OAAO,CAAC,IAAI,0CAAE,MAAM,EAAE,CAAC;QACzB,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,IAAI,MAAA,OAAO,CAAC,SAAS,0CAAE,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAA,OAAO,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,CAAC;IAE1D,OAAO,IAAA,qBAAY,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface RunExecutorSchema {
2
+ cwd?: string;
3
+ package?: string;
4
+ python?: string;
5
+ with?: string[];
6
+ command: string;
7
+ args?: string[];
8
+ extraArgs?: string[];
9
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "version": 2,
4
+ "title": "uv run executor",
5
+ "description": "Run a command with uv run in the selected project directory.",
6
+ "type": "object",
7
+ "properties": {
8
+ "cwd": {
9
+ "type": "string",
10
+ "description": "Working directory relative to the workspace root."
11
+ },
12
+ "package": {
13
+ "type": "string",
14
+ "description": "Workspace package passed through as --package."
15
+ },
16
+ "python": {
17
+ "type": "string",
18
+ "description": "Python version or interpreter passed through as --python."
19
+ },
20
+ "with": {
21
+ "type": "array",
22
+ "description": "Additional dependencies passed through as repeated --with values.",
23
+ "items": {
24
+ "type": "string"
25
+ }
26
+ },
27
+ "command": {
28
+ "type": "string",
29
+ "description": "Command to execute with uv run."
30
+ },
31
+ "args": {
32
+ "type": "array",
33
+ "description": "Arguments for the command executed by uv run.",
34
+ "items": {
35
+ "type": "string"
36
+ }
37
+ },
38
+ "extraArgs": {
39
+ "type": "array",
40
+ "description": "Additional arguments appended before command execution.",
41
+ "items": {
42
+ "type": "string"
43
+ }
44
+ }
45
+ },
46
+ "required": ["command"],
47
+ "additionalProperties": false
48
+ }
@@ -0,0 +1,9 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ type BaseExecutorOptions = {
3
+ cwd?: string;
4
+ };
5
+ export declare function resolveWorkingDirectory(options: BaseExecutorOptions, context: ExecutorContext): string;
6
+ export declare function runUvCommand(args: string[], options: BaseExecutorOptions, context: ExecutorContext): {
7
+ success: boolean;
8
+ };
9
+ export {};
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveWorkingDirectory = resolveWorkingDirectory;
4
+ exports.runUvCommand = runUvCommand;
5
+ const devkit_1 = require("@nx/devkit");
6
+ const childProcess = require("child_process");
7
+ const path = require("path");
8
+ function resolveWorkingDirectory(options, context) {
9
+ var _a, _b, _c;
10
+ if (options.cwd) {
11
+ return path.resolve(context.root, options.cwd);
12
+ }
13
+ const projectName = context.projectName;
14
+ const projectRoot = projectName && ((_c = (_b = (_a = context.projectsConfigurations) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b[projectName]) === null || _c === void 0 ? void 0 : _c.root);
15
+ if (projectRoot) {
16
+ return path.resolve(context.root, projectRoot);
17
+ }
18
+ return context.root;
19
+ }
20
+ function runUvCommand(args, options, context) {
21
+ const cwd = resolveWorkingDirectory(options, context);
22
+ devkit_1.logger.info(`Running: uv ${args.join(' ')}`);
23
+ devkit_1.logger.info(`Working directory: ${cwd}`);
24
+ const result = childProcess.spawnSync('uv', args, {
25
+ cwd,
26
+ env: process.env,
27
+ stdio: 'inherit',
28
+ });
29
+ if (result.error) {
30
+ devkit_1.logger.error(result.error.message);
31
+ return { success: false };
32
+ }
33
+ return { success: result.status === 0 };
34
+ }
35
+ //# sourceMappingURL=run-uv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-uv.js","sourceRoot":"","sources":["../../../../src/executors/shared/run-uv.ts"],"names":[],"mappings":";;AAQA,0DAiBC;AAED,oCAsBC;AAjDD,uCAAqD;AACrD,8CAA8C;AAC9C,6BAA6B;AAM7B,SAAgB,uBAAuB,CACrC,OAA4B,EAC5B,OAAwB;;IAExB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACxC,MAAM,WAAW,GACf,WAAW,KAAI,MAAA,MAAA,MAAA,OAAO,CAAC,sBAAsB,0CAAE,QAAQ,0CAAG,WAAW,CAAC,0CAAE,IAAI,CAAA,CAAC;IAE/E,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED,SAAgB,YAAY,CAC1B,IAAc,EACd,OAA4B,EAC5B,OAAwB;IAExB,MAAM,GAAG,GAAG,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEtD,eAAM,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7C,eAAM,CAAC,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE;QAChD,GAAG;QACH,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface SyncExecutorSchema {
2
+ cwd?: string;
3
+ package?: string;
4
+ frozen?: boolean;
5
+ extraArgs?: string[];
6
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "version": 2,
4
+ "title": "uv sync executor",
5
+ "description": "Run uv sync in the selected project directory.",
6
+ "type": "object",
7
+ "properties": {
8
+ "cwd": {
9
+ "type": "string",
10
+ "description": "Working directory relative to the workspace root."
11
+ },
12
+ "package": {
13
+ "type": "string",
14
+ "description": "Workspace package passed through as --package."
15
+ },
16
+ "frozen": {
17
+ "type": "boolean",
18
+ "description": "Pass --frozen to uv sync.",
19
+ "default": false
20
+ },
21
+ "extraArgs": {
22
+ "type": "array",
23
+ "description": "Additional arguments appended to uv sync.",
24
+ "items": {
25
+ "type": "string"
26
+ }
27
+ }
28
+ },
29
+ "additionalProperties": false
30
+ }
@@ -0,0 +1,4 @@
1
+ import { PromiseExecutor } from '@nx/devkit';
2
+ import { SyncExecutorSchema } from './schema';
3
+ declare const syncExecutor: PromiseExecutor<SyncExecutorSchema>;
4
+ export default syncExecutor;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const run_uv_1 = require("../shared/run-uv");
4
+ const syncExecutor = async (options, context) => {
5
+ var _a;
6
+ const args = ['sync'];
7
+ if (options.package) {
8
+ args.push('--package', options.package);
9
+ }
10
+ if (options.frozen) {
11
+ args.push('--frozen');
12
+ }
13
+ if ((_a = options.extraArgs) === null || _a === void 0 ? void 0 : _a.length) {
14
+ args.push(...options.extraArgs);
15
+ }
16
+ return (0, run_uv_1.runUvCommand)(args, options, context);
17
+ };
18
+ exports.default = syncExecutor;
19
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../src/executors/sync/sync.ts"],"names":[],"mappings":";;AAEA,6CAAgD;AAEhD,MAAM,YAAY,GAAwC,KAAK,EAC7D,OAAO,EACP,OAAO,EACP,EAAE;;IACF,MAAM,IAAI,GAAa,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,MAAA,OAAO,CAAC,SAAS,0CAAE,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,IAAA,qBAAY,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,kBAAe,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ # <%= packageName %>
2
+
3
+ Generated by `@mgwilt/nx-uv`.
@@ -0,0 +1,14 @@
1
+ [project]
2
+ name = "<%= packageName %>"
3
+ version = "0.1.0"
4
+ description = "Python package generated by @mgwilt/nx-uv"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = []
8
+
9
+ [build-system]
10
+ requires = ["hatchling>=1.27.0"]
11
+ build-backend = "hatchling.build"
12
+
13
+ [tool.hatch.build.targets.wheel]
14
+ packages = ["src/<%= moduleName %>"]
@@ -0,0 +1,5 @@
1
+ """<%= packageName %> package."""
2
+
3
+
4
+ def hello() -> str:
5
+ return "hello from <%= moduleName %>"
@@ -0,0 +1,5 @@
1
+ from <%= moduleName %> import hello
2
+
3
+
4
+ def test_hello() -> None:
5
+ assert hello().startswith("hello")
@@ -0,0 +1,4 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import { PythonPackageGeneratorSchema } from './schema';
3
+ export declare function pythonPackageGenerator(tree: Tree, options: PythonPackageGeneratorSchema): Promise<void>;
4
+ export default pythonPackageGenerator;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pythonPackageGenerator = pythonPackageGenerator;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const path = require("path");
6
+ async function pythonPackageGenerator(tree, options) {
7
+ const normalized = normalizeOptions(options);
8
+ (0, devkit_1.addProjectConfiguration)(tree, normalized.projectName, {
9
+ root: normalized.projectRoot,
10
+ projectType: 'library',
11
+ sourceRoot: `${normalized.projectRoot}/src`,
12
+ tags: normalized.tags,
13
+ targets: {
14
+ sync: {
15
+ executor: '@mgwilt/nx-uv:sync',
16
+ options: {
17
+ cwd: normalized.projectRoot,
18
+ },
19
+ },
20
+ add: {
21
+ executor: '@mgwilt/nx-uv:add',
22
+ options: {
23
+ cwd: normalized.projectRoot,
24
+ },
25
+ },
26
+ run: {
27
+ executor: '@mgwilt/nx-uv:run',
28
+ options: {
29
+ cwd: normalized.projectRoot,
30
+ command: 'python',
31
+ args: ['-V'],
32
+ },
33
+ },
34
+ test: {
35
+ executor: '@mgwilt/nx-uv:run',
36
+ options: {
37
+ cwd: normalized.projectRoot,
38
+ command: 'pytest',
39
+ with: ['pytest>=8.0.0'],
40
+ },
41
+ },
42
+ lint: {
43
+ executor: '@mgwilt/nx-uv:run',
44
+ options: {
45
+ cwd: normalized.projectRoot,
46
+ command: 'ruff',
47
+ args: ['check', '.'],
48
+ with: ['ruff>=0.5.0'],
49
+ },
50
+ },
51
+ },
52
+ });
53
+ (0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files/package'), normalized.projectRoot, {
54
+ ...normalized,
55
+ tmpl: '',
56
+ });
57
+ if (!normalized.withTests) {
58
+ tree.delete(`${normalized.projectRoot}/tests/test_smoke.py`);
59
+ }
60
+ await (0, devkit_1.formatFiles)(tree);
61
+ }
62
+ function normalizeOptions(options) {
63
+ var _a, _b;
64
+ const trimmedName = options.name.trim();
65
+ const nameSegments = trimmedName.split('/').filter(Boolean);
66
+ let directory = (_a = options.directory) === null || _a === void 0 ? void 0 : _a.trim();
67
+ let name = trimmedName;
68
+ if (nameSegments.length > 1) {
69
+ name = nameSegments[nameSegments.length - 1];
70
+ if (!directory) {
71
+ directory = nameSegments.slice(0, -1).join('/');
72
+ }
73
+ }
74
+ const normalizedName = (0, devkit_1.names)(name).fileName;
75
+ const normalizedDirectory = directory
76
+ ? directory.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '')
77
+ : 'packages/py';
78
+ const projectRoot = (0, devkit_1.joinPathFragments)(normalizedDirectory, normalizedName);
79
+ return {
80
+ name: normalizedName,
81
+ projectName: normalizedName,
82
+ packageName: normalizedName.replace(/_/g, '-'),
83
+ directory: normalizedDirectory,
84
+ projectRoot,
85
+ moduleName: options.moduleName
86
+ ? (0, devkit_1.names)(options.moduleName).fileName.replace(/-/g, '_')
87
+ : normalizedName.replace(/-/g, '_'),
88
+ tags: options.tags
89
+ ? options.tags
90
+ .split(',')
91
+ .map((tag) => tag.trim())
92
+ .filter(Boolean)
93
+ : [],
94
+ withTests: (_b = options.withTests) !== null && _b !== void 0 ? _b : true,
95
+ };
96
+ }
97
+ exports.default = pythonPackageGenerator;
98
+ //# sourceMappingURL=python-package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python-package.js","sourceRoot":"","sources":["../../../../src/generators/python-package/python-package.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface PythonPackageGeneratorSchema {
2
+ name: string;
3
+ directory?: string;
4
+ moduleName?: string;
5
+ withTests?: boolean;
6
+ tags?: string;
7
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "PythonPackage",
4
+ "title": "Python package generator",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "Package name or full path for the new Python package.",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ },
14
+ "x-prompt": "What name would you like to use?"
15
+ },
16
+ "directory": {
17
+ "type": "string",
18
+ "description": "Directory for the package root. Defaults to packages/py."
19
+ },
20
+ "moduleName": {
21
+ "type": "string",
22
+ "description": "Python import module name. Defaults to a normalized package name."
23
+ },
24
+ "withTests": {
25
+ "type": "boolean",
26
+ "description": "Generate a default smoke test.",
27
+ "default": true
28
+ },
29
+ "tags": {
30
+ "type": "string",
31
+ "description": "Comma-delimited Nx project tags."
32
+ }
33
+ },
34
+ "required": ["name"],
35
+ "additionalProperties": false
36
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { default as syncExecutor } from './executors/sync/sync';
2
+ export type { SyncExecutorSchema } from './executors/sync/schema';
3
+ export { default as runExecutor } from './executors/run/run';
4
+ export type { RunExecutorSchema } from './executors/run/schema';
5
+ export { default as addExecutor } from './executors/add/add';
6
+ export type { AddExecutorSchema } from './executors/add/schema';
7
+ export { default as pythonPackageGenerator } from './generators/python-package/python-package';
8
+ export type { PythonPackageGeneratorSchema } from './generators/python-package/schema';
package/src/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pythonPackageGenerator = exports.addExecutor = exports.runExecutor = exports.syncExecutor = void 0;
4
+ var sync_1 = require("./executors/sync/sync");
5
+ Object.defineProperty(exports, "syncExecutor", { enumerable: true, get: function () { return sync_1.default; } });
6
+ var run_1 = require("./executors/run/run");
7
+ Object.defineProperty(exports, "runExecutor", { enumerable: true, get: function () { return run_1.default; } });
8
+ var add_1 = require("./executors/add/add");
9
+ Object.defineProperty(exports, "addExecutor", { enumerable: true, get: function () { return add_1.default; } });
10
+ var python_package_1 = require("./generators/python-package/python-package");
11
+ Object.defineProperty(exports, "pythonPackageGenerator", { enumerable: true, get: function () { return python_package_1.default; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,8CAAgE;AAAvD,oGAAA,OAAO,OAAgB;AAGhC,2CAA6D;AAApD,kGAAA,OAAO,OAAe;AAG/B,2CAA6D;AAApD,kGAAA,OAAO,OAAe;AAG/B,6EAA+F;AAAtF,wHAAA,OAAO,OAA0B"}