Skip to content

Commit

Permalink
Fix rye add and rye remove to create proper tool.rye section on -…
Browse files Browse the repository at this point in the history
…-dev and --exclude flags (#1256)

Hey!

This is to address issue #1249

Closes #1249

Looks like the `[tool.rye]` section in `pyproject.toml` is not created
properly if it was not already presented in the file.
This was due to the it not being created as a table.

Tested it like that:
- Have `pyproject.toml` without `[tool.rye]` table:
```
[project]
authors = [{ name = "xxx", email = "xxx@xxx.com" }]
name = "rye-test"
version = "0.1.0"
description = "wasm sample use py2wasm, rust, wasmer, gowasm, wasmedge"
readme = "README.md"
requires-python = ">=3.11.7"


[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```
- 
```
$ rye add --dev ipython
```
results in 
`pyproject.toml`
```
[project]
authors = [{ name = "xxx", email = "xxx@xxx.com" }]
name = "rye-test"
version = "0.1.0"
description = "wasm sample use py2wasm, rust, wasmer, gowasm, wasmedge"
readme = "README.md"
requires-python = ">=3.11.7"


[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.rye]
dev-dependencies = [
    "ipython>=8.26.0",
]
```

Before fix it was:
`pyproject.toml`
```
tool = { rye = { dev-dependencies = [
    "ipython>=8.26.0",
] } }
[project]
authors = [{ name = "xxx", email = "xxx@xxx.com" }]
name = "rye-test"
version = "0.1.0"
description = "wasm sample use py2wasm, rust, wasmer, gowasm, wasmedge"
readme = "README.md"
requires-python = ">=3.11.7"


[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

```
  • Loading branch information
flyaroundme authored Jul 21, 2024
1 parent 09b67c4 commit 57b7c08
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 11 deletions.
40 changes: 36 additions & 4 deletions rye/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@ pub struct PyProject {
doc: DocumentMut,
}

/// Returns an implicit table.
fn implicit() -> Item {
let mut table = Table::new();
table.set_implicit(true);
Item::Table(table)
}

impl PyProject {
/// Load a pyproject toml if explicitly given, else discover from current directory
///
Expand Down Expand Up @@ -912,8 +919,14 @@ impl PyProject {
) -> Result<(), Error> {
let dependencies = match kind {
DependencyKind::Normal => &mut self.doc["project"]["dependencies"],
DependencyKind::Dev => &mut self.doc["tool"]["rye"]["dev-dependencies"],
DependencyKind::Excluded => &mut self.doc["tool"]["rye"]["excluded-dependencies"],
DependencyKind::Dev => self
.obtain_tool_config_table()?
.entry("dev-dependencies")
.or_insert(Item::Value(Value::Array(Array::new()))),
DependencyKind::Excluded => self
.obtain_tool_config_table()?
.entry("excluded-dependencies")
.or_insert(Item::Value(Value::Array(Array::new()))),
DependencyKind::Optional(ref section) => {
// add this as a proper non-inline table if it's missing
let table = &mut self.doc["project"]["optional-dependencies"];
Expand Down Expand Up @@ -943,8 +956,14 @@ impl PyProject {
) -> Result<Option<Requirement>, Error> {
let dependencies = match kind {
DependencyKind::Normal => &mut self.doc["project"]["dependencies"],
DependencyKind::Dev => &mut self.doc["tool"]["rye"]["dev-dependencies"],
DependencyKind::Excluded => &mut self.doc["tool"]["rye"]["excluded-dependencies"],
DependencyKind::Dev => self
.obtain_tool_config_table()?
.entry("dev-dependencies")
.or_insert(Item::Value(Value::Array(Array::new()))),
DependencyKind::Excluded => self
.obtain_tool_config_table()?
.entry("excluded-dependencies")
.or_insert(Item::Value(Value::Array(Array::new()))),
DependencyKind::Optional(ref section) => {
&mut self.doc["project"]["optional-dependencies"][section as &str]
}
Expand Down Expand Up @@ -1047,6 +1066,19 @@ impl PyProject {
fs::write(&path, self.doc.to_string()).path_context(&path, "unable to write changes")?;
Ok(())
}

/// Gets or creates the [tool.rye] table in pyproject.toml
fn obtain_tool_config_table(&mut self) -> Result<&mut Table, Error> {
self.doc
.entry("tool")
.or_insert(implicit())
.as_table_mut()
.ok_or(anyhow!("[tool.rye] in pyproject.toml is malformed"))?
.entry("rye")
.or_insert(implicit())
.as_table_mut()
.ok_or(anyhow!("[tool.rye] in pyproject.toml is malformed"))
}
}

pub fn normalize_package_name(x: &str) -> String {
Expand Down
74 changes: 67 additions & 7 deletions rye/tests/test_add.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use insta::assert_snapshot;
use std::fs;

use toml_edit::{value, ArrayOfTables, Table};

use crate::common::{rye_cmd_snapshot, Space};
Expand Down Expand Up @@ -39,6 +39,14 @@ fn test_add_flask() {
+ my-project==0.1.0 (from file:[TEMP_PATH]/project)
+ werkzeug==3.0.1
"###);

assert_snapshot!(space.read_toml("pyproject.toml")["project"]["dependencies"], @r###"
[
"flask>=3.0.0",
"colorama>=0.4.6",
]
"###
);
}

#[test]
Expand Down Expand Up @@ -76,12 +84,13 @@ fn test_add_flask_dotenv() {
+ werkzeug==3.0.1
"###);

space.load_toml("pyproject.toml", |doc| {
let deps = doc["project"]["dependencies"].as_array().unwrap();
assert!(deps
.iter()
.any(|x| x.as_str() == Some("flask[dotenv]>=3.0.0")));
});
assert_snapshot!(space.read_toml("pyproject.toml")["project"]["dependencies"], @r###"
[
"flask[dotenv]>=3.0.0",
"colorama>=0.4.6",
]
"###
);
}

#[test]
Expand Down Expand Up @@ -120,6 +129,13 @@ fn test_add_from_find_links() {
+ my-project==0.1.0 (from file:[TEMP_PATH]/project)
+ tqdm==4.66.1
"###);

assert_snapshot!(space.read_toml("pyproject.toml")["tool"]["rye"], @r###"
managed = true
dev-dependencies = []
sources = [{ name = "extra", type = "find-links", url = "https://download.pytorch.org/whl/torch_stable.html" }]
"###
);
}

#[test]
Expand Down Expand Up @@ -208,3 +224,47 @@ fn test_add_explicit_version_or_url() {
+ pip==1.3.1 (from https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686)
"###);
}

#[test]
fn test_add_dev() {
let space = Space::new();
space.init("my-project");
// add colorama to ensure we have this as a dependency on all platforms
rye_cmd_snapshot!(space.rye_cmd().arg("add").arg("flask").arg("colorama").arg("--dev"), @r###"
success: true
exit_code: 0
----- stdout -----
Initializing new virtualenv in [TEMP_PATH]/project/.venv
Python version: cpython@3.12.3
Added flask>=3.0.0 as dev dependency
Added colorama>=0.4.6 as dev dependency
Reusing already existing virtualenv
Generating production lockfile: [TEMP_PATH]/project/requirements.lock
Generating dev lockfile: [TEMP_PATH]/project/requirements-dev.lock
Installing dependencies
Done!
----- stderr -----
Resolved 9 packages in [EXECUTION_TIME]
Prepared 9 packages in [EXECUTION_TIME]
Installed 9 packages in [EXECUTION_TIME]
+ blinker==1.7.0
+ click==8.1.7
+ colorama==0.4.6
+ flask==3.0.0
+ itsdangerous==2.1.2
+ jinja2==3.1.2
+ markupsafe==2.1.3
+ my-project==0.1.0 (from file:[TEMP_PATH]/project)
+ werkzeug==3.0.1
"###);

assert_snapshot!(space.read_toml("pyproject.toml")["tool"]["rye"], @r###"
managed = true
dev-dependencies = [
"flask>=3.0.0",
"colorama>=0.4.6",
]
"###
);
}

0 comments on commit 57b7c08

Please sign in to comment.