Skip to content

Commit

Permalink
feat: remove hash_input from rendered recipe (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
baszalmstra authored May 28, 2024
1 parent ef78781 commit a3bb077
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 68 deletions.
58 changes: 36 additions & 22 deletions src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,42 @@ pub struct HashInfo {
/// The hash (first 7 letters of the sha1sum)
pub hash: String,

/// The exact input that was used to compute the hash
pub hash_input: String,

/// The hash prefix (e.g. `py38` or `np111`)
pub hash_prefix: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub prefix: String,
}

/// Represents the input to compute the hash
pub struct HashInput(String);

impl HashInput {
/// Create a new hash input from a variant
pub fn from_variant(variant: &BTreeMap<String, String>) -> Self {
let mut buf = Vec::new();
let mut ser = serde_json::Serializer::with_formatter(&mut buf, PythonFormatter {});

// BTree has sorted keys, which is important for hashing
variant
.serialize(&mut ser)
.expect("Failed to serialize input");

Self(String::from_utf8(buf).expect("Failed to convert to string"))
}

/// Get the hash input as a string
pub fn as_str(&self) -> &str {
&self.0
}

/// Returns the hash input as bytes
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}

impl std::fmt::Display for HashInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}h{}", self.hash_prefix, self.hash)
write!(f, "{}h{}", self.prefix, self.hash)
}
}

Expand Down Expand Up @@ -136,34 +162,22 @@ impl HashInfo {
result
}

fn hash_variant(variant: &BTreeMap<String, String>) -> (String, String) {
let mut buf = Vec::new();
let mut ser = serde_json::Serializer::with_formatter(&mut buf, PythonFormatter {});

// BTree has sorted keys, which is important for hashing
variant
.serialize(&mut ser)
.expect("Failed to serialize input");

let string = String::from_utf8(buf).expect("Failed to convert to string");

fn hash_from_input(hash_input: &HashInput) -> String {
let mut hasher = Sha1::new();
hasher.update(string.as_bytes());
hasher.update(hash_input.as_bytes());
let result = hasher.finalize();

const HASH_LENGTH: usize = 7;

let res = format!("{:x}", result);
(res[..HASH_LENGTH].to_string(), string)
res[..HASH_LENGTH].to_string()
}

/// Compute the build string for a given variant
pub fn from_variant(variant: &BTreeMap<String, String>, noarch: &NoArchType) -> Self {
let (hash, hash_input) = Self::hash_variant(variant);
Self {
hash,
hash_input,
hash_prefix: Self::hash_prefix(variant, noarch),
hash: Self::hash_from_input(&HashInput::from_variant(variant)),
prefix: Self::hash_prefix(variant, noarch),
}
}
}
Expand Down
20 changes: 8 additions & 12 deletions src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ mod tests {

#[cfg(test)]
mod test {
use rstest::*;
use std::str::FromStr;

use chrono::TimeZone;
Expand Down Expand Up @@ -716,21 +717,16 @@ mod test {
assert_eq!("pip", parsed_yaml3.specs[0].render(false));
}

#[test]
fn read_full_recipe() {
#[rstest]
#[case::rich("rich_recipe.yaml")]
#[case::curl("curl_recipe.yaml")]
fn read_full_recipe(#[case] recipe_path: String) {
let test_data_dir =
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("test-data/rendered_recipes");
let recipe_1 = test_data_dir.join("rich_recipe.yaml");

let recipe_1 = std::fs::read_to_string(recipe_1).unwrap();

let output_rich: Output = serde_yaml::from_str(&recipe_1).unwrap();
assert_yaml_snapshot!(output_rich);

let recipe_2 = test_data_dir.join("curl_recipe.yaml");
let recipe_2 = std::fs::read_to_string(recipe_2).unwrap();
let output_curl: Output = serde_yaml::from_str(&recipe_2).unwrap();
assert_yaml_snapshot!(output_curl);
let recipe = std::fs::read_to_string(test_data_dir.join(&recipe_path)).unwrap();
let output: Output = serde_yaml::from_str(&recipe).unwrap();
assert_yaml_snapshot!(recipe_path, output);
}

#[test]
Expand Down
42 changes: 24 additions & 18 deletions src/packaging/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ use rattler_digest::{compute_bytes_digest, compute_file_digest};
use std::{
borrow::Cow,
collections::HashSet,
io::Write,
ops::Deref,
path::{Path, PathBuf},
};

use rattler_conda_types::package::PackageFile;
#[cfg(target_family = "unix")]
use std::os::unix::prelude::OsStrExt;

use crate::hash::HashInput;
use crate::{metadata::Output, recipe::parser::PrefixDetection};

use super::{PackagingError, TempFiles};
Expand Down Expand Up @@ -202,6 +203,11 @@ impl Output {
}
}

/// Returns the contents of the `hash_input.json` file.
pub fn hash_input(&self) -> HashInput {
HashInput::from_variant(&self.build_configuration.variant)
}

/// Create the about.json file for the given output.
pub fn about_json(&self) -> AboutJson {
let recipe = &self.recipe;
Expand Down Expand Up @@ -416,36 +422,36 @@ impl Output {
temp_files: &TempFiles,
) -> Result<HashSet<PathBuf>, PackagingError> {
let mut new_files = HashSet::new();
let root_dir = temp_files.temp_dir.path();
let info_folder = temp_files.temp_dir.path().join("info");
fs::create_dir_all(&info_folder)?;

let paths_json = File::create(info_folder.join("paths.json"))?;
let paths_json_struct = self.paths_json(temp_files)?;
serde_json::to_writer_pretty(paths_json, &paths_json_struct)?;
new_files.insert(info_folder.join("paths.json"));
let paths_json_path = root_dir.join(PathsJson::package_path());
let paths_json = File::create(&paths_json_path)?;
serde_json::to_writer_pretty(paths_json, &self.paths_json(temp_files)?)?;
new_files.insert(paths_json_path);

let index_json = File::create(info_folder.join("index.json"))?;
let index_json_path = root_dir.join(IndexJson::package_path());
let index_json = File::create(&index_json_path)?;
serde_json::to_writer_pretty(index_json, &self.index_json()?)?;
new_files.insert(info_folder.join("index.json"));
new_files.insert(index_json_path);

let hash_input_json = File::create(info_folder.join("hash_input.json"))?;
serde_json::to_writer_pretty(hash_input_json, &self.build_configuration.hash.hash_input)?;
new_files.insert(info_folder.join("hash_input.json"));
let hash_input_path = info_folder.join("hash_input.json");
std::fs::write(&hash_input_path, self.hash_input().as_bytes())?;
new_files.insert(hash_input_path);

let about_json = File::create(info_folder.join("about.json"))?;
let about_json_path = root_dir.join(AboutJson::package_path());
let about_json = File::create(&about_json_path)?;
serde_json::to_writer_pretty(about_json, &self.about_json())?;
new_files.insert(info_folder.join("about.json"));
new_files.insert(about_json_path);

if let Some(run_exports) = self.run_exports_json()? {
let run_exports_json = File::create(info_folder.join("run_exports.json"))?;
let run_exports_path = root_dir.join(RunExportsJson::package_path());
let run_exports_json = File::create(&run_exports_path)?;
serde_json::to_writer_pretty(run_exports_json, &run_exports)?;
new_files.insert(info_folder.join("run_exports.json"));
new_files.insert(run_exports_path);
}

let mut variant_config = File::create(info_folder.join("hash_input.json"))?;
variant_config.write_all(
serde_json::to_string_pretty(&self.build_configuration.variant)?.as_bytes(),
)?;
Ok(new_files)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
source: src/metadata.rs
assertion_line: 733
expression: output_curl
assertion_line: 729
expression: output
---
recipe:
schema_version: 1
Expand Down Expand Up @@ -38,8 +38,6 @@ build_configuration:
target_platform: osx-arm64
hash:
hash: 60d57d3
hash_input: "{\"target_platform\": \"osx-arm64\"}"
hash_prefix: ""
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_curl_1700573293/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_curl_1700573293/build_env
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ build_configuration:
target_platform: osx-arm64
hash:
hash: 60d57d3
hash_input: "{\"target_platform\": \"osx-arm64\"}"
hash_prefix: ""
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_git_source_1704379826/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_git_source_1704379826/build_env
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
source: src/metadata.rs
assertion_line: 728
expression: output_rich
assertion_line: 729
expression: output
---
recipe:
schema_version: 1
Expand Down Expand Up @@ -54,8 +54,7 @@ build_configuration:
target_platform: noarch
hash:
hash: 4616a5c
hash_input: "{\"target_platform\": \"noarch\"}"
hash_prefix: py
prefix: py
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_rich_1702492812/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_rich_1702492812/build_env
Expand Down
2 changes: 0 additions & 2 deletions test-data/rendered_recipes/curl_recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ build_configuration:
target_platform: osx-arm64
hash:
hash: 60d57d3
hash_input: '{"target_platform": "osx-arm64"}'
hash_prefix: ''
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_curl_1700573293/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_curl_1700573293/build_env
Expand Down
2 changes: 0 additions & 2 deletions test-data/rendered_recipes/git_source.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ build_configuration:
target_platform: osx-arm64
hash:
hash: 60d57d3
hash_input: '{"target_platform": "osx-arm64"}'
hash_prefix: ''
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_git_source_1704379826/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_git_source_1704379826/build_env
Expand Down
3 changes: 1 addition & 2 deletions test-data/rendered_recipes/rich_recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ build_configuration:
target_platform: noarch
hash:
hash: 4616a5c
hash_input: '{"target_platform": "noarch"}'
hash_prefix: py
prefix: py
directories:
host_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_rich_1702492812/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold
build_prefix: /Users/wolfv/Programs/rattler-build/output/bld/rattler-build_rich_1702492812/build_env
Expand Down

0 comments on commit a3bb077

Please sign in to comment.