diff --git a/Cargo.lock b/Cargo.lock index e16c2d5..98b7d51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2294,70 +2294,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-util" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lexical-write-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" -dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", -] - -[[package]] -name = "lexical-write-integer" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" -dependencies = [ - "lexical-util", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.155" @@ -2525,21 +2461,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nondestructive" -version = "0.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8c6dda9b7e104ebb1ff495a2c95c9c14bf9ef285328f08617ed2170c681196" -dependencies = [ - "bstr", - "itoa", - "lexical-core", - "memchr", - "ryu", - "slab", - "twox-hash", -] - [[package]] name = "num" version = "0.4.3" @@ -2761,7 +2682,6 @@ dependencies = [ "inquire", "keyring", "log", - "nondestructive", "once_cell", "open", "pathdiff", @@ -2772,11 +2692,11 @@ dependencies = [ "serde", "serde_json", "serde_with", - "serde_yaml", "tar", "thiserror", "threadpool", "toml", + "toml_edit 0.22.16", "url", "zip", ] @@ -3352,19 +3272,6 @@ dependencies = [ "syn 2.0.71", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.2.6", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "sha1" version = "0.10.6" @@ -3812,17 +3719,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "rand", - "static_assertions", -] - [[package]] name = "typenum" version = "1.17.0" @@ -3888,12 +3784,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 88a3974..5e5b96d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ repository = "https://github.com/daimond113/pesde" include = ["src/**/*", "Cargo.toml", "Cargo.lock", "README.md", "LICENSE", "CHANGELOG.md"] [features] -bin = ["clap", "directories", "pretty_env_logger", "reqwest/json", "reqwest/multipart", "indicatif", "indicatif-log-bridge", "inquire", "nondestructive", "colored", "anyhow", "keyring", "open", "gix/worktree-mutation"] -wally-compat = ["toml", "zip"] +bin = ["clap", "directories", "pretty_env_logger", "reqwest/json", "reqwest/multipart", "indicatif", "indicatif-log-bridge", "inquire", "toml_edit", "colored", "anyhow", "keyring", "open", "gix/worktree-mutation"] +wally-compat = ["zip"] roblox = [] lune = [] luau = [] @@ -26,7 +26,7 @@ uninlined_format_args = "warn" [dependencies] serde = { version = "1.0.204", features = ["derive"] } -serde_yaml = "0.9.34" +toml = "0.8.15" serde_json = "1.0.120" serde_with = "3.9.0" gix = { version = "0.63.0", default-features = false, features = ["blocking-http-transport-reqwest-rust-tls", "revparse-regex", "credentials", "serde"] } @@ -47,14 +47,13 @@ once_cell = "1.19.0" # secrecy = "0.8.0" chrono = { version = "0.4.38", features = ["serde"] } -toml = { version = "0.8.15", optional = true } zip = { version = "2.1.5", optional = true } anyhow = { version = "1.0.86", optional = true } open = { version = "5.3.0", optional = true } keyring = { version = "3.0.3", features = ["crypto-rust", "windows-native", "apple-native", "linux-native"], optional = true } colored = { version = "2.1.0", optional = true } -nondestructive = { version = "0.0.25", optional = true } +toml_edit = { version = "0.22.16", optional = true } clap = { version = "4.5.9", features = ["derive"], optional = true } directories = { version = "5.0.1", optional = true } pretty_env_logger = { version = "0.5.0", optional = true } diff --git a/src/cli/init.rs b/src/cli/init.rs index 2e5606a..975f6b5 100644 --- a/src/cli/init.rs +++ b/src/cli/init.rs @@ -35,11 +35,9 @@ impl InitCommand { Ok(()) } Err(ManifestReadError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => { - let mut manifest = nondestructive::yaml::from_slice(b"").unwrap(); - let mut mapping = manifest.as_mut().make_mapping(); + let mut manifest = toml_edit::DocumentMut::new(); - mapping.insert_str( - "name", + manifest["name"] = toml_edit::value( inquire::Text::new("What is the name of the project?") .with_validator(|name: &str| { Ok(match PackageName::from_str(name) { @@ -50,7 +48,7 @@ impl InitCommand { .prompt() .unwrap(), ); - mapping.insert_str("version", "0.1.0"); + manifest["version"] = toml_edit::value("0.1.0"); let description = inquire::Text::new( "What is the description of the project? (leave empty for none)", @@ -59,7 +57,7 @@ impl InitCommand { .unwrap(); if !description.is_empty() { - mapping.insert_str("description", description); + manifest["description"] = toml_edit::value(description); } let authors = inquire::Text::new( @@ -72,16 +70,14 @@ impl InitCommand { .split(',') .map(|s| s.trim()) .filter(|s| !s.is_empty()) - .collect::>(); + .map(|s| s.into()) + .collect::>(); if !authors.is_empty() { - let mut authors_field = mapping - .insert("authors", nondestructive::yaml::Separator::Auto) - .make_sequence(); + let mut authors_arr = toml_edit::Array::new(); + authors_arr.extend(authors); - for author in authors { - authors_field.push_string(author); - } + manifest["authors"] = toml_edit::value(authors_arr); } let repo = inquire::Text::new( @@ -100,7 +96,7 @@ impl InitCommand { .prompt() .unwrap(); if !repo.is_empty() { - mapping.insert_str("repository", repo); + manifest["repository"] = toml_edit::value(repo); } let license = inquire::Text::new( @@ -110,7 +106,7 @@ impl InitCommand { .prompt() .unwrap(); if !license.is_empty() { - mapping.insert_str("license", license); + manifest["license"] = toml_edit::value(license); } let target_env = inquire::Select::new( @@ -127,10 +123,8 @@ impl InitCommand { .prompt() .unwrap(); - let mut target = mapping - .insert("target", nondestructive::yaml::Separator::Auto) - .make_mapping(); - target.insert_str("environment", target_env); + let mut target = toml_edit::Table::new(); + target["environment"] = toml_edit::value(target_env); if target_env == "roblox" || inquire::Confirm::new(&format!( @@ -152,25 +146,22 @@ impl InitCommand { ) .context("failed to write script file")?; - mapping - .insert("scripts", nondestructive::yaml::Separator::Auto) - .make_mapping() - .insert_str( - ScriptName::RobloxSyncConfigGenerator.to_string(), - format!( - concat!(concat!(".", env!("CARGO_PKG_NAME")), "/{}.luau"), - ScriptName::RobloxSyncConfigGenerator - ), - ); + let mut scripts = manifest + .entry("scripts") + .or_insert(toml_edit::Item::Table(toml_edit::Table::new())) + .to_owned() + .into_table() + .unwrap(); + scripts[&ScriptName::RobloxSyncConfigGenerator.to_string()] = + toml_edit::value(format!( + concat!(".", env!("CARGO_PKG_NAME"), "/{}.luau"), + ScriptName::RobloxSyncConfigGenerator + )); } - let mut indices = mapping - .insert("indices", nondestructive::yaml::Separator::Auto) - .make_mapping(); - indices.insert_str( - DEFAULT_INDEX_NAME, - read_config(project.data_dir())?.default_index.as_str(), - ); + let mut indices = toml_edit::Table::new(); + indices[DEFAULT_INDEX_NAME] = + toml_edit::value(read_config(project.data_dir())?.default_index.as_str()); project.write_manifest(manifest.to_string())?; diff --git a/src/cli/install.rs b/src/cli/install.rs index 4a4a3e0..e0b1b79 100644 --- a/src/cli/install.rs +++ b/src/cli/install.rs @@ -1,6 +1,7 @@ +use crate::cli::IsUpToDate; use anyhow::Context; use clap::Args; -use pesde::Project; +use pesde::{lockfile::Lockfile, Project}; use std::collections::HashSet; #[derive(Debug, Args)] @@ -9,8 +10,46 @@ pub struct InstallCommand {} impl InstallCommand { pub fn run(self, project: Project) -> anyhow::Result<()> { let mut refreshed_sources = HashSet::new(); + + let manifest = project + .deser_manifest() + .context("failed to read manifest")?; + + let lockfile = if project + .is_up_to_date() + .context("failed to check if project is up to date")? + { + match project.deser_lockfile() { + Ok(lockfile) => Some(lockfile), + Err(pesde::errors::LockfileReadError::Io(e)) + if e.kind() == std::io::ErrorKind::NotFound => + { + None + } + Err(e) => return Err(e.into()), + } + } else { + None + }; + + let old_graph = lockfile.map(|lockfile| { + lockfile + .graph + .into_iter() + .map(|(name, versions)| { + ( + name, + versions + .into_iter() + .map(|(version, node)| (version, node.node)) + .collect(), + ) + }) + .collect() + }); + let graph = project - .dependency_graph(None, &mut refreshed_sources) + .dependency_graph(old_graph.as_ref(), &mut refreshed_sources) .context("failed to build dependency graph")?; let downloaded_graph = project .download_graph(&graph, &mut refreshed_sources) @@ -20,6 +59,16 @@ impl InstallCommand { .link_dependencies(&downloaded_graph) .context("failed to link dependencies")?; + project + .write_lockfile(Lockfile { + name: manifest.name, + version: manifest.version, + overrides: manifest.overrides, + + graph: downloaded_graph, + }) + .context("failed to write lockfile")?; + Ok(()) } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a5f6fa5..a007ed2 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -18,6 +18,7 @@ mod self_install; pub struct CliConfig { pub default_index: url::Url, pub scripts_repo: url::Url, + #[serde(default, skip_serializing_if = "Option::is_none")] pub token: Option, } @@ -34,7 +35,7 @@ impl Default for CliConfig { } pub fn read_config(data_dir: &Path) -> anyhow::Result { - let config_string = match std::fs::read_to_string(data_dir.join("config.yaml")) { + let config_string = match std::fs::read_to_string(data_dir.join("config.toml")) { Ok(config_string) => config_string, Err(e) if e.kind() == std::io::ErrorKind::NotFound => { return Ok(CliConfig::default()); @@ -42,14 +43,14 @@ pub fn read_config(data_dir: &Path) -> anyhow::Result { Err(e) => return Err(e).context("failed to read config file"), }; - let config = serde_yaml::from_str(&config_string).context("failed to parse config file")?; + let config = toml::from_str(&config_string).context("failed to parse config file")?; Ok(config) } pub fn write_config(data_dir: &Path, config: &CliConfig) -> anyhow::Result<()> { - let config_string = serde_yaml::to_string(config).context("failed to serialize config")?; - std::fs::write(data_dir.join("config.yaml"), config_string) + let config_string = toml::to_string(config).context("failed to serialize config")?; + std::fs::write(data_dir.join("config.toml"), config_string) .context("failed to write config file")?; Ok(()) @@ -258,7 +259,7 @@ impl IsUpToDate for Project { }) .collect::>(); - Ok(!manifest + Ok(manifest .all_dependencies() .context("failed to get all dependencies")? .iter() diff --git a/src/cli/publish.rs b/src/cli/publish.rs index f7cd41d..160315f 100644 --- a/src/cli/publish.rs +++ b/src/cli/publish.rs @@ -2,7 +2,7 @@ use anyhow::Context; use clap::Args; use colored::Colorize; use pesde::{manifest::Target, Project, MANIFEST_FILE_NAME, MAX_ARCHIVE_SIZE}; -use std::{io::Seek, path::Component}; +use std::path::Component; #[derive(Debug, Args)] pub struct PublishCommand { @@ -239,19 +239,14 @@ impl PublishCommand { .data_dir() .join(format!("temp_manifest_{}", chrono::Utc::now().timestamp())); - let mut temp_manifest = std::fs::File::options() - .read(true) - .write(true) - .create(true) - .truncate(true) - .open(&temp_manifest_path) - .context("failed to create temp manifest file")?; + std::fs::write( + &temp_manifest_path, + toml::to_string(&manifest).context("failed to serialize manifest")?, + ) + .context("failed to write temp manifest file")?; - serde_yaml::to_writer(&mut temp_manifest, &manifest) - .context("failed to write temp manifest file")?; - temp_manifest - .rewind() - .context("failed to rewind temp manifest file")?; + let mut temp_manifest = std::fs::File::open(&temp_manifest_path) + .context("failed to open temp manifest file")?; archive.append_file(MANIFEST_FILE_NAME, &mut temp_manifest)?; diff --git a/src/lib.rs b/src/lib.rs index cf89d33..db8f11e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ pub mod resolver; pub mod scripts; pub mod source; -pub const MANIFEST_FILE_NAME: &str = "pesde.yaml"; +pub const MANIFEST_FILE_NAME: &str = "pesde.toml"; pub const LOCKFILE_FILE_NAME: &str = "pesde.lock"; pub const DEFAULT_INDEX_NAME: &str = "default"; pub const PACKAGES_CONTAINER_NAME: &str = ".pesde"; @@ -105,8 +105,8 @@ impl Project { } pub fn deser_manifest(&self) -> Result { - let bytes = std::fs::read(self.path.join(MANIFEST_FILE_NAME))?; - Ok(serde_yaml::from_slice(&bytes)?) + let string = std::fs::read_to_string(self.path.join(MANIFEST_FILE_NAME))?; + Ok(toml::from_str(&string)?) } pub fn write_manifest>(&self, manifest: S) -> Result<(), std::io::Error> { @@ -114,13 +114,13 @@ impl Project { } pub fn deser_lockfile(&self) -> Result { - let bytes = std::fs::read(self.path.join(LOCKFILE_FILE_NAME))?; - Ok(serde_yaml::from_slice(&bytes)?) + let string = std::fs::read_to_string(self.path.join(LOCKFILE_FILE_NAME))?; + Ok(toml::from_str(&string)?) } pub fn write_lockfile(&self, lockfile: Lockfile) -> Result<(), errors::LockfileWriteError> { - let writer = std::fs::File::create(self.path.join(LOCKFILE_FILE_NAME))?; - serde_yaml::to_writer(writer, &lockfile)?; + let string = toml::to_string(&lockfile)?; + std::fs::write(self.path.join(LOCKFILE_FILE_NAME), string)?; Ok(()) } } @@ -135,26 +135,26 @@ pub mod errors { Io(#[from] std::io::Error), #[error("error deserializing manifest file")] - Serde(#[from] serde_yaml::Error), + Serde(#[from] toml::de::Error), } #[derive(Debug, Error)] #[non_exhaustive] pub enum LockfileReadError { - #[error("io error reading lockfile file")] + #[error("io error reading lockfile")] Io(#[from] std::io::Error), - #[error("error deserializing lockfile file")] - Serde(#[from] serde_yaml::Error), + #[error("error deserializing lockfile")] + Serde(#[from] toml::de::Error), } #[derive(Debug, Error)] #[non_exhaustive] pub enum LockfileWriteError { - #[error("io error writing lockfile file")] + #[error("io error writing lockfile")] Io(#[from] std::io::Error), - #[error("error serializing lockfile file")] - Serde(#[from] serde_yaml::Error), + #[error("error serializing lockfile")] + Serde(#[from] toml::ser::Error), } } diff --git a/src/linking/mod.rs b/src/linking/mod.rs index c097993..ada63b5 100644 --- a/src/linking/mod.rs +++ b/src/linking/mod.rs @@ -1,23 +1,17 @@ use crate::{ linking::generator::get_file_types, lockfile::DownloadedGraph, - manifest::{Manifest, ScriptName, Target}, + manifest::{ScriptName, Target}, names::PackageNames, scripts::execute_script, source::PackageRef, - Project, MANIFEST_FILE_NAME, PACKAGES_CONTAINER_NAME, + Project, PACKAGES_CONTAINER_NAME, }; use semver::Version; use std::{collections::BTreeMap, fs::create_dir_all}; pub mod generator; -fn read_manifest(path: &std::path::Path) -> Result { - let manifest = std::fs::read_to_string(path.join(MANIFEST_FILE_NAME))?; - serde_yaml::from_str(&manifest) - .map_err(|e| errors::LinkingError::DependencyManifest(path.display().to_string(), e)) -} - impl Project { pub fn link_dependencies(&self, graph: &DownloadedGraph) -> Result<(), errors::LinkingError> { let manifest = self.deser_manifest()?; @@ -106,8 +100,6 @@ impl Project { node.node .container_folder(&packages_container_folder, name, version); - let node_manifest = read_manifest(&container_folder)?; - if let Some((alias, types)) = package_types .get(name) .and_then(|v| v.get(version)) @@ -115,7 +107,7 @@ impl Project { { let module = generator::generate_linking_module( &generator::get_require_path( - &node_manifest.target, + &node.target, &base_folder, &container_folder, node.node.pkg_ref.use_new_structure(), @@ -145,8 +137,6 @@ impl Project { dependency_version, ); - let dependency_manifest = read_manifest(&dependency_container_folder)?; - let linker_folder = container_folder .join(dependency_node.node.base_folder(node.target.kind(), false)); create_dir_all(&linker_folder)?; @@ -156,7 +146,7 @@ impl Project { let module = generator::generate_linking_module( &generator::get_require_path( - &dependency_manifest.target, + &dependency_node.target, &linker_file, &dependency_container_folder, node.node.pkg_ref.use_new_structure(), @@ -185,9 +175,6 @@ pub mod errors { #[error("error deserializing project manifest")] Manifest(#[from] crate::errors::ManifestReadError), - #[error("error deserializing manifest at {0}")] - DependencyManifest(String, #[source] serde_yaml::Error), - #[error("error interacting with filesystem")] Io(#[from] std::io::Error), diff --git a/src/lockfile.rs b/src/lockfile.rs index 67959ee..89a2678 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -49,8 +49,13 @@ pub fn insert_node( graph: &mut DependencyGraph, name: PackageNames, version: Version, - node: DependencyGraphNode, + mut node: DependencyGraphNode, + is_top_level: bool, ) { + if !is_top_level { + node.direct.take(); + } + match graph .entry(name.clone()) .or_default() @@ -89,7 +94,9 @@ pub type DownloadedGraph = Graph; pub struct Lockfile { pub name: PackageName, pub version: Version, + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub overrides: BTreeMap, + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub graph: DownloadedGraph, } diff --git a/src/manifest.rs b/src/manifest.rs index ae707cd..826924f 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -229,7 +229,7 @@ pub struct Manifest { #[serde(default)] pub indices: BTreeMap, #[cfg(feature = "wally-compat")] - #[serde(default)] + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub wally_indices: BTreeMap, #[serde(default, skip_serializing)] pub overrides: BTreeMap, diff --git a/src/names.rs b/src/names.rs index df6ee62..c3d3bb5 100644 --- a/src/names.rs +++ b/src/names.rs @@ -70,6 +70,7 @@ impl PackageName { } #[derive(Debug, Deserialize, Serialize, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[serde(untagged)] pub enum PackageNames { Pesde(PackageName), } diff --git a/src/resolver.rs b/src/resolver.rs index ca4c93c..9f9581b 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -45,7 +45,13 @@ impl Project { } log::debug!("resolved {}@{} from old dependency graph", name, version); - insert_node(&mut graph, name.clone(), version.clone(), node.clone()); + insert_node( + &mut graph, + name.clone(), + version.clone(), + node.clone(), + true, + ); let mut queue = node .dependencies @@ -71,6 +77,7 @@ impl Project { dep_name.clone(), dep_version.clone(), dep_node.clone(), + false, ); dep_node @@ -209,6 +216,7 @@ impl Project { name.clone(), target_version.clone(), node.clone(), + depth == 0, ); log::debug!( diff --git a/src/source/pesde/mod.rs b/src/source/pesde/mod.rs index ee80bc5..c2e21c8 100644 --- a/src/source/pesde/mod.rs +++ b/src/source/pesde/mod.rs @@ -23,7 +23,7 @@ pub struct PesdePackageSource { repo_url: gix::Url, } -const OWNERS_FILE: &str = "owners.yaml"; +const SCOPE_INFO_FILE: &str = "scope.toml"; impl PesdePackageSource { pub fn new(repo_url: gix::Url) -> Self { @@ -101,7 +101,7 @@ impl PesdePackageSource { &self, file_path: I, project: &Project, - ) -> Result>, Box> { + ) -> Result, Box> { let path = self.path(project); let repo = match gix::open(&path) { @@ -134,15 +134,19 @@ impl PesdePackageSource { }; let blob = object.into_blob(); - Ok(Some(blob.data.clone())) + let string = String::from_utf8(blob.data.clone()) + .map_err(|e| Box::new(errors::ReadFile::Utf8(file_path_str, e)))?; + + Ok(Some(string)) } pub fn config(&self, project: &Project) -> Result> { let file = self - .read_file(["config.yaml"], project) + .read_file(["config.toml"], project) .map_err(|e| Box::new(e.into()))?; - let bytes = match file { - Some(bytes) => bytes, + + let string = match file { + Some(s) => s, None => { return Err(Box::new(errors::ConfigError::Missing( self.repo_url.clone(), @@ -150,7 +154,7 @@ impl PesdePackageSource { } }; - let config: IndexConfig = serde_yaml::from_slice(&bytes).map_err(|e| Box::new(e.into()))?; + let config: IndexConfig = toml::from_str(&string).map_err(|e| Box::new(e.into()))?; Ok(config) } @@ -208,12 +212,16 @@ impl PesdePackageSource { let package_name = inner_entry.filename().to_string(); - if package_name == OWNERS_FILE { + if package_name == SCOPE_INFO_FILE { continue; } let blob = object.into_blob(); - let file: IndexFileEntry = match serde_yaml::from_slice(&blob.data) { + let string = String::from_utf8(blob.data.clone()).map_err(|e| { + Box::new(errors::AllPackagesError::Utf8(package_name.to_string(), e)) + })?; + + let file: IndexFile = match toml::from_str(&string) { Ok(file) => file, Err(e) => { return Err(Box::new(errors::AllPackagesError::Deserialize( @@ -227,10 +235,7 @@ impl PesdePackageSource { // if this panics, it's an issue with the index. let name = format!("{package_scope}/{package_name}").parse().unwrap(); - packages - .entry(name) - .or_default() - .insert(file.version.clone(), file); + packages.insert(name, file); } } @@ -297,26 +302,26 @@ impl PackageSource for PesdePackageSource { project: &Project, ) -> Result, Self::ResolveError> { let (scope, name) = specifier.name.as_str(); - let bytes = match self.read_file([scope, name], project) { - Ok(Some(bytes)) => bytes, + let string = match self.read_file([scope, name], project) { + Ok(Some(s)) => s, Ok(None) => return Err(Self::ResolveError::NotFound(specifier.name.to_string())), Err(e) => return Err(Self::ResolveError::Read(specifier.name.to_string(), e)), }; - let entries: Vec = serde_yaml::from_slice(&bytes) + let entries: IndexFile = toml::from_str(&string) .map_err(|e| Self::ResolveError::Parse(specifier.name.to_string(), e))?; Ok(( PackageNames::Pesde(specifier.name.clone()), entries .into_iter() - .filter(|entry| specifier.version.matches(&entry.version)) - .map(|entry| { + .filter(|(version, _)| specifier.version.matches(version)) + .map(|(version, entry)| { ( - entry.version.clone(), + version.clone(), PesdePackageRef { name: specifier.name.clone(), - version: entry.version, + version, index_url: self.repo_url.clone(), dependencies: entry.dependencies, target: entry.target, @@ -388,9 +393,8 @@ impl IndexConfig { } } -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct IndexFileEntry { - pub version: Version, pub target: Target, #[serde(default = "chrono::Utc::now")] pub published_at: chrono::DateTime, @@ -402,20 +406,6 @@ pub struct IndexFileEntry { pub dependencies: BTreeMap, } -impl Ord for IndexFileEntry { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.target - .cmp(&other.target) - .then_with(|| self.version.cmp(&other.version)) - } -} - -impl PartialOrd for IndexFileEntry { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - pub type IndexFile = BTreeMap; pub mod errors { @@ -499,6 +489,9 @@ pub mod errors { #[error("error looking up entry {0} in tree")] Lookup(String, #[source] gix::object::find::existing::Error), + + #[error("error parsing file for {0} as utf8")] + Utf8(String, #[source] std::string::FromUtf8Error), } #[derive(Debug, Error)] @@ -514,7 +507,10 @@ pub mod errors { Read(String, #[source] Box), #[error("error parsing file for {0}")] - Parse(String, #[source] serde_yaml::Error), + Parse(String, #[source] toml::de::Error), + + #[error("error parsing file for {0} to utf8")] + Utf8(String, #[source] std::string::FromUtf8Error), } #[derive(Debug, Error)] @@ -524,7 +520,7 @@ pub mod errors { ReadFile(#[from] Box), #[error("error parsing config file")] - Parse(#[from] serde_yaml::Error), + Parse(#[from] toml::de::Error), #[error("missing config file for index at {0}")] Missing(gix::Url), @@ -546,7 +542,10 @@ pub mod errors { Convert(PathBuf, #[source] gix::object::find::existing::Error), #[error("error deserializing file {0} in repository at {1}")] - Deserialize(String, PathBuf, #[source] serde_yaml::Error), + Deserialize(String, PathBuf, #[source] toml::de::Error), + + #[error("error parsing file for {0} as utf8")] + Utf8(String, #[source] std::string::FromUtf8Error), } #[derive(Debug, Error)]