Skip to content

Commit 41dfaa2

Browse files
committed
✨ Allow setting hex mirrors
1 parent 271d5b7 commit 41dfaa2

File tree

5 files changed

+93
-19
lines changed

5 files changed

+93
-19
lines changed

compiler-cli/src/dependencies.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::{
3939
build_lock::{BuildLock, Guard},
4040
cli,
4141
fs::{self, ProjectIO},
42+
get_hex_config,
4243
http::HttpClient,
4344
text_layout::space_table,
4445
};
@@ -66,12 +67,12 @@ pub enum CheckMajorVersions {
6667
}
6768

6869
pub fn list(paths: &ProjectPaths) -> Result<()> {
69-
let (_, manifest) = get_manifest_details(paths)?;
70+
let (_, manifest) = get_manifest_details(paths, &get_hex_config()?)?;
7071
list_manifest_packages(std::io::stdout(), manifest)
7172
}
7273

7374
pub fn tree(paths: &ProjectPaths, options: TreeOptions) -> Result<()> {
74-
let (config, manifest) = get_manifest_details(paths)?;
75+
let (config, manifest) = get_manifest_details(paths, &get_hex_config()?)?;
7576

7677
// Initialize the root package since it is not part of the manifest
7778
let root_package = ManifestPackage {
@@ -92,10 +93,13 @@ pub fn tree(paths: &ProjectPaths, options: TreeOptions) -> Result<()> {
9293
list_package_and_dependencies_tree(std::io::stdout(), options, packages.clone(), config.name)
9394
}
9495

95-
fn get_manifest_details(paths: &ProjectPaths) -> Result<(PackageConfig, Manifest)> {
96+
fn get_manifest_details(
97+
paths: &ProjectPaths,
98+
hex_config: &hexpm::Config,
99+
) -> Result<(PackageConfig, Manifest)> {
96100
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
97101
let config = crate::config::root_config(paths)?;
98-
let package_fetcher = PackageFetcher::new(runtime.handle().clone());
102+
let package_fetcher = PackageFetcher::new(runtime.handle().clone(), hex_config.clone());
99103
let dependency_manager = DependencyManagerConfig {
100104
use_manifest: UseManifest::Yes,
101105
check_major_versions: CheckMajorVersions::No,
@@ -105,6 +109,7 @@ fn get_manifest_details(paths: &ProjectPaths) -> Result<(PackageConfig, Manifest
105109
package_fetcher,
106110
cli::Reporter::new(),
107111
Mode::Dev,
112+
hex_config.clone(),
108113
);
109114
let manifest = dependency_manager
110115
.resolve_versions(paths, &config, Vec::new())?
@@ -220,10 +225,11 @@ fn list_dependencies_tree(
220225
}
221226

222227
pub fn outdated(paths: &ProjectPaths) -> Result<()> {
223-
let (_, manifest) = get_manifest_details(paths)?;
228+
let hex_config = get_hex_config()?;
229+
let (_, manifest) = get_manifest_details(paths, &hex_config)?;
224230

225231
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
226-
let package_fetcher = PackageFetcher::new(runtime.handle().clone());
232+
let package_fetcher = PackageFetcher::new(runtime.handle().clone(), hex_config);
227233

228234
let version_updates = dependency::check_for_version_updates(&manifest, &package_fetcher);
229235

@@ -400,13 +406,15 @@ pub fn resolve_and_download<Telem: Telemetry>(
400406
) -> Result<Manifest> {
401407
// Start event loop so we can run async functions to call the Hex API
402408
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
403-
let package_fetcher = PackageFetcher::new(runtime.handle().clone());
409+
let hex_config = get_hex_config()?;
410+
let package_fetcher = PackageFetcher::new(runtime.handle().clone(), hex_config.clone());
404411

405412
let dependency_manager = config.into_dependency_manager(
406413
runtime.handle().clone(),
407414
package_fetcher,
408415
telemetry,
409416
Mode::Dev,
417+
hex_config,
410418
);
411419

412420
dependency_manager.resolve_and_download_versions(paths, new_package, packages_to_update)
@@ -443,6 +451,7 @@ async fn add_missing_packages<Telem: Telemetry>(
443451
local: &LocalPackages,
444452
project_name: EcoString,
445453
telemetry: &Telem,
454+
hex_config: &hexpm::Config,
446455
) -> Result<(), Error> {
447456
let missing_packages = local.missing_local_packages(manifest, &project_name);
448457

@@ -469,7 +478,14 @@ async fn add_missing_packages<Telem: Telemetry>(
469478
// If we need to download at-least one package
470479
if missing_hex_packages.peek().is_some() || !missing_git_packages.is_empty() {
471480
let http = HttpClient::boxed();
472-
let downloader = hex::Downloader::new(fs.clone(), fs, http, Untar::boxed(), paths.clone());
481+
let downloader = hex::Downloader::new(
482+
fs.clone(),
483+
fs,
484+
http,
485+
Untar::boxed(),
486+
hex_config.clone(),
487+
paths.clone(),
488+
);
473489
let start = Instant::now();
474490
telemetry.downloading_package("packages");
475491
downloader
@@ -1089,13 +1105,13 @@ async fn lookup_package(
10891105
name: String,
10901106
version: Version,
10911107
provided: &HashMap<EcoString, ProvidedPackage>,
1108+
hex_config: &hexpm::Config,
10921109
) -> Result<ManifestPackage> {
10931110
match provided.get(name.as_str()) {
10941111
Some(provided_package) => Ok(provided_package.to_manifest_package(name.as_str())),
10951112
None => {
1096-
let config = hexpm::Config::new();
10971113
let release =
1098-
hex::get_package_release(&name, &version, &config, &HttpClient::new()).await?;
1114+
hex::get_package_release(&name, &version, hex_config, &HttpClient::new()).await?;
10991115
let build_tools = release
11001116
.meta
11011117
.build_tools
@@ -1125,14 +1141,16 @@ struct PackageFetcher {
11251141
runtime_cache: RefCell<HashMap<String, Rc<hexpm::Package>>>,
11261142
runtime: tokio::runtime::Handle,
11271143
http: HttpClient,
1144+
hex_config: hexpm::Config,
11281145
}
11291146

11301147
impl PackageFetcher {
1131-
pub fn new(runtime: tokio::runtime::Handle) -> Self {
1148+
pub fn new(runtime: tokio::runtime::Handle, hex_config: hexpm::Config) -> Self {
11321149
Self {
11331150
runtime_cache: RefCell::new(HashMap::new()),
11341151
runtime,
11351152
http: HttpClient::new(),
1153+
hex_config,
11361154
}
11371155
}
11381156

@@ -1183,8 +1201,7 @@ impl dependency::PackageFetcher for PackageFetcher {
11831201
}
11841202

11851203
tracing::debug!(package = package, "looking_up_hex_package");
1186-
let config = hexpm::Config::new();
1187-
let request = hexpm::repository_v2_get_package_request(package, None, &config);
1204+
let request = hexpm::repository_v2_get_package_request(package, None, &self.hex_config);
11881205
let response = self
11891206
.runtime
11901207
.block_on(self.http.send(request))

compiler-cli/src/dependencies/dependency_manager.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ impl DependencyManagerConfig {
4040
package_fetcher: P,
4141
telemetry: Telem,
4242
mode: Mode,
43+
hex_config: hexpm::Config,
4344
) -> DependencyManager<Telem, P> {
4445
DependencyManager {
4546
runtime,
@@ -49,6 +50,8 @@ impl DependencyManagerConfig {
4950
mode,
5051
use_manifest: self.use_manifest,
5152
check_major_versions: self.check_major_versions,
53+
54+
hex_config,
5255
}
5356
}
5457
}
@@ -60,6 +63,7 @@ pub struct DependencyManager<Telem, P> {
6063
use_manifest: UseManifest,
6164
telemetry: Telem,
6265
check_major_versions: CheckMajorVersions,
66+
hex_config: hexpm::Config,
6367
}
6468

6569
impl<Telem, P> DependencyManager<Telem, P>
@@ -171,6 +175,7 @@ where
171175
&local,
172176
project_name,
173177
&self.telemetry,
178+
&self.hex_config,
174179
))?;
175180

176181
if resolved.any_changes() {
@@ -281,11 +286,13 @@ where
281286
)?;
282287

283288
// Convert the hex packages and local packages into manifest packages
284-
let manifest_packages = self.runtime.block_on(future::try_join_all(
285-
resolved
286-
.into_iter()
287-
.map(|(name, version)| lookup_package(name, version, &provided_packages)),
288-
))?;
289+
let manifest_packages =
290+
self.runtime
291+
.block_on(future::try_join_all(resolved.into_iter().map(
292+
|(name, version)| {
293+
lookup_package(name, version, &provided_packages, &self.hex_config)
294+
},
295+
)))?;
289296

290297
let manifest = Manifest {
291298
packages: manifest_packages,

compiler-cli/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,36 @@ fn project_paths_at_current_directory_without_toml() -> ProjectPaths {
818818
ProjectPaths::new(current_dir)
819819
}
820820

821+
fn get_hex_config() -> Result<hexpm::Config> {
822+
let mut config = hexpm::Config::new();
823+
824+
if let Some(url) = parse_url_from_env_variable("HEXPM_API_URL")? {
825+
config.api_base = url;
826+
}
827+
828+
if let Some(url) = parse_url_from_env_variable("HEXPM_REPOSITORY_URL")? {
829+
config.repository_base = url;
830+
}
831+
832+
Ok(config)
833+
}
834+
835+
fn parse_url_from_env_variable(name: &str) -> Result<Option<::http::Uri>> {
836+
let Ok(url) = std::env::var(name) else {
837+
return Ok(None);
838+
};
839+
let url = ::http::Uri::from_str(&url)
840+
.ok()
841+
.filter(|uri| uri.scheme().is_some())
842+
.ok_or(Error::InvalidEnvironmentVariable {
843+
name: name.into(),
844+
value: url,
845+
problem: "Expected a valid URL with a scheme.".into(),
846+
})?;
847+
848+
Ok(Some(url))
849+
}
850+
821851
fn download_dependencies(paths: &ProjectPaths) -> Result<()> {
822852
_ = dependencies::resolve_and_download(
823853
paths,

compiler-core/src/error.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,13 @@ file_names.iter().map(|x| x.as_str()).join(", "))]
337337

338338
#[error("Cannot add a package with the same name as a dependency")]
339339
CannotAddSelfAsDependency { name: EcoString },
340+
341+
#[error("Invalid environment variable '{name}': {problem}")]
342+
InvalidEnvironmentVariable {
343+
name: String,
344+
value: String,
345+
problem: String,
346+
},
340347
}
341348

342349
// A wrapper that ignores the inner value for equality:
@@ -4572,6 +4579,18 @@ add `gleam add {name}` in this project."
45724579
location: None,
45734580
hint: None,
45744581
}],
4582+
4583+
Error::InvalidEnvironmentVariable { name, value, problem } => vec![Diagnostic {
4584+
title: "Invalid environment variable".into(),
4585+
text: wrap_format!(
4586+
"You provided the environment variable `{name}` with an invalid value of `{value}`.
4587+
4588+
{problem}"
4589+
),
4590+
level: Level::Error,
4591+
location: None,
4592+
hint: None,
4593+
}],
45754594
}
45764595
}
45774596
}

compiler-core/src/hex.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,15 @@ impl Downloader {
165165
fs_writer: Box<dyn FileSystemWriter>,
166166
http: Box<dyn HttpClient>,
167167
untar: Box<dyn TarUnpacker>,
168+
hex_config: hexpm::Config,
168169
paths: ProjectPaths,
169170
) -> Self {
170171
Self {
171172
fs_reader: DebugIgnore(fs_reader),
172173
fs_writer: DebugIgnore(fs_writer),
173174
http: DebugIgnore(http),
174175
untar: DebugIgnore(untar),
175-
hex_config: hexpm::Config::new(),
176+
hex_config,
176177
paths,
177178
}
178179
}

0 commit comments

Comments
 (0)