feat: use lockfile + transition to toml

This commit is contained in:
daimond113 2024-07-22 19:40:30 +02:00
parent d81f2350df
commit 67d662939f
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
13 changed files with 172 additions and 245 deletions

112
Cargo.lock generated
View file

@ -2294,70 +2294,6 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 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]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.155"
@ -2525,21 +2461,6 @@ dependencies = [
"memoffset", "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]] [[package]]
name = "num" name = "num"
version = "0.4.3" version = "0.4.3"
@ -2761,7 +2682,6 @@ dependencies = [
"inquire", "inquire",
"keyring", "keyring",
"log", "log",
"nondestructive",
"once_cell", "once_cell",
"open", "open",
"pathdiff", "pathdiff",
@ -2772,11 +2692,11 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_with", "serde_with",
"serde_yaml",
"tar", "tar",
"thiserror", "thiserror",
"threadpool", "threadpool",
"toml", "toml",
"toml_edit 0.22.16",
"url", "url",
"zip", "zip",
] ]
@ -3352,19 +3272,6 @@ dependencies = [
"syn 2.0.71", "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]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.6"
@ -3812,17 +3719,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 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]] [[package]]
name = "typenum" name = "typenum"
version = "1.17.0" version = "1.17.0"
@ -3888,12 +3784,6 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.9.0" version = "0.9.0"

View file

@ -10,8 +10,8 @@ repository = "https://github.com/daimond113/pesde"
include = ["src/**/*", "Cargo.toml", "Cargo.lock", "README.md", "LICENSE", "CHANGELOG.md"] include = ["src/**/*", "Cargo.toml", "Cargo.lock", "README.md", "LICENSE", "CHANGELOG.md"]
[features] [features]
bin = ["clap", "directories", "pretty_env_logger", "reqwest/json", "reqwest/multipart", "indicatif", "indicatif-log-bridge", "inquire", "nondestructive", "colored", "anyhow", "keyring", "open", "gix/worktree-mutation"] 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 = ["toml", "zip"] wally-compat = ["zip"]
roblox = [] roblox = []
lune = [] lune = []
luau = [] luau = []
@ -26,7 +26,7 @@ uninlined_format_args = "warn"
[dependencies] [dependencies]
serde = { version = "1.0.204", features = ["derive"] } serde = { version = "1.0.204", features = ["derive"] }
serde_yaml = "0.9.34" toml = "0.8.15"
serde_json = "1.0.120" serde_json = "1.0.120"
serde_with = "3.9.0" serde_with = "3.9.0"
gix = { version = "0.63.0", default-features = false, features = ["blocking-http-transport-reqwest-rust-tls", "revparse-regex", "credentials", "serde"] } 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" # secrecy = "0.8.0"
chrono = { version = "0.4.38", features = ["serde"] } chrono = { version = "0.4.38", features = ["serde"] }
toml = { version = "0.8.15", optional = true }
zip = { version = "2.1.5", optional = true } zip = { version = "2.1.5", optional = true }
anyhow = { version = "1.0.86", optional = true } anyhow = { version = "1.0.86", optional = true }
open = { version = "5.3.0", 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 } keyring = { version = "3.0.3", features = ["crypto-rust", "windows-native", "apple-native", "linux-native"], optional = true }
colored = { version = "2.1.0", 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 } clap = { version = "4.5.9", features = ["derive"], optional = true }
directories = { version = "5.0.1", optional = true } directories = { version = "5.0.1", optional = true }
pretty_env_logger = { version = "0.5.0", optional = true } pretty_env_logger = { version = "0.5.0", optional = true }

View file

