Skip to content

Commit 9e631a2

Browse files
feat(nx-python): add ruff check executor and project generator (#185)
* feat(nx-python): add ruff linter * chore(nx-python-e2e): eslint auto fixes * feat(nx-python): add ruff check executor and project generator re #170 * docs(nx-python): add ruff linter to readme * fix(nx-python): sonarcloud code smells
1 parent 9d1ddf9 commit 9e631a2

File tree

15 files changed

+1071
-21
lines changed

15 files changed

+1071
-21
lines changed

e2e/nx-python-e2e/jest.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@ export default {
1212
],
1313
},
1414
moduleFileExtensions: ['ts', 'js', 'html'],
15-
coverageDirectory: '../../coverage/e2e/nx-python-e2e',
1615
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`nx-python e2e shared virtual environment should create nx-python project with 3 levels with shared virtual environment 1`] = `
4+
"[tool.nx]
5+
autoActivate = true
6+
7+
[tool.poetry]
8+
name = "@proj/source"
9+
version = "1.0.0"
10+
description = ""
11+
authors = [ ]
12+
license = "Proprietary"
13+
readme = "README.md"
14+
15+
[tool.poetry.dependencies]
16+
python = ">=3.9,<3.11"
17+
18+
[tool.poetry.dependencies.app1]
19+
path = "apps/app1"
20+
develop = true
21+
22+
[tool.poetry.dependencies.lib1]
23+
path = "libs/lib1"
24+
develop = true
25+
26+
[tool.poetry.dependencies.lib2]
27+
path = "libs/lib2"
28+
develop = true
29+
30+
[tool.poetry.group.dev.dependencies]
31+
autopep8 = "2.0.2"
32+
flake8 = "6.0.0"
33+
pytest = "7.3.1"
34+
pytest-sugar = "0.9.7"
35+
pytest-cov = "4.1.0"
36+
pytest-html = "3.2.0"
37+
38+
[build-system]
39+
requires = [ "poetry-core==1.1.0" ]
40+
build-backend = "poetry.core.masonry.api"
41+
"
42+
`;
43+
44+
exports[`nx-python e2e shared virtual environment should create one nx-python project, migrate to shared venv and add 3 levels 1`] = `
45+
"[tool.nx]
46+
autoActivate = true
47+
48+
[tool.poetry]
49+
name = "@proj/source"
50+
version = "1.0.0"
51+
description = ""
52+
authors = [ ]
53+
license = "Proprietary"
54+
readme = "README.md"
55+
56+
[tool.poetry.dependencies]
57+
python = ">=3.9,<3.11"
58+
59+
[tool.poetry.dependencies.app1]
60+
path = "apps/app1"
61+
develop = true
62+
63+
[tool.poetry.dependencies.lib1]
64+
path = "libs/lib1"
65+
develop = true
66+
67+
[tool.poetry.dependencies.lib2]
68+
path = "libs/lib2"
69+
develop = true
70+
71+
[tool.poetry.group.dev.dependencies]
72+
autopep8 = "2.0.2"
73+
flake8 = "6.0.0"
74+
pytest = "7.3.1"
75+
pytest-sugar = "0.9.7"
76+
pytest-cov = "4.1.0"
77+
pytest-html = "3.2.0"
78+
79+
[build-system]
80+
requires = [ "poetry-core==1.1.0" ]
81+
build-backend = "poetry.core.masonry.api"
82+
"
83+
`;

