Skip to content

Commit

Permalink
feat(nx-python): add ruff check executor and project generator (#185)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
lucasvieirasilva authored Nov 10, 2023
1 parent 9d1ddf9 commit 9e631a2
Show file tree
Hide file tree
Showing 15 changed files with 1,071 additions and 21 deletions.
1 change: 0 additions & 1 deletion e2e/nx-python-e2e/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ export default {
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/e2e/nx-python-e2e',
};
83 changes: 83 additions & 0 deletions e2e/nx-python-e2e/tests/__snapshots__/nx-python.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`nx-python e2e shared virtual environment should create nx-python project with 3 levels with shared virtual environment 1`] = `
"[tool.nx]
autoActivate = true
[tool.poetry]
name = "@proj/source"
version = "1.0.0"
description = ""
authors = [ ]
license = "Proprietary"
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.9,<3.11"
[tool.poetry.dependencies.app1]
path = "apps/app1"
develop = true
[tool.poetry.dependencies.lib1]
path = "libs/lib1"
develop = true
[tool.poetry.dependencies.lib2]
path = "libs/lib2"
develop = true
[tool.poetry.group.dev.dependencies]
autopep8 = "2.0.2"
flake8 = "6.0.0"
pytest = "7.3.1"
pytest-sugar = "0.9.7"
pytest-cov = "4.1.0"
pytest-html = "3.2.0"
[build-system]
requires = [ "poetry-core==1.1.0" ]
build-backend = "poetry.core.masonry.api"
"
`;

exports[`nx-python e2e shared virtual environment should create one nx-python project, migrate to shared venv and add 3 levels 1`] = `
"[tool.nx]
autoActivate = true
[tool.poetry]
name = "@proj/source"
version = "1.0.0"
description = ""
authors = [ ]
license = "Proprietary"
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.9,<3.11"
[tool.poetry.dependencies.app1]
path = "apps/app1"
develop = true
[tool.poetry.dependencies.lib1]
path = "libs/lib1"
develop = true
[tool.poetry.dependencies.lib2]
path = "libs/lib2"
develop = true
[tool.poetry.group.dev.dependencies]
autopep8 = "2.0.2"
flake8 = "6.0.0"
pytest = "7.3.1"
pytest-sugar = "0.9.7"
pytest-cov = "4.1.0"
pytest-html = "3.2.0"
[build-system]
requires = [ "poetry-core==1.1.0" ]
build-backend = "poetry.core.masonry.api"
"
`;
139 changes: 134 additions & 5 deletions e2e/nx-python-e2e/tests/nx-python.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
runNxCommandAsync,
updateFile,
checkFilesExist,
readFile,
} from '@nx/plugin/testing';
describe('nx-python e2e', () => {
it('should create nx-python project', async () => {
Expand All @@ -17,11 +18,45 @@ describe('nx-python e2e', () => {
updateFile('nx.json', JSON.stringify(nxJson, null, 4));

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

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

await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);

await runNxCommandAsync(`run ${lib1}:add --name pendulum`);

await runNxCommandAsync(`run ${app1}:lint`);

await runNxCommandAsync(`run ${app1}:build`);

expect(() =>
checkFilesExist(
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
)
).not.toThrow();
}, 3000000);

it('should create nx-python project with ruff', async () => {
const app1 = 'app1';
const lib1 = 'lib1';
ensureNxProject('@nxlv/python', 'dist/packages/nx-python');

const nxJson = readJson('nx.json');
nxJson.plugins = ['@nxlv/python'];

updateFile('nx.json', JSON.stringify(nxJson, null, 4));

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1} --linter ruff`
);

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1} --linter ruff`
);

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

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

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

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

await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);
Expand All @@ -79,4 +114,98 @@ describe('nx-python e2e', () => {
)
).not.toThrow();
}, 3000000);

describe('shared virtual environment', () => {
it('should create nx-python project with 3 levels with shared virtual environment', async () => {
const app1 = 'app1';
const lib1 = 'lib1';
const lib2 = 'lib2';

ensureNxProject('@nxlv/python', 'dist/packages/nx-python');

const nxJson = readJson('nx.json');
nxJson.plugins = ['@nxlv/python'];

updateFile('nx.json', JSON.stringify(nxJson, null, 4));

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
);

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
);

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${lib2} --projectType "library" --packageName ${lib2} --description ${lib2}`
);

await runNxCommandAsync(`generate @nxlv/python:migrate-to-shared-venv`);

await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);

await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);

await runNxCommandAsync(`run ${lib2}:add --name numpy`);

await runNxCommandAsync(`run ${app1}:build`);

expect(() =>
checkFilesExist(
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
)
).not.toThrow();

expect(() => checkFilesExist(`.venv`, 'pyproject.toml')).not.toThrow();

expect(readFile('pyproject.toml')).toMatchSnapshot();
}, 3000000);

it('should create one nx-python project, migrate to shared venv and add 3 levels', async () => {
const app1 = 'app1';
const lib1 = 'lib1';
const lib2 = 'lib2';

ensureNxProject('@nxlv/python', 'dist/packages/nx-python');

const nxJson = readJson('nx.json');
nxJson.plugins = ['@nxlv/python'];

updateFile('nx.json', JSON.stringify(nxJson, null, 4));

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${app1} --projectType "application" --packageName ${app1} --description ${app1}`
);

await runNxCommandAsync(`generate @nxlv/python:migrate-to-shared-venv`);

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${lib1} --projectType "library" --packageName ${lib1} --description ${lib1}`
);

await runNxCommandAsync(
`generate @nxlv/python:poetry-project ${lib2} --projectType "library" --packageName ${lib2} --description ${lib2}`
);

await runNxCommandAsync(`run ${lib1}:add --name ${lib2} --local`);

await runNxCommandAsync(`run ${app1}:add --name ${lib1} --local`);

await runNxCommandAsync(`run ${lib2}:add --name numpy`);

await runNxCommandAsync(`run ${app1}:build`);

expect(() =>
checkFilesExist(
`apps/${app1}/dist/${app1.replace('-', '_')}-1.0.0-py3-none-any.whl`,
`apps/${app1}/dist/${app1}-1.0.0.tar.gz`
)
).not.toThrow();

expect(() => checkFilesExist(`.venv`, 'pyproject.toml')).not.toThrow();

expect(readFile('pyproject.toml')).toMatchSnapshot();
}, 3000000);
});
});
2 changes: 1 addition & 1 deletion packages/nx-python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ nx generate @nxlv/python:poetry-project myproject
| `--publishable` | `boolean` | Specifies if the project is publishable or not | `false` | `true` |
| `--buildLockedVersions` | `boolean` | Use locked versions for build dependencies | `false` | `true` |
| `--buildBundleLocalDependencies` | `boolean` | Bundle local dependencies | `false` | `true` |
| `--linter` | `string` | Linter framework (`flake8` or `none`) | `false` | `flake8` |
| `--linter` | `string` | Linter framework (`flake8`, `ruff` or `none`) | `false` | `flake8` |
| `--unitTestRunner` | `string` | Unit Test Runner (`pytest` or `none`) | `false` | `pytest` |
| `--unitTestHtmlReport` | `boolean` | Enable HTML Pytest Reports | `false` | `true` |
| `--unitTestJUnitReport` | `boolean` | Enable JUnit Pytest Reports | `false` | `true` |
Expand Down
5 changes: 5 additions & 0 deletions packages/nx-python/executors.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
"implementation": "./src/executors/run-commands/executor",
"schema": "./src/executors/run-commands/schema.json",
"description": "Python Venv Run Commands Executor"
},
"ruff-check": {
"implementation": "./src/executors/ruff-check/executor",
"schema": "./src/executors/ruff-check/schema.json",
"description": "Ruff Check Executor"
}
}
}
Loading

0 comments on commit 9e631a2

Please sign in to comment.