Skip to content

Commit 86f7e99

Browse files
authored
Merge pull request #23 from ranfdev/next
Next
2 parents de58fb1 + 45dedaf commit 86f7e99

File tree

12 files changed

+722
-136
lines changed

12 files changed

+722
-136
lines changed

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ anyhow = "1.0.92"
1414
regex = "1.11.1"
1515
tracing = "0.1"
1616
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
17+
serde = { version = "1.0", features = ["derive"] }
18+
serde_json = "1.0.140"
1719

1820
[dependencies.adw]
1921
package = "libadwaita"

data/com.ranfdev.DistroShelf.metainfo.xml.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@
7171
</screenshots>
7272

7373
<releases>
74+
<release version="1.0.7" date="2025-05-23">
75+
<description translate="no">
76+
<ul>
77+
<li>Added support for custom terminal commands</li>
78+
<li>Refactored code to improve support of flatpak and non-flatpak versions</li>
79+
</ul>
80+
</description>
81+
</release>
7482
<release version="1.0.6" date="2025-05-12">
7583
<description translate="no">
7684
<ul>

meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
project('distroshelf', 'rust',
2-
version: '1.0.6',
2+
version: '1.0.7',
33
meson_version: '>= 1.0.0',
44
default_options: [ 'warning_level=2', 'werror=false', ],
55
)

src/application.rs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@
1818
* SPDX-License-Identifier: GPL-3.0-or-later
1919
*/
2020

21+
use std::path::Path;
22+
use std::rc::Rc;
23+
2124
use adw::prelude::*;
2225
use adw::subclass::prelude::*;
2326
use gettextrs::gettext;
2427
use gtk::{gio, glib};
2528

2629
use crate::config::VERSION;
27-
use crate::distrobox::{Distrobox, DistroboxCommandRunnerResponse};
30+
use crate::distrobox::{
31+
CommandRunner, Distrobox, DistroboxCommandRunnerResponse, FlatpakCommandRunner,
32+
RealCommandRunner,
33+
};
2834
use crate::root_store::RootStore;
2935
use crate::DistroShelfWindow;
3036

@@ -191,33 +197,41 @@ impl DistroShelfApplication {
191197
.build()
192198
}
193199

