Skip to content

Commit d17eab7

Browse files
committed
wire up --directory with static and PyPI downloads
1 parent 39d4d66 commit d17eab7

File tree

5 files changed

+44
-20
lines changed

5 files changed

+44
-20
lines changed

clang-installer/src/downloader/pypi.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ impl PyPiDownloader {
416416
pub async fn download_tool(
417417
clang_tool: &ClangTool,
418418
version: &VersionReq,
419+
directory: Option<&PathBuf>,
419420
) -> Result<PathBuf, PyPiDownloadError> {
420421
let info = Self::get_pypi_release_info(clang_tool).await?;
421422
let (ver, info) = Self::get_best_pypi_release(clang_tool, &info, version)?;
@@ -435,11 +436,15 @@ impl PyPiDownloader {
435436
log::info!("Verifying wheel file integrity with digest: {digest:?}");
436437
digest.verify(&cached_wheel)?;
437438
}
438-
let extracted_bin = cached_dir.join(format!(
439-
"bin/{clang_tool}-{}{}",
439+
let bin_name = format!(
440+
"{clang_tool}-{}{}",
440441
ver.major,
441442
if cfg!(windows) { ".exe" } else { "" }
442-
));
443+
);
444+
let extracted_bin = match directory {
445+
None => cached_dir.join(format!("bin/{bin_name}",)),
446+
Some(dir) => dir.join(&bin_name),
447+
};
443448
Self::extract_bin(clang_tool, &cached_wheel, &extracted_bin)?;
444449
Ok(extracted_bin)
445450
}

clang-installer/src/downloader/static_dist.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ pub enum StaticDistDownloadError {
4242
#[error("Failed to parse the SHA512 sum file")]
4343
Sha512Corruption,
4444
}
45+
const MIN_CLANG_TOOLS_VERSION: &str = "9";
46+
const MAX_CLANG_TOOLS_VERSION: &str = "21";
47+
const CLANG_TOOLS_REPO: &str = "https://github.com/cpp-linter/clang-tools-static-binaries";
48+
const CLANG_TOOLS_TAG: &str = "master-6e612956";
4549

4650
/// A downloader that uses statically linked binary distribution files
4751
/// provided by the cpp-linter team.
@@ -56,11 +60,11 @@ impl StaticDistDownloader {
5660
/// `MAX_CLANG_TOOLS_VERSION` environment variables (inclusive) at compile time.
5761
fn find_suitable_version(req_ver: &VersionReq) -> Option<Version> {
5862
let min_clang_tools_version: u8 = option_env!("MIN_CLANG_TOOLS_VERSION")
59-
.unwrap_or("9")
63+
.unwrap_or(MIN_CLANG_TOOLS_VERSION)
6064
.parse()
6165
.expect("Invalid MIN_CLANG_TOOLS_VERSION env var value");
6266
let max_clang_tools_version: u8 = option_env!("MAX_CLANG_TOOLS_VERSION")
63-
.unwrap_or("21")
67+
.unwrap_or(MAX_CLANG_TOOLS_VERSION)
6468
.parse()
6569
.expect("Invalid MAX_CLANG_TOOLS_VERSION env var value");
6670
let clang_tools_versions: RangeInclusive<u8> =
@@ -101,6 +105,7 @@ impl StaticDistDownloader {
101105
pub async fn download_tool(
102106
tool: &ClangTool,
103107
requested_version: &VersionReq,
108+
directory: Option<&PathBuf>,
104109
) -> Result<PathBuf, StaticDistDownloadError> {
105110
if consts::ARCH != "x86_64" {
106111
return Err(StaticDistDownloadError::UnsupportedArchitecture);
@@ -117,9 +122,8 @@ impl StaticDistDownloader {
117122
} else {
118123
""
119124
};
120-
let clang_tools_repo: &str = option_env!("CLANG_TOOLS_REPO")
121-
.unwrap_or("https://github.com/cpp-linter/clang-tools-static-binaries");
122-
let clang_tools_tag: &str = option_env!("CLANG_TOOLS_TAG").unwrap_or("master-6e612956");
125+
let clang_tools_repo: &str = option_env!("CLANG_TOOLS_REPO").unwrap_or(CLANG_TOOLS_REPO);
126+
let clang_tools_tag: &str = option_env!("CLANG_TOOLS_TAG").unwrap_or(CLANG_TOOLS_TAG);
123127

124128
let base_url = format!(
125129
"{clang_tools_repo}/releases/download/{clang_tools_tag}/{tool}-{ver_str}_{}-amd64",
@@ -133,9 +137,11 @@ impl StaticDistDownloader {
133137
);
134138
let url = Url::parse(format!("{base_url}{suffix}").as_str())?;
135139
let cache_path = Self::get_cache_dir();
136-
let download_path = cache_path
137-
.join("bin")
138-
.join(format!("{tool}-{ver_str}{suffix}").as_str());
140+
let bin_name = format!("{tool}-{ver_str}{suffix}");
141+
let download_path = match directory {
142+
None => cache_path.join("bin").join(&bin_name),
143+
Some(dir) => dir.join(&bin_name),
144+
};
139145
if download_path.exists() {
140146
log::info!(
141147
"Using cached static binary for {tool} version {ver_str} from {:?}",

clang-installer/src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub struct CliOptions {
107107
default_value = "",
108108
)]
109109
pub version: Option<RequestedVersion>,
110+
110111
/// The clang tool to install.
111112
#[arg(
112113
short,
@@ -115,9 +116,11 @@ pub struct CliOptions {
115116
default_value = "clang-format clang-tidy"
116117
)]
117118
pub tool: Option<Vec<ClangTool>>,
119+
118120
/// The directory where the clang tools should be installed.
119121
#[arg(short, long)]
120122
pub directory: Option<PathBuf>,
123+
121124
/// Force overwriting symlink to the installed binary.
122125
///
123126
/// This will only overwrite an existing symlink.
@@ -144,7 +147,10 @@ async fn main() -> Result<()> {
144147
req_ver => {
145148
let mut map_tools = HashMap::new();
146149
for t in tool {
147-
if let Some(version) = req_ver.eval_tool(&t, options.force).await? {
150+
if let Some(version) = req_ver
151+
.eval_tool(&t, options.force, options.directory.as_ref())
152+
.await?
153+
{
148154
map_tools.entry(t).or_insert(version);
149155
}
150156
}

clang-installer/src/version.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl RequestedVersion {
7777
&self,
7878
tool: &ClangTool,
7979
overwrite_symlink: bool,
80+
directory: Option<&PathBuf>,
8081
) -> Result<Option<ClangVersion>, GetToolError> {
8182
match self {
8283
RequestedVersion::Path(_) => {
@@ -134,15 +135,17 @@ impl RequestedVersion {
134135
}
135136

136137
// try to download a suitable version
137-
let bin = match PyPiDownloader::download_tool(tool, version_req).await {
138+
let bin = match PyPiDownloader::download_tool(tool, version_req, directory).await {
138139
Ok(bin) => bin,
139140
Err(e) => {
140141
log::error!("Failed to download {tool} {version_req} from PyPi: {e}");
141142
if let Some(result) = try_install_package(tool, version_req, &min_ver)? {
142143
return Ok(Some(result));
143144
}
144145
log::info!("Falling back to downloading {tool} static binaries.");
145-
match StaticDistDownloader::download_tool(tool, version_req).await {
146+
match StaticDistDownloader::download_tool(tool, version_req, directory)
147+
.await
148+
{
146149
Ok(bin) => bin,
147150
Err(e) => {
148151
log::error!(
@@ -283,7 +286,7 @@ mod tests {
283286
#[tokio::test]
284287
async fn eval_no_value() {
285288
let result = RequestedVersion::NoValue
286-
.eval_tool(&ClangTool::ClangFormat, false)
289+
.eval_tool(&ClangTool::ClangFormat, false, None)
287290
.await
288291
.unwrap();
289292
assert!(result.is_none());
@@ -303,13 +306,17 @@ mod tests {
303306
let version_req =
304307
VersionReq::parse(option_env!("MIN_CLANG_TOOLS_VERSION").unwrap_or("11")).unwrap();
305308
let downloaded_clang = RequestedVersion::Requirement(version_req.clone())
306-
.eval_tool(&tool, false)
309+
.eval_tool(&tool, false, Some(&PathBuf::from(tmp_cache_dir.path())))
307310
.await
308311
.unwrap()
309312
.unwrap();
310313
println!("Downloaded clang-format: {downloaded_clang:?}");
311314
let req_ver = RequestedVersion::Path(downloaded_clang.path.parent().unwrap().to_owned());
312-
let result = req_ver.eval_tool(&tool, false).await.unwrap().unwrap();
315+
let result = req_ver
316+
.eval_tool(&tool, false, None)
317+
.await
318+
.unwrap()
319+
.unwrap();
313320
println!("Evaluated clang-format from path: {result:?}");
314321
assert!(
315322
version_req.matches(&result.version),
@@ -328,7 +335,7 @@ mod tests {
328335
for tool in [ClangTool::ClangFormat, ClangTool::ClangTidy] {
329336
let version_req = VersionReq::parse(clang_version).unwrap();
330337
let clang_path = RequestedVersion::Requirement(version_req.clone())
331-
.eval_tool(&tool, false)
338+
.eval_tool(&tool, false, None)
332339
.await
333340
.unwrap()
334341
.unwrap();

cpp-linter/src/clang_tools/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ pub async fn capture_clang_tools_output(
108108
// info as debugging output.
109109
if clang_params.tidy_checks != "-*" {
110110
let tool = ClangTool::ClangTidy;
111-
let tool_info = version.eval_tool(&tool, false).await?.ok_or(anyhow!(
111+
let tool_info = version.eval_tool(&tool, false, None).await?.ok_or(anyhow!(
112112
"Failed to find {tool} or install a suitable version"
113113
))?;
114114
clang_versions.tidy_version = Some(tool_info.version);
115115
clang_params.clang_tidy_command = Some(tool_info.path);
116116
}
117117
if !clang_params.style.is_empty() {
118118
let tool = ClangTool::ClangFormat;
119-
let tool_info = version.eval_tool(&tool, false).await?.ok_or(anyhow!(
119+
let tool_info = version.eval_tool(&tool, false, None).await?.ok_or(anyhow!(
120120
"Failed to find {tool} or install a suitable version"
121121
))?;
122122
clang_versions.format_version = Some(tool_info.version);

0 commit comments

Comments
 (0)