Skip to content

Commit dda6f2a

Browse files
Nemo157syphar
authored andcommitted
Separate registry-api from the index, use the configured base url
1 parent 4ed23c0 commit dda6f2a

14 files changed

+74
-87
lines changed

src/bin/cratesfyi.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ 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, InstanceMetrics, PackageKind, RegistryApi, RustwideBuilder, ServiceMetrics,
20+
Storage,
2021
};
2122
use humantime::Duration;
2223
use once_cell::sync::OnceCell;
@@ -537,12 +538,10 @@ impl DatabaseSubcommand {
537538
}
538539

539540
Self::UpdateCrateRegistryFields { name } => {
540-
let index = ctx.index()?;
541-
542541
db::update_crate_data_in_database(
543542
&mut *ctx.conn()?,
544543
&name,
545-
&index.api().get_crate_data(&name)?,
544+
&ctx.registry_api()?.get_crate_data(&name)?,
546545
)?;
547546
}
548547

@@ -719,6 +718,7 @@ struct BinContext {
719718
service_metrics: OnceCell<Arc<ServiceMetrics>>,
720719
instance_metrics: OnceCell<Arc<InstanceMetrics>>,
721720
index: OnceCell<Arc<Index>>,
721+
registry_api: OnceCell<Arc<RegistryApi>>,
722722
repository_stats_updater: OnceCell<Arc<RepositoryStatsUpdater>>,
723723
runtime: OnceCell<Arc<Runtime>>,
724724
}
@@ -734,6 +734,7 @@ impl BinContext {
734734
service_metrics: OnceCell::new(),
735735
instance_metrics: OnceCell::new(),
736736
index: OnceCell::new(),
737+
registry_api: OnceCell::new(),
737738
repository_stats_updater: OnceCell::new(),
738739
runtime: OnceCell::new(),
739740
}
@@ -783,11 +784,15 @@ impl Context for BinContext {
783784
let config = self.config()?;
784785
let path = config.registry_index_path.clone();
785786
if let Some(registry_url) = config.registry_url.clone() {
786-
Index::from_url(path, registry_url, config.crates_io_api_call_retries)
787+
Index::from_url(path, registry_url)
787788
} else {
788-
Index::new(path, config.crates_io_api_call_retries)
789+
Index::new(path)
789790
}?
790791
};
792+
fn registry_api(self) -> RegistryApi = {
793+
let config = self.config()?;
794+
RegistryApi::new(config.registry_api_host.clone(), config.crates_io_api_call_retries)?
795+
};
791796
fn repository_stats_updater(self) -> RepositoryStatsUpdater = {
792797
let config = self.config()?;
793798
let pool = self.pool()?;

src/config.rs

+6-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,10 @@ 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(
145+
"DOCSRS_REGISTRY_API_HOST",
146+
"https://crates.io".parse().unwrap(),
147+
)?,
144148
prefix: prefix.clone(),
145149

146150
database_url: require_env("DOCSRS_DATABASE_URL")?,

src/context.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ 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::{
6+
AsyncStorage, BuildQueue, Config, Index, InstanceMetrics, RegistryApi, ServiceMetrics, Storage,
7+
};
68
use std::sync::Arc;
79
use tokio::runtime::Runtime;
810

@@ -16,6 +18,7 @@ pub trait Context {
1618
fn service_metrics(&self) -> Result<Arc<ServiceMetrics>>;
1719
fn instance_metrics(&self) -> Result<Arc<InstanceMetrics>>;
1820
fn index(&self) -> Result<Arc<Index>>;
21+
fn registry_api(&self) -> Result<Arc<RegistryApi>>;
1922
fn repository_stats_updater(&self) -> Result<Arc<RepositoryStatsUpdater>>;
2023
fn runtime(&self) -> Result<Arc<Runtime>>;
2124
}

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,

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;

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, InstanceMetrics, RegistryApi, 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
}

src/index/mod.rs 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")

src/index/crates.rs

Whitespace-only changes.

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub use self::docbuilder::PackageKind;
99
pub use self::docbuilder::RustwideBuilder;
1010
pub use self::index::Index;
1111
pub use self::metrics::{InstanceMetrics, ServiceMetrics};
12+
pub use self::registry_api::RegistryApi;
1213
pub use self::storage::{AsyncStorage, Storage};
1314
pub use self::web::{start_background_metrics_webserver, start_web_server};
1415

@@ -21,6 +22,7 @@ mod docbuilder;
2122
mod error;
2223
pub mod index;
2324
pub mod metrics;
25+
mod registry_api;
2426
pub mod repositories;
2527
pub mod storage;
2628
#[cfg(test)]

src/index/api.rs 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"]);

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;

src/test/mod.rs

+21-4
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, InstanceMetrics, RegistryApi, 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(),
@@ -406,11 +408,22 @@ impl TestEnvironment {
406408
self.index
407409
.get_or_init(|| {
408410
Arc::new(
409-
Index::new(
410-
self.config().registry_index_path.clone(),
411+
Index::new(self.config().registry_index_path.clone())
412+
.expect("failed to initialize the index"),
413+
)
414+
})
415+
.clone()
416+
}
417+
418+
pub(crate) fn registry_api(&self) -> Arc<RegistryApi> {
419+
self.registry_api
420+
.get_or_init(|| {
421+
Arc::new(
422+
RegistryApi::new(
423+
self.config().registry_api_host.clone(),
411424
self.config().crates_io_api_call_retries,
412425
)
413-
.expect("failed to initialize the index"),
426+
.expect("failed to initialize the registry api"),
414427
)
415428
})
416429
.clone()
@@ -489,6 +502,10 @@ impl Context for TestEnvironment {
489502
Ok(self.index())
490503
}
491504

505+
fn registry_api(&self) -> Result<Arc<RegistryApi>> {
506+
Ok(self.registry_api())
507+
}
508+
492509
fn repository_stats_updater(&self) -> Result<Arc<RepositoryStatsUpdater>> {
493510
Ok(self.repository_stats_updater())
494511
}

0 commit comments

Comments
 (0)