e2e/nx-python-e2e/tests/nx-python.spec.ts

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
runNxCommandAsync,
55
updateFile,
66
checkFilesExist,
7+
readFile,
78
} from '@nx/plugin/testing';
89
describe('nx-python e2e', () => {
910
it('should create nx-python project', async () => {
@@ -17,11 +18,45 @@ describe('nx-python e2e', () => {
1718
updateFile('nx.json', JSON.stringify(nxJson, null, 4));
1819

1920
await runNxCommandAsync(
20-
`generate @nxlv/python:project ${app1} --type "application" --packageName ${app1} --description ${app1}`
21+
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
2122
);
2223

2324
await runNxCommandAsync(
24-
`generate @nxlv/python:project ${lib1} --type "library" --packageName ${lib1} --description ${lib1}`
25+
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
26+
);
27+
28+
await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);
29+
30+
await runNxCommandAsync(`run ${lib1}:add --name pendulum`);
31+
32+
await runNxCommandAsync(`run ${app1}:lint`);
33+
34+
await runNxCommandAsync(`run ${app1}:build`);
35+
36+
expect(() =>
37+
checkFilesExist(
38+
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
39+
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
40+
)
41+
).not.toThrow();
42+
}, 3000000);
43+
44+
it('should create nx-python project with ruff', async () => {
45+
const app1 = 'app1';
46+
const lib1 = 'lib1';
47+
ensureNxProject('@nxlv/python', 'dist/packages/nx-python');
48+
49+
const nxJson = readJson('nx.json');
50+
nxJson.plugins = ['@nxlv/python'];
51+
52+
updateFile('nx.json', JSON.stringify(nxJson, null, 4));
53+
54+
await runNxCommandAsync(
55+
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1} --linter ruff`
56+
);
57+
58+
await runNxCommandAsync(
59+
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1} --linter ruff`
2560
);
2661

2762
await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);
@@ -53,15 +88,15 @@ describe('nx-python e2e', () => {
5388
updateFile('nx.json', JSON.stringify(nxJson, null, 4));
5489

5590
await runNxCommandAsync(
56-
`generate @nxlv/python:project ${app1} --type "application" --packageName ${app1} --description ${app1}`
91+
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
5792
);
5893

5994
await runNxCommandAsync(
60-
`generate @nxlv/python:project ${lib1} --type "library" --packageName ${lib1} --description ${lib1}`
95+
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
6196
);
6297

6398
await runNxCommandAsync(
64-
`generate @nxlv/python:project ${lib2} --type "library" --packageName ${lib2} --description ${lib2}`
99+
`generate @nxlv/python:poetry-project ${lib2} --projectType "library" --packageName ${lib2} --description ${lib2}`
65100
);
66101

67102
await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);
@@ -79,4 +114,98 @@ describe('nx-python e2e', () => {
79114
)
80115
).not.toThrow();
81116
}, 3000000);
117+
118+
describe('shared virtual environment', () => {
119+
it('should create nx-python project with 3 levels with shared virtual environment', async () => {
120+
const app1 = 'app1';
121+
const lib1 = 'lib1';
122+
const lib2 = 'lib2';
123+
124+
ensureNxProject('@nxlv/python', 'dist/packages/nx-python');
125+
126+
const nxJson = readJson('nx.json');
127+
nxJson.plugins = ['@nxlv/python'];
128+
129+
updateFile('nx.json', JSON.stringify(nxJson, null, 4));
130+
131+
await runNxCommandAsync(
132+
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
133+
);
134+
135+
await runNxCommandAsync(
136+
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
137+
);
138+
139+
await runNxCommandAsync(
140+
`generate @nxlv/python:poetry-project ${lib2} --projectType "library" --packageName ${lib2} --description ${lib2}`
141+
);
142+
143+
await runNxCommandAsync(`generate @nxlv/python:migrate-to-shared-venv`);
144+
145+
await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);
146+
147+
await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);
148+
149+
await runNxCommandAsync(`run ${lib2}:add --name numpy`);
150+
151+
await runNxCommandAsync(`run ${app1}:build`);
152+
153+
expect(() =>
154+
checkFilesExist(
155+
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
156+
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
157+
)
158+
).not.toThrow();
159+
160+
expect(() => checkFilesExist(`.venv`, 'pyproject.toml')).not.toThrow();
161+
162+
expect(readFile('pyproject.toml')).toMatchSnapshot();
163+
}, 3000000);
164+
165+
it('should create one nx-python project, migrate to shared venv and add 3 levels', async () => {
166+
const app1 = 'app1';
167+
const lib1 = 'lib1';
168+
const lib2 = 'lib2';
169+
170+
ensureNxProject('@nxlv/python', 'dist/packages/nx-python');
171+
172+
const nxJson = readJson('nx.json');
173+
nxJson.plugins = ['@nxlv/python'];
174+
175+
updateFile('nx.json', JSON.stringify(nxJson, null, 4));
176+
177+
await runNxCommandAsync(
178+
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
179+
);
180+
181+
await runNxCommandAsync(`generate @nxlv/python:migrate-to-shared-venv`);
182+
183+
await runNxCommandAsync(
184+
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
185+
);
186+
187+
await runNxCommandAsync(
188+
`generate @nxlv/python:poetry-project ${lib2} --projectType "library" --packageName ${lib2} --description ${lib2}`
189+
);
190+
191+
await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);
192+
193+
await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);
194+
195+
await runNxCommandAsync(`run ${lib2}:add --name numpy`);
196+
197+
await runNxCommandAsync(`run ${app1}:build`);
198+
199+
expect(() =>
200+
checkFilesExist(
201+
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
202+
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
203+
)
204+
).not.toThrow();
205+
206+
expect(() => checkFilesExist(`.venv`, 'pyproject.toml')).not.toThrow();
207+
208+
expect(readFile('pyproject.toml')).toMatchSnapshot();
209+
}, 3000000);
210+
});
82211
});

packages/nx-python/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ nx generate @nxlv/python:poetry-project myproject
5757
| `--publishable` | `boolean` | Specifies if the project is publishable or not | `false` | `true` |
5858
| `--buildLockedVersions` | `boolean` | Use locked versions for build dependencies | `false` | `true` |
5959
| `--buildBundleLocalDependencies` | `boolean` | Bundle local dependencies | `false` | `true` |
60-
| `--linter` | `string` | Linter framework (`flake8` or `none`) | `false` | `flake8` |
60+
| `--linter` | `string` | Linter framework (`flake8`, `ruff` or `none`) | `false` | `flake8` |
6161
| `--unitTestRunner` | `string` | Unit Test Runner (`pytest` or `none`) | `false` | `pytest` |
6262
| `--unitTestHtmlReport` | `boolean` | Enable HTML Pytest Reports | `false` | `true` |
6363
| `--unitTestJUnitReport` | `boolean` | Enable JUnit Pytest Reports | `false` | `true` |

packages/nx-python/executors.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
"implementation": "./src/executors/run-commands/executor",
5151
"schema": "./src/executors/run-commands/schema.json",
5252
"description": "Python Venv Run Commands Executor"
53+
},
54+
"ruff-check": {
55+
"implementation": "./src/executors/ruff-check/executor",
56+
"schema": "./src/executors/ruff-check/schema.json",
57+
"description": "Ruff Check Executor"
5358
}
5459
}
5560
}

0 commit comments

Comments
 (0)