Skip to content

Commit 8a9b79e

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

File tree

3 files changed

+96
-6
lines changed

3 files changed

+96
-6
lines changed

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
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};
99

1010
#[derive(Debug, Serialize, Deserialize)]
1111
/// A Qt manifest.json file, which specifies a set of artifacts needed for installation
@@ -17,7 +17,7 @@ pub(crate) struct ParsedQtManifest {
1717
#[derive(Debug, Serialize, Deserialize, PartialEq)]
1818
/// Descriptor for a Qt artifact, included download information
1919
pub(crate) struct ParsedQtArtifact {
20-
pub(crate) version: semver::Version,
20+
pub(crate) version: Version,
2121
pub(crate) arch: String,
2222
pub(crate) os: String,
2323
pub(crate) url: String,
@@ -29,7 +29,10 @@ impl ParsedQtArtifact {
2929
/// Download the artifact and extract to the given target path
3030
pub fn download_and_extract(&self, target_path: &Path) -> PathBuf {
3131
// Download to a temporary location
32-
let http_client = reqwest::blocking::Client::new();
32+
let http_client = reqwest::blocking::Client::builder()
33+
.timeout(None)
34+
.build()
35+
.expect("Http client failed to build");
3336
let temp_dir = tempfile::TempDir::new().expect("Could not create temporary directory");
3437
let archive_path =
3538
super::download::download_from_url(&self.url, &self.sha256, &temp_dir, &http_client)
@@ -46,6 +49,24 @@ impl ParsedQtArtifact {
4649
target_path.to_path_buf()
4750
}
4851

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

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

Lines changed: 70 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,70 @@ impl QtInstallationQtMinimal {
185187

186188
path
187189
}
190+
191+
/// Get a collection of the locally installed Qt artifacts
192+
pub(crate) 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: &Path) -> Vec<DirEntry> {
255+
path.read_dir().unwrap().flatten().collect()
188256
}

crates/qt-build-utils/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ impl QtBuild {
145145
// Search existing installed qt_minimal versions
146146
//
147147
// TODO: have API to do this
148+
let _ = QtInstallationQtMinimal::local_artifacts();
148149

149150
// Download from Qt artifacts
150151
//

0 commit comments

Comments
 (0)