use zenwave::Client as _;
mod clone;
pub use clone::{checkout, source};
fn github_slug(git: &str) -> &str {
git.trim_end_matches('/')
.trim_end_matches(".git")
.strip_prefix("https://github.com/")
.unwrap_or_else(|| panic!("{git} is not a github.com remote"))
}
pub fn fetch(url: &str) -> Vec<u8> {
smol::block_on(async {
let mut client = zenwave::client();
let response = client
.method(zenwave::Method::GET, url)
.and_then(|request| request.header("User-Agent", env!("CARGO_PKG_NAME")))
.unwrap_or_else(|error| panic!("invalid request to {url}: {error}"))
.await
.unwrap_or_else(|error| panic!("GET {url} failed: {error}"));
assert!(
response.status().is_success(),
"GET {url} returned HTTP {}",
response.status()
);
response
.into_body()
.into_bytes()
.await
.unwrap_or_else(|error| panic!("reading {url} failed: {error}"))
.to_vec()
})
}
pub fn gitlink(git: &str, path: &str, rev: &str) -> (String, String) {
let url = format!(
"https://api.github.com/repos/{}/contents/{path}?ref={rev}",
github_slug(git)
);
let entry: serde_json::Value = serde_json::from_slice(&fetch(&url))
.unwrap_or_else(|error| panic!("contents API for {path}@{rev} returned no JSON: {error}"));
let sha = entry["sha"]
.as_str()
.unwrap_or_else(|| panic!("contents API entry for {path}@{rev} carries no sha"));
let submodule = entry["submodule_git_url"]
.as_str()
.unwrap_or_else(|| panic!("{path}@{rev} is not a submodule gitlink"));
(sha.to_owned(), submodule.to_owned())
}
pub fn raw_url(git: &str, rev: &str, path: &str) -> String {
format!(
"https://raw.githubusercontent.com/{}/{rev}/{path}",
github_slug(git)
)
}
pub fn android_backend(git: &str, rev: &str) -> (String, String) {
let manifest = fetch(&raw_url(git, rev, "Cargo.toml"));
let manifest: toml::Value =
toml::from_str(std::str::from_utf8(&manifest).unwrap_or_else(|error| {
panic!("the framework manifest at {rev} is not UTF-8: {error}")
}))
.unwrap_or_else(|error| panic!("the framework manifest at {rev} is not TOML: {error}"));
let metadata = &manifest["package"]["metadata"]["waterui"];
match (
metadata
.get("android-backend-revision")
.and_then(toml::Value::as_str),
metadata
.get("android-backend-url")
.and_then(toml::Value::as_str),
) {
(Some(revision), Some(url)) => (revision.to_owned(), url.to_owned()),
(None, _) => gitlink(git, "backends/android", rev),
(Some(_), None) => panic!(
"the framework manifest at {rev} declares android-backend-revision without android-backend-url"
),
}
}