-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(nx-python): add support for [email protected]
In the [email protected] the requirements.txt format has changed for local dependencies from `<packageName> @ file://<location>` to `-e file:///` re #206
- Loading branch information
1 parent
cc94090
commit 038b936
Showing
6 changed files
with
416 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,6 +312,338 @@ describe('Build Executor', () => { | |
expect(output.success).toBe(true); | ||
}); | ||
|
||
it('should build python project with local dependencies [email protected]', async () => { | ||
fsMock({ | ||
'apps/app/.venv/pyvenv.cfg': 'fake', | ||
'apps/app/app/index.py': 'print("Hello from app")', | ||
'apps/app/poetry.lock': dedent` | ||
[[package]] | ||
name = "click" | ||
version = "7.1.2" | ||
description = "Composable command line interface toolkit" | ||
category = "main" | ||
optional = false | ||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | ||
[[package]] | ||
name = "dep1" | ||
version = "1.0.0" | ||
description = "Dep1" | ||
category = "main" | ||
optional = false | ||
python-versions = "^3.8" | ||
develop = false | ||
[package.dependencies] | ||
numpy = "1.21.0" | ||
[package.source] | ||
type = "directory" | ||
url = "../../libs/dep1" | ||
[[package]] | ||
name = "numpy" | ||
version = "1.21.0" | ||
description = "NumPy is the fundamental package for array computing with Python." | ||
category = "main" | ||
optional = false | ||
python-versions = ">=3.7" | ||
`, | ||
|
||
'apps/app/pyproject.toml': dedent` | ||
[tool.poetry] | ||
name = "app" | ||
version = "1.0.0" | ||
[[tool.poetry.packages]] | ||
include = "app" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
click = "7.1.2" | ||
dep1 = { path = "../../libs/dep1" } | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
|
||
'libs/dep1/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" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
numpy = "1.21.0" | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
|
||
'libs/dep2/dep2/index.py': 'print("Hello from dep2")', | ||
'libs/dep2/pyproject.toml': dedent` | ||
[tool.poetry] | ||
name = "dep2" | ||
version = "1.0.0" | ||
[[tool.poetry.packages]] | ||
include = "dep2" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
}); | ||
|
||
vi.mocked(spawn.sync).mockImplementation((_, args, opts) => { | ||
if (args[0] == 'build') { | ||
spawnBuildMockImpl(opts); | ||
} else if (args[0] == 'export' && opts.cwd === 'apps/app') { | ||
writeFileSync( | ||
join(buildPath, 'requirements.txt'), | ||
dedent` | ||
click==7.1.2 | ||
-e file://${process.cwd()}/libs/dep1 | ||
numpy==1.21.0; python_version >= "3.8" and python_version < "4.0" | ||
`, | ||
); | ||
} | ||
return { | ||
status: 0, | ||
output: [''], | ||
pid: 0, | ||
signal: null, | ||
stderr: null, | ||
stdout: null, | ||
}; | ||
}); | ||
|
||
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, | ||
projects: { | ||
app: { | ||
root: 'apps/app', | ||
targets: {}, | ||
}, | ||
dep1: { | ||
root: 'libs/dep1', | ||
targets: {}, | ||
}, | ||
dep2: { | ||
root: 'libs/dep2', | ||
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(spawn.sync).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', | ||
click: '7.1.2', | ||
numpy: { | ||
version: '1.21.0', | ||
optional: false, | ||
markers: 'python_version >= "3.8" and python_version < "4.0"', | ||
}, | ||
}); | ||
expect(projectTomlData.tool.poetry.group.dev.dependencies).toStrictEqual( | ||
{}, | ||
); | ||
|
||
expect(output.success).toBe(true); | ||
}); | ||
|
||
it('should throw an exception when [email protected] local project is not a valid poetry project', async () => { | ||
fsMock({ | ||
'apps/app/.venv/pyvenv.cfg': 'fake', | ||
'apps/app/app/index.py': 'print("Hello from app")', | ||
'apps/app/poetry.lock': dedent` | ||
[[package]] | ||
name = "click" | ||
version = "7.1.2" | ||
description = "Composable command line interface toolkit" | ||
category = "main" | ||
optional = false | ||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | ||
[[package]] | ||
name = "dep1" | ||
version = "1.0.0" | ||
description = "Dep1" | ||
category = "main" | ||
optional = false | ||
python-versions = "^3.8" | ||
develop = false | ||
[package.dependencies] | ||
numpy = "1.21.0" | ||
[package.source] | ||
type = "directory" | ||
url = "../../libs/dep1" | ||
[[package]] | ||
name = "numpy" | ||
version = "1.21.0" | ||
description = "NumPy is the fundamental package for array computing with Python." | ||
category = "main" | ||
optional = false | ||
python-versions = ">=3.7" | ||
`, | ||
|
||
'apps/app/pyproject.toml': dedent` | ||
[tool.poetry] | ||
name = "app" | ||
version = "1.0.0" | ||
[[tool.poetry.packages]] | ||
include = "app" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
click = "7.1.2" | ||
dep1 = { path = "../../libs/dep1" } | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
|
||
'libs/dep1/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" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
numpy = "1.21.0" | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
|
||
'libs/dep2/dep2/index.py': 'print("Hello from dep2")', | ||
'libs/dep2/pyproject.toml': dedent` | ||
[tool.poetry] | ||
name = "dep2" | ||
version = "1.0.0" | ||
[[tool.poetry.packages]] | ||
include = "dep2" | ||
[tool.poetry.dependencies] | ||
python = "^3.8" | ||
[tool.poetry.group.dev.dependencies] | ||
pytest = "6.2.4" | ||
`, | ||
}); | ||
|
||
vi.mocked(spawn.sync).mockImplementation((_, args, opts) => { | ||
if (args[0] == 'build') { | ||
spawnBuildMockImpl(opts); | ||
} else if (args[0] == 'export' && opts.cwd === 'apps/app') { | ||
writeFileSync( | ||
join(buildPath, 'requirements.txt'), | ||
dedent` | ||
click==7.1.2 | ||
-e file://${process.cwd()}/libs/dep10 | ||
numpy==1.21.0; python_version >= "3.8" and python_version < "4.0" | ||
`, | ||
); | ||
} | ||
return { | ||
status: 0, | ||
output: [''], | ||
pid: 0, | ||
signal: null, | ||
stderr: null, | ||
stdout: null, | ||
}; | ||
}); | ||
|
||
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, | ||
projects: { | ||
app: { | ||
root: 'apps/app', | ||
targets: {}, | ||
}, | ||
dep1: { | ||
root: 'libs/dep1', | ||
targets: {}, | ||
}, | ||
dep2: { | ||
root: 'libs/dep2', | ||
targets: {}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
expect(output.success).toBe(false); | ||
}); | ||
|
||
it('should build python project with git dependency with revision and markers', async () => { | ||
fsMock({ | ||
'apps/app/.venv/pyvenv.cfg': 'fake', | ||
|
Oops, something went wrong.