diff --git a/Cargo.lock b/Cargo.lock index 058ca20d..cf16d38f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -246,8 +246,8 @@ version = "0.15.0" dependencies = [ "async-trait", "atomic-file-install", - "base16", "binstalk-downloader", + "binstalk-registry", "binstalk-types", "cargo-toml-workspace", "command-group", @@ -264,18 +264,13 @@ dependencies = [ "normalize-path", "once_cell", "semver", - "serde", - "serde_json", - "sha2", "strum", "target-lexicon", "tempfile", "thiserror", "tokio", - "toml_edit", "tracing", "url", - "xz2", ] [[package]] @@ -335,6 +330,32 @@ dependencies = [ "url", ] +[[package]] +name = "binstalk-registry" +version = "0.0.0" +dependencies = [ + "async-trait", + "base16", + "binstalk-downloader", + "binstalk-types", + "cargo-toml-workspace", + "compact_str", + "leon", + "miette", + "normalize-path", + "once_cell", + "semver", + "serde", + "serde_json", + "sha2", + "tempfile", + "thiserror", + "tokio", + "toml_edit", + "tracing", + "url", +] + [[package]] name = "binstalk-types" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 365c1fdd..39c2e512 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "crates/atomic-file-install", "crates/bin", "crates/binstalk", + "crates/binstalk-registry", "crates/binstalk-manifests", "crates/binstalk-types", "crates/binstalk-downloader", diff --git a/crates/bin/src/args.rs b/crates/bin/src/args.rs index 55162bd0..31ef8885 100644 --- a/crates/bin/src/args.rs +++ b/crates/bin/src/args.rs @@ -8,10 +8,10 @@ use std::{ }; use binstalk::{ - drivers::Registry, helpers::remote, manifests::cargo_toml_binstall::PkgFmt, ops::resolve::{CrateName, VersionReqExt}, + registry::Registry, }; use clap::{error::ErrorKind, CommandFactory, Parser, ValueEnum}; use compact_str::CompactString; @@ -102,7 +102,7 @@ pub struct Args { /// /// This option cannot be used with `--manifest-path`. #[clap(help_heading = "Overrides", long, conflicts_with("manifest_path"))] - pub(crate) git: Option, + pub(crate) git: Option, /// Override Cargo.toml package manifest bin-dir. #[clap(help_heading = "Overrides", long)] diff --git a/crates/binstalk-downloader/src/remote.rs b/crates/binstalk-downloader/src/remote.rs index 6d7e7713..e32a4ab8 100644 --- a/crates/binstalk-downloader/src/remote.rs +++ b/crates/binstalk-downloader/src/remote.rs @@ -37,6 +37,7 @@ const MAX_RETRY_DURATION: Duration = Duration::from_secs(120); const MAX_RETRY_COUNT: u8 = 3; const DEFAULT_RETRY_DURATION_FOR_RATE_LIMIT: Duration = Duration::from_millis(200); const RETRY_DURATION_FOR_TIMEOUT: Duration = Duration::from_millis(200); +#[allow(dead_code)] const DEFAULT_MIN_TLS: TLSVersion = TLSVersion::TLS_1_2; #[derive(Debug, ThisError)] diff --git a/crates/binstalk-registry/Cargo.toml b/crates/binstalk-registry/Cargo.toml new file mode 100644 index 00000000..a021c8d0 --- /dev/null +++ b/crates/binstalk-registry/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "binstalk-registry" +version = "0.0.0" +edition = "2021" +rust-version = "1.65.0" + +description = "The binstall toolkit for fetching package from arbitrary registry" +repository = "https://github.com/cargo-bins/cargo-binstall" +documentation = "https://docs.rs/binstalk-registry" +authors = ["Jiahao_XU@outlook "] +license = "Apache-2.0 OR MIT" + +[dependencies] +async-trait = "0.1.68" +base16 = "0.2.1" +binstalk-downloader = { version = "0.7.0", path = "../binstalk-downloader", default-features = false, features = ["json"] } +binstalk-types = { version = "0.5.0", path = "../binstalk-types" } +cargo-toml-workspace = { version = "0.0.0", path = "../cargo-toml-workspace" } +compact_str = { version = "0.7.0", features = ["serde"] } +leon = { version = "2.0.1", path = "../leon" } +miette = "5.9.0" +normalize-path = { version = "0.2.1", path = "../normalize-path" } +once_cell = "1.18.0" +semver = { version = "1.0.17", features = ["serde"] } +serde = { version = "1.0.163", features = ["derive"] } +serde_json = "1.0.99" +sha2 = "0.10.7" +tempfile = "3.5.0" +thiserror = "1.0.40" +tokio = { version = "1.30.0", features = ["rt", "sync", "time"], default-features = false } +tracing = "0.1.37" +url = "2.3.1" + +[dev-dependencies] +tokio = { version = "1", features = ["rt-multi-thread", "macros"] } +toml_edit = { version = "0.19.11", features = ["serde"] } + +[features] +git = ["binstalk-downloader/git"] + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crates/binstalk-registry/LICENSE-APACHE b/crates/binstalk-registry/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/crates/binstalk-registry/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/crates/binstalk-registry/LICENSE-MIT b/crates/binstalk-registry/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/crates/binstalk-registry/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/crates/binstalk/src/drivers/registry/common.rs b/crates/binstalk-registry/src/common.rs similarity index 90% rename from crates/binstalk/src/drivers/registry/common.rs rename to crates/binstalk-registry/src/common.rs index a471ffed..c5574e46 100644 --- a/crates/binstalk/src/drivers/registry/common.rs +++ b/crates/binstalk-registry/src/common.rs @@ -1,6 +1,13 @@ use std::borrow::Cow; use base16::{decode as decode_base16, encode_lower as encode_base16}; +use binstalk_downloader::{ + bytes::Bytes, + download::{DataVerifier, Download}, + remote::{Client, Url}, +}; +use binstalk_types::cargo_toml_binstall::{Meta, TarBasedFmt}; +use cargo_toml_workspace::cargo_toml::Manifest; use compact_str::{format_compact, CompactString, ToCompactString}; use leon::{Template, Values}; use semver::{Version, VersionReq}; @@ -9,17 +16,7 @@ use serde_json::Error as JsonError; use sha2::{Digest, Sha256}; use tracing::debug; -use crate::{ - drivers::registry::{visitor::ManifestVisitor, RegistryError}, - errors::BinstallError, - helpers::{ - bytes::Bytes, - cargo_toml::Manifest, - download::{DataVerifier, Download}, - remote::{Client, Url}, - }, - manifests::cargo_toml_binstall::{Meta, TarBasedFmt}, -}; +use crate::{visitor::ManifestVisitor, RegistryError}; #[derive(Deserialize)] pub(super) struct RegistryConfig { @@ -45,7 +42,7 @@ pub(super) async fn parse_manifest( crate_name: &str, crate_url: Url, MatchedVersion { version, cksum }: MatchedVersion, -) -> Result, BinstallError> { +) -> Result, RegistryError> { debug!("Fetching crate from: {crate_url} and extracting Cargo.toml from it"); let mut manifest_visitor = ManifestVisitor::new(format!("{crate_name}-{version}").into()); @@ -61,10 +58,9 @@ pub(super) async fn parse_manifest( if digest_checksum.as_slice() != checksum.as_slice() { Err(RegistryError::UnmatchedChecksum { - expected: cksum, - actual: encode_base16(digest_checksum.as_slice()), - } - .into()) + expected: cksum.into(), + actual: encode_base16(digest_checksum.as_slice()).into(), + }) } else { manifest_visitor.load_manifest() } @@ -154,7 +150,7 @@ impl MatchedVersion { pub(super) fn find( it: &mut dyn Iterator>, version_req: &VersionReq, - ) -> Result { + ) -> Result { let mut ret = Option::<(Self, Version)>::None; for res in it { @@ -189,7 +185,7 @@ impl MatchedVersion { } ret.map(|(num, _)| num) - .ok_or_else(|| BinstallError::VersionMismatch { + .ok_or_else(|| RegistryError::VersionMismatch { req: version_req.clone(), }) } diff --git a/crates/binstalk/src/drivers/registry/crates_io_registry.rs b/crates/binstalk-registry/src/crates_io_registry.rs similarity index 93% rename from crates/binstalk/src/drivers/registry/crates_io_registry.rs rename to crates/binstalk-registry/src/crates_io_registry.rs index 8649a331..31859df3 100644 --- a/crates/binstalk/src/drivers/registry/crates_io_registry.rs +++ b/crates/binstalk-registry/src/crates_io_registry.rs @@ -1,4 +1,6 @@ -use binstalk_downloader::remote::Error as RemoteError; +use binstalk_downloader::remote::{Client, Error as RemoteError, Url}; +use binstalk_types::cargo_toml_binstall::Meta; +use cargo_toml_workspace::cargo_toml::Manifest; use compact_str::{CompactString, ToCompactString}; use semver::{Comparator, Op as ComparatorOp, Version as SemVersion, VersionReq}; use serde::Deserialize; @@ -8,15 +10,7 @@ use tokio::{ }; use tracing::debug; -use crate::{ - drivers::registry::{parse_manifest, MatchedVersion, RegistryError}, - errors::BinstallError, - helpers::{ - cargo_toml::Manifest, - remote::{Client, Url}, - }, - manifests::cargo_toml_binstall::Meta, -}; +use crate::{parse_manifest, MatchedVersion, RegistryError}; #[derive(Debug)] pub struct CratesIoRateLimit(Mutex); @@ -148,7 +142,7 @@ pub async fn fetch_crate_cratesio( name: &str, version_req: &VersionReq, crates_io_rate_limit: &CratesIoRateLimit, -) -> Result, BinstallError> { +) -> Result, RegistryError> { // Wait until we can make another request to crates.io crates_io_rate_limit.tick().await; @@ -184,7 +178,7 @@ pub async fn fetch_crate_cratesio( RemoteError::Http(e) if e.is_status() => RegistryError::NotFound(name.into()), e => e.into(), })? - .ok_or_else(|| BinstallError::VersionMismatch { + .ok_or_else(|| RegistryError::VersionMismatch { req: version_req.clone(), })?; diff --git a/crates/binstalk/src/drivers/registry/git_registry.rs b/crates/binstalk-registry/src/git_registry.rs similarity index 87% rename from crates/binstalk/src/drivers/registry/git_registry.rs rename to crates/binstalk-registry/src/git_registry.rs index c72b504a..511d59f0 100644 --- a/crates/binstalk/src/drivers/registry/git_registry.rs +++ b/crates/binstalk-registry/src/git_registry.rs @@ -1,5 +1,11 @@ use std::{io, path::PathBuf, sync::Arc}; +use binstalk_downloader::{ + git::{GitCancellationToken, GitUrl, Repository}, + remote::Client, +}; +use binstalk_types::cargo_toml_binstall::Meta; +use cargo_toml_workspace::cargo_toml::Manifest; use compact_str::{CompactString, ToCompactString}; use once_cell::sync::OnceCell; use semver::VersionReq; @@ -9,17 +15,8 @@ use tokio::task::spawn_blocking; use url::Url; use crate::{ - drivers::registry::{ - crate_prefix_components, parse_manifest, render_dl_template, MatchedVersion, - RegistryConfig, RegistryError, - }, - errors::BinstallError, - helpers::{ - cargo_toml::Manifest, - git::{GitCancellationToken, GitUrl, Repository}, - remote::Client, - }, - manifests::cargo_toml_binstall::Meta, + crate_prefix_components, parse_manifest, render_dl_template, MatchedVersion, RegistryConfig, + RegistryError, }; #[derive(Debug)] @@ -30,7 +27,7 @@ struct GitIndex { } impl GitIndex { - fn new(url: GitUrl, cancellation_token: GitCancellationToken) -> Result { + fn new(url: GitUrl, cancellation_token: GitCancellationToken) -> Result { let tempdir = TempDir::new()?; let repo = Repository::shallow_clone_bare( @@ -83,7 +80,7 @@ impl GitRegistry { crate_name: &str, (c1, c2): &(CompactString, Option), version_req: &VersionReq, - ) -> Result { + ) -> Result { let mut path = PathBuf::with_capacity(128); path.push(&**c1); if let Some(c2) = c2 { @@ -106,7 +103,7 @@ impl GitRegistry { client: Client, name: &str, version_req: &VersionReq, - ) -> Result, BinstallError> { + ) -> Result, RegistryError> { let crate_prefix = crate_prefix_components(name)?; let crate_name = name.to_compact_string(); let version_req = version_req.clone(); @@ -136,7 +133,7 @@ impl GitRegistry { &matched_version, )?)?; - Ok::<_, BinstallError>((matched_version, url)) + Ok::<_, RegistryError>((matched_version, url)) }) .await??; diff --git a/crates/binstalk/src/drivers/registry.rs b/crates/binstalk-registry/src/lib.rs similarity index 81% rename from crates/binstalk/src/drivers/registry.rs rename to crates/binstalk-registry/src/lib.rs index b010a198..eb273b22 100644 --- a/crates/binstalk/src/drivers/registry.rs +++ b/crates/binstalk-registry/src/lib.rs @@ -1,24 +1,25 @@ -use std::{str::FromStr, sync::Arc}; +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + +use std::{io, str::FromStr, sync::Arc}; use base16::DecodeError as Base16DecodeError; +use binstalk_downloader::{ + download::DownloadError, + remote::{Client, Error as RemoteError}, +}; +use binstalk_types::cargo_toml_binstall::Meta; +use cargo_toml_workspace::cargo_toml::{Error as CargoTomlError, Manifest}; use compact_str::CompactString; use leon::{ParseError, RenderError}; use miette::Diagnostic; use semver::VersionReq; use serde_json::Error as JsonError; use thiserror::Error as ThisError; - -use crate::{ - errors::BinstallError, - helpers::{ - cargo_toml::Manifest, - remote::{Client, Error as RemoteError, Url, UrlParseError}, - }, - manifests::cargo_toml_binstall::Meta, -}; +use tokio::task; +use url::{ParseError as UrlParseError, Url}; #[cfg(feature = "git")] -pub use crate::helpers::git::{GitUrl, GitUrlParseError}; +pub use binstalk_downloader::git::{GitError, GitUrl, GitUrlParseError}; mod vfs; @@ -64,7 +65,39 @@ pub enum RegistryError { InvalidHex(#[from] Base16DecodeError), #[error("Expected checksum `{expected}`, actual checksum `{actual}`")] - UnmatchedChecksum { expected: String, actual: String }, + UnmatchedChecksum { + expected: Box, + actual: Box, + }, + + #[error("no version matching requirement '{req}'")] + VersionMismatch { req: semver::VersionReq }, + + #[error("Failed to parse cargo manifest: {0}")] + #[diagnostic(help("If you used --manifest-path, check the Cargo.toml syntax."))] + CargoManifest(#[from] Box), + + #[error("Failed to parse url: {0}")] + UrlParse(#[from] url::ParseError), + + #[error(transparent)] + Download(#[from] DownloadError), + + #[error("I/O Error: {0}")] + Io(#[from] io::Error), + + #[error(transparent)] + TaskJoinError(#[from] task::JoinError), + + #[cfg(feature = "git")] + #[error("Failed to shallow clone git repository: {0}")] + GitError(#[from] GitError), +} + +impl From for RegistryError { + fn from(e: CargoTomlError) -> Self { + Self::from(Box::new(e)) + } } #[derive(Clone, Debug)] @@ -101,8 +134,8 @@ enum InvalidRegistryErrorInner { #[error("failed to parse sparse registry url: {0}")] UrlParseErr(#[from] UrlParseError), - #[error("expected protocol http(s), actual protocl {0}")] - InvalidScheme(CompactString), + #[error("expected protocol http(s), actual url `{0}`")] + InvalidScheme(Box), #[cfg(not(feature = "git"))] #[error("git registry not supported")] @@ -116,7 +149,7 @@ impl Registry { let scheme = url.scheme(); if scheme != "http" && scheme != "https" { - Err(InvalidRegistryErrorInner::InvalidScheme(scheme.into())) + Err(InvalidRegistryErrorInner::InvalidScheme(Box::new(url))) } else { Ok(Self::Sparse(Arc::new(SparseRegistry::new(url)))) } @@ -140,7 +173,7 @@ impl Registry { client: Client, crate_name: &str, version_req: &VersionReq, - ) -> Result, BinstallError> { + ) -> Result, RegistryError> { match self { Self::CratesIo(rate_limit) => { fetch_crate_cratesio(client, crate_name, version_req, rate_limit).await diff --git a/crates/binstalk/src/drivers/registry/sparse_registry.rs b/crates/binstalk-registry/src/sparse_registry.rs similarity index 86% rename from crates/binstalk/src/drivers/registry/sparse_registry.rs rename to crates/binstalk-registry/src/sparse_registry.rs index 18bcf91d..e03197ad 100644 --- a/crates/binstalk/src/drivers/registry/sparse_registry.rs +++ b/crates/binstalk-registry/src/sparse_registry.rs @@ -1,3 +1,6 @@ +use binstalk_downloader::remote::{Client, Error as RemoteError}; +use binstalk_types::cargo_toml_binstall::Meta; +use cargo_toml_workspace::cargo_toml::Manifest; use compact_str::CompactString; use semver::VersionReq; use serde_json::Deserializer as JsonDeserializer; @@ -5,16 +8,8 @@ use tokio::sync::OnceCell; use url::Url; use crate::{ - drivers::registry::{ - crate_prefix_components, parse_manifest, render_dl_template, MatchedVersion, - RegistryConfig, RegistryError, - }, - errors::BinstallError, - helpers::{ - cargo_toml::Manifest, - remote::{Client, Error as RemoteError}, - }, - manifests::cargo_toml_binstall::Meta, + crate_prefix_components, parse_manifest, render_dl_template, MatchedVersion, RegistryConfig, + RegistryError, }; #[derive(Debug)] @@ -53,7 +48,7 @@ impl SparseRegistry { crate_name: &str, (c1, c2): &(CompactString, Option), version_req: &VersionReq, - ) -> Result { + ) -> Result { { let mut path = url.path_segments_mut().unwrap(); @@ -87,7 +82,7 @@ impl SparseRegistry { client: Client, crate_name: &str, version_req: &VersionReq, - ) -> Result, BinstallError> { + ) -> Result, RegistryError> { let crate_prefix = crate_prefix_components(crate_name)?; let dl_template = self.get_dl_template(&client).await?; let matched_version = Self::find_crate_matched_ver( diff --git a/crates/binstalk/src/drivers/registry/vfs.rs b/crates/binstalk-registry/src/vfs.rs similarity index 95% rename from crates/binstalk/src/drivers/registry/vfs.rs rename to crates/binstalk-registry/src/vfs.rs index 420be92a..b3339a81 100644 --- a/crates/binstalk/src/drivers/registry/vfs.rs +++ b/crates/binstalk-registry/src/vfs.rs @@ -4,7 +4,7 @@ use std::{ path::Path, }; -use crate::helpers::cargo_toml::AbstractFilesystem; +use cargo_toml_workspace::cargo_toml::AbstractFilesystem; use normalize_path::NormalizePath; /// This type stores the filesystem structure for the crate tarball diff --git a/crates/binstalk/src/drivers/registry/visitor.rs b/crates/binstalk-registry/src/visitor.rs similarity index 90% rename from crates/binstalk/src/drivers/registry/visitor.rs rename to crates/binstalk-registry/src/visitor.rs index ff5a0eff..717ec57f 100644 --- a/crates/binstalk/src/drivers/registry/visitor.rs +++ b/crates/binstalk-registry/src/visitor.rs @@ -1,18 +1,13 @@ use std::path::{Path, PathBuf}; +use binstalk_downloader::download::{DownloadError, TarEntriesVisitor, TarEntry}; +use binstalk_types::cargo_toml_binstall::Meta; +use cargo_toml_workspace::cargo_toml::{Manifest, Value}; use normalize_path::NormalizePath; use tokio::io::AsyncReadExt; use tracing::debug; -use super::vfs::Vfs; -use crate::{ - errors::BinstallError, - helpers::{ - cargo_toml::{Manifest, Value}, - download::{DownloadError, TarEntriesVisitor, TarEntry}, - }, - manifests::cargo_toml_binstall::Meta, -}; +use crate::{vfs::Vfs, RegistryError}; #[derive(Debug)] pub(super) struct ManifestVisitor { @@ -71,7 +66,7 @@ impl TarEntriesVisitor for ManifestVisitor { impl ManifestVisitor { /// Load binstall metadata using the extracted information stored in memory. - pub(super) fn load_manifest(self) -> Result, BinstallError> { + pub(super) fn load_manifest(self) -> Result, RegistryError> { debug!("Loading manifest directly from extracted file"); // Load and parse manifest diff --git a/crates/binstalk/Cargo.toml b/crates/binstalk/Cargo.toml index aebb0b60..2e70281e 100644 --- a/crates/binstalk/Cargo.toml +++ b/crates/binstalk/Cargo.toml @@ -12,8 +12,8 @@ license = "GPL-3.0-only" [dependencies] async-trait = "0.1.68" atomic-file-install = { version = "0.0.0", path = "../atomic-file-install" } -base16 = "0.2.1" binstalk-downloader = { version = "0.7.0", path = "../binstalk-downloader", default-features = false, features = ["gh-api-client"] } +binstalk-registry = { version = "0.0.0", path = "../binstalk-registry" } binstalk-types = { version = "0.5.0", path = "../binstalk-types" } cargo-toml-workspace = { version = "0.0.0", path = "../cargo-toml-workspace" } command-group = { version = "2.1.0", features = ["with-tokio"] } @@ -30,9 +30,6 @@ miette = "5.9.0" normalize-path = { version = "0.2.1", path = "../normalize-path" } once_cell = "1.18.0" semver = { version = "1.0.17", features = ["serde"] } -serde = { version = "1.0.163", features = ["derive"] } -serde_json = "1.0.99" -sha2 = "0.10.7" strum = "0.25.0" target-lexicon = { version = "0.12.11", features = ["std"] } tempfile = "3.5.0" @@ -40,16 +37,12 @@ thiserror = "1.0.40" tokio = { version = "1.30.0", features = ["rt", "process", "sync"], default-features = false } tracing = "0.1.37" url = { version = "2.3.1", features = ["serde"] } -xz2 = "0.1.7" - -[dev-dependencies] -toml_edit = { version = "0.19.11", features = ["serde"] } [features] default = ["static", "rustls", "git"] -git = ["binstalk-downloader/git"] -git-max-perf = ["binstalk-downloader/git-max-perf"] +git = ["binstalk-registry/git"] +git-max-perf = ["git", "binstalk-downloader/git-max-perf"] static = ["binstalk-downloader/static"] pkg-config = ["binstalk-downloader/pkg-config"] diff --git a/crates/binstalk/src/drivers.rs b/crates/binstalk/src/drivers.rs deleted file mode 100644 index 15604fea..00000000 --- a/crates/binstalk/src/drivers.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod registry; -pub use registry::{ - fetch_crate_cratesio, CratesIoRateLimit, InvalidRegistryError, Registry, RegistryError, - SparseRegistry, -}; - -#[cfg(feature = "git")] -pub use registry::{GitRegistry, GitUrl, GitUrlParseError}; diff --git a/crates/binstalk/src/errors.rs b/crates/binstalk/src/errors.rs index 8f73be6c..db2e19cd 100644 --- a/crates/binstalk/src/errors.rs +++ b/crates/binstalk/src/errors.rs @@ -15,10 +15,10 @@ use tokio::task; use tracing::{error, warn}; use crate::{ - drivers::{InvalidRegistryError, RegistryError}, helpers::{ cargo_toml::Error as CargoTomlError, cargo_toml_workspace::Error as LoadManifestFromWSError, }, + registry::{InvalidRegistryError, RegistryError}, }; #[derive(Debug, Error)] @@ -198,18 +198,6 @@ pub enum BinstallError { #[diagnostic(severity(error), code(binstall::version::parse))] VersionParse(#[from] Box), - /// No available version matches the requirements. - /// - /// This may be the case when using the `--version` option. - /// - /// Note that using `--version 1.2.3` is interpreted as the requirement `=1.2.3`. - /// - /// - Code: `binstall::version::mismatch` - /// - Exit: 82 - #[error("no version matching requirement '{req}'")] - #[diagnostic(severity(error), code(binstall::version::mismatch))] - VersionMismatch { req: semver::VersionReq }, - /// The crate@version syntax was used at the same time as the --version option. /// /// You can't do that as it's ambiguous which should apply. @@ -374,7 +362,6 @@ impl BinstallError { CargoManifest { .. } => 78, RegistryParseError(..) => 79, VersionParse { .. } => 80, - VersionMismatch { .. } => 82, SuperfluousVersionOption => 84, UnspecifiedBinaries => 86, NoViableTargets => 87, diff --git a/crates/binstalk/src/helpers.rs b/crates/binstalk/src/helpers.rs index 2844b8d3..bbe9411e 100644 --- a/crates/binstalk/src/helpers.rs +++ b/crates/binstalk/src/helpers.rs @@ -4,8 +4,8 @@ pub mod remote; pub(crate) mod target_triple; pub mod tasks; +pub(crate) use binstalk_downloader::download; pub use binstalk_downloader::gh_api_client; -pub(crate) use binstalk_downloader::{bytes, download}; #[cfg(feature = "git")] pub(crate) use binstalk_downloader::git; diff --git a/crates/binstalk/src/lib.rs b/crates/binstalk/src/lib.rs index 35a0b381..c3b467ff 100644 --- a/crates/binstalk/src/lib.rs +++ b/crates/binstalk/src/lib.rs @@ -1,13 +1,13 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] mod bins; -pub mod drivers; pub mod errors; pub mod fetchers; pub mod helpers; pub mod ops; use atomic_file_install as fs; +pub use binstalk_registry as registry; pub use binstalk_types as manifests; pub use detect_targets::{get_desired_targets, DesiredTargets, TARGET}; pub use home; diff --git a/crates/binstalk/src/ops.rs b/crates/binstalk/src/ops.rs index c28ee280..d996e4d0 100644 --- a/crates/binstalk/src/ops.rs +++ b/crates/binstalk/src/ops.rs @@ -5,12 +5,12 @@ use std::{path::PathBuf, sync::Arc}; use semver::VersionReq; use crate::{ - drivers::Registry, fetchers::{Data, Fetcher, TargetData}, helpers::{ self, gh_api_client::GhApiClient, jobserver_client::LazyJobserverClient, remote::Client, }, manifests::cargo_toml_binstall::PkgOverride, + registry::Registry, DesiredTargets, };