Skip to content

Commit 33a4698

Browse files
author
Gaurav Sheni
authored
Support dependencies in pyproject.toml (#13)
* Update minimum_dependency_generator.py * support pyproject toml * fix integration test * fix integration test * fix filename * fix pip * fix output * clean list 1 * better unit test * better name * lint
1 parent f705cb9 commit 33a4698

File tree

8 files changed

+151
-45
lines changed

8 files changed

+151
-45
lines changed

.github/workflows/integration_tests.yml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,29 +97,59 @@ jobs:
9797
uses: ./
9898
with:
9999
paths: 'setup_example.cfg'
100-
options: 'install_requires setup_requires'
100+
options: 'install_requires'
101101
extras_require: 'dev test'
102102
output_filepath: 'output_filepath.txt'
103-
- name: Save the output minimum install_requires, setup_requires and dev, test requirements
103+
- name: Save the output minimum install_requires and dev, test requirements
104104
run: printf "${{ steps.min_dep_gen_6.outputs.min_reqs }}" >> generated-min-setupcfg-multiple-reqs.txt
105105
- name: Verify output
106106
run: |
107+
107108
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "scipy==1.3.3"
108109
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "pandas==1.3.0"
109110
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "featuretools==1.5.0"
110111
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "woodwork==0.8.1"
111-
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "setuptools==47"
112-
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "wheel==0.37.1"
113112
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "autopep8==1.6.0"
114113
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "pip==22.0.2"
114+
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "wheel==0.37.1"
115115
echo "${{ steps.min_dep_gen_6.outputs.min_reqs }}" | grep -c "pytest==5.2.0"
116116
- name: Check file existence
117-
id: check_files
117+
id: check_files_1
118118
uses: andstor/file-existence-action@v1
119119
with:
120120
files: "output_filepath.txt"
121121
- name: File exists
122-
if: steps.check_files.outputs.files_exists == 'false'
122+
if: steps.check_files_1.outputs.files_exists == 'false'
123123
run: exit 1
124124
- name: Print text file
125125
run: cat output_filepath.txt
126+
- name: Run Minimum Dependency Generator with pyproject.toml
127+
id: min_dep_gen_7
128+
uses: ./
129+
with:
130+
paths: 'pyproject_example.toml'
131+
options: 'dependencies'
132+
extras_require: 'dev test'
133+
output_filepath: 'output_filepath_toml.txt'
134+
- name: Save the output minimum install_requires and dev, test requirements
135+
run: printf "${{ steps.min_dep_gen_7.outputs.min_reqs }}" >> generated-min-pyproject-multiple-reqs.txt
136+
- name: Verify output
137+
run: |
138+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "scipy==1.3.3"
139+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "pandas==1.3.0"
140+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "featuretools==1.5.0"
141+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "woodwork==0.8.1"
142+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "wheel==0.37.1"
143+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "autopep8==1.6.0"
144+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "pip==22.0.2"
145+
echo "${{ steps.min_dep_gen_7.outputs.min_reqs }}" | grep -c "pytest==5.2.0"
146+
- name: Check file existence
147+
id: check_files_2
148+
uses: andstor/file-existence-action@v1
149+
with:
150+
files: "output_filepath_toml.txt"
151+
- name: Print text file
152+
run: cat output_filepath_toml.txt
153+
- name: File exists
154+
if: steps.check_files_2.outputs.files_exists == 'false'
155+
run: exit 1

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ steps:
3939
uses: alteryx/[email protected]
4040
with:
4141
paths: 'setup.cfg'
42-
options: 'install_requires setup_requires'
42+
options: 'install_requires'
4343
extras_require: 'dev test'
4444
output_filepath: 'generated-min-reqs.txt'
4545
```

minimum_dependency_generator/minimum_dependency_generator.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
from collections import defaultdict
44

5+
import tomli
56
from packaging.requirements import Requirement
67
from packaging.specifiers import Specifier
78

@@ -50,7 +51,7 @@ def determine_package_name(package):
5051
return name
5152

5253

53-
def clean_cfg_section(section):
54+
def clean_section(section):
5455
section = section.split('\n')
5556
section = [x for x in section if len(x) > 1]
5657
return section
@@ -112,10 +113,26 @@ def parse_setup_cfg(paths, options, extras_require):
112113
extras_require = clean_list_length_one(extras_require)
113114
if options and len(options) > 0:
114115
for option in options:
115-
requirements += clean_cfg_section(config['options'][option])
116+
requirements += clean_section(config['options'][option])
116117
if extras_require and len(extras_require) > 0:
117118
for extra in extras_require:
118-
requirements += clean_cfg_section(config['options.extras_require'][extra])
119+
requirements += clean_section(config['options.extras_require'][extra])
120+
return requirements
121+
122+
123+
def parse_pyproject_toml(paths, options, extras_require):
124+
requirements = []
125+
with open(paths[0], "rb") as f:
126+
toml_dict = tomli.load(f)
127+
128+
options = clean_list_length_one(options)
129+
extras_require = clean_list_length_one(extras_require)
130+
if options and len(options) > 0:
131+
for option in options:
132+
requirements += toml_dict['project'][option]
133+
if extras_require and len(extras_require) > 0:
134+
for extra in extras_require:
135+
requirements += toml_dict['project']['optional-dependencies'][extra]
119136
return requirements
120137

121138

@@ -125,6 +142,8 @@ def generate_min_requirements(paths, options=None, extras_require=None, output_f
125142

126143
if len(paths) == 1 and paths[0].endswith('.cfg') and os.path.basename(paths[0]).startswith('setup'):
127144
requirements = parse_setup_cfg(paths, options, extras_require)
145+
elif len(paths) == 1 and paths[0].endswith('.toml') and os.path.basename(paths[0]).startswith('pyproject'):
146+
requirements = parse_pyproject_toml(paths, options, extras_require)
128147
else:
129148
requirements = parse_requirements_text_file(paths)
130149

minimum_dependency_generator/tests/conftest.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,51 @@ def setuptools():
4444
@pytest.fixture(scope="session", autouse=True)
4545
def p_ytest_dep():
4646
return "pytest >= 5.2.0"
47+
48+
49+
@pytest.fixture(scope="session", autouse=True)
50+
def cfg_str(dask_dep, pandas_dep, woodwork_dep, numpy_lower, ploty_dep, numpy_upper, p_ytest_dep):
51+
setup_cfg_str = f'''\
52+
[metadata]
53+
name = example_package
54+
55+
[options]
56+
install_requires =
57+
{dask_dep}
58+
{pandas_dep}
59+
{woodwork_dep}
60+
{numpy_lower}
61+
62+
[options.extras_require] =
63+
dev =
64+
{ploty_dep}
65+
{numpy_upper}
66+
test =
67+
{p_ytest_dep}
68+
'''
69+
return setup_cfg_str
70+
71+
72+
@pytest.fixture(scope="session", autouse=True)
73+
def toml_cfg(pandas_dep, woodwork_dep, numpy_upper, ploty_dep, p_ytest_dep, dask_dep, numpy_lower):
74+
pyproject_str = f'''\
75+
[project]
76+
name = "example_package"
77+
requires-python = ">=3.7,<3.10"
78+
dependencies = [
79+
"{pandas_dep}",
80+
"{woodwork_dep}",
81+
"{numpy_upper}",
82+
]
83+
84+
[project.optional-dependencies]
85+
test = [
86+
"{ploty_dep}",
87+
"{p_ytest_dep}",
88+
]
89+
dev = [
90+
"{dask_dep}",
91+
"{numpy_lower}",
92+
]
93+
'''
94+
return pyproject_str

minimum_dependency_generator/tests/test_setup_cfg.py renamed to minimum_dependency_generator/tests/test_cfg_toml.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
11
import tempfile
22

3+
import pytest
4+
35
from ..minimum_dependency_generator import generate_min_requirements
46

57

6-
def test_with_setup_cfg(
7-
dask_dep, pandas_dep, woodwork_dep, numpy_lower, ploty_dep, numpy_upper, setuptools, p_ytest_dep
8+
@pytest.mark.parametrize(
9+
"file_prefix,file_extension,options",
10+
[('setup', 'cfg', 'install_requires'), ('pyproject', 'toml', 'dependencies')],
11+
)
12+
def test_with_toml_cfg(
13+
file_prefix, file_extension, options, cfg_str, toml_cfg
814
):
9-
setup_cfg_str = f'''\
10-
[metadata]
11-
name = example_package
12-
13-
[options]
14-
install_requires =
15-
{dask_dep}
16-
{pandas_dep}
17-
{woodwork_dep}
18-
{numpy_lower}
19-
setup_requires =
20-
{setuptools}
21-
22-
[options.extras_require] =
23-
koalas =
24-
{ploty_dep}
25-
{numpy_upper}
26-
test =
27-
{p_ytest_dep}
28-
'''
15+
file_str = toml_cfg
16+
if file_prefix == 'setup':
17+
file_str = cfg_str
2918
with tempfile.NamedTemporaryFile(
30-
mode="w", suffix=".cfg", prefix="setup"
31-
) as setup_cfg_f:
32-
setup_cfg_f.write(setup_cfg_str)
33-
setup_cfg_f.flush()
19+
mode="w", suffix="." + file_extension, prefix=file_prefix
20+
) as pyproject_file:
21+
pyproject_file.write(file_str)
22+
pyproject_file.flush()
3423

35-
paths = [setup_cfg_f.name]
36-
options = ['install_requires setup_requires']
37-
extra_requires = ['koalas test']
24+
paths = [pyproject_file.name]
25+
options = [options]
26+
extra_requires = ['test dev']
3827
min_requirements = generate_min_requirements(paths, options, extra_requires)
28+
verify_min_reqs_cfg_toml(min_requirements)
29+
30+
31+
def verify_min_reqs_cfg_toml(min_requirements):
3932
assert '-r' not in min_requirements
4033
assert '.txt' not in min_requirements
4134
assert 'core-requirements.txt' not in min_requirements
@@ -48,7 +41,6 @@ def test_with_setup_cfg(
4841
"pandas==0.24.1",
4942
"plotly==4.14.0",
5043
"pytest==5.2.0",
51-
"setuptools==47",
5244
"woodwork==0.0.11",
5345
]
5446
expected_min_reqs = sorted(expected_min_reqs)

pyproject_example.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[project]
2+
name = "my_custom_pkg"
3+
dependencies = [
4+
"scipy>=1.3.3",
5+
"pandas>=1.3.0",
6+
"featuretools>=1.5.0,<2.0.0",
7+
"woodwork>=0.8.1",
8+
]
9+
10+
[project.optional-dependencies]
11+
dev = [
12+
"autopep8>=1.6.0",
13+
"pandas<1.4.0",
14+
]
15+
16+
test = [
17+
"pip>=22.0.2",
18+
"wheel>=0.37.1",
19+
"pytest>=5.2.0",
20+
]

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
packaging>=20.9
22
requests>=2.25.1
3-
wheel>=0.36.2
3+
wheel>=0.36.2
4+
tomli>=2.0.1

setup_example.cfg

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ install_requires =
77
pandas >= 1.3.0
88
featuretools >= 1.5.0, <2.0.0
99
woodwork >= 0.8.1
10-
setup_requires =
11-
setuptools >= 47
12-
wheel
13-
python_requires = >= 3.8, <4
1410

1511
[options.extras_require]
1612
dev =

0 commit comments

Comments
 (0)