Skip to content

Commit ef6270a

Browse files
Add directory walk to find qt artifacts
1 parent 66bc253 commit ef6270a

File tree

2 files changed

+100
-6
lines changed

2 files changed

+100
-6
lines changed

crates/qt-build-utils/src/installation/qt_minimal/artifact.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6-
use std::path::{Path, PathBuf};
7-
6+
use semver::Version;
87
use serde::{Deserialize, Serialize};
8+
use std::path::{Path, PathBuf};
9+
use std::time::Duration;
910

1011
#[derive(Debug, Serialize, Deserialize)]
1112
/// A Qt manifest.json file, which specifies a set of artifacts needed for installation
@@ -17,7 +18,7 @@ pub(crate) struct ParsedQtManifest {
1718
#[derive(Debug, Serialize, Deserialize, PartialEq)]
1819
/// Descriptor for a Qt artifact, included download information
1920
pub(crate) struct ParsedQtArtifact {
20-
pub(crate) version: semver::Version,
21+
pub(crate) version: Version,
2122
pub(crate) arch: String,
2223
pub(crate) os: String,
2324
pub(crate) url: String,
@@ -29,7 +30,10 @@ impl ParsedQtArtifact {
2930
/// Download the artifact and extract to the given target path
3031
pub fn download_and_extract(&self, target_path: &Path) -> PathBuf {
3132
// Download to a temporary location
32-
let http_client = reqwest::blocking::Client::new();
33+
let http_client = reqwest::blocking::Client::builder()
34+
.timeout(None)
35+
.build()
36+
.expect("Http client failed to build");
3337
let temp_dir = tempfile::TempDir::new().expect("Could not create temporary directory");
3438
let archive_path =
3539
super::download::download_from_url(&self.url, &self.sha256, &temp_dir, &http_client)
@@ -46,6 +50,24 @@ impl ParsedQtArtifact {
4650
target_path.to_path_buf()
4751
}
4852

53+
/// Used to create a found artifact without a checksum, used by local artifact discovery
54+
pub fn new(
55+
version: Version,
56+
arch: String,
57+
os: String,
58+
url: String,
59+
content_type: String,
60+
) -> Self {
61+
Self {
62+
version,
63+
arch,
64+
os,
65+
url,
66+
sha256: "".to_string(),
67+
content: vec![content_type],
68+
}
69+
}
70+
4971
/// Assert that the hashes are the same, from bytes
5072
pub fn verify(&self, hash: &[u8]) -> anyhow::Result<()> {
5173
let mut hash_string = String::new();

crates/qt-build-utils/src/installation/qt_minimal/mod.rs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ mod checksum;
88
mod download;
99
mod extract;
1010

11-
use std::path::PathBuf;
11+
use std::fs::DirEntry;
12+
use std::path::{Path, PathBuf};
1213

14+
use crate::installation::qt_minimal::artifact::ParsedQtArtifact;
1315
use crate::{QtBuildError, QtInstallation};
1416

1517
/// A implementation of [QtInstallation] using qtminimal
@@ -84,7 +86,7 @@ impl TryFrom<semver::Version> for QtInstallationQtMinimal {
8486
let os = target_parts
8587
.get(2)
8688
.expect("TARGET to have a <sys> component");
87-
let artifacts: Vec<artifact::ParsedQtArtifact> = manifest
89+
let artifacts: Vec<ParsedQtArtifact> = manifest
8890
.artifacts
8991
.into_iter()
9092
.filter(|artifact| {
@@ -185,4 +187,74 @@ impl QtInstallationQtMinimal {
185187

186188
path
187189
}
190+
191+
/// Get a collection of the locally installed Qt artifacts
192+
fn local_artifacts() -> anyhow::Result<Vec<ParsedQtArtifact>> {
193+
let base_dir = Self::qt_minimal_root();
194+
195+
// Expects folder structure like:
196+
// version/os/arch/qt/{bin, include}
197+
// e.g. will find an artifact at 6.10.0/linux/x86_64/qt/bin
198+
let mut artifacts = vec![];
199+
200+
// Iterate versions
201+
for version in list_dirs(&base_dir) {
202+
let path = version;
203+
// TODO: Later skip unknown folders,
204+
// this will error if a directory exists which isn't a version number
205+
let semver = semver::Version::parse(path.file_name().to_str().unwrap())
206+
.expect("Could not parse semver from directory name");
207+
208+
for os in list_dirs(&path.path()) {
209+
let path = os;
210+
let os = path.file_name().to_str().unwrap().to_string();
211+
212+
for arch in list_dirs(&path.path()) {
213+
let path = arch;
214+
let dir_entries = list_dirs(&path.path());
215+
216+
// Expects one qt dir
217+
let qt_dir_path = dir_entries
218+
.iter()
219+
.filter(|dir| dir.file_name() == "qt")
220+
.last()
221+
.expect("Expected to find a Qt dir in this folder");
222+
223+
let qt_folders = list_dirs(&qt_dir_path.path());
224+
for dir in qt_folders {
225+
let filename = dir.file_name();
226+
// Will be set if bin or include dirs are found
227+
let mut artifact_type = None;
228+
229+
if filename == "bin" {
230+
artifact_type = Some("bin");
231+
} else if filename == "include" {
232+
artifact_type = Some("include");
233+
}
234+
235+
if let Some(artifact_type) = artifact_type {
236+
artifacts.push(ParsedQtArtifact::new(
237+
semver.clone(),
238+
path.file_name().to_string_lossy().to_string(),
239+
os.clone(),
240+
qt_dir_path.path().to_string_lossy().to_string(),
241+
artifact_type.to_string(),
242+
))
243+
}
244+
}
245+
}
246+
}
247+
}
248+
249+
Ok(artifacts)
250+
}
251+
}
252+
253+
/// Get all valid directories in path bufs, ignoring errors
254+
fn list_dirs(path: &PathBuf) -> Vec<DirEntry> {
255+
path.read_dir()
256+
.unwrap()
257+
.filter(|d| d.is_ok())
258+
.map(|d| d.unwrap())
259+
.collect()
188260
}

0 commit comments

Comments
 (0)