Skip to content

Commit bfa373f

Browse files
committed
feat: Add initial extractor loader
1 parent 2b05fd5 commit bfa373f

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/extractors.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::path::PathBuf;
2+
3+
use anyhow::Result;
4+
use ghastoolkit::codeql::CodeQLExtractor;
5+
use ghastoolkit::Repository;
6+
use octocrab::models::repos::{Asset, Release};
7+
8+
async fn fetch_releases(client: &octocrab::Octocrab, repository: &Repository) -> Result<Release> {
9+
let release = if let Some(rel) = repository.reference() {
10+
client
11+
.repos(repository.owner(), repository.name())
12+
.releases()
13+
.get_by_tag(rel)
14+
.await?
15+
} else {
16+
// Get Latest Release
17+
client
18+
.repos(repository.owner(), repository.name())
19+
.releases()
20+
.get_latest()
21+
.await?
22+
};
23+
24+
log::debug!("Release :: {} - {:?}", release.tag_name, release.created_at);
25+
26+
Ok(release)
27+
}
28+
29+
/// Fetch the CodeQL Extractor from the repository
30+
///
31+
/// Finds the correct asset based on ending in `.tar.gz`.
32+
pub async fn fetch_extractor(
33+
client: &octocrab::Octocrab,
34+
repository: &Repository,
35+
output: &PathBuf,
36+
) -> Result<CodeQLExtractor> {
37+
let release = fetch_releases(client, repository).await?;
38+
39+
let Some(release_asset) = release.assets.iter().find(|a| a.name.ends_with(".tar.gz")) else {
40+
return Err(anyhow::anyhow!("No asset found"));
41+
};
42+
log::info!("Asset URL :: {}", release_asset.browser_download_url);
43+
44+
let asset: Asset = client.get(release_asset.url.clone(), None::<&()>).await?;
45+
46+
let extractor_tarball = output.join("extractor.tar.gz");
47+
let extractor_path = output.join("extractor-pack").join("codeql-extractor.yml");
48+
49+
let toolcache = ghactions::ToolCache::new();
50+
51+
if !extractor_tarball.exists() {
52+
log::info!("Downloading asset to {:?}", extractor_tarball);
53+
54+
toolcache.download_asset(&asset, &extractor_tarball).await?;
55+
}
56+
57+
if extractor_path.exists() {
58+
log::info!("Removing existing asset {:?}", extractor_path);
59+
std::fs::remove_dir_all(&extractor_path)?;
60+
}
61+
62+
log::info!("Extracting asset to {:?}", extractor_path);
63+
toolcache
64+
.extract_archive(&extractor_tarball, &output)
65+
.await?;
66+
67+
if !extractor_path.exists() {
68+
return Err(anyhow::anyhow!("Extractor not found"));
69+
}
70+
71+
log::info!("Loading CodeQL Extractor from {:?}", extractor_path);
72+
let extractor = CodeQLExtractor::load_path(extractor_path)?;
73+
74+
Ok(extractor)
75+
}

0 commit comments

Comments
 (0)