Skip to content

Commit b96b9f1

Browse files
committed
Generate flatpakref files for addon/plugin refs during publish
The publish job was only generating .flatpakref files for app/ refs. Mirror the commit job's logic by also generating them for runtime/ refs that are not auto-generated sub-refs (.Debug, .Locale, .Sources, .Docs), so addons and plugins get a .flatpakref in the main repo appstream dir. Extract the shared predicate into should_generate_flatpakref() in utils.rs so both jobs stay in sync from a single source of truth. Add unit tests for both should_generate_flatpakref() and generate_flatpakref().
1 parent 2b53b46 commit b96b9f1

File tree

3 files changed

+261
-13
lines changed

3 files changed

+261
-13
lines changed

src/jobs/commit_job.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::ffi::OsString;
77
use std::fs::{self, File};
88
use std::io::Write;
99
use std::process::Command;
10-
use std::str;
1110

1211
use crate::config::{Config, RepoConfig};
1312
use crate::errors::{JobError, JobResult};
@@ -22,6 +21,7 @@ use super::job_executor::JobExecutor;
2221
use super::job_instance::{InvalidJobInstance, JobInstance};
2322
use super::utils::{
2423
add_gpg_args, do_command, generate_flatpakref, load_build_and_config, load_build_refs,
24+
should_generate_flatpakref,
2525
};
2626

