Merge pull request #20 from teackot/flatpak-backend

add support for flatpak
This commit is contained in:
steven-omaha
2023-05-16 19:18:52 +02:00
committed by GitHub
7 changed files with 141 additions and 7 deletions
+7 -6
View File
@@ -85,12 +85,13 @@ Note that the name of the section corresponds to the ecosystem it relates to, ra
At the moment, supported backends are the following. At the moment, supported backends are the following.
Pull requests for additional backends are welcome! Pull requests for additional backends are welcome!
| Application | Package Manager | Section | feature flag | Notes | | Application | Package Manager | Section | feature flag | Notes |
|-------------|-----------------|-----------|--------------|-----------------------------------------------------------------------------------------------------------| |-------------|-----------------|-------------|--------------|-----------------------------------------------------------------------------------------------------------|
| Arch Linux | `pacman` | `[arch]` | `arch` | includes pacman-wrapping AUR helpers (configurable) | | Arch Linux | `pacman` | `[arch]` | `arch` | includes pacman-wrapping AUR helpers (configurable) |
| Debian | `apt` | `[debian]`| `debian` | minimum supported apt-version unknown ([upstream issue](https://gitlab.com/volian/rust-apt/-/issues/20)) | | Debian | `apt` | `[debian]` | `debian` | minimum supported apt-version unknown ([upstream issue](https://gitlab.com/volian/rust-apt/-/issues/20)) |
| Python | `pip` | `[python]`| built-in | | | Flatpak | `flatpak` | `[flatpak]` | built-in | can manage either system-wide or per-user installation (configurable) |
| Rust | `cargo` | `[rust]` | built-in | | | Python | `pip` | `[python]` | built-in | |
| Rust | `cargo` | `[rust]` | built-in | |
Backends that have a `feature flag` require setting the respective flag for the build process. Backends that have a `feature flag` require setting the respective flag for the build process.
The appropriate system libraries and their header files must be present on the machine and be detectable by `pkg-config`. The appropriate system libraries and their header files must be present on the machine and be detectable by `pkg-config`.
@@ -0,0 +1,121 @@
use std::collections::HashSet;
use std::process::Command;
use std::process::ExitStatus;
use anyhow::{Context, Result};
use crate::backend::backend_trait::{Backend, Switches, Text};
use crate::{impl_backend_constants, Group, Package};
#[derive(Debug, Clone)]
pub struct Flatpak {
pub(crate) packages: HashSet<Package>,
pub(crate) systemwide: bool,
}
const BINARY: Text = "flatpak";
const SECTION: Text = "flatpak";
const SWITCHES_INSTALL: Switches = &["install"];
const SWITCHES_INFO: Switches = &["info"];
const SWITCHES_MAKE_DEPENDENCY: Switches = &[];
const SWITCHES_NOCONFIRM: Switches = &["--assumeyes"];
const SWITCHES_REMOVE: Switches = &["uninstall"];
const SUPPORTS_AS_DEPENDENCY: bool = false;
impl Backend for Flatpak {
impl_backend_constants!();
fn get_all_installed_packages(&self) -> Result<HashSet<Package>> {
self.get_installed_packages(true)
}
fn get_explicitly_installed_packages(&self) -> Result<HashSet<Package>> {
self.get_installed_packages(false)
}
/// Install the specified packages.
fn install_packages(&self, packages: &[Package], noconfirm: bool) -> Result<ExitStatus> {
let mut cmd = Command::new(self.get_binary());
cmd.args(self.get_switches_install());
cmd.args(self.get_switches_runtime());
if noconfirm {
cmd.args(self.get_switches_noconfirm());
}
for p in packages {
cmd.arg(format!("{p}"));
}
cmd.status()
.with_context(|| format!("running command {cmd:?}"))
}
fn make_dependency(&self, _: &[Package]) -> Result<ExitStatus> {
panic!("not supported by {}", BINARY)
}
/// Remove the specified packages.
fn remove_packages(&self, packages: &[Package], noconfirm: bool) -> Result<ExitStatus> {
let mut cmd = Command::new(self.get_binary());
cmd.args(self.get_switches_remove());
cmd.args(self.get_switches_runtime());
if noconfirm {
cmd.args(self.get_switches_noconfirm());
}
for p in packages {
cmd.arg(format!("{p}"));
}
cmd.status()
.with_context(|| format!("running command [{cmd:?}]"))
}
/// Show information from package manager for package.
fn show_package_info(&self, package: &Package) -> Result<ExitStatus> {
let mut cmd = Command::new(self.get_binary());
cmd.args(self.get_switches_info());
cmd.args(self.get_switches_runtime());
cmd.arg(format!("{package}"));
cmd.status()
.with_context(|| format!("running command {cmd:?}"))
}
}
impl Flatpak {
pub(crate) fn new() -> Self {
Self {
packages: HashSet::new(),
systemwide: true,
}
}
fn get_switches_runtime(&self) -> Switches {
if self.systemwide {
&[]
} else {
&["--user"]
}
}
fn get_installed_packages(&self, include_implicit: bool) -> Result<HashSet<Package>> {
let mut cmd = Command::new(BINARY);
cmd.args(["list", "--columns=application"]);
if !include_implicit {
cmd.arg("--app");
}
if !self.systemwide {
cmd.arg("--user");
}
let output = String::from_utf8(cmd.output()?.stdout)?;
Ok(output
.lines()
.map(Package::from)
.collect::<HashSet<Package>>())
}
}
@@ -2,5 +2,6 @@
pub mod arch; pub mod arch;
#[cfg(feature = "debian")] #[cfg(feature = "debian")]
pub mod debian; pub mod debian;
pub mod flatpak;
pub mod python; pub mod python;
pub mod rust; pub mod rust;
@@ -177,7 +177,7 @@ where
let mut map = HashMap::new(); let mut map = HashMap::new();
for (value, key) in to_assign { for (value, key) in to_assign {
let inner = map.entry(key).or_insert(vec![]); let inner: &mut Vec<V> = map.entry(key).or_default();
inner.push(value); inner.push(value);
} }
+1
View File
@@ -16,6 +16,7 @@ pub enum Backends {
Arch, Arch,
#[cfg(feature = "debian")] #[cfg(feature = "debian")]
Debian, Debian,
Flatpak,
Python, Python,
Rust, Rust,
} }
+3
View File
@@ -13,6 +13,8 @@ pub struct Config {
pub aur_helper: String, pub aur_helper: String,
/// Additional arguments to pass to `aur_helper` when removing a package. /// Additional arguments to pass to `aur_helper` when removing a package.
pub aur_rm_args: Option<Vec<String>>, pub aur_rm_args: Option<Vec<String>>,
/// Install Flatpak packages system-wide
pub flatpak_systemwide: bool,
/// Warn the user when a group is not a symlink. /// Warn the user when a group is not a symlink.
pub warn_not_symlinks: bool, pub warn_not_symlinks: bool,
/// Backends the user does not want to use even though the binary exists. /// Backends the user does not want to use even though the binary exists.
@@ -68,6 +70,7 @@ impl Default for Config {
Self { Self {
aur_helper: "paru".into(), aur_helper: "paru".into(),
aur_rm_args: None, aur_rm_args: None,
flatpak_systemwide: true,
warn_not_symlinks: true, warn_not_symlinks: true,
disabled_backends: vec![], disabled_backends: vec![],
} }
+7
View File
@@ -128,6 +128,13 @@ impl Pacdef {
arch.aur_rm_args = self.config.aur_rm_args.take(); arch.aur_rm_args = self.config.aur_rm_args.take();
} }
} }
if let Some(flatpak) = backend
.as_any_mut()
.downcast_mut::<crate::backend::Flatpak>()
{
flatpak.systemwide = self.config.flatpak_systemwide;
}
} }
fn install_packages(&mut self, args: &ArgMatches) -> Result<()> { fn install_packages(&mut self, args: &ArgMatches) -> Result<()> {