diff --git a/scarb/src/bin/scarb/main.rs b/scarb/src/bin/scarb/main.rs index 8d2bfb2b5..ba529cf63 100644 --- a/scarb/src/bin/scarb/main.rs +++ b/scarb/src/bin/scarb/main.rs @@ -75,6 +75,7 @@ fn cli_main(args: ScarbArgs) -> Result<()> { .offline(args.offline) .log_filter_directive(Some(scarb_log)) .profile(args.profile_spec.determine()?) + .with_registry() .build()?; commands::run(args.command, &mut config) diff --git a/scarb/src/core/config.rs b/scarb/src/core/config.rs index ba30895f1..3a24e4de7 100644 --- a/scarb/src/core/config.rs +++ b/scarb/src/core/config.rs @@ -9,18 +9,20 @@ use camino::{Utf8Path, Utf8PathBuf}; use once_cell::sync::OnceCell; use tokio::runtime::{Builder, Handle, Runtime}; use tracing::trace; +use url::Url; use which::which_in; use scarb_ui::{OutputFormat, Ui, Verbosity}; use crate::compiler::plugin::CairoPluginRepository; use crate::compiler::{CompilerRepository, Profile}; +use crate::core::registry::DEFAULT_REGISTRY_INDEX; use crate::core::AppDirs; #[cfg(doc)] use crate::core::Workspace; use crate::flock::AdvisoryLock; use crate::internal::fsx; -use crate::SCARB_ENV; +use crate::{REGISTRY_URL_ENV, SCARB_ENV}; use super::ManifestDependency; @@ -46,6 +48,7 @@ pub struct Config { tokio_handle: OnceCell, profile: Profile, http_client: OnceCell, + registry_url: Url, } impl Config { @@ -77,6 +80,7 @@ impl Config { if let Some(handle) = b.tokio_handle { tokio_handle.set(handle).unwrap(); } + let registry_url = b.registry_url.unwrap_or(DEFAULT_REGISTRY_INDEX.clone()); Ok(Self { manifest_path: b.manifest_path, @@ -95,6 +99,7 @@ impl Config { tokio_handle, profile, http_client: OnceCell::new(), + registry_url, }) } @@ -285,6 +290,10 @@ impl Config { ); self.http() } + + pub fn registry_url(&self) -> &Url { + &self.registry_url + } } #[derive(Debug)] @@ -303,6 +312,7 @@ pub struct ConfigBuilder { custom_source_patches: Option>, tokio_handle: Option, profile: Option, + registry_url: Option, } impl ConfigBuilder { @@ -322,6 +332,7 @@ impl ConfigBuilder { custom_source_patches: None, tokio_handle: None, profile: None, + registry_url: None, } } @@ -405,4 +416,15 @@ impl ConfigBuilder { self.profile = Some(profile); self } + + pub fn with_registry(mut self) -> Self { + self.registry_url = match env::var(REGISTRY_URL_ENV) { + Ok(value) => match Url::parse(&value) { + Ok(parsed_url) => Some(parsed_url), + Err(_) => panic!("Failed to parse url set by SCARB_REGISTRY_URL env variable"), + }, + Err(_) => None, + }; + self + } } diff --git a/scarb/src/core/manifest/summary.rs b/scarb/src/core/manifest/summary.rs index abb876f21..cb56e4955 100644 --- a/scarb/src/core/manifest/summary.rs +++ b/scarb/src/core/manifest/summary.rs @@ -7,7 +7,7 @@ use typed_builder::TypedBuilder; #[cfg(doc)] use crate::core::Manifest; use crate::core::{ - Checksum, DepKind, DependencyVersionReq, ManifestDependency, PackageId, PackageName, + Checksum, DepKind, DependencyVersionReq, ManifestDependency, PackageId, PackageName, SourceId, }; /// Subset of a [`Manifest`] that contains only the most important information about a package. @@ -74,6 +74,7 @@ impl Summary { ManifestDependency::builder() .name(PackageName::CORE) .version_req(DependencyVersionReq::exact(&cairo_version)) + .source_id(SourceId::for_std()) .build() }); let mut deps: Vec<&ManifestDependency> = Vec::new(); diff --git a/scarb/src/core/manifest/toml_manifest.rs b/scarb/src/core/manifest/toml_manifest.rs index 9a40ab91e..99a713649 100644 --- a/scarb/src/core/manifest/toml_manifest.rs +++ b/scarb/src/core/manifest/toml_manifest.rs @@ -356,10 +356,11 @@ impl TomlManifest { } impl TomlDependency { - fn resolve(&self) -> Cow<'_, DetailedTomlDependency> { + fn resolve(&self, registry_url: &Url) -> Cow<'_, DetailedTomlDependency> { match self { TomlDependency::Simple(version) => Cow::Owned(DetailedTomlDependency { version: Some(version.clone()), + registry: Some(registry_url.to_owned()), ..Default::default() }), TomlDependency::Detailed(detailed) => Cow::Borrowed(detailed), @@ -392,6 +393,7 @@ impl TomlManifest { source_id: SourceId, profile: Profile, workspace_manifest: Option<&TomlManifest>, + registry_url: &Url, ) -> Result { let root = manifest_path .parent() @@ -443,11 +445,18 @@ impl TomlManifest { .and_then(|deps| deps.get(name.as_str())) .cloned() .ok_or_else(|| anyhow!("dependency `{}` not found in workspace", name.clone()))? - .to_dependency(name.clone(), workspace_manifest_path, kind.clone()) + .to_dependency( + name.clone(), + workspace_manifest_path, + kind.clone(), + registry_url, + ) }; let toml_dep = toml_dep .clone() - .map(|dep| dep.to_dependency(name.clone(), manifest_path, kind.clone()))? + .map(|dep| { + dep.to_dependency(name.clone(), manifest_path, kind.clone(), registry_url) + })? .resolve(name.as_str(), inherit_ws)?; dependencies.push(toml_dep); } @@ -959,8 +968,10 @@ impl TomlDependency { name: PackageName, manifest_path: &Utf8Path, dep_kind: DepKind, + registry_url: &Url, ) -> Result { - self.resolve().to_dependency(name, manifest_path, dep_kind) + self.resolve(registry_url) + .to_dependency(name, manifest_path, dep_kind) } } diff --git a/scarb/src/core/registry/index/config.rs b/scarb/src/core/registry/index/config.rs index 136d68193..0a5d28f53 100644 --- a/scarb/src/core/registry/index/config.rs +++ b/scarb/src/core/registry/index/config.rs @@ -44,7 +44,7 @@ pub struct IndexConfig { } impl IndexConfig { - pub const WELL_KNOWN_PATH: &'static str = "config.json"; + pub const WELL_KNOWN_PATH: &'static str = "api/v1/index/config.json"; } #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] diff --git a/scarb/src/core/registry/mod.rs b/scarb/src/core/registry/mod.rs index dc1a235f0..ca205da81 100644 --- a/scarb/src/core/registry/mod.rs +++ b/scarb/src/core/registry/mod.rs @@ -1,5 +1,7 @@ use anyhow::Result; use async_trait::async_trait; +use once_cell::sync::Lazy; +use url::Url; use crate::core::{ManifestDependency, Package, PackageId, Summary}; @@ -11,7 +13,10 @@ pub mod patch_map; pub mod patcher; pub mod source_map; -pub const DEFAULT_REGISTRY_INDEX: &str = "https://there-is-no-default-registry-yet.com"; +pub static DEFAULT_REGISTRY_INDEX: Lazy = Lazy::new(|| { + Url::parse("https://there-is-no-default-registry-yet.com") + .expect("Default registry URL is invalid") +}); #[async_trait(?Send)] pub trait Registry { diff --git a/scarb/src/core/source/id.rs b/scarb/src/core/source/id.rs index fcc5387f6..38c6c1dff 100644 --- a/scarb/src/core/source/id.rs +++ b/scarb/src/core/source/id.rs @@ -237,8 +237,7 @@ impl SourceId { pub fn default_registry() -> Self { static CACHE: Lazy = Lazy::new(|| { - let url = Url::parse(DEFAULT_REGISTRY_INDEX).unwrap(); - SourceId::new(url, SourceKind::Registry).unwrap() + SourceId::new(DEFAULT_REGISTRY_INDEX.clone(), SourceKind::Registry).unwrap() }); *CACHE } diff --git a/scarb/src/lib.rs b/scarb/src/lib.rs index 47225fcbd..0df08f4d4 100644 --- a/scarb/src/lib.rs +++ b/scarb/src/lib.rs @@ -40,3 +40,4 @@ pub const STARKNET_PLUGIN_NAME: &str = "starknet"; pub const TEST_PLUGIN_NAME: &str = "cairo_test"; pub const TEST_ASSERTS_PLUGIN_NAME: &str = "assert_macros"; pub const CAIRO_RUN_PLUGIN_NAME: &str = "cairo_run"; +pub const REGISTRY_URL_ENV: &str = "SCARB_REGISTRY_URL"; diff --git a/scarb/src/ops/resolve.rs b/scarb/src/ops/resolve.rs index 2edfc044f..55a41f71a 100644 --- a/scarb/src/ops/resolve.rs +++ b/scarb/src/ops/resolve.rs @@ -75,7 +75,10 @@ pub fn resolve_workspace_with_opts( let cairo_version = crate::version::get().cairo.version.parse().unwrap(); let version_req = DependencyVersionReq::exact(&cairo_version); patch_map.insert( - SourceId::default().canonical_url.clone(), + SourceId::for_registry(ws.config().registry_url()) + .expect("Failed to obtain registry url") + .canonical_url + .clone(), [ ManifestDependency::builder() .name(PackageName::CORE) diff --git a/scarb/src/ops/workspace.rs b/scarb/src/ops/workspace.rs index 6dbb9f7d2..d3db447a7 100644 --- a/scarb/src/ops/workspace.rs +++ b/scarb/src/ops/workspace.rs @@ -86,6 +86,7 @@ fn read_workspace_root<'c>( source_id, config.profile(), Some(&toml_manifest), + config.registry_url(), ) .with_context(|| format!("failed to parse manifest at: {manifest_path}"))?; let manifest = Box::new(manifest); @@ -118,6 +119,7 @@ fn read_workspace_root<'c>( source_id, config.profile(), Some(&toml_manifest), + config.registry_url(), ) .with_context(|| format!("failed to parse manifest at: {manifest_path}"))?; let manifest = Box::new(manifest);