Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add to_path() method to ExplicitEnvironmentSpec #781

Merged
merged 3 commits into from
Jul 20, 2024

Conversation

synapticarbors
Copy link
Contributor

Based on feedback from @baszalmstra on discord, I added a to_path method to the ExplicitEnvironmentSpec struct so that it could be dumped to file. This would be a first step in a pixi export PR to be submitted later.

This is my first rust-based PR to a project (although I've fooled around with it a bit on my own), so feedback is very welcome. For testing, ExplicitEnvironmentSpec and ExplicitEnvironmentEntry didn't implement PartialEq, so I just unrolled the content. This isn't ideal, but I didn't want to start poking around on the main struct definitions, but I can if that's preferred.

@synapticarbors synapticarbors changed the title Add to_path() method to ExplicitEnvironmentSpec feat: Add to_path() method to ExplicitEnvironmentSpec Jul 17, 2024
let mut out = String::new();
out.push_str("# This file may be used to create an environment using:\n");
out.push_str("# $ conda create --name <env> --file <this file>\n");
out.push_str(&format!("# platform: {plat}\n"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe only write this part if the platform is specified.

E.g.

Suggested change
out.push_str(&format!("# platform: {plat}\n"));
if let Some(platf) = &self.platform {
out.push_str(&format!("# platform: {plat}\n"));
}

Comment on lines 161 to 162
out.push_str("# This file may be used to create an environment using:\n");
out.push_str("# $ conda create --name <env> --file <this file>\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure if this part should be included by default. E.g. you could also use (micro)mamba for instance.

out.push_str(&format!("# platform: {plat}\n"));
out.push_str("@EXPLICIT\n");

for p in self.packages.iter() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for p in self.packages.iter() {
for p in &self.packages {

.collect::<Vec<_>>()
);

tmp_dir.close().unwrap()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need, this happens on drop.

Suggested change
tmp_dir.close().unwrap()

let tmp_dir = tempfile::tempdir().unwrap();
let file_path = tmp_dir.path().join("temp_explicit_env.txt");

assert_matches!(env.to_path(file_path.clone()), Ok(()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert_matches!(env.to_path(file_path.clone()), Ok(()));
env.to_path(file_path.clone()).expect("failed to write to path!")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized I missed this one suggestion in the tests. Do you want me to open another PR?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its fine, dont worry about it! 👍

Thanks again for contributing!

@baszalmstra
Copy link
Collaborator

Might also be interesting to implement this (still draft) spec completely: conda/ceps#79

@synapticarbors
Copy link
Contributor Author

@baszalmstra -- Thank you for the quick review. I'll make the code changes later today. I did have a few questions:

Might also be interesting to implement this (still draft) spec completely: conda/ceps#79

I read through the CEP and was trying to figure out what was needed to implement this completely. The only ideas that I had were arguments to the proposed to_string method like to_string(&self, include_platform: bool, comments: Option<String>). Those some arguments would be passed to the to_path method and then would be passed down to to_string. Let me know if that sounds reasonable or if you prefer a different way or signature.

The other requirements in the CEP were:

  • Topologically sorted url list: This seems outside of the scope of this struct as it has no information or knowledge about package inter-dependencies
  • Expanding paths and no environment variables: I wasn't sure about this as the Url type in rust seems to be "absolute" and will error on relative file paths when using from_path() for example.

Please let me know what in the CEP is missing in your mind and I'll try to implement it.

@baszalmstra
Copy link
Collaborator

I hadnt really checked what needed to happen to implement the CEP. 😅 I think most of it is related to how we parse the file not so much how we write it. In that sense I think your implementation already contains everything required.

I dont think it makes sense to add a comments argument to to_string. Users can just call the to_string method and prepend whatever if they really want to. The platform is also not really needed because you could just as well set it to None in the struct itself.

@synapticarbors
Copy link
Contributor Author

@baszalmstra -- So it sounds like what you think is the best approach is:

  1. Add to_string(). This should take the ExplicitEnvironmentSpec and return String containing:
"# platform: linux-64\n@EXPLICIT\nURL_1\nURL_2\n...."

if Some(plat), else:

"@EXPLICIT\nURL_1\nURL_2\n...."
  1. Modify my current to_path to use to_string(). I guess here maybe we'd still want comments: Option<String> to allow custom comments to be written to the file? Or just basically write the output of to_string() to file and leave it to the user to write their own custom function if they want any prepended comments.

@baszalmstra
Copy link
Collaborator

Indeed. And I would indeed forgo the comments for now. If people want that they can write their custom function.

@synapticarbors
Copy link
Contributor Author

@baszalmstra -- I made the requested changes. I just wanted to note that cargo clippy complains about the to_string method:

❯ cargo clippy
    Checking rattler_conda_types v0.26.1 (.../rattler/crates/rattler_conda_types)
warning: implementation of inherent method `to_string(&self) -> String` for type `explicit_environment_spec::ExplicitEnvironmentSpec`
   --> crates/rattler_conda_types/src/explicit_environment_spec.rs:156:5
    |
156 | /     pub fn to_string(&self) -> String {
157 | |         let mut s = String::new();
158 | |
159 | |         if let Some(plat) = &self.platform {
...   |
169 | |         s
170 | |     }
    | |_____^
    |
    = help: implement trait `Display` for type `explicit_environment_spec::ExplicitEnvironmentSpec` instead
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string

So maybe an alternative name? Ignore the warning? Or implement Display?. Also, I'm wondering if the to_path() is worth adding since it does so little.

@baszalmstra
Copy link
Collaborator

If you can think of a better name be my guest. I would also be fine with suppressing this particular lint.

Even though to_path does little its a nice little utlity function. 👍

@synapticarbors
Copy link
Contributor Author

The best alternatives I could think of at this point are to_spec_string() and render_spec_string(). You're right that implementing Display doesn't seem correct since what this is outputting is a rendering of the struct to the spec, rather than a general representation of the struct. If you like this alternative, I could also change to_path() -> to_spec_path()/render_spec_path().

@baszalmstra
Copy link
Collaborator

I think to_path is still fine and to_spec_string also sounds great!

@synapticarbors
Copy link
Contributor Author

@baszalmstra I've renamed the method so everything should be in order now.

@baszalmstra baszalmstra enabled auto-merge (squash) July 20, 2024 04:45
@baszalmstra baszalmstra merged commit 3a916ba into conda:main Jul 20, 2024
15 checks passed
@baszalmstra baszalmstra mentioned this pull request Jul 20, 2024
baszalmstra added a commit that referenced this pull request Jul 23, 2024
## 🤖 New release
* `rattler_conda_types`: 0.26.1 -> 0.26.2
* `rattler`: 0.27.0 -> 0.27.1
* `rattler_cache`: 0.1.2 -> 0.1.3
* `rattler_package_streaming`: 0.21.5 -> 0.21.6
* `rattler_shell`: 0.21.1 -> 0.21.2
* `rattler_lock`: 0.22.14 -> 0.22.15
* `rattler_repodata_gateway`: 0.21.1 -> 0.21.2
* `rattler_solve`: 0.25.1 -> 0.25.2
* `rattler_virtual_packages`: 0.19.18 -> 0.19.19
* `rattler_index`: 0.19.19 -> 0.19.20

<details><summary><i><b>Changelog</b></i></summary><p>

## `rattler_conda_types`
<blockquote>

##
[0.26.2](rattler_conda_types-v0.26.1...rattler_conda_types-v0.26.2)
- 2024-07-23

### Added
- `environment.yaml` type
([#786](#786))
- Add to_path() method to ExplicitEnvironmentSpec
([#781](#781))
- expose `HasPrefixEntry` for public use
([#784](#784))
</blockquote>

## `rattler`
<blockquote>

##
[0.27.1](rattler-v0.27.0...rattler-v0.27.1)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_cache`
<blockquote>

##
[0.1.3](rattler_cache-v0.1.2...rattler_cache-v0.1.3)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_package_streaming`
<blockquote>

##
[0.21.6](rattler_package_streaming-v0.21.5...rattler_package_streaming-v0.21.6)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_shell`
<blockquote>

##
[0.21.2](rattler_shell-v0.21.1...rattler_shell-v0.21.2)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_lock`
<blockquote>

##
[0.22.15](rattler_lock-v0.22.14...rattler_lock-v0.22.15)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_repodata_gateway`
<blockquote>

##
[0.21.2](rattler_repodata_gateway-v0.21.1...rattler_repodata_gateway-v0.21.2)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_solve`
<blockquote>

##
[0.25.2](rattler_solve-v0.25.1...rattler_solve-v0.25.2)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_virtual_packages`
<blockquote>

##
[0.19.19](rattler_virtual_packages-v0.19.18...rattler_virtual_packages-v0.19.19)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_index`
<blockquote>

##
[0.19.20](rattler_index-v0.19.19...rattler_index-v0.19.20)
- 2024-07-23

### Other
- updated the following local packages: rattler_conda_types
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/MarcoIeni/release-plz/).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants