@@ -366,6 +366,24 @@ fn build_latest_dev_dependencies(project_info: &ProjectInfo) -> Result<String> {
366366 }
367367 }
368368
369+ if let Some ( extras) = & project_info. extra_python_dev_packages {
370+ for extra in extras {
371+ if let Ok ( p) = ExtraPythonPackageVersion :: new ( extra. to_lowercase ( ) . clone ( ) ) {
372+ if let ProjectManager :: Poetry = project_info. project_manager {
373+ version_string. push_str ( & format ! ( "{} = \" {}\" \n " , p. package, p. version) ) ;
374+ } else {
375+ version_string. push_str ( & format ! ( "{}=={}\n " , p. package, p. version) ) ;
376+ }
377+ } else {
378+ let error_message = format ! (
379+ "Error retrieving latest python package version for {}, skipping." ,
380+ extra
381+ ) ;
382+ println ! ( "\n {}" , error_message. yellow( ) ) ;
383+ }
384+ }
385+ }
386+
369387 match project_info. project_manager {
370388 ProjectManager :: Poetry => Ok ( version_string. trim ( ) . to_string ( ) ) ,
371389 ProjectManager :: Uv => {
@@ -1156,6 +1174,7 @@ mod tests {
11561174 include_docs : false ,
11571175 docs_info : None ,
11581176 extra_python_packages : None ,
1177+ extra_python_dev_packages : None ,
11591178 download_latest_packages : false ,
11601179 project_root_dir : Some ( tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ) ,
11611180 }
@@ -1279,6 +1298,26 @@ mod tests {
12791298 assert_yaml_snapshot ! ( content) ;
12801299 }
12811300
1301+ #[ test]
1302+ fn test_save_poetry_pyproject_toml_with_python_dev_extras ( ) {
1303+ let mut project_info = project_info_dummy ( ) ;
1304+ project_info. project_manager = ProjectManager :: Poetry ;
1305+ project_info. extra_python_dev_packages = Some ( vec ! [
1306+ 1307+ 1308+ ] ) ;
1309+ let base = project_info. base_dir ( ) ;
1310+ create_dir_all ( & base) . unwrap ( ) ;
1311+ let expected_file = base. join ( "pyproject.toml" ) ;
1312+ save_pyproject_toml_file ( & project_info) . unwrap ( ) ;
1313+
1314+ assert ! ( expected_file. is_file( ) ) ;
1315+
1316+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1317+
1318+ assert_yaml_snapshot ! ( content) ;
1319+ }
1320+
12821321 #[ test]
12831322 fn test_save_poetry_pyproject_toml_file_apache_application ( ) {
12841323 let mut project_info = project_info_dummy ( ) ;
@@ -1393,6 +1432,26 @@ mod tests {
13931432 assert_yaml_snapshot ! ( content) ;
13941433 }
13951434
1435+ #[ test]
1436+ fn test_save_pyo3_pyproject_toml_with_python_dev_extras ( ) {
1437+ let mut project_info = project_info_dummy ( ) ;
1438+ project_info. project_manager = ProjectManager :: Maturin ;
1439+ project_info. extra_python_dev_packages = Some ( vec ! [
1440+ 1441+ 1442+ ] ) ;
1443+ let base = project_info. base_dir ( ) ;
1444+ create_dir_all ( & base) . unwrap ( ) ;
1445+ let expected_file = base. join ( "pyproject.toml" ) ;
1446+ save_pyproject_toml_file ( & project_info) . unwrap ( ) ;
1447+
1448+ assert ! ( expected_file. is_file( ) ) ;
1449+
1450+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1451+
1452+ assert_yaml_snapshot ! ( content) ;
1453+ }
1454+
13961455 #[ test]
13971456 fn test_save_pyproject_toml_file_apache_pyo3 ( ) {
13981457 let mut project_info = project_info_dummy ( ) ;
@@ -1489,6 +1548,26 @@ mod tests {
14891548 assert_yaml_snapshot ! ( content) ;
14901549 }
14911550
1551+ #[ test]
1552+ fn test_save_setuptools_pyproject_toml_with_python_dev_extras ( ) {
1553+ let mut project_info = project_info_dummy ( ) ;
1554+ project_info. project_manager = ProjectManager :: Setuptools ;
1555+ project_info. extra_python_dev_packages = Some ( vec ! [
1556+ 1557+ 1558+ ] ) ;
1559+ let base = project_info. base_dir ( ) ;
1560+ create_dir_all ( & base) . unwrap ( ) ;
1561+ let expected_file = base. join ( "pyproject.toml" ) ;
1562+ save_pyproject_toml_file ( & project_info) . unwrap ( ) ;
1563+
1564+ assert ! ( expected_file. is_file( ) ) ;
1565+
1566+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1567+
1568+ assert_yaml_snapshot ! ( content) ;
1569+ }
1570+
14921571 #[ test]
14931572 fn test_save_setuptools_pyproject_toml_file_apache_application ( ) {
14941573 let mut project_info = project_info_dummy ( ) ;
@@ -1603,6 +1682,26 @@ mod tests {
16031682 assert_yaml_snapshot ! ( content) ;
16041683 }
16051684
1685+ #[ test]
1686+ fn test_save_uv_pyproject_toml_with_python_dev_extras ( ) {
1687+ let mut project_info = project_info_dummy ( ) ;
1688+ project_info. project_manager = ProjectManager :: Uv ;
1689+ project_info. extra_python_dev_packages = Some ( vec ! [
1690+ 1691+ 1692+ ] ) ;
1693+ let base = project_info. base_dir ( ) ;
1694+ create_dir_all ( & base) . unwrap ( ) ;
1695+ let expected_file = base. join ( "pyproject.toml" ) ;
1696+ save_pyproject_toml_file ( & project_info) . unwrap ( ) ;
1697+
1698+ assert ! ( expected_file. is_file( ) ) ;
1699+
1700+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1701+
1702+ assert_yaml_snapshot ! ( content) ;
1703+ }
1704+
16061705 #[ test]
16071706 fn test_save_uv_pyproject_toml_file_apache_application ( ) {
16081707 let mut project_info = project_info_dummy ( ) ;
@@ -1717,6 +1816,26 @@ mod tests {
17171816 assert_yaml_snapshot ! ( content) ;
17181817 }
17191818
1819+ #[ test]
1820+ fn test_save_pixi_pyproject_toml_with_python_dev_extras ( ) {
1821+ let mut project_info = project_info_dummy ( ) ;
1822+ project_info. project_manager = ProjectManager :: Pixi ;
1823+ project_info. extra_python_dev_packages = Some ( vec ! [
1824+ 1825+ 1826+ ] ) ;
1827+ let base = project_info. base_dir ( ) ;
1828+ create_dir_all ( & base) . unwrap ( ) ;
1829+ let expected_file = base. join ( "pyproject.toml" ) ;
1830+ save_pyproject_toml_file ( & project_info) . unwrap ( ) ;
1831+
1832+ assert ! ( expected_file. is_file( ) ) ;
1833+
1834+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1835+
1836+ assert_yaml_snapshot ! ( content) ;
1837+ }
1838+
17201839 #[ test]
17211840 fn test_save_pixi_pyproject_toml_file_apache_application ( ) {
17221841 let mut project_info = project_info_dummy ( ) ;
@@ -1821,6 +1940,26 @@ mod tests {
18211940 assert_yaml_snapshot ! ( content) ;
18221941 }
18231942
1943+ #[ test]
1944+ fn test_save_pyo3_dev_requirements_extras_file ( ) {
1945+ let mut project_info = project_info_dummy ( ) ;
1946+ project_info. project_manager = ProjectManager :: Maturin ;
1947+ project_info. extra_python_dev_packages = Some ( vec ! [
1948+ 1949+ 1950+ ] ) ;
1951+ let base = project_info. base_dir ( ) ;
1952+ create_dir_all ( & base) . unwrap ( ) ;
1953+ let expected_file = base. join ( "requirements-dev.txt" ) ;
1954+ save_dev_requirements ( & project_info) . unwrap ( ) ;
1955+
1956+ assert ! ( expected_file. is_file( ) ) ;
1957+
1958+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
1959+
1960+ assert_yaml_snapshot ! ( content) ;
1961+ }
1962+
18241963 #[ test]
18251964 fn test_save_setuptools_dev_requirements_application_file ( ) {
18261965 let mut project_info = project_info_dummy ( ) ;
@@ -1855,6 +1994,26 @@ mod tests {
18551994 assert_yaml_snapshot ! ( content) ;
18561995 }
18571996
1997+ #[ test]
1998+ fn test_save_setuptools_dev_requirements_extras_file ( ) {
1999+ let mut project_info = project_info_dummy ( ) ;
2000+ project_info. project_manager = ProjectManager :: Setuptools ;
2001+ project_info. extra_python_dev_packages = Some ( vec ! [
2002+ 2003+ 2004+ ] ) ;
2005+ let base = project_info. base_dir ( ) ;
2006+ create_dir_all ( & base) . unwrap ( ) ;
2007+ let expected_file = base. join ( "requirements-dev.txt" ) ;
2008+ save_dev_requirements ( & project_info) . unwrap ( ) ;
2009+
2010+ assert ! ( expected_file. is_file( ) ) ;
2011+
2012+ let content = std:: fs:: read_to_string ( expected_file) . unwrap ( ) ;
2013+
2014+ assert_yaml_snapshot ! ( content) ;
2015+ }
2016+
18582017 #[ test]
18592018 fn test_save_mkdocs_yaml ( ) {
18602019 let mut project_info = project_info_dummy ( ) ;
0 commit comments