Skip to content

Commit ca3630a

Browse files
committed
Separate registry-api from the index, use the configured base url
1 parent 2582dbe commit ca3630a

14 files changed

+65
-81
lines changed

Diff for: src/bin/cratesfyi.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use docs_rs::utils::{
1616
};
1717
use docs_rs::{
1818
start_background_metrics_webserver, start_web_server, AsyncStorage, BuildQueue, Config,
19-
Context, Index, InstanceMetrics, PackageKind, RustwideBuilder, ServiceMetrics, Storage,
19+
Context, Index, RegistryApi, InstanceMetrics, PackageKind, RustwideBuilder, ServiceMetrics, Storage,
2020
};
2121
use humantime::Duration;
2222
use once_cell::sync::OnceCell;
@@ -537,12 +537,10 @@ impl DatabaseSubcommand {
537537
}
538538

539539
Self::UpdateCrateRegistryFields { name } => {
540-
let index = ctx.index()?;
541-
542540
db::update_crate_data_in_database(
543541
&mut *ctx.conn()?,
544542
&name,
545-
&index.api().get_crate_data(&name)?,
543+
&ctx.registry_api()?.get_crate_data(&name)?,
546544
)?;
547545
}
548546

@@ -719,6 +717,7 @@ struct BinContext {
719717
service_metrics: OnceCell<Arc<ServiceMetrics>>,
720718
instance_metrics: OnceCell<Arc<InstanceMetrics>>,
721719
index: OnceCell<Arc<Index>>,
720+
registry_api: OnceCell<Arc<RegistryApi>>,
722721
repository_stats_updater: OnceCell<Arc<RepositoryStatsUpdater>>,
723722
runtime: OnceCell<Arc<Runtime>>,
724723
}
@@ -734,6 +733,7 @@ impl BinContext {
734733
service_metrics: OnceCell::new(),
735734
instance_metrics: OnceCell::new(),
736735
index: OnceCell::new(),
736+
registry_api: OnceCell::new(),
737737
repository_stats_updater: OnceCell::new(),
738738
runtime: OnceCell::new(),
739739
}
@@ -783,11 +783,15 @@ impl Context for BinContext {
783783
let config = self.config()?;
784784
let path = config.registry_index_path.clone();
785785
if let Some(registry_url) = config.registry_url.clone() {
786-
Index::from_url(path, registry_url, config.crates_io_api_call_retries)
786+
Index::from_url(path, registry_url)
787787
} else {
788-
Index::new(path, config.crates_io_api_call_retries)
788+
Index::new(path)
789789
}?
790790
};
791+
fn registry_api(self) -> RegistryApi = {
792+
let config = self.config()?;
793+
RegistryApi::new(config.registry_api_host.clone(), config.crates_io_api_call_retries)?
794+
};
791795
fn repository_stats_updater(self) -> RepositoryStatsUpdater = {
792796
let config = self.config()?;
793797
let pool = self.pool()?;

Diff for: src/config.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ use crate::{cdn::CdnKind, storage::StorageKind};
22
use anyhow::{anyhow, bail, Context, Result};
33
use std::{env::VarError, error::Error, path::PathBuf, str::FromStr, time::Duration};
44
use tracing::trace;
5+
use url::Url;
56

67
#[derive(Debug)]
78
pub struct Config {
89
pub prefix: PathBuf,
910
pub registry_index_path: PathBuf,
1011
pub registry_url: Option<String>,
11-
pub registry_api_host: String,
12+
pub registry_api_host: Url,
1213

1314
// Database connection params
1415
pub(crate) database_url: String,
@@ -140,7 +141,7 @@ impl Config {
140141

141142
registry_index_path: env("REGISTRY_INDEX_PATH", prefix.join("crates.io-index"))?,
142143
registry_url: maybe_env("REGISTRY_URL")?,
143-
registry_api_host: env("DOCSRS_REGISTRY_API_HOST", "https://crates.io".into())?,
144+
registry_api_host: env("DOCSRS_REGISTRY_API_HOST", "https://crates.io".parse().unwrap())?,
144145
prefix: prefix.clone(),
145146

146147
database_url: require_env("DOCSRS_DATABASE_URL")?,

Diff for: src/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::cdn::CdnBackend;
22
use crate::db::Pool;
33
use crate::error::Result;
44
use crate::repositories::RepositoryStatsUpdater;
5-
use crate::{AsyncStorage, BuildQueue, Config, Index, InstanceMetrics, ServiceMetrics, Storage};
5+
use crate::{AsyncStorage, BuildQueue, Config, Index, InstanceMetrics, ServiceMetrics, Storage, RegistryApi};
66
use std::sync::Arc;
77
use tokio::runtime::Runtime;
88

@@ -16,6 +16,7 @@ pub trait Context {
1616
fn service_metrics(&self) -> Result<Arc<ServiceMetrics>>;
1717
fn instance_metrics(&self) -> Result<Arc<InstanceMetrics>>;
1818
fn index(&self) -> Result<Arc<Index>>;
19+
fn registry_api(&self) -> Result<Arc<RegistryApi>>;
1920
fn repository_stats_updater(&self) -> Result<Arc<RepositoryStatsUpdater>>;
2021
fn runtime(&self) -> Result<Arc<Runtime>>;
2122
}

Diff for: src/db/add_package.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
db::types::Feature,
33
docbuilder::{BuildResult, DocCoverage},
44
error::Result,
5-
index::api::{CrateData, CrateOwner, ReleaseData},
5+
registry_api::{CrateData, CrateOwner, ReleaseData},
66
storage::CompressionAlgorithm,
77
utils::MetadataPackage,
88
web::crate_details::CrateDetails,

Diff for: src/db/delete.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ fn delete_crate_from_database(conn: &mut Client, name: &str, crate_id: i32) -> R
194194
#[cfg(test)]
195195
mod tests {
196196
use super::*;
197-
use crate::index::api::CrateOwner;
197+
use crate::registry_api::CrateOwner;
198198
use crate::test::{assert_success, wrapper};
199199
use postgres::Client;
200200
use test_case::test_case;

Diff for: src/docbuilder/rustwide_builder.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::utils::{
1313
};
1414
use crate::RUSTDOC_STATIC_STORAGE_PREFIX;
1515
use crate::{db::blacklist::is_blacklisted, utils::MetadataPackage};
16-
use crate::{Config, Context, Index, InstanceMetrics, Storage};
16+
use crate::{Config, Context, RegistryApi, InstanceMetrics, Storage};
1717
use anyhow::{anyhow, bail, Context as _, Error};
1818
use docsrs_metadata::{BuildTargets, Metadata, DEFAULT_TARGETS, HOST_TARGET};
1919
use failure::Error as FailureError;
@@ -87,7 +87,7 @@ pub struct RustwideBuilder {
8787
db: Pool,
8888
storage: Arc<Storage>,
8989
metrics: Arc<InstanceMetrics>,
90-
index: Arc<Index>,
90+
registry_api: Arc<RegistryApi>,
9191
rustc_version: String,
9292
repository_stats_updater: Arc<RepositoryStatsUpdater>,
9393
workspace_initialize_time: Instant,
@@ -105,7 +105,7 @@ impl RustwideBuilder {
105105
db: pool,
106106
storage: context.storage()?,
107107
metrics: context.instance_metrics()?,
108-
index: context.index()?,
108+
registry_api: context.registry_api()?,
109109
rustc_version: String::new(),
110110
repository_stats_updater: context.repository_stats_updater()?,
111111
workspace_initialize_time: Instant::now(),
@@ -519,8 +519,7 @@ impl RustwideBuilder {
519519

520520
let release_data = if !is_local {
521521
match self
522-
.index
523-
.api()
522+
.registry_api
524523
.get_release_data(name, version)
525524
.with_context(|| {
526525
format!("could not fetch releases-data for {name}-{version}")
@@ -565,7 +564,7 @@ impl RustwideBuilder {
565564

566565
// Some crates.io crate data is mutable, so we proactively update it during a release
567566
if !is_local {
568-
match self.index.api().get_crate_data(name) {
567+
match self.registry_api.get_crate_data(name) {
569568
Ok(crate_data) => {
570569
update_crate_data_in_database(&mut conn, name, &crate_data)?
571570
}

Diff for: src/index/mod.rs renamed to src/index.rs

+6-42
Original file line numberDiff line numberDiff line change
@@ -3,72 +3,40 @@ use std::{path::PathBuf, process::Command};
33

44
use anyhow::Context;
55
use crates_index_diff::gix;
6-
use url::Url;
76

8-
use self::api::Api;
97
use crate::error::Result;
108
use crate::utils::report_error;
119

12-
pub(crate) mod api;
13-
1410
pub struct Index {
1511
path: PathBuf,
16-
api: Api,
1712
repository_url: Option<String>,
1813
}
1914

20-
#[derive(Debug, serde::Deserialize, Clone)]
21-
#[serde(rename_all = "kebab-case")]
22-
struct IndexConfig {
23-
#[serde(default)]
24-
api: Option<Url>,
25-
}
26-
27-
/// Inspects the given repository to find the config as specified in [RFC 2141][], assumes that the
28-
/// repository has a remote called `origin` and that the branch `master` exists on it.
29-
///
30-
/// [RFC 2141]: https://rust-lang.github.io/rfcs/2141-alternative-registries.html
31-
fn load_config(repo: &gix::Repository) -> Result<IndexConfig> {
32-
let file = repo
33-
.rev_parse_single("refs/remotes/origin/master:config.json")
34-
.with_context(|| anyhow::anyhow!("registry index missing ./config.json in root"))?
35-
.object()?;
36-
37-
let config = serde_json::from_slice(&file.data)?;
38-
Ok(config)
39-
}
40-
4115
impl Index {
42-
pub fn from_url(path: PathBuf, url: String, max_api_call_retries: u32) -> Result<Self> {
43-
let diff = crates_index_diff::Index::from_path_or_cloned_with_options(
16+
pub fn from_url(path: PathBuf, url: String) -> Result<Self> {
17+
crates_index_diff::Index::from_path_or_cloned_with_options(
4418
&path,
4519
gix::progress::Discard,
4620
&AtomicBool::default(),
4721
crates_index_diff::index::CloneOptions { url: url.clone() },
4822
)
23+
.map(|_| ())
4924
.context("initialising registry index repository")?;
5025

51-
let config = load_config(diff.repository()).context("loading registry config")?;
52-
let api = Api::new(config.api, max_api_call_retries)
53-
.context("initialising registry api client")?;
5426
Ok(Self {
5527
path,
56-
api,
5728
repository_url: Some(url),
5829
})
5930
}
6031

61-
pub fn new(path: PathBuf, max_api_call_retries: u32) -> Result<Self> {
32+
pub fn new(path: PathBuf) -> Result<Self> {
6233
// This initializes the repository, then closes it afterwards to avoid leaking file descriptors.
6334
// See https://github.com/rust-lang/docs.rs/pull/847
64-
let diff = crates_index_diff::Index::from_path_or_cloned(&path)
35+
crates_index_diff::Index::from_path_or_cloned(&path)
36+
.map(|_| ())
6537
.context("initialising registry index repository")?;
66-
let config = load_config(diff.repository()).context("loading registry config")?;
67-
let api = Api::new(config.api, max_api_call_retries)
68-
.context("initialising registry api client")?;
6938
Ok(Self {
7039
path,
71-
api,
7240
repository_url: None,
7341
})
7442
}
@@ -102,10 +70,6 @@ impl Index {
10270
Ok(index)
10371
}
10472

105-
pub fn api(&self) -> &Api {
106-
&self.api
107-
}
108-
10973
pub fn run_git_gc(&self) {
11074
let gc = Command::new("git")
11175
.arg("-C")

Diff for: src/index/crates.rs

Whitespace-only changes.

Diff for: src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ pub use self::context::Context;
88
pub use self::docbuilder::PackageKind;
99
pub use self::docbuilder::RustwideBuilder;
1010
pub use self::index::Index;
11+
pub use self::registry_api::RegistryApi;
1112
pub use self::metrics::{InstanceMetrics, ServiceMetrics};
1213
pub use self::storage::{AsyncStorage, Storage};
1314
pub use self::web::{start_background_metrics_webserver, start_web_server};
1415

16+
mod registry_api;
1517
mod build_queue;
1618
pub mod cdn;
1719
mod config;

Diff for: src/index/api.rs renamed to src/registry_api.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const APP_USER_AGENT: &str = concat!(
1313
);
1414

1515
#[derive(Debug)]
16-
pub struct Api {
17-
api_base: Option<Url>,
16+
pub struct RegistryApi {
17+
api_base: Url,
1818
max_retries: u32,
1919
client: reqwest::blocking::Client,
2020
}
@@ -47,8 +47,8 @@ pub struct CrateOwner {
4747
pub(crate) login: String,
4848
}
4949

50-
impl Api {
51-
pub(super) fn new(api_base: Option<Url>, max_retries: u32) -> Result<Self> {
50+
impl RegistryApi {
51+
pub fn new(api_base: Url, max_retries: u32) -> Result<Self> {
5252
let headers = vec![
5353
(USER_AGENT, HeaderValue::from_static(APP_USER_AGENT)),
5454
(ACCEPT, HeaderValue::from_static("application/json")),
@@ -67,12 +67,6 @@ impl Api {
6767
})
6868
}
6969

70-
fn api_base(&self) -> Result<Url> {
71-
self.api_base
72-
.clone()
73-
.with_context(|| anyhow!("index is missing an api base url"))
74-
}
75-
7670
pub fn get_crate_data(&self, name: &str) -> Result<CrateData> {
7771
let owners = self
7872
.get_owners(name)
@@ -100,7 +94,7 @@ impl Api {
10094
version: &str,
10195
) -> Result<(DateTime<Utc>, bool, i32)> {
10296
let url = {
103-
let mut url = self.api_base()?;
97+
let mut url = self.api_base.clone();
10498
url.path_segments_mut()
10599
.map_err(|()| anyhow!("Invalid API url"))?
106100
.extend(&["api", "v1", "crates", name, "versions"]);
@@ -142,7 +136,7 @@ impl Api {
142136
/// Fetch owners from the registry's API
143137
fn get_owners(&self, name: &str) -> Result<Vec<CrateOwner>> {
144138
let url = {
145-
let mut url = self.api_base()?;
139+
let mut url = self.api_base.clone();
146140
url.path_segments_mut()
147141
.map_err(|()| anyhow!("Invalid API url"))?
148142
.extend(&["api", "v1", "crates", name, "owners"]);

Diff for: src/test/fakes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::TestDatabase;
22

33
use crate::docbuilder::{BuildResult, DocCoverage};
44
use crate::error::Result;
5-
use crate::index::api::{CrateData, CrateOwner, ReleaseData};
5+
use crate::registry_api::{CrateData, CrateOwner, ReleaseData};
66
use crate::storage::{rustdoc_archive_path, source_archive_path, Storage};
77
use crate::utils::{Dependency, MetadataPackage, Target};
88
use anyhow::Context;

Diff for: src/test/mod.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::error::Result;
77
use crate::repositories::RepositoryStatsUpdater;
88
use crate::storage::{AsyncStorage, Storage, StorageKind};
99
use crate::web::{build_axum_app, cache, page::TemplateData};
10-
use crate::{BuildQueue, Config, Context, Index, InstanceMetrics, ServiceMetrics};
10+
use crate::{BuildQueue, Config, Context, Index, RegistryApi, InstanceMetrics, ServiceMetrics};
1111
use anyhow::Context as _;
1212
use fn_error_context::context;
1313
use once_cell::unsync::OnceCell;
@@ -229,6 +229,7 @@ pub(crate) struct TestEnvironment {
229229
async_storage: OnceCell<Arc<AsyncStorage>>,
230230
cdn: OnceCell<Arc<CdnBackend>>,
231231
index: OnceCell<Arc<Index>>,
232+
registry_api: OnceCell<Arc<RegistryApi>>,
232233
runtime: OnceCell<Arc<Runtime>>,
233234
instance_metrics: OnceCell<Arc<InstanceMetrics>>,
234235
service_metrics: OnceCell<Arc<ServiceMetrics>>,
@@ -263,6 +264,7 @@ impl TestEnvironment {
263264
async_storage: OnceCell::new(),
264265
cdn: OnceCell::new(),
265266
index: OnceCell::new(),
267+
registry_api: OnceCell::new(),
266268
instance_metrics: OnceCell::new(),
267269
service_metrics: OnceCell::new(),
268270
frontend: OnceCell::new(),
@@ -408,14 +410,27 @@ impl TestEnvironment {
408410
Arc::new(
409411
Index::new(
410412
self.config().registry_index_path.clone(),
411-
self.config().crates_io_api_call_retries,
412413
)
413414
.expect("failed to initialize the index"),
414415
)
415416
})
416417
.clone()
417418
}
418419

420+
pub(crate) fn registry_api(&self) -> Arc<RegistryApi> {
421+
self.registry_api
422+
.get_or_init(|| {
423+
Arc::new(
424+
RegistryApi::new(
425+
self.config().registry_api_host.clone(),
426+
self.config().crates_io_api_call_retries,
427+
)
428+
.expect("failed to initialize the registry api"),
429+
)
430+
})
431+
.clone()
432+
}
433+
419434
pub(crate) fn repository_stats_updater(&self) -> Arc<RepositoryStatsUpdater> {
420435
self.repository_stats_updater
421436
.get_or_init(|| {
@@ -489,6 +504,10 @@ impl Context for TestEnvironment {
489504
Ok(self.index())
490505
}
491506

507+
fn registry_api(&self) -> Result<Arc<RegistryApi>> {
508+
Ok(self.registry_api())
509+
}
510+
492511
fn repository_stats_updater(&self) -> Result<Arc<RepositoryStatsUpdater>> {
493512
Ok(self.repository_stats_updater())
494513
}

0 commit comments

Comments
 (0)