From 1c2d005fd42c6425a0f589b562613063eb096613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Mon, 4 Jul 2022 23:53:47 +1200 Subject: [PATCH 1/3] Write to .crates.toml --- Cargo.lock | 11 +++ Cargo.toml | 2 + src/helpers.rs | 2 +- src/lib.rs | 1 + src/main.rs | 20 +++++- src/metafiles.rs | 173 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 src/metafiles.rs diff --git a/Cargo.lock b/Cargo.lock index e03717bb..3a5a3bc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,6 +143,7 @@ dependencies = [ "flate2", "futures-util", "guess_host_triple", + "home", "log", "miette", "once_cell", @@ -158,6 +159,7 @@ dependencies = [ "thiserror", "tinytemplate", "tokio", + "toml", "url", "xz2", "zip", @@ -595,6 +597,15 @@ dependencies = [ "libc", ] +[[package]] +name = "home" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" +dependencies = [ + "winapi", +] + [[package]] name = "http" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index f121f595..aa0ee739 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ crates_io_api = { version = "0.8.0", default-features = false, features = ["rust dirs = "4.0.0" flate2 = { version = "1.0.24", features = ["zlib-ng"], default-features = false } futures-util = { version = "0.3.21", default-features = false } +home = "0.5.3" log = "0.4.14" miette = { version = "5.1.0", features = ["fancy-no-backtrace"] } once_cell = "1.12.0" @@ -43,6 +44,7 @@ tempfile = "3.3.0" thiserror = "1.0.31" tinytemplate = "1.2.1" tokio = { version = "1.19.1", features = ["rt-multi-thread", "process", "sync"], default-features = false } +toml = "0.5.9" url = "2.2.2" xz2 = "0.1.6" diff --git a/src/helpers.rs b/src/helpers.rs index e476464c..4be08709 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -6,7 +6,7 @@ use cargo_toml::Manifest; use futures_util::stream::Stream; use log::debug; use once_cell::sync::OnceCell; -use reqwest::{Client, ClientBuilder, Method, Response, tls}; +use reqwest::{tls, Client, ClientBuilder, Method, Response}; use serde::Serialize; use tinytemplate::TinyTemplate; use tokio::task::block_in_place; diff --git a/src/lib.rs b/src/lib.rs index 2ec0eb1b..eb475ac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub use helpers::*; pub mod bins; pub mod fetchers; +pub mod metafiles; mod target; pub use target::*; diff --git a/src/main.rs b/src/main.rs index f5684031..fffdccd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -201,7 +201,10 @@ async fn entry() -> Result<()> { // Initialize REQWESTGLOBALCONFIG REQWESTGLOBALCONFIG - .set(ReqwestConfig { secure: opts.secure, min_tls: opts.min_tls_version.map(|v| v.into()) }) + .set(ReqwestConfig { + secure: opts.secure, + min_tls: opts.min_tls_version.map(|v| v.into()), + }) .unwrap(); // Setup logging @@ -451,6 +454,21 @@ async fn install_from_package( uithread.confirm().await?; + debug!("Writing .crates.toml"); + if let Ok(mut ctoml) = metafiles::CratesToml::load().await { + ctoml.insert( + metafiles::CrateVersionSource { + name: opts.name.into(), + version: package.version.parse().into_diagnostic()?, + source: metafiles::Source::Registry( + url::Url::parse("https://github.com/rust-lang/crates.io-index").unwrap(), + ), + }, + bin_files.iter().map(|bin| bin.base_name.clone()), + ); + ctoml.write().await?; + } + info!("Installing binaries..."); block_in_place(|| { for file in &bin_files { diff --git a/src/metafiles.rs b/src/metafiles.rs new file mode 100644 index 00000000..013d31be --- /dev/null +++ b/src/metafiles.rs @@ -0,0 +1,173 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + fmt, + path::{Path, PathBuf}, + str::FromStr, +}; + +use miette::Diagnostic; +use semver::Version; +use serde::{Deserialize, Serialize}; +use thiserror::Error; +use tokio::fs; +use url::Url; + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct CratesTomlRaw { + #[serde(default)] + pub v1: BTreeMap>, +} + +#[derive(Clone, Debug, Default)] +pub struct CratesToml(BTreeMap>); + +impl CratesToml { + pub fn default_path() -> Result { + Ok(home::cargo_home()?.join(".crates.toml")) + } + + pub async fn load() -> Result { + Self::load_from_path(Self::default_path()?).await + } + + pub async fn load_from_path(path: impl AsRef) -> Result { + let file = fs::read_to_string(path).await?; + Self::from_str(&file) + } + + pub fn insert(&mut self, cvs: CrateVersionSource, bins: impl Iterator) { + self.0.insert(cvs, bins.collect()); + } + + pub async fn write(&self) -> Result<(), CratesTomlParseError> { + self.write_to_path(Self::default_path()?).await + } + + pub async fn write_to_path(&self, path: impl AsRef) -> Result<(), CratesTomlParseError> { + let raw = CratesTomlRaw { + v1: self + .0 + .iter() + .map(|(cvs, bins)| (cvs.to_string(), bins.clone())) + .collect(), + }; + + fs::write(path, &toml::to_vec(&raw)?).await?; + Ok(()) + } +} + +impl FromStr for CratesToml { + type Err = CratesTomlParseError; + fn from_str(s: &str) -> Result { + let raw: CratesTomlRaw = toml::from_str(s).unwrap(); + + Ok(Self( + raw.v1 + .into_iter() + .map(|(name, bins)| CrateVersionSource::from_str(&name).map(|cvs| (cvs, bins))) + .collect::>()?, + )) + } +} + +#[derive(Debug, Diagnostic, Error)] +pub enum CratesTomlParseError { + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + TomlParse(#[from] toml::de::Error), + + #[error(transparent)] + TomlWrite(#[from] toml::ser::Error), + + #[error(transparent)] + CvsParse(#[from] CvsParseError), +} + +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +pub struct CrateVersionSource { + pub name: String, + pub version: Version, + pub source: Source, +} + +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +pub enum Source { + Git(Url), + Path(Url), + Registry(Url), +} + +impl FromStr for CrateVersionSource { + type Err = CvsParseError; + fn from_str(s: &str) -> Result { + match s.splitn(3, ' ').collect::>()[..] { + [name, version, source] => { + let version = version.parse()?; + let source = match source + .trim_matches(&['(', ')'][..]) + .splitn(2, '+') + .collect::>()[..] + { + ["git", url] => Source::Git(Url::parse(url)?), + ["path", url] => Source::Path(Url::parse(url)?), + ["registry", url] => Source::Registry(Url::parse(url)?), + [kind, arg] => { + return Err(CvsParseError::UnknownSourceType { + kind: kind.to_string(), + arg: arg.to_string(), + }) + } + _ => return Err(CvsParseError::BadSource), + }; + Ok(Self { + name: name.to_string(), + version, + source, + }) + } + _ => Err(CvsParseError::BadFormat), + } + } +} + +#[derive(Debug, Diagnostic, Error)] +pub enum CvsParseError { + #[error(transparent)] + UrlParse(#[from] url::ParseError), + + #[error(transparent)] + VersionParse(#[from] semver::Error), + + #[error("unknown source type {kind}+{arg}")] + UnknownSourceType { kind: String, arg: String }, + + #[error("bad source format")] + BadSource, + + #[error("bad CVS format")] + BadFormat, +} + +impl fmt::Display for CrateVersionSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + name, + version, + source, + } = &self; + write!(f, "{name} {version} ({source})") + } +} + +impl fmt::Display for Source { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Source::Git(url) => write!(f, "git+{url}"), + Source::Path(url) => write!(f, "path+{url}"), + Source::Registry(url) => write!(f, "registry+{url}"), + } + } +} From 17cf6f5dc5817489bbd9d0055511ebc274657fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Tue, 5 Jul 2022 00:32:08 +1200 Subject: [PATCH 2/3] Write to .crates2.json --- Cargo.lock | 5 +- Cargo.toml | 1 + src/main.rs | 46 +++++++---- src/metafiles.rs | 176 +------------------------------------------ src/metafiles/cvs.rs | 111 +++++++++++++++++++++++++++ src/metafiles/v1.rs | 67 ++++++++++++++++ src/metafiles/v2.rs | 78 +++++++++++++++++++ 7 files changed, 296 insertions(+), 188 deletions(-) create mode 100644 src/metafiles/cvs.rs create mode 100644 src/metafiles/v1.rs create mode 100644 src/metafiles/v2.rs diff --git a/Cargo.lock b/Cargo.lock index 3a5a3bc7..9fad27a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,7 @@ dependencies = [ "scopeguard", "semver", "serde", + "serde_json", "simplelog", "strum", "strum_macros", @@ -1204,9 +1205,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index aa0ee739..453e0d2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ reqwest = { version = "0.11.11", features = ["rustls-tls", "stream"], default-fe scopeguard = "1.1.0" semver = "1.0.10" serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0.82" simplelog = "0.12.0" strum = "0.24.1" strum_macros = "0.24.2" diff --git a/src/main.rs b/src/main.rs index fffdccd0..4b331aa4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use std::{ + collections::BTreeSet, ffi::OsString, path::PathBuf, process::{ExitCode, Termination}, @@ -454,20 +455,13 @@ async fn install_from_package( uithread.confirm().await?; - debug!("Writing .crates.toml"); - if let Ok(mut ctoml) = metafiles::CratesToml::load().await { - ctoml.insert( - metafiles::CrateVersionSource { - name: opts.name.into(), - version: package.version.parse().into_diagnostic()?, - source: metafiles::Source::Registry( - url::Url::parse("https://github.com/rust-lang/crates.io-index").unwrap(), - ), - }, - bin_files.iter().map(|bin| bin.base_name.clone()), - ); - ctoml.write().await?; - } + let cvs = metafiles::CrateVersionSource { + name: opts.name, + version: package.version.parse().into_diagnostic()?, + source: metafiles::Source::Registry( + url::Url::parse("https://github.com/rust-lang/crates.io-index").unwrap(), + ), + }; info!("Installing binaries..."); block_in_place(|| { @@ -490,6 +484,30 @@ async fn install_from_package( }); } + let bins: BTreeSet = bin_files.iter().map(|bin| bin.base_name.clone()).collect(); + + debug!("Writing .crates.toml"); + if let Ok(mut c1) = metafiles::v1::CratesToml::load() { + c1.insert(cvs.clone(), bins.clone()); + c1.write()?; + } + + debug!("Writing .crates2.json"); + if let Ok(mut c2) = metafiles::v2::Crates2Json::load() { + c2.insert( + cvs.clone(), + metafiles::v2::CrateInfo { + version_req: Some(opts.version), + bins, + profile: "release".into(), + target: fetcher.target().to_string(), + rustc: format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")), + ..Default::default() + }, + ); + c2.write()?; + } + Ok(()) }) } diff --git a/src/metafiles.rs b/src/metafiles.rs index 013d31be..06323a52 100644 --- a/src/metafiles.rs +++ b/src/metafiles.rs @@ -1,173 +1,5 @@ -use std::{ - collections::{BTreeMap, BTreeSet}, - fmt, - path::{Path, PathBuf}, - str::FromStr, -}; +mod cvs; +pub use cvs::*; -use miette::Diagnostic; -use semver::Version; -use serde::{Deserialize, Serialize}; -use thiserror::Error; -use tokio::fs; -use url::Url; - -#[derive(Clone, Debug, Default, Deserialize, Serialize)] -pub struct CratesTomlRaw { - #[serde(default)] - pub v1: BTreeMap>, -} - -#[derive(Clone, Debug, Default)] -pub struct CratesToml(BTreeMap>); - -impl CratesToml { - pub fn default_path() -> Result { - Ok(home::cargo_home()?.join(".crates.toml")) - } - - pub async fn load() -> Result { - Self::load_from_path(Self::default_path()?).await - } - - pub async fn load_from_path(path: impl AsRef) -> Result { - let file = fs::read_to_string(path).await?; - Self::from_str(&file) - } - - pub fn insert(&mut self, cvs: CrateVersionSource, bins: impl Iterator) { - self.0.insert(cvs, bins.collect()); - } - - pub async fn write(&self) -> Result<(), CratesTomlParseError> { - self.write_to_path(Self::default_path()?).await - } - - pub async fn write_to_path(&self, path: impl AsRef) -> Result<(), CratesTomlParseError> { - let raw = CratesTomlRaw { - v1: self - .0 - .iter() - .map(|(cvs, bins)| (cvs.to_string(), bins.clone())) - .collect(), - }; - - fs::write(path, &toml::to_vec(&raw)?).await?; - Ok(()) - } -} - -impl FromStr for CratesToml { - type Err = CratesTomlParseError; - fn from_str(s: &str) -> Result { - let raw: CratesTomlRaw = toml::from_str(s).unwrap(); - - Ok(Self( - raw.v1 - .into_iter() - .map(|(name, bins)| CrateVersionSource::from_str(&name).map(|cvs| (cvs, bins))) - .collect::>()?, - )) - } -} - -#[derive(Debug, Diagnostic, Error)] -pub enum CratesTomlParseError { - #[error(transparent)] - Io(#[from] std::io::Error), - - #[error(transparent)] - TomlParse(#[from] toml::de::Error), - - #[error(transparent)] - TomlWrite(#[from] toml::ser::Error), - - #[error(transparent)] - CvsParse(#[from] CvsParseError), -} - -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] -pub struct CrateVersionSource { - pub name: String, - pub version: Version, - pub source: Source, -} - -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] -pub enum Source { - Git(Url), - Path(Url), - Registry(Url), -} - -impl FromStr for CrateVersionSource { - type Err = CvsParseError; - fn from_str(s: &str) -> Result { - match s.splitn(3, ' ').collect::>()[..] { - [name, version, source] => { - let version = version.parse()?; - let source = match source - .trim_matches(&['(', ')'][..]) - .splitn(2, '+') - .collect::>()[..] - { - ["git", url] => Source::Git(Url::parse(url)?), - ["path", url] => Source::Path(Url::parse(url)?), - ["registry", url] => Source::Registry(Url::parse(url)?), - [kind, arg] => { - return Err(CvsParseError::UnknownSourceType { - kind: kind.to_string(), - arg: arg.to_string(), - }) - } - _ => return Err(CvsParseError::BadSource), - }; - Ok(Self { - name: name.to_string(), - version, - source, - }) - } - _ => Err(CvsParseError::BadFormat), - } - } -} - -#[derive(Debug, Diagnostic, Error)] -pub enum CvsParseError { - #[error(transparent)] - UrlParse(#[from] url::ParseError), - - #[error(transparent)] - VersionParse(#[from] semver::Error), - - #[error("unknown source type {kind}+{arg}")] - UnknownSourceType { kind: String, arg: String }, - - #[error("bad source format")] - BadSource, - - #[error("bad CVS format")] - BadFormat, -} - -impl fmt::Display for CrateVersionSource { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - name, - version, - source, - } = &self; - write!(f, "{name} {version} ({source})") - } -} - -impl fmt::Display for Source { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Source::Git(url) => write!(f, "git+{url}"), - Source::Path(url) => write!(f, "path+{url}"), - Source::Registry(url) => write!(f, "registry+{url}"), - } - } -} +pub mod v1; +pub mod v2; diff --git a/src/metafiles/cvs.rs b/src/metafiles/cvs.rs new file mode 100644 index 00000000..a111d02f --- /dev/null +++ b/src/metafiles/cvs.rs @@ -0,0 +1,111 @@ +use std::{fmt, str::FromStr}; + +use miette::Diagnostic; +use semver::Version; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use thiserror::Error; +use url::Url; + +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +pub struct CrateVersionSource { + pub name: String, + pub version: Version, + pub source: Source, +} + +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +pub enum Source { + Git(Url), + Path(Url), + Registry(Url), +} + +impl FromStr for CrateVersionSource { + type Err = CvsParseError; + fn from_str(s: &str) -> Result { + match s.splitn(3, ' ').collect::>()[..] { + [name, version, source] => { + let version = version.parse()?; + let source = match source + .trim_matches(&['(', ')'][..]) + .splitn(2, '+') + .collect::>()[..] + { + ["git", url] => Source::Git(Url::parse(url)?), + ["path", url] => Source::Path(Url::parse(url)?), + ["registry", url] => Source::Registry(Url::parse(url)?), + [kind, arg] => { + return Err(CvsParseError::UnknownSourceType { + kind: kind.to_string(), + arg: arg.to_string(), + }) + } + _ => return Err(CvsParseError::BadSource), + }; + Ok(Self { + name: name.to_string(), + version, + source, + }) + } + _ => Err(CvsParseError::BadFormat), + } + } +} + +#[derive(Debug, Diagnostic, Error)] +pub enum CvsParseError { + #[error(transparent)] + UrlParse(#[from] url::ParseError), + + #[error(transparent)] + VersionParse(#[from] semver::Error), + + #[error("unknown source type {kind}+{arg}")] + UnknownSourceType { kind: String, arg: String }, + + #[error("bad source format")] + BadSource, + + #[error("bad CVS format")] + BadFormat, +} + +impl fmt::Display for CrateVersionSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + name, + version, + source, + } = &self; + write!(f, "{name} {version} ({source})") + } +} + +impl fmt::Display for Source { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Source::Git(url) => write!(f, "git+{url}"), + Source::Path(url) => write!(f, "path+{url}"), + Source::Registry(url) => write!(f, "registry+{url}"), + } + } +} + +impl Serialize for CrateVersionSource { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for CrateVersionSource { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Self::from_str(&String::deserialize(deserializer)?).map_err(serde::de::Error::custom) + } +} diff --git a/src/metafiles/v1.rs b/src/metafiles/v1.rs new file mode 100644 index 00000000..1180814a --- /dev/null +++ b/src/metafiles/v1.rs @@ -0,0 +1,67 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::{Path, PathBuf}, + str::FromStr, +}; + +use miette::Diagnostic; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use super::CrateVersionSource; + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct CratesToml { + v1: BTreeMap>, +} + +impl CratesToml { + pub fn default_path() -> Result { + Ok(home::cargo_home()?.join(".crates.toml")) + } + + pub fn load() -> Result { + Self::load_from_path(Self::default_path()?) + } + + pub fn load_from_path(path: impl AsRef) -> Result { + let file = fs::read_to_string(path)?; + Self::from_str(&file) + } + + pub fn insert(&mut self, cvs: CrateVersionSource, bins: BTreeSet) { + self.v1.insert(cvs, bins); + } + + pub fn write(&self) -> Result<(), CratesTomlParseError> { + self.write_to_path(Self::default_path()?) + } + + pub fn write_to_path(&self, path: impl AsRef) -> Result<(), CratesTomlParseError> { + fs::write(path, &toml::to_vec(&self)?)?; + Ok(()) + } +} + +impl FromStr for CratesToml { + type Err = CratesTomlParseError; + fn from_str(s: &str) -> Result { + Ok(toml::from_str(s)?) + } +} + +#[derive(Debug, Diagnostic, Error)] +pub enum CratesTomlParseError { + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + TomlParse(#[from] toml::de::Error), + + #[error(transparent)] + TomlWrite(#[from] toml::ser::Error), + + #[error(transparent)] + CvsParse(#[from] super::CvsParseError), +} diff --git a/src/metafiles/v2.rs b/src/metafiles/v2.rs new file mode 100644 index 00000000..70c4e46e --- /dev/null +++ b/src/metafiles/v2.rs @@ -0,0 +1,78 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::{Path, PathBuf}, +}; + +use miette::Diagnostic; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use super::CrateVersionSource; + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct Crates2Json { + pub installs: BTreeMap, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct CrateInfo { + #[serde(default)] + pub version_req: Option, + + #[serde(default)] + pub bins: BTreeSet, + + #[serde(default)] + pub features: BTreeSet, + + #[serde(default)] + pub all_features: bool, + + #[serde(default)] + pub no_default_features: bool, + + pub profile: String, + pub target: String, + pub rustc: String, +} + +impl Crates2Json { + pub fn default_path() -> Result { + Ok(home::cargo_home()?.join(".crates2.json")) + } + + pub fn load() -> Result { + Self::load_from_path(Self::default_path()?) + } + + pub fn load_from_path(path: impl AsRef) -> Result { + let file = fs::read_to_string(path)?; + Ok(serde_json::from_str(&file)?) + } + + pub fn insert(&mut self, cvs: CrateVersionSource, info: CrateInfo) { + self.installs.insert(cvs, info); + } + + pub fn write(&self) -> Result<(), Crates2JsonParseError> { + self.write_to_path(Self::default_path()?) + } + + pub fn write_to_path(&self, path: impl AsRef) -> Result<(), Crates2JsonParseError> { + fs::write(path, &serde_json::to_vec(&self)?)?; + Ok(()) + } +} + +#[derive(Debug, Diagnostic, Error)] +pub enum Crates2JsonParseError { + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Json(#[from] serde_json::Error), + + #[error(transparent)] + CvsParse(#[from] super::CvsParseError), +} From 68ba9b06f5252d4baabd7a8a7cf326af4e5fb3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Tue, 5 Jul 2022 21:46:58 +1200 Subject: [PATCH 3/3] Create meta files if not present --- src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4b331aa4..5a155bad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -486,14 +486,16 @@ async fn install_from_package( let bins: BTreeSet = bin_files.iter().map(|bin| bin.base_name.clone()).collect(); - debug!("Writing .crates.toml"); - if let Ok(mut c1) = metafiles::v1::CratesToml::load() { + { + debug!("Writing .crates.toml"); + let mut c1 = metafiles::v1::CratesToml::load().unwrap_or_default(); c1.insert(cvs.clone(), bins.clone()); c1.write()?; } - debug!("Writing .crates2.json"); - if let Ok(mut c2) = metafiles::v2::Crates2Json::load() { + { + debug!("Writing .crates2.json"); + let mut c2 = metafiles::v2::Crates2Json::load().unwrap_or_default(); c2.insert( cvs.clone(), metafiles::v2::CrateInfo {