#![allow(dead_code)]
use crate::util::CommandLog;
use color_eyre::Report;
use flatpak::application::FlatpakApplication;
use std::{
env,
fmt::Display,
path::{Path, PathBuf},
};
use tokio::process::Command;
type Result<T> = std::result::Result<T, Report>;
pub enum FlatpakArtifact {
Ref(String),
Bundle(PathBuf),
}
impl Display for FlatpakArtifact {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FlatpakArtifact::Ref(ref r) => write!(f, "ref {}", r),
FlatpakArtifact::Bundle(ref b) => write!(f, "bundle {}", b.display()),
}
}
}
pub struct FlatpakBuilder {
output_dir: PathBuf,
output_repo: PathBuf,
bundles_dir: PathBuf,
extra_sources: Vec<PathBuf>,
extra_sources_urls: Vec<String>,
extra_args: Vec<String>,
}
impl FlatpakBuilder {
pub fn new(output_dir: PathBuf, output_repo: PathBuf, bundles_dir: PathBuf) -> Self {
Self {
output_dir,
output_repo,
bundles_dir,
extra_sources: Vec::new(),
extra_sources_urls: Vec::new(),
extra_args: Vec::new(),
}
}
pub fn add_extra_source(&mut self, source: PathBuf) {
self.extra_sources.push(source);
}
pub fn extra_sources_iter<I: IntoIterator<Item = PathBuf>>(&mut self, iter: I) {
self.extra_sources.extend(iter);
}
pub fn extra_args_iter<I: IntoIterator<Item = String>>(&mut self, iter: I) {
self.extra_args.extend(iter);
}
pub fn add_extra_args(&mut self, arg: String) {
self.extra_args.push(arg);
}
pub fn add_extra_source_url(&mut self, source: String) {
self.extra_sources_urls.push(source);
}
pub fn extra_sources_urls_iter<I: IntoIterator<Item = String>>(&mut self, iter: I) {
self.extra_sources_urls.extend(iter);
}
pub async fn build(&self, manifest: &Path) -> Result<String> {
let flatpak_meta = FlatpakApplication::load_from_file(manifest.display().to_string())
.map_err(color_eyre::Report::msg)?;
let output_dir =
env::current_dir()?.join(".flatpak-builder/build").join(&flatpak_meta.app_id);
std::fs::create_dir_all(&output_dir)?;
std::fs::create_dir_all(&self.output_repo)?;
let mut flatpak = Command::new("flatpak-builder");
flatpak
.arg(output_dir)
.arg(manifest)
.arg("--force-clean")
.arg("--repo")
.arg(&self.output_repo.canonicalize().unwrap());
for source in &self.extra_sources {
flatpak.arg("--extra-sources").arg(source);
}
for source in &self.extra_sources_urls {
flatpak.arg("--extra-sources-url").arg(source);
}
flatpak.args(&self.extra_args);
flatpak.log().await?;
Ok(flatpak_meta.app_id)
}
pub async fn bundle(&self, app_id: &str) -> Result<PathBuf> {
std::fs::create_dir_all(&self.bundles_dir)?;
let bundle_path = self.bundles_dir.join(format!("{app_id}.flatpak"));
let mut flatpak = Command::new("flatpak");
flatpak
.arg("build-bundle")
.arg(&self.output_repo.canonicalize().unwrap())
.arg(&bundle_path)
.arg(app_id);
flatpak.log().await?;
Ok(bundle_path)
}
}
#[cfg(test)]
mod test_super {}