@ -35,11 +35,9 @@ impl InitCommand {
Ok(()) Ok(())
} }
Err(ManifestReadError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => { Err(ManifestReadError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => {
let mut manifest = nondestructive::yaml::from_slice(b"").unwrap(); let mut manifest = toml_edit::DocumentMut::new();
let mut mapping = manifest.as_mut().make_mapping();
mapping.insert_str( manifest["name"] = toml_edit::value(
"name",
inquire::Text::new("What is the name of the project?") inquire::Text::new("What is the name of the project?")
.with_validator(|name: &str| { .with_validator(|name: &str| {
Ok(match PackageName::from_str(name) { Ok(match PackageName::from_str(name) {
@ -50,7 +48,7 @@ impl InitCommand {
.prompt() .prompt()
.unwrap(), .unwrap(),
); );
mapping.insert_str("version", "0.1.0"); manifest["version"] = toml_edit::value("0.1.0");
let description = inquire::Text::new( let description = inquire::Text::new(
"What is the description of the project? (leave empty for none)", "What is the description of the project? (leave empty for none)",
@ -59,7 +57,7 @@ impl InitCommand {
.unwrap(); .unwrap();
if !description.is_empty() { if !description.is_empty() {
mapping.insert_str("description", description); manifest["description"] = toml_edit::value(description);
} }
let authors = inquire::Text::new( let authors = inquire::Text::new(
@ -72,16 +70,14 @@ impl InitCommand {
.split(',') .split(',')
.map(|s| s.trim()) .map(|s| s.trim())
.filter(|s| !s.is_empty()) .filter(|s| !s.is_empty())
.collect::<Vec<_>>(); .map(|s| s.into())
.collect::<Vec<toml_edit::Value>>();
if !authors.is_empty() { if !authors.is_empty() {
let mut authors_field = mapping let mut authors_arr = toml_edit::Array::new();
.insert("authors", nondestructive::yaml::Separator::Auto) authors_arr.extend(authors);
.make_sequence();
for author in authors { manifest["authors"] = toml_edit::value(authors_arr);
authors_field.push_string(author);
}
} }
let repo = inquire::Text::new( let repo = inquire::Text::new(
@ -100,7 +96,7 @@ impl InitCommand {
.prompt() .prompt()
.unwrap(); .unwrap();
if !repo.is_empty() { if !repo.is_empty() {
mapping.insert_str("repository", repo); manifest["repository"] = toml_edit::value(repo);
} }
let license = inquire::Text::new( let license = inquire::Text::new(
@ -110,7 +106,7 @@ impl InitCommand {
.prompt() .prompt()
.unwrap(); .unwrap();
if !license.is_empty() { if !license.is_empty() {
mapping.insert_str("license", license); manifest["license"] = toml_edit::value(license);
} }
let target_env = inquire::Select::new( let target_env = inquire::Select::new(
@ -127,10 +123,8 @@ impl InitCommand {
.prompt() .prompt()
.unwrap(); .unwrap();
let mut target = mapping let mut target = toml_edit::Table::new();
.insert("target", nondestructive::yaml::Separator::Auto) target["environment"] = toml_edit::value(target_env);
.make_mapping();
target.insert_str("environment", target_env);
if target_env == "roblox" if target_env == "roblox"
|| inquire::Confirm::new(&format!( || inquire::Confirm::new(&format!(
@ -152,25 +146,22 @@ impl InitCommand {
) )
.context("failed to write script file")?; .context("failed to write script file")?;
mapping let mut scripts = manifest
.insert("scripts", nondestructive::yaml::Separator::Auto) .entry("scripts")
.make_mapping() .or_insert(toml_edit::Item::Table(toml_edit::Table::new()))
.insert_str( .to_owned()
ScriptName::RobloxSyncConfigGenerator.to_string(), .into_table()
format!( .unwrap();
concat!(concat!(".", env!("CARGO_PKG_NAME")), "/{}.luau"), scripts[&ScriptName::RobloxSyncConfigGenerator.to_string()] =
ScriptName::RobloxSyncConfigGenerator toml_edit::value(format!(
), concat!(".", env!("CARGO_PKG_NAME"), "/{}.luau"),
); ScriptName::RobloxSyncConfigGenerator
));
} }
let mut indices = mapping let mut indices = toml_edit::Table::new();
.insert("indices", nondestructive::yaml::Separator::Auto) indices[DEFAULT_INDEX_NAME] =
.make_mapping(); toml_edit::value(read_config(project.data_dir())?.default_index.as_str());
indices.insert_str(
DEFAULT_INDEX_NAME,
read_config(project.data_dir())?.default_index.as_str(),
);
project.write_manifest(manifest.to_string())?; project.write_manifest(manifest.to_string())?;

View file

@ -1,6 +1,7 @@
use crate::cli::IsUpToDate;
use anyhow::Context; use anyhow::Context;
use clap::Args; use clap::Args;
use pesde::Project; use pesde::{lockfile::Lockfile, Project};
use std::collections::HashSet; use std::collections::HashSet;
#[derive(Debug, Args)] #[derive(Debug, Args)]
@ -9,8 +10,46 @@ pub struct InstallCommand {}
impl InstallCommand { impl InstallCommand {
pub fn run(self, project: Project) -> anyhow::Result<()> { pub fn run(self, project: Project) -> anyhow::Result<()> {
let mut refreshed_sources = HashSet::new(); 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 let graph = project
.dependency_graph(None, &mut refreshed_sources) .dependency_graph(old_graph.as_ref(), &mut refreshed_sources)
.context("failed to build dependency graph")?; .context("failed to build dependency graph")?;
let downloaded_graph = project let downloaded_graph = project
.download_graph(&graph, &mut refreshed_sources) .download_graph(&graph, &mut refreshed_sources)
@ -20,6 +59,16 @@ impl InstallCommand {
.link_dependencies(&downloaded_graph) .link_dependencies(&downloaded_graph)
.context("failed to link dependencies")?; .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(()) Ok(())
} }
} }

View file

@ -18,6 +18,7 @@ mod self_install;
pub struct CliConfig { pub struct CliConfig {
pub default_index: url::Url, pub default_index: url::Url,
pub scripts_repo: url::Url, pub scripts_repo: url::Url,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub token: Option<String>, pub token: Option<String>,
} }
@ -34,7 +35,7 @@ impl Default for CliConfig {
} }
pub fn read_config(data_dir: &Path) -> anyhow::Result<CliConfig> { pub fn read_config(data_dir: &Path) -> anyhow::Result<CliConfig> {
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, Ok(config_string) => config_string,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => { Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
return Ok(CliConfig::default()); return Ok(CliConfig::default());
@ -42,14 +43,14 @@ pub fn read_config(data_dir: &Path) -> anyhow::Result<CliConfig> {
Err(e) => return Err(e).context("failed to read config file"), 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) Ok(config)
} }
pub fn write_config(data_dir: &Path, config: &CliConfig) -> anyhow::Result<()> { pub fn write_config(data_dir: &Path, config: &CliConfig) -> anyhow::Result<()> {
let config_string = serde_yaml::to_string(config).context("failed to serialize config")?; let config_string = toml::to_string(config).context("failed to serialize config")?;
std::fs::write(data_dir.join("config.yaml"), config_string) std::fs::write(data_dir.join("config.toml"), config_string)
.context("failed to write config file")?; .context("failed to write config file")?;
Ok(()) Ok(())
@ -258,7 +259,7 @@ impl IsUpToDate for Project {
}) })
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
Ok(!manifest Ok(manifest
.all_dependencies() .all_dependencies()
.context("failed to get all dependencies")? .context("failed to get all dependencies")?
.iter() .iter()

View file

@ -2,7 +2,7 @@ use anyhow::Context;
use clap::Args; use clap::Args;
use colored::Colorize; use colored::Colorize;
use pesde::{manifest::Target, Project, MANIFEST_FILE_NAME, MAX_ARCHIVE_SIZE}; use pesde::{manifest::Target, Project, MANIFEST_FILE_NAME, MAX_ARCHIVE_SIZE};
use std::{io::Seek, path::Component}; use std::path::Component;
#[derive(Debug, Args)] #[derive(Debug, Args)]
pub struct PublishCommand { pub struct PublishCommand {
@ -239,19 +239,14 @@ impl PublishCommand {
.data_dir() .data_dir()
.join(format!("temp_manifest_{}", chrono::Utc::now().timestamp())); .join(format!("temp_manifest_{}", chrono::Utc::now().timestamp()));
let mut temp_manifest = std::fs::File::options() std::fs::write(
.read(true) &temp_manifest_path,
.write(true) toml::to_string(&manifest).context("failed to serialize manifest")?,
.create(true) )
.truncate(true) .context("failed to write temp manifest file")?;
.open(&temp_manifest_path)
.context("failed to create temp manifest file")?;
serde_yaml::to_writer(&mut temp_manifest, &manifest) let mut temp_manifest = std::fs::File::open(&temp_manifest_path)
.context("failed to write temp manifest file")?; .context("failed to open temp manifest file")?;
temp_manifest
.rewind()
.context("failed to rewind temp manifest file")?;
archive.append_file(MANIFEST_FILE_NAME, &mut temp_manifest)?; archive.append_file(MANIFEST_FILE_NAME, &mut temp_manifest)?;

View file

@ -17,7 +17,7 @@ pub mod resolver;
pub mod scripts; pub mod scripts;
pub mod source; 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 LOCKFILE_FILE_NAME: &str = "pesde.lock";
pub const DEFAULT_INDEX_NAME: &str = "default"; pub const DEFAULT_INDEX_NAME: &str = "default";
pub const PACKAGES_CONTAINER_NAME: &str = ".pesde"; pub const PACKAGES_CONTAINER_NAME: &str = ".pesde";
@ -105,8 +105,8 @@ impl Project {
} }
pub fn deser_manifest(&self) -> Result<manifest::Manifest, errors::ManifestReadError> { pub fn deser_manifest(&self) -> Result<manifest::Manifest, errors::ManifestReadError> {
let bytes = std::fs::read(self.path.join(MANIFEST_FILE_NAME))?; let string = std::fs::read_to_string(self.path.join(MANIFEST_FILE_NAME))?;
Ok(serde_yaml::from_slice(&bytes)?) Ok(toml::from_str(&string)?)
} }
pub fn write_manifest<S: AsRef<[u8]>>(&self, manifest: S) -> Result<(), std::io::Error> { pub fn write_manifest<S: AsRef<[u8]>>(&self, manifest: S) -> Result<(), std::io::Error> {
@ -114,13 +114,13 @@ impl Project {
} }
pub fn deser_lockfile(&self) -> Result<Lockfile, errors::LockfileReadError> { pub fn deser_lockfile(&self) -> Result<Lockfile, errors::LockfileReadError> {
let bytes = std::fs::read(self.path.join(LOCKFILE_FILE_NAME))?; let string = std::fs::read_to_string(self.path.join(LOCKFILE_FILE_NAME))?;
Ok(serde_yaml::from_slice(&bytes)?) Ok(toml::from_str(&string)?)
} }
pub fn write_lockfile(&self, lockfile: Lockfile) -> Result<(), errors::LockfileWriteError> { pub fn write_lockfile(&self, lockfile: Lockfile) -> Result<(), errors::LockfileWriteError> {
let writer = std::fs::File::create(self.path.join(LOCKFILE_FILE_NAME))?; let string = toml::to_string(&lockfile)?;
serde_yaml::to_writer(writer, &lockfile)?; std::fs::write(self.path.join(LOCKFILE_FILE_NAME), string)?;
Ok(()) Ok(())
} }
} }
@ -135,26 +135,26 @@ pub mod errors {
Io(#[from] std::io::Error), Io(#[from] std::io::Error),
#[error("error deserializing manifest file")] #[error("error deserializing manifest file")]
Serde(#[from] serde_yaml::Error), Serde(#[from] toml::de::Error),
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[non_exhaustive] #[non_exhaustive]
pub enum LockfileReadError { pub enum LockfileReadError {
#[error("io error reading lockfile file")] #[error("io error reading lockfile")]
Io(#[from] std::io::Error), Io(#[from] std::io::Error),
#[error("error deserializing lockfile file")] #[error("error deserializing lockfile")]
Serde(#[from] serde_yaml::Error), Serde(#[from] toml::de::Error),
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[non_exhaustive] #[non_exhaustive]
pub enum LockfileWriteError { pub enum LockfileWriteError {
#[error("io error writing lockfile file")] #[error("io error writing lockfile")]
Io(#[from] std::io::Error), Io(#[from] std::io::Error),
#[error("error serializing lockfile file")] #[error("error serializing lockfile")]
Serde(#[from] serde_yaml::Error), Serde(#[from] toml::ser::Error),
} }
} }

View file

@ -1,23 +1,17 @@
use crate::{ use crate::{
linking::generator::get_file_types, linking::generator::get_file_types,
lockfile::DownloadedGraph, lockfile::DownloadedGraph,
manifest::{Manifest, ScriptName, Target}, manifest::{ScriptName, Target},
names::PackageNames, names::PackageNames,
scripts::execute_script, scripts::execute_script,
source::PackageRef, source::PackageRef,
Project, MANIFEST_FILE_NAME, PACKAGES_CONTAINER_NAME, Project, PACKAGES_CONTAINER_NAME,
}; };
use semver::Version; use semver::Version;
use std::{collections::BTreeMap, fs::create_dir_all}; use std::{collections::BTreeMap, fs::create_dir_all};
pub mod generator; pub mod generator;
fn read_manifest(path: &std::path::Path) -> Result<Manifest, errors::LinkingError> {
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 { impl Project {
pub fn link_dependencies(&self, graph: &DownloadedGraph) -> Result<(), errors::LinkingError> { pub fn link_dependencies(&self, graph: &DownloadedGraph) -> Result<(), errors::LinkingError> {
let manifest = self.deser_manifest()?; let manifest = self.deser_manifest()?;
@ -106,8 +100,6 @@ impl Project {
node.node node.node
.container_folder(&packages_container_folder, name, version); .container_folder(&packages_container_folder, name, version);
let node_manifest = read_manifest(&container_folder)?;
if let Some((alias, types)) = package_types if let Some((alias, types)) = package_types
.get(name) .get(name)
.and_then(|v| v.get(version)) .and_then(|v| v.get(version))
@ -115,7 +107,7 @@ impl Project {
{ {
let module = generator::generate_linking_module( let module = generator::generate_linking_module(
&generator::get_require_path( &generator::get_require_path(
&node_manifest.target, &node.target,
&base_folder, &base_folder,
&container_folder, &container_folder,
node.node.pkg_ref.use_new_structure(), node.node.pkg_ref.use_new_structure(),
@ -145,8 +137,6 @@ impl Project {
dependency_version, dependency_version,
); );
let dependency_manifest = read_manifest(&dependency_container_folder)?;
let linker_folder = container_folder let linker_folder = container_folder
.join(dependency_node.node.base_folder(node.target.kind(), false)); .join(dependency_node.node.base_folder(node.target.kind(), false));
create_dir_all(&linker_folder)?; create_dir_all(&linker_folder)?;
@ -156,7 +146,7 @@ impl Project {
let module = generator::generate_linking_module( let module = generator::generate_linking_module(
&generator::get_require_path( &generator::get_require_path(
&dependency_manifest.target, &dependency_node.target,
&linker_file, &linker_file,
&dependency_container_folder, &dependency_container_folder,
node.node.pkg_ref.use_new_structure(), node.node.pkg_ref.use_new_structure(),
@ -185,9 +175,6 @@ pub mod errors {
#[error("error deserializing project manifest")] #[error("error deserializing project manifest")]
Manifest(#[from] crate::errors::ManifestReadError), Manifest(#[from] crate::errors::ManifestReadError),
#[error("error deserializing manifest at {0}")]
DependencyManifest(String, #[source] serde_yaml::Error),
#[error("error interacting with filesystem")] #[error("error interacting with filesystem")]
Io(#[from] std::io::Error), Io(#[from] std::io::Error),

View file

@ -49,8 +49,13 @@ pub fn insert_node(
graph: &mut DependencyGraph, graph: &mut DependencyGraph,
name: PackageNames, name: PackageNames,
version: Version, version: Version,
node: DependencyGraphNode, mut node: DependencyGraphNode,
is_top_level: bool,
) { ) {
if !is_top_level {
node.direct.take();
}
match graph match graph
.entry(name.clone()) .entry(name.clone())
.or_default() .or_default()
@ -89,7 +94,9 @@ pub type DownloadedGraph = Graph<DownloadedDependencyGraphNode>;
pub struct Lockfile { pub struct Lockfile {
pub name: PackageName, pub name: PackageName,
pub version: Version, pub version: Version,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>, pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub graph: DownloadedGraph, pub graph: DownloadedGraph,
} }

View file

@ -229,7 +229,7 @@ pub struct Manifest {
#[serde(default)] #[serde(default)]
pub indices: BTreeMap<String, url::Url>, pub indices: BTreeMap<String, url::Url>,
#[cfg(feature = "wally-compat")] #[cfg(feature = "wally-compat")]
#[serde(default)] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub wally_indices: BTreeMap<String, url::Url>, pub wally_indices: BTreeMap<String, url::Url>,
#[serde(default, skip_serializing)] #[serde(default, skip_serializing)]
pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>, pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>,

View file

@ -70,6 +70,7 @@ impl PackageName {
} }
#[derive(Debug, Deserialize, Serialize, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Deserialize, Serialize, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[serde(untagged)]
pub enum PackageNames { pub enum PackageNames {
Pesde(PackageName), Pesde(PackageName),
} }

View file

@ -45,7 +45,13 @@ impl Project {
} }
log::debug!("resolved {}@{} from old dependency graph", name, version); 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 let mut queue = node
.dependencies .dependencies
@ -71,6 +77,7 @@ impl Project {
dep_name.clone(), dep_name.clone(),
dep_version.clone(), dep_version.clone(),
dep_node.clone(), dep_node.clone(),
false,
); );
dep_node dep_node
@ -209,6 +216,7 @@ impl Project {
name.clone(), name.clone(),
target_version.clone(), target_version.clone(),
node.clone(), node.clone(),
depth == 0,
); );
log::debug!( log::debug!(

View file

@ -23,7 +23,7 @@ pub struct PesdePackageSource {
repo_url: gix::Url, repo_url: gix::Url,
} }
const OWNERS_FILE: &str = "owners.yaml"; const SCOPE_INFO_FILE: &str = "scope.toml";
impl PesdePackageSource { impl PesdePackageSource {
pub fn new(repo_url: gix::Url) -> Self { pub fn new(repo_url: gix::Url) -> Self {
@ -101,7 +101,7 @@ impl PesdePackageSource {
&self, &self,
file_path: I, file_path: I,
project: &Project, project: &Project,
) -> Result<Option<Vec<u8>>, Box<errors::ReadFile>> { ) -> Result<Option<String>, Box<errors::ReadFile>> {
let path = self.path(project); let path = self.path(project);
let repo = match gix::open(&path) { let repo = match gix::open(&path) {
@ -134,15 +134,19 @@ impl PesdePackageSource {
}; };
let blob = object.into_blob(); 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<IndexConfig, Box<errors::ConfigError>> { pub fn config(&self, project: &Project) -> Result<IndexConfig, Box<errors::ConfigError>> {
let file = self let file = self
.read_file(["config.yaml"], project) .read_file(["config.toml"], project)
.map_err(|e| Box::new(e.into()))?; .map_err(|e| Box::new(e.into()))?;
let bytes = match file {
Some(bytes) => bytes, let string = match file {
Some(s) => s,
None => { None => {
return Err(Box::new(errors::ConfigError::Missing( return Err(Box::new(errors::ConfigError::Missing(
self.repo_url.clone(), 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) Ok(config)
} }
@ -208,12 +212,16 @@ impl PesdePackageSource {
let package_name = inner_entry.filename().to_string(); let package_name = inner_entry.filename().to_string();
if package_name == OWNERS_FILE { if package_name == SCOPE_INFO_FILE {
continue; continue;
} }
let blob = object.into_blob(); 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, Ok(file) => file,
Err(e) => { Err(e) => {
return Err(Box::new(errors::AllPackagesError::Deserialize( return Err(Box::new(errors::AllPackagesError::Deserialize(
@ -227,10 +235,7 @@ impl PesdePackageSource {
// if this panics, it's an issue with the index. // if this panics, it's an issue with the index.
let name = format!("{package_scope}/{package_name}").parse().unwrap(); let name = format!("{package_scope}/{package_name}").parse().unwrap();
packages packages.insert(name, file);
.entry(name)
.or_default()
.insert(file.version.clone(), file);
} }
} }
@ -297,26 +302,26 @@ impl PackageSource for PesdePackageSource {
project: &Project, project: &Project,
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> { ) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> {
let (scope, name) = specifier.name.as_str(); let (scope, name) = specifier.name.as_str();
let bytes = match self.read_file([scope, name], project) { let string = match self.read_file([scope, name], project) {
Ok(Some(bytes)) => bytes, Ok(Some(s)) => s,
Ok(None) => return Err(Self::ResolveError::NotFound(specifier.name.to_string())), Ok(None) => return Err(Self::ResolveError::NotFound(specifier.name.to_string())),
Err(e) => return Err(Self::ResolveError::Read(specifier.name.to_string(), e)), Err(e) => return Err(Self::ResolveError::Read(specifier.name.to_string(), e)),
}; };
let entries: Vec<IndexFileEntry> = serde_yaml::from_slice(&bytes) let entries: IndexFile = toml::from_str(&string)
.map_err(|e| Self::ResolveError::Parse(specifier.name.to_string(), e))?; .map_err(|e| Self::ResolveError::Parse(specifier.name.to_string(), e))?;
Ok(( Ok((
PackageNames::Pesde(specifier.name.clone()), PackageNames::Pesde(specifier.name.clone()),
entries entries
.into_iter() .into_iter()
.filter(|entry| specifier.version.matches(&entry.version)) .filter(|(version, _)| specifier.version.matches(version))
.map(|entry| { .map(|(version, entry)| {
( (
entry.version.clone(), version.clone(),
PesdePackageRef { PesdePackageRef {
name: specifier.name.clone(), name: specifier.name.clone(),
version: entry.version, version,
index_url: self.repo_url.clone(), index_url: self.repo_url.clone(),
dependencies: entry.dependencies, dependencies: entry.dependencies,
target: entry.target, 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 struct IndexFileEntry {
pub version: Version,
pub target: Target, pub target: Target,
#[serde(default = "chrono::Utc::now")] #[serde(default = "chrono::Utc::now")]
pub published_at: chrono::DateTime<chrono::Utc>, pub published_at: chrono::DateTime<chrono::Utc>,
@ -402,20 +406,6 @@ pub struct IndexFileEntry {
pub dependencies: BTreeMap<String, (DependencySpecifiers, DependencyType)>, pub dependencies: BTreeMap<String, (DependencySpecifiers, DependencyType)>,
} }
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<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
pub type IndexFile = BTreeMap<Version, IndexFileEntry>; pub type IndexFile = BTreeMap<Version, IndexFileEntry>;
pub mod errors { pub mod errors {
@ -499,6 +489,9 @@ pub mod errors {
#[error("error looking up entry {0} in tree")] #[error("error looking up entry {0} in tree")]
Lookup(String, #[source] gix::object::find::existing::Error), 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)] #[derive(Debug, Error)]
@ -514,7 +507,10 @@ pub mod errors {
Read(String, #[source] Box<ReadFile>), Read(String, #[source] Box<ReadFile>),
#[error("error parsing file for {0}")] #[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)] #[derive(Debug, Error)]
@ -524,7 +520,7 @@ pub mod errors {
ReadFile(#[from] Box<ReadFile>), ReadFile(#[from] Box<ReadFile>),
#[error("error parsing config file")] #[error("error parsing config file")]
Parse(#[from] serde_yaml::Error), Parse(#[from] toml::de::Error),
#[error("missing config file for index at {0}")] #[error("missing config file for index at {0}")]
Missing(gix::Url), Missing(gix::Url),
@ -546,7 +542,10 @@ pub mod errors {
Convert(PathBuf, #[source] gix::object::find::existing::Error), Convert(PathBuf, #[source] gix::object::find::existing::Error),
#[error("error deserializing file {0} in repository at {1}")] #[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)] #[derive(Debug, Error)]