200+
fn get_is_in_flatpak() -> bool {
201+
let fp_env = std::env::var("FLATPAK_ID").is_ok();
202+
if fp_env {
203+
return true;
204+
}
205+
206+
Path::new("/.flatpak-info").exists()
207+
}
208+
194209
fn recreate_window(&self) -> adw::ApplicationWindow {
195-
let distrobox = match { self.imp().distrobox_store_ty.borrow().to_owned() } {
196-
DistroboxStoreTy::NullWorking => Distrobox::new_null_with_responses(
197-
&[
198-
DistroboxCommandRunnerResponse::Version,
199-
DistroboxCommandRunnerResponse::new_list_common_distros(),
200-
DistroboxCommandRunnerResponse::new_common_images(),
201-
DistroboxCommandRunnerResponse::new_common_exported_apps(),
202-
],
203-
false,
204-
),
205-
DistroboxStoreTy::NullEmpty => Distrobox::new_null_with_responses(
206-
&[
207-
DistroboxCommandRunnerResponse::Version,
208-
DistroboxCommandRunnerResponse::List(vec![]),
209-
DistroboxCommandRunnerResponse::new_common_images(),
210-
],
211-
false,
212-
),
213-
DistroboxStoreTy::NullNoVersion => Distrobox::new_null_with_responses(
214-
&[DistroboxCommandRunnerResponse::NoVersion],
215-
false,
216-
),
217-
_ => Distrobox::new(),
210+
let command_runner = match { self.imp().distrobox_store_ty.borrow().to_owned() } {
211+
DistroboxStoreTy::NullWorking => Distrobox::null_command_runner(&[
212+
DistroboxCommandRunnerResponse::Version,
213+
DistroboxCommandRunnerResponse::new_list_common_distros(),
214+
DistroboxCommandRunnerResponse::new_common_images(),
215+
DistroboxCommandRunnerResponse::new_common_exported_apps(),
216+
]),
217+
DistroboxStoreTy::NullEmpty => Distrobox::null_command_runner(&[
218+
DistroboxCommandRunnerResponse::Version,
219+
DistroboxCommandRunnerResponse::List(vec![]),
220+
DistroboxCommandRunnerResponse::new_common_images(),
221+
]),
222+
DistroboxStoreTy::NullNoVersion => {
223+
Distrobox::null_command_runner(&[DistroboxCommandRunnerResponse::NoVersion])
224+
}
225+
_ => {
226+
if Self::get_is_in_flatpak() {
227+
Rc::new(FlatpakCommandRunner::new(Rc::new(RealCommandRunner {}))) as Rc<dyn CommandRunner>
228+
} else {
229+
Rc::new(RealCommandRunner {}) as Rc<dyn CommandRunner>
230+
}
231+
}
218232
};
219233

220-
self.set_root_store(RootStore::new(distrobox));
234+
self.set_root_store(RootStore::new(command_runner));
221235
let window =
222236
DistroShelfWindow::new(self.upcast_ref::<adw::Application>(), self.root_store());
223237
window.upcast()

src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub static VERSION: &str = "1.0.6";
1+
pub static VERSION: &str = "1.0.7";
22
pub static GETTEXT_PACKAGE: &str = "distroshelf";
33
pub static LOCALEDIR: &str = "/app/share/locale";
44
pub static PKGDATADIR: &str = "/app/share/distroshelf";

src/distrobox/command_runner.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use futures::{
1818
FutureExt,
1919
};
2020

21+
use super::wrap_flatpak_cmd;
22+
2123
pub trait CommandRunner {
2224
fn spawn(&self, command: Command) -> io::Result<Box<dyn Child + Send>>;
2325
fn output(
@@ -43,6 +45,29 @@ impl CommandRunner for RealCommandRunner {
4345
}
4446
}
4547

48+
#[derive(Clone)]
49+
pub struct FlatpakCommandRunner {
50+
pub command_runner: Rc<dyn CommandRunner>,
51+
}
52+
impl FlatpakCommandRunner {
53+
pub fn new(command_runner: Rc<dyn CommandRunner>) -> Self {
54+
FlatpakCommandRunner { command_runner }
55+
}
56+
}
57+
58+
impl CommandRunner for FlatpakCommandRunner {
59+
fn spawn(&self, command: Command) -> io::Result<Box<dyn Child + Send>> {
60+
self.command_runner.spawn(wrap_flatpak_cmd(command))
61+
}
62+
fn output(
63+
&self,
64+
command: Command,
65+
) -> Pin<Box<dyn Future<Output = io::Result<std::process::Output>>>> {
66+
self.command_runner.output(wrap_flatpak_cmd(command))
67+
}
68+
}
69+
70+
4671
#[derive(Default, Clone)]
4772
pub struct NullCommandRunnerBuilder {
4873
responses: HashMap<Vec<String>, Rc<dyn Fn() -> Result<String, io::Error>>>,

src/distrobox/mod.rs

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ impl<T: Clone + std::fmt::Debug> OutputTracker<T> {
3838
}
3939

4040
pub struct Distrobox {
41-
cmd_runner: Box<dyn CommandRunner>,
41+
cmd_runner: Rc<dyn CommandRunner>,
4242
output_tracker: OutputTracker<String>,
43-
is_in_flatpak: bool,
4443
}
4544

4645
impl std::fmt::Debug for Distrobox {
4746
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4847
f.debug_struct("Distrobox")
49-
.field("is_in_flatpak", &self.is_in_flatpak)
5048
.field("output_tracker", &self.output_tracker)
5149
.finish()
5250
}
@@ -412,25 +410,22 @@ impl DistroboxCommandRunnerResponse {
412410
}
413411

414412
impl Distrobox {
415-
pub fn new() -> Self {
413+
pub fn new(cmd_runner:Rc<dyn CommandRunner + 'static> ) -> Self {
416414
Self {
417-
cmd_runner: Box::new(RealCommandRunner {}),
418-
is_in_flatpak: Self::get_is_in_flatpak(),
415+
cmd_runner,
419416
output_tracker: Default::default(),
420417
}
421418
}
422-
pub fn new_null(runner: NullCommandRunner, is_in_flatpak: bool) -> Self {
419+
pub fn new_null(runner: NullCommandRunner) -> Self {
423420
Self {
424-
cmd_runner: Box::new(runner),
421+
cmd_runner: Rc::new(runner),
425422
output_tracker: OutputTracker::default(),
426-
is_in_flatpak,
427423
}
428424
}
429425

430-
pub fn new_null_with_responses(
426+
pub fn null_command_runner(
431427
responses: &[DistroboxCommandRunnerResponse],
432-
is_in_flatpak: bool,
433-
) -> Self {
428+
) -> Rc<dyn CommandRunner> {
434429
let cmd_runner = {
435430
let mut builder = NullCommandRunnerBuilder::new();
436431
for res in responses {
@@ -440,33 +435,17 @@ impl Distrobox {
440435
}
441436
builder.build()
442437
};
443-
Self {
444-
cmd_runner: Box::new(cmd_runner),
445-
output_tracker: OutputTracker::default(),
446-
is_in_flatpak,
447-
}
438+
Rc::new(cmd_runner) as Rc<dyn CommandRunner>
448439
}
449440

450441
pub fn output_tracker(&self) -> OutputTracker<String> {
451442
self.output_tracker.enable();
452443
self.output_tracker.clone()
453444
}
454445

455-
fn get_is_in_flatpak() -> bool {
456-
let fp_env = std::env::var("FLATPAK_ID").is_ok();
457-
if fp_env {
458-
return true;
459-
}
460-
461-
Path::new("/.flatpak-info").exists()
462-
}
446+
463447

464-
pub fn cmd_spawn(&self, cmd: Command) -> Result<Box<dyn Child + Send>, Error> {
465-
let mut cmd = if self.is_in_flatpak {
466-
wrap_flatpak_cmd(cmd)
467-
} else {
468-
cmd
469-
};
448+
pub fn cmd_spawn(&self, mut cmd: Command) -> Result<Box<dyn Child + Send>, Error> {
470449
wrap_capture_cmd(&mut cmd);
471450

472451
let program = cmd.program.to_string_lossy().to_string();
@@ -491,12 +470,7 @@ impl Distrobox {
491470
Ok(child)
492471
}
493472

494-
async fn cmd_output(&self, cmd: Command) -> Result<Output, Error> {
495-
let mut cmd = if self.is_in_flatpak {
496-
wrap_flatpak_cmd(cmd)
497-
} else {
498-
cmd
499-
};
473+
async fn cmd_output(&self, mut cmd: Command) -> Result<Output, Error> {
500474
wrap_capture_cmd(&mut cmd);
501475

502476
let program = cmd.program.to_string_lossy().to_string();
@@ -838,7 +812,7 @@ impl Distrobox {
838812

839813
impl Default for Distrobox {
840814
fn default() -> Self {
841-
Self::new()
815+
Self::new(Rc::new(NullCommandRunner::default()))
842816
}
843817
}
844818

@@ -856,7 +830,6 @@ d24405b14180 | ubuntu | Created | ghcr.io/ublue-os/ubun
856830
NullCommandRunnerBuilder::new()
857831
.cmd(&["distrobox", "ls", "--no-color"], output)
858832
.build(),
859-
false,
860833
);
861834
assert_eq!(
862835
db.list().await?,
@@ -879,7 +852,6 @@ d24405b14180 | ubuntu | Created | ghcr.io/ublue-os/ubun
879852
NullCommandRunnerBuilder::new()
880853
.cmd(&["distrobox", "version"], output)
881854
.build(),
882-
false,
883855
);
884856
assert_eq!(db.version().await?, "1.7.2.1".to_string(),);
885857
Ok(())
@@ -935,7 +907,6 @@ Comment=A brief description of my application
935907
Categories=Utility;Network;
936908
",)
937909
.build(),
938-
false
939910
);
940911

941912
let apps = block_on(db.list_apps("ubuntu"))?;
@@ -950,7 +921,7 @@ Categories=Utility;Network;
950921
#[test]
951922
fn create() -> Result<(), Error> {
952923
let _ = tracing_subscriber::fmt().with_test_writer().try_init();
953-
let db = Distrobox::new_null(NullCommandRunner::default(), false);
924+
let db = Distrobox::new_null(NullCommandRunner::default());
954925
let output_tracker = db.output_tracker();
955926
debug!("Testing container creation");
956927
let args = CreateArgs {
@@ -969,7 +940,7 @@ Categories=Utility;Network;
969940
}
970941
#[test]
971942
fn assemble() -> Result<(), Error> {
972-
let db = Distrobox::new_null(NullCommandRunner::default(), false);
943+
let db = Distrobox::new_null(NullCommandRunner::default());
973944
let output_tracker = db.output_tracker();
974945
db.assemble("/path/to/assemble.yml")?;
975946
assert_eq!(
@@ -981,7 +952,7 @@ Categories=Utility;Network;
981952

982953
#[test]
983954
fn remove() -> Result<(), Error> {
984-
let db = Distrobox::new_null(NullCommandRunner::default(), false);
955+
let db = Distrobox::new_null(NullCommandRunner::default());
985956
let output_tracker = db.output_tracker();
986957
block_on(db.remove("ubuntu"))?;
987958
assert_eq!(

0 commit comments

Comments
 (0)