| 73 |
73 |
|
/// via `repo()` to `cd` into the checkout — commands don't auto-cd, and each
|
| 74 |
74 |
|
/// `sh` is a fresh shell.
|
| 75 |
75 |
|
pub repo: String,
|
|
76 |
+ |
/// Cargo features this app's release builds enable (topology `features`).
|
|
77 |
+ |
/// Recipes read it via `feature_flags()`.
|
|
78 |
+ |
pub features: Vec<String>,
|
| 76 |
79 |
|
pub target_run_id: i64,
|
| 77 |
80 |
|
/// Capability-scoped executor per build host. Recipe commands dispatch
|
| 78 |
81 |
|
/// through these — the transport (local / ssh / in-session agent) and the
|
| 111 |
114 |
|
target: Target,
|
| 112 |
115 |
|
build_host: String,
|
| 113 |
116 |
|
repo: String,
|
|
117 |
+ |
features: Vec<String>,
|
| 114 |
118 |
|
target_run_id: i64,
|
| 115 |
119 |
|
execs: Arc<ExecutorMap>,
|
| 116 |
120 |
|
syncs: Arc<ExecutorMap>,
|
| 127 |
131 |
|
target,
|
| 128 |
132 |
|
build_host,
|
| 129 |
133 |
|
repo,
|
|
134 |
+ |
features,
|
| 130 |
135 |
|
target_run_id,
|
| 131 |
136 |
|
execs,
|
| 132 |
137 |
|
syncs,
|
| 505 |
510 |
|
engine.register_fn("repo", move || -> String { ctx.repo.clone() });
|
| 506 |
511 |
|
}
|
| 507 |
512 |
|
|
|
513 |
+ |
// --- feature_flags() -> string: `--features a,b`, or "" when the app
|
|
514 |
+ |
// declares none. Returns the whole flag rather than a bare list so an
|
|
515 |
+ |
// app with no features cannot produce a dangling `--features`. ---
|
|
516 |
+ |
{
|
|
517 |
+ |
let ctx = ctx.clone();
|
|
518 |
+ |
engine.register_fn("feature_flags", move || -> String {
|
|
519 |
+ |
if ctx.features.is_empty() {
|
|
520 |
+ |
String::new()
|
|
521 |
+ |
} else {
|
|
522 |
+ |
format!("--features {}", ctx.features.join(","))
|
|
523 |
+ |
}
|
|
524 |
+ |
});
|
|
525 |
+ |
}
|
|
526 |
+ |
|
| 508 |
527 |
|
// --- target() / platform() / arch(): the target axis, for one per-platform
|
| 509 |
528 |
|
// recipe to branch on arch (bundle paths differ between x86_64/aarch64). ---
|
| 510 |
529 |
|
{
|
| 954 |
973 |
|
"linux/x86_64".parse().unwrap(),
|
| 955 |
974 |
|
"fw13".into(),
|
| 956 |
975 |
|
"/tmp".into(),
|
|
976 |
+ |
vec![],
|
| 957 |
977 |
|
1,
|
| 958 |
978 |
|
Arc::new(std::collections::HashMap::new()),
|
| 959 |
979 |
|
Arc::new(std::collections::HashMap::new()),
|
| 971 |
991 |
|
assert!(ctx.is_cancelled());
|
| 972 |
992 |
|
}
|
| 973 |
993 |
|
|
|
994 |
+ |
/// `feature_flags()` returns a whole flag or nothing at all. An app with
|
|
995 |
+ |
/// no declared features must not yield a bare `--features`, which would
|
|
996 |
+ |
/// swallow the next word of the build command as its argument.
|
|
997 |
+ |
#[tokio::test]
|
|
998 |
+ |
async fn feature_flags_renders_whole_flag_or_empty() {
|
|
999 |
+ |
async fn flags_for(features: Vec<String>) -> String {
|
|
1000 |
+ |
let dir = tempfile::tempdir().unwrap();
|
|
1001 |
+ |
let cfg = Arc::new(Config::for_tests(dir.path()));
|
|
1002 |
+ |
let pool = crate::db::open(&cfg.db_path).await.unwrap();
|
|
1003 |
+ |
let ctx = Arc::new(RecipeCtx::new(
|
|
1004 |
+ |
AppId::new("demo"),
|
|
1005 |
+ |
Version::parse("0.1.0").unwrap(),
|
|
1006 |
+ |
"linux/x86_64".parse().unwrap(),
|
|
1007 |
+ |
"fw13".into(),
|
|
1008 |
+ |
"/tmp".into(),
|
|
1009 |
+ |
features,
|
|
1010 |
+ |
1,
|
|
1011 |
+ |
Arc::new(std::collections::HashMap::new()),
|
|
1012 |
+ |
Arc::new(std::collections::HashMap::new()),
|
|
1013 |
+ |
pool,
|
|
1014 |
+ |
crate::events::channel(),
|
|
1015 |
+ |
cfg,
|
|
1016 |
+ |
Arc::new(OtaRegistry::standard("https://makenot.work")),
|
|
1017 |
+ |
tokio::runtime::Handle::current(),
|
|
1018 |
+ |
Arc::new(AtomicBool::new(false)),
|
|
1019 |
+ |
));
|
|
1020 |
+ |
let engine = build_engine(ctx);
|
|
1021 |
+ |
engine.eval::<String>("feature_flags()").unwrap()
|
|
1022 |
+ |
}
|
|
1023 |
+ |
|
|
1024 |
+ |
assert_eq!(flags_for(vec![]).await, "");
|
|
1025 |
+ |
assert_eq!(flags_for(vec!["supernote".into()]).await, "--features supernote");
|
|
1026 |
+ |
assert_eq!(
|
|
1027 |
+ |
flags_for(vec!["supernote".into(), "extra".into()]).await,
|
|
1028 |
+ |
"--features supernote,extra"
|
|
1029 |
+ |
);
|
|
1030 |
+ |
}
|
|
1031 |
+ |
|
| 974 |
1032 |
|
#[test]
|
| 975 |
1033 |
|
fn expand_tilde_handles_home() {
|
| 976 |
1034 |
|
unsafe { std::env::set_var("HOME", "/home/test") };
|