Skip to content

Commit

Permalink
fix: removed setuptools installation on the plugin (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
gemaxim authored Aug 2, 2024
1 parent 710311f commit fca32a6
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 49 deletions.
2 changes: 0 additions & 2 deletions lib/dependencies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export async function getDependencies(
options = {};
}
let command = options.command || 'python';
const pythonCmd = command;
const includeDevDeps = !!(options.dev || false);

// handle poetry projects by parsing manifest & lockfile and return a dep-graph
Expand All @@ -52,7 +51,6 @@ export async function getDependencies(
getMetaData(command, baseargs, root, targetFile),
inspectInstalledDeps(
command,
pythonCmd,
baseargs,
root,
targetFile,
Expand Down
40 changes: 0 additions & 40 deletions lib/dependencies/inspect-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { buildDepGraph, PartialDepTree } from './build-dep-graph';
import { FILENAMES } from '../types';
import { EmptyManifestError, RequiredPackagesMissingError } from '../errors';

const PYTHON_3_12_REGEX = new RegExp('^Python 3.12.*');
const UPDATED_SETUPTOOLS_VERSION = '68.0.0';

const returnedTargetFile = (originalTargetFile) => {
const basename = path.basename(originalTargetFile);

Expand Down Expand Up @@ -209,38 +206,8 @@ function dumpAllFilesInTempDir(tempDirName: string) {
});
}

async function updateSetuptools(
setuptoolsVersion: string,
dir: string,
pythonEnv,
command: string
) {
// For python 3.12, setuptools needs to be updated
// due to removal of some deprecated packages
// see: https://github.com/pypa/pip/pull/11997

const pythonVersion = await subProcess.execute(command, ['--version'], {
cwd: dir,
env: pythonEnv,
});

if (!PYTHON_3_12_REGEX.test(pythonVersion)) {
return;
}

await subProcess.execute(
`${command} -m pip install setuptools==${setuptoolsVersion}`,
[],
{
cwd: dir,
env: pythonEnv,
}
);
}

export async function inspectInstalledDeps(
command: string,
pythonCmd: string,
baseargs: string[],
root: string,
targetFile: string,
Expand All @@ -258,13 +225,6 @@ export async function inspectInstalledDeps(
try {
const pythonEnv = getPythonEnv(targetFile);

await updateSetuptools(
UPDATED_SETUPTOOLS_VERSION,
root,
pythonEnv,
pythonCmd
);

// See ../../pysrc/README.md
const output = await subProcess.execute(
command,
Expand Down
5 changes: 3 additions & 2 deletions pysrc/pip_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import utils
import requirements
import pipfile
import setup_file
import codecs
from operator import le, lt, gt, ge, eq, ne
from constants import DepsManager
Expand Down Expand Up @@ -135,6 +134,7 @@ def create_children_recursive(
def create_dir_as_root():
name, version = None, None
if os.path.basename(req_file_path) == 'setup.py':
import setup_file
with open(req_file_path, "r") as setup_py_file:
name, version = setup_file.parse_name_and_version(setup_py_file.read())

Expand Down Expand Up @@ -231,7 +231,7 @@ def matches_python_version(requirement):

# Gloss over the 'and' case and return true on the first matching python version

for sub_exp in re.split("\s*(?:and|or)\s*", cond_text):
for sub_exp in re.split(r"\s*(?:and|or)\s*", cond_text):
match = PYTHON_MARKER_REGEX.search(sub_exp)

if match:
Expand Down Expand Up @@ -329,6 +329,7 @@ def get_requirements_for_setuptools(requirements_file_path):
list[Requirement]: if requirements were found.
empty list: if no requirements were found in the requirements file.
"""
import setup_file
with open(requirements_file_path, 'r') as f:
setup_py_file_content = f.read()
requirements_data = setup_file.parse_requirements(setup_py_file_content)
Expand Down
220 changes: 215 additions & 5 deletions test/system/inspect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,221 @@ describe('inspect', () => {
compareTransitiveLines(result.dependencyGraph, expected);
}
);
it.each([
{
workspace: 'pip-app',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'jaraco.collections',
version: '5.0.1',
},
directDeps: ['irc'],
},
{
pkg: {
name: 'django-appconf',
version: '1.0.6',
},
directDeps: ['django-select2'],
},
],
},
{
workspace: 'pip-app-bom',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'markupsafe',
version: '2.1.5',
},
directDeps: ['jinja2'],
},
],
},
{
workspace: 'pip-app-deps-with-urls',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'markupsafe',
version: '2.1.5',
},
directDeps: ['jinja2'],
},
],
},
{
workspace: 'pip-app-without-markupsafe',
uninstallPackages: ['MarkupSafe'],
pluginOpts: { allowMissing: true },
expected: [
{
pkg: {
name: 'markupsafe',
version: '?',
},
directDeps: ['jinja2'],
},
],
},
{
workspace: 'pip-app-deps-not-installed',
uninstallPackages: [],
pluginOpts: { allowMissing: true },
expected: [
{
pkg: {
name: 's3transfer',
version: '0.10.2',
},
directDeps: ['awss'],
},
],
},
{
workspace: 'pip-app-trusted-host',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'markupsafe',
version: '2.1.5',
},
directDeps: ['jinja2'],
},
],
},
{
workspace: 'pip-app-deps-with-dashes',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'dj-database-url',
version: '0.4.2',
},
directDeps: ['dj-database-url'],
},
],
},
{
workspace: 'pip-app-with-openapi_spec_validator',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'jsonschema',
version: '4.23.0',
},
directDeps: ['openapi-spec-validator'],
},
],
},
{
workspace: 'pip-app-deps-conditional',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'posix-ipc',
version: '1.0.0',
},
directDeps: ['posix-ipc'],
},
],
},
{
workspace: 'pip-app-deps-editable',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'posix-ipc',
version: '1.0.0',
},
directDeps: ['posix-ipc'],
},
],
},
{
workspace: 'pip-app-deps-canonicalization',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'zope.interface',
version: '5.4.0',
},
directDeps: ['zope.interface'],
},
{
pkg: {
name: 'twisted',
version: '23.10.0',
},
directDeps: ['twisted'],
},
],
},
{
workspace: 'pip-app-optional-dependencies',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'opentelemetry-distro',
version: '0.35b0',
},
directDeps: ['opentelemetry-distro'],
},
],
},
{
workspace: 'pip-app-dev-alpha-beta-python-version',
uninstallPackages: [],
pluginOpts: {},
expected: [
{
pkg: {
name: 'requests',
version: '2.31.0',
},
directDeps: ['requests'],
},
],
},
])(
'should get a valid dependency graph for workspace = $workspace without setuptools previously installed',
async ({ workspace, uninstallPackages, pluginOpts, expected }) => {
testUtils.chdirWorkspaces(workspace);
testUtils.ensureVirtualenv(workspace);
tearDown = testUtils.activateVirtualenv(workspace);
testUtils.pipUninstall('setuptools');
testUtils.pipInstall();
if (uninstallPackages) {
uninstallPackages.forEach((pkg) => {
testUtils.pipUninstall(pkg);
});
}

const result = await inspect('.', FILENAMES.pip.manifest, pluginOpts);
compareTransitiveLines(result.dependencyGraph, expected);
}
);

it('should fail on missing transitive dependencies', async () => {
const workspace = 'pip-app';
Expand Down Expand Up @@ -439,7 +654,6 @@ describe('inspect', () => {
status: 0,
} as SpawnSyncReturns<Buffer>);
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce(
'{"name": "pipenv-app", "version": "0.0.0", "dependencies": {"jinja2": {"name": "jinja2", "version": "3.0.1", "dependencies": {"MarkupSafe": {"name": "markupsafe", "version": "2.0.1"}}}}, "packageFormatVersion": "pip:0.0.1"}'
);
Expand Down Expand Up @@ -563,7 +777,6 @@ describe('inspect', () => {
});

it('should return correct target file for setuptools project when relative path to setup lock file is passed', async () => {
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce(
'{"name": "pipenv-app", "version": "0.0.0", "dependencies": {"jinja2": {"name": "jinja2", "version": "3.0.1", "dependencies": {"MarkupSafe": {"name": "markupsafe", "version": "2.0.1"}}}}, "packageFormatVersion": "pip:0.0.1"}'
Expand All @@ -589,7 +802,6 @@ describe('inspect', () => {
status: 0,
} as SpawnSyncReturns<Buffer>);
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce(
fs.readFileSync(
'test/fixtures/dence-dep-graph/pip_resolve_output.json',
Expand Down Expand Up @@ -640,7 +852,6 @@ describe('inspect', () => {

describe('manifest file is empty', () => {
it('should throw EmptyManifestError', async () => {
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockRejectedValueOnce(
'No dependencies detected in manifest.'
Expand All @@ -655,7 +866,6 @@ describe('inspect', () => {

describe('required packages were not installed', () => {
it('should throw RequiredPackagesMissingError', async () => {
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockResolvedValueOnce('Python 3.9.5');
mockedExecute.mockRejectedValueOnce('Required packages missing');
const manifestFilePath = 'path/to/requirements.txt';
Expand Down

0 comments on commit fca32a6

Please sign in to comment.