2727
#[derive(Debug)]
@@ -122,15 +122,7 @@ impl CommitJobInstance {
122122
let commit = ostree::parse_ref(&build_repo_path, &build_ref.ref_name)?;
123123
commits.insert(build_ref.ref_name.to_string(), commit);
124124

125-
let unwanted_exts = [".Debug", ".Locale", ".Sources", ".Docs"];
126-
let ref_id_parts: Vec<&str> = build_ref.ref_name.split('/').collect();
127-
128-
if build_ref.ref_name.starts_with("app/")
129-
|| (build_ref.ref_name.starts_with("runtime/")
130-
&& !unwanted_exts
131-
.iter()
132-
.any(|&ext| ref_id_parts[1].ends_with(ext)))
133-
{
125+
if should_generate_flatpakref(&build_ref.ref_name) {
134126
let (filename, contents) = generate_flatpakref(
135127
&build_ref.ref_name,
136128
Some(self.build_id),

src/jobs/publish_job.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use super::job_executor::JobExecutor;
2121
use super::job_instance::{InvalidJobInstance, JobInstance};
2222
use super::utils::{
2323
add_gpg_args, do_command, generate_flatpakref, load_build_and_config, load_build_refs,
24-
schedule_update_job,
24+
schedule_update_job, should_generate_flatpakref,
2525
};
2626

2727
#[derive(Debug)]
@@ -111,7 +111,7 @@ impl PublishJobInstance {
111111
commits.insert(build_ref.ref_name.to_string(), commit);
112112
}
113113

114-
if build_ref.ref_name.starts_with("app/") {
114+
if should_generate_flatpakref(&build_ref.ref_name) {
115115
let (filename, contents) =
116116
generate_flatpakref(&build_ref.ref_name, None, config, repoconfig);
117117
let path = appstream_dir.join(&filename);

src/jobs/utils.rs

Lines changed: 257 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ use crate::schema::*;
1515

1616
use super::job_queue::queue_update_job;
1717

18+
/// We generate flatpakref files for all `app/` refs and for `runtime/` refs that represent
19+
/// actual runtimes or addons/plugins/extensions. The sub-refs that Flatpak generates
20+
/// automatically (`.Debug`, `.Locale`, `.Sources`, `.Docs`) are excluded because they are
21+
/// not directly installable by end-users.
22+
///
23+
/// **Both the commit job and the publish job use this predicate** to decide which refs get a
24+
/// `.flatpakref` file.
25+
pub fn should_generate_flatpakref(ref_name: &str) -> bool {
26+
let unwanted_exts = [".Debug", ".Locale", ".Sources", ".Docs"];
27+
let ref_id = ref_name.split('/').nth(1).unwrap_or("");
28+
29+
ref_name.starts_with("app/")
30+
|| (ref_name.starts_with("runtime/")
31+
&& !unwanted_exts.iter().any(|&ext| ref_id.ends_with(ext)))
32+
}
33+
1834
pub fn generate_flatpakref(
1935
ref_name: &str,
2036
maybe_build_id: Option<i32>,
@@ -23,7 +39,7 @@ pub fn generate_flatpakref(
2339
) -> (String, String) {
2440
let parts: Vec<&str> = ref_name.split('/').collect();
2541

26-
let filename = format!("{}.flatpakref", parts[1]);
42+
let filename = format!("{}.{}.flatpakref", parts[1], parts[3]);
2743
let app_id = &parts[1];
2844
let branch = &parts[3];
2945

@@ -230,3 +246,243 @@ pub fn load_build_refs(build_id: i32, conn: &mut PgConnection) -> JobResult<Vec<
230246

231247
Ok(refs)
232248
}
249+
250+
#[cfg(test)]
251+
mod tests {
252+
use super::*;
253+
254+
fn make_config(base_url: &str) -> Config {
255+
serde_json::from_str(&format!(
256+
r#"{{
257+
"database-url": "postgres://example",
258+
"secret": "c2VjcmV0",
259+
"repos": {{}},
260+
"build-repo-base": "/tmp/build-repo",
261+
"base-url": "{base_url}"
262+
}}"#
263+
))
264+
.unwrap()
265+
}
266+
267+
fn make_repoconfig(name: &str, base_url: Option<&str>) -> RepoConfig {
268+
let base_url_field = match base_url {
269+
Some(u) => format!(r#""base-url": "{u}","#),
270+
None => String::new(),
271+
};
272+
let mut repo: RepoConfig = serde_json::from_str(&format!(
273+
r#"{{
274+
"path": "/tmp/repo",
275+
"subsets": {{}},
276+
{base_url_field}
277+
"runtime-repo-url": null
278+
}}"#
279+
))
280+
.unwrap();
281+
repo.name = name.to_string();
282+
repo
283+
}
284+
285+
#[test]
286+
fn app_refs_always_get_a_flatpakref() {
287+
assert!(should_generate_flatpakref(
288+
"app/org.gnome.eog/x86_64/stable"
289+
));
290+
assert!(should_generate_flatpakref("app/org.gnome.eog/aarch64/beta"));
291+
}
292+
293+
#[test]
294+
fn plain_runtime_refs_get_a_flatpakref() {
295+
assert!(should_generate_flatpakref(
296+
"runtime/org.gnome.Platform/x86_64/46"
297+
));
298+
}
299+
300+
#[test]
301+
fn addon_and_plugin_refs_get_a_flatpakref() {
302+
assert!(should_generate_flatpakref(
303+
"runtime/org.gnome.eog.Plugin/x86_64/stable"
304+
));
305+
assert!(should_generate_flatpakref(
306+
"runtime/com.example.App.Addon/x86_64/stable"
307+
));
308+
}
309+
310+
#[test]
311+
fn debug_extension_refs_do_not_get_a_flatpakref() {
312+
assert!(!should_generate_flatpakref(
313+
"runtime/org.gnome.eog.Debug/x86_64/stable"
314+
));
315+
}
316+
317+
#[test]
318+
fn locale_extension_refs_do_not_get_a_flatpakref() {
319+
assert!(!should_generate_flatpakref(
320+
"runtime/org.gnome.eog.Locale/x86_64/stable"
321+
));
322+
}
323+
324+
#[test]
325+
fn sources_extension_refs_do_not_get_a_flatpakref() {
326+
assert!(!should_generate_flatpakref(
327+
"runtime/org.gnome.eog.Sources/x86_64/stable"
328+
));
329+
}
330+
331+
#[test]
332+
fn docs_extension_refs_do_not_get_a_flatpakref() {
333+
assert!(!should_generate_flatpakref(
334+
"runtime/org.gnome.eog.Docs/x86_64/stable"
335+
));
336+
}
337+
338+
#[test]
339+
fn screenshot_and_appstream_refs_do_not_get_a_flatpakref() {
340+
assert!(!should_generate_flatpakref(
341+
"screenshots/org.gnome.eog/x86_64/stable"
342+
));
343+
assert!(!should_generate_flatpakref("appstream/x86_64"));
344+
}
345+
346+
#[test]
347+
fn generate_flatpakref_for_app_ref_in_main_repo() {
348+
let config = make_config("https://dl.example.com");
349+
let repoconfig = make_repoconfig("stable", Some("https://dl.example.com/repo/stable"));
350+
351+
let (filename, contents) = generate_flatpakref(
352+
"app/org.gnome.eog/x86_64/stable",
353+
None,
354+
&config,
355+
&repoconfig,
356+
);
357+
358+
assert_eq!(filename, "org.gnome.eog.stable.flatpakref");
359+
assert!(contents.contains("Name=org.gnome.eog"));
360+
assert!(contents.contains("Branch=stable"));
361+
assert!(contents.contains("IsRuntime=false"));
362+
assert!(contents.contains("Url=https://dl.example.com/repo/stable"));
363+
assert!(contents.contains("org.gnome.eog from"));
364+
}
365+
366+
#[test]
367+
fn generate_flatpakref_for_app_ref_in_build_repo() {
368+
let config = make_config("https://dl.example.com");
369+
let repoconfig = make_repoconfig("stable", None);
370+
371+
let (filename, contents) = generate_flatpakref(
372+
"app/org.gnome.eog/x86_64/stable",
373+
Some(42),
374+
&config,
375+
&repoconfig,
376+
);
377+
378+
assert_eq!(filename, "org.gnome.eog.stable.flatpakref");
379+
assert!(contents.contains("IsRuntime=false"));
380+
assert!(contents.contains("Url=https://dl.example.com/build-repo/42"));
381+
assert!(contents.contains("Title=org.gnome.eog build nr 42"));
382+
}
383+
384+
#[test]
385+
fn generate_flatpakref_for_runtime_ref_sets_is_runtime_true() {
386+
let config = make_config("https://dl.example.com");
387+
let repoconfig = make_repoconfig("stable", None);
388+
389+
let (_filename, contents) = generate_flatpakref(
390+
"runtime/org.gnome.Platform/x86_64/46",
391+
None,
392+
&config,
393+
&repoconfig,
394+
);
395+
396+
assert!(contents.contains("IsRuntime=true"));
397+
assert!(contents.contains("Name=org.gnome.Platform"));
398+
assert!(contents.contains("Branch=46"));
399+
}
400+
401+
#[test]
402+
fn generate_flatpakref_for_addon_ref_sets_is_runtime_true() {
403+
let config = make_config("https://dl.example.com");
404+
let repoconfig = make_repoconfig("stable", None);
405+
406+
let (filename, contents) = generate_flatpakref(
407+
"runtime/org.gnome.eog.Plugin/x86_64/stable",
408+
None,
409+
&config,
410+
&repoconfig,
411+
);
412+
413+
assert_eq!(filename, "org.gnome.eog.Plugin.stable.flatpakref");
414+
assert!(contents.contains("IsRuntime=true"));
415+
assert!(contents.contains("Name=org.gnome.eog.Plugin"));
416+
}
417+
418+
#[test]
419+
fn generate_flatpakref_includes_deploy_collection_id_for_main_repo_only() {
420+
let config = make_config("https://dl.example.com");
421+
let mut repoconfig = make_repoconfig("stable", None);
422+
repoconfig.collection_id = Some("org.example.Repo".to_string());
423+
repoconfig.deploy_collection_id = true;
424+
425+
let (_filename, contents) = generate_flatpakref(
426+
"app/org.gnome.eog/x86_64/stable",
427+
None,
428+
&config,
429+
&repoconfig,
430+
);
431+
assert!(contents.contains("DeployCollectionID=org.example.Repo"));
432+
433+
let (_filename, contents) = generate_flatpakref(
434+
"app/org.gnome.eog/x86_64/stable",
435+
Some(1),
436+
&config,
437+
&repoconfig,
438+
);
439+
assert!(!contents.contains("DeployCollectionID"));
440+
}
441+
442+
#[test]
443+
fn generate_flatpakref_includes_suggested_remote_name_for_main_repo_only() {
444+
let config = make_config("https://dl.example.com");
445+
let mut repoconfig = make_repoconfig("stable", None);
446+
repoconfig.suggested_repo_name = Some("flathub".to_string());
447+
448+
let (_filename, contents) = generate_flatpakref(
449+
"app/org.gnome.eog/x86_64/stable",
450+
None,
451+
&config,
452+
&repoconfig,
453+
);
454+
assert!(contents.contains("SuggestRemoteName=flathub"));
455+
assert!(contents.contains("org.gnome.eog from flathub"));
456+
457+
let (_filename, contents) = generate_flatpakref(
458+
"app/org.gnome.eog/x86_64/stable",
459+
Some(7),
460+
&config,
461+
&repoconfig,
462+
);
463+
assert!(!contents.contains("SuggestRemoteName"));
464+
}
465+
466+
#[test]
467+
fn different_branches_of_same_ref_produce_distinct_filenames() {
468+
let config = make_config("https://dl.example.com");
469+
let repoconfig = make_repoconfig("stable", None);
470+
471+
let (stable_filename, _) = generate_flatpakref(
472+
"runtime/org.gnome.eog.Plugin/x86_64/stable",
473+
None,
474+
&config,
475+
&repoconfig,
476+
);
477+
let (beta_filename, _) = generate_flatpakref(
478+
"runtime/org.gnome.eog.Plugin/x86_64/beta",
479+
None,
480+
&config,
481+
&repoconfig,
482+
);
483+
484+
assert_ne!(stable_filename, beta_filename);
485+
assert_eq!(stable_filename, "org.gnome.eog.Plugin.stable.flatpakref");
486+
assert_eq!(beta_filename, "org.gnome.eog.Plugin.beta.flatpakref");
487+
}
488+
}

0 commit comments

Comments
 (0)