Skip to content

Commit

Permalink
fix(nx-python): handle "from" for packages in pyproject.toml during t…
Browse files Browse the repository at this point in the history
…he build process (#184)

* fix(nx-python): handle "from" for packages

Packages in the pyproject.yml can have a "from" property, which is used to accomodate the "src"
layout instead of the "flat" or "adhoc" layout. This change attempts to add prepend any
specified "from" directory to the package name.

* test(nx-python): cover the new branch statement for handling packages with "from"
  • Loading branch information
ap0nia authored Nov 10, 2023
1 parent d7347a7 commit 5d9a99f
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
126 changes: 126 additions & 0 deletions packages/nx-python/src/executors/build/executor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,132 @@ describe('Build Executor', () => {
expect(output.success).toBe(true);
});

it('should build python project with local dependencies that specify a "from" directory', async () => {
fsMock({
'apps/app/.venv/pyvenv.cfg': 'fake',
'apps/app/app/index.py': 'print("Hello from app")',
'apps/app/poetry.lock': dedent`
[[package]]
name = "dep1"
version = "1.0.0"
description = "Dep1"
category = "main"
optional = false
python-versions = "^3.8"
develop = false
[package.source]
type = "directory"
url = "../../libs/dep1"
`,
'apps/app/pyproject.toml': dedent`
[tool.poetry]
name = "app"
version = "1.0.0"
[[tool.poetry.packages]]
include = "app"
[tool.poetry.dependencies]
python = "^3.8"
dep1 = { path = "../../libs/dep1" }
`,

'libs/dep1/src/dep1/index.py': 'print("Hello from dep1")',
'libs/dep1/pyproject.toml': dedent`
[tool.poetry]
name = "dep1"
version = "1.0.0"
[[tool.poetry.packages]]
include = "dep1"
from = "src"
[tool.poetry.dependencies]
python = "^3.8"
`,
});

spawnSyncMock.mockImplementation((_, args, opts) => {
if (args[0] == 'build') {
spawnBuildMockImpl(opts);
} else if (args[0] == 'export' && opts.cwd === 'apps/app') {
writeFileSync(
join(buildPath, 'requirements.txt'),
dedent`
dep1 @ file://${process.cwd()}/libs/dep1
`
);
}
return { status: 0 };
});

const options: BuildExecutorSchema = {
ignorePaths: ['.venv', '.tox', 'tests/'],
silent: false,
outputPath: 'dist/apps/app',
keepBuildFolder: true,
devDependencies: false,
lockedVersions: true,
bundleLocalDependencies: true,
};

const output = await executor(options, {
cwd: '',
root: '.',
isVerbose: false,
projectName: 'app',
workspace: {
version: 2,
npmScope: 'nxlv',
projects: {
app: {
root: 'apps/app',
targets: {},
},
dep1: {
root: 'libs/dep1',
targets: {},
},
},
},
});

expect(checkPoetryExecutableMock).toHaveBeenCalled();
expect(activateVenvMock).toHaveBeenCalledWith('.');
expect(existsSync(buildPath)).toBeTruthy();
expect(existsSync(`${buildPath}/app`)).toBeTruthy();
expect(existsSync(`${buildPath}/dep1`)).toBeTruthy();
expect(existsSync(`${buildPath}/dist/app.fake`)).toBeTruthy();
expect(spawnSyncMock).toHaveBeenCalledWith('poetry', ['build'], {
cwd: buildPath,
shell: false,
stdio: 'inherit',
});

const projectTomlData = parse(
readFileSync(`${buildPath}/pyproject.toml`).toString('utf-8')
) as PyprojectToml;

expect(projectTomlData.tool.poetry.packages).toStrictEqual([
{
include: 'app',
},
{
include: 'dep1',
},
]);

expect(projectTomlData.tool.poetry.dependencies).toStrictEqual({
python: '^3.8',
});

expect(projectTomlData.tool.poetry.group.dev.dependencies).toStrictEqual(
{}
);

expect(output.success).toBe(true);
});

it('should build python project with local dependencies and extras', async () => {
fsMock({
'apps/app/.venv/pyvenv.cfg': 'fake',
Expand Down
2 changes: 1 addition & 1 deletion packages/nx-python/src/executors/build/resolvers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function includeDependencyPackage(
buildTomlData: PyprojectToml
) {
for (const pkg of tomlData.tool.poetry.packages) {
const pkgFolder = join(root, pkg.include);
const pkgFolder = join(root, pkg.from ?? '', pkg.include);
const buildPackageFolder = join(buildFolderPath, pkg.include);

copySync(pkgFolder, buildPackageFolder);
Expand Down
1 change: 1 addition & 0 deletions packages/nx-python/src/graph/dependency-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type PyprojectToml = {
version: string;
packages?: Array<{
include: string;
from?: string;
}>;
dependencies?: PyprojectTomlDependencies;
group?: {
Expand Down

0 comments on commit 5d9a99f

Please sign in to comment.