Skip to content

Commit a08157e

Browse files
committed
Handle enabled global dictation fallback
1 parent abcdf49 commit a08157e

1 file changed

Lines changed: 82 additions & 13 deletions

File tree

updater/src/builder.rs

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ pub async fn build_update_from(
122122
state.artifact_paths.workspace_dir = Some(workspace.workspace_dir.clone());
123123
state.save(&paths.state_file)?;
124124

125-
copy_builder_bundle(bundle_source, &workspace.bundle_dir)?;
125+
let feature_config = crate::config::effective_feature_config_path(config);
126+
copy_builder_bundle(
127+
bundle_source,
128+
&workspace.bundle_dir,
129+
feature_config.as_deref(),
130+
)?;
126131

127132
state.status = UpdateStatus::PatchingApp;
128133
state.save(&paths.state_file)?;
@@ -146,7 +151,7 @@ pub async fn build_update_from(
146151
// writes it to a stable per-user path) so the rebuild stages exactly those
147152
// features. Only set it when the file actually exists; an absent path would
148153
// make linux-features.js see an empty enabled set and stage nothing.
149-
if let Some(feature_config) = crate::config::effective_feature_config_path(config) {
154+
if let Some(feature_config) = feature_config {
150155
install.env("CODEX_LINUX_FEATURES_CONFIG", &feature_config);
151156
}
152157
run_and_log(&mut install, &workspace.install_log)
@@ -246,7 +251,11 @@ fn package_build_script(bundle_dir: &Path) -> PathBuf {
246251
}
247252
}
248253

249-
fn copy_builder_bundle(source_root: &Path, destination_root: &Path) -> Result<()> {
254+
fn copy_builder_bundle(
255+
source_root: &Path,
256+
destination_root: &Path,
257+
feature_config: Option<&Path>,
258+
) -> Result<()> {
250259
let manifest_path = source_root.join(UPDATE_BUILDER_MANIFEST);
251260
if manifest_path.exists() {
252261
return copy_builder_bundle_from_manifest(source_root, destination_root, &manifest_path);
@@ -268,9 +277,34 @@ fn copy_builder_bundle(source_root: &Path, destination_root: &Path) -> Result<()
268277
)?;
269278
}
270279

280+
if linux_feature_enabled_in_config(feature_config, "global-dictation") {
281+
copy_entry(
282+
&source_root.join("global-dictation-linux"),
283+
&destination_root.join("global-dictation-linux"),
284+
false,
285+
)?;
286+
}
287+
271288
Ok(())
272289
}
273290

291+
fn linux_feature_enabled_in_config(feature_config: Option<&Path>, feature_id: &str) -> bool {
292+
let Some(feature_config) = feature_config else {
293+
return false;
294+
};
295+
let Ok(contents) = fs::read_to_string(feature_config) else {
296+
return false;
297+
};
298+
let Ok(config) = serde_json::from_str::<serde_json::Value>(&contents) else {
299+
return false;
300+
};
301+
302+
config
303+
.get("enabled")
304+
.and_then(serde_json::Value::as_array)
305+
.is_some_and(|enabled| enabled.iter().any(|id| id.as_str() == Some(feature_id)))
306+
}
307+
274308
fn copy_builder_bundle_from_manifest(
275309
source_root: &Path,
276310
destination_root: &Path,
@@ -950,12 +984,7 @@ fi
950984
Ok(())
951985
}
952986

953-
#[test]
954-
fn bundle_copy_skips_missing_optional_package_scripts() -> Result<()> {
955-
let temp = tempdir()?;
956-
let source_root = temp.path().join("source");
957-
let destination_root = temp.path().join("destination");
958-
987+
fn write_fake_fallback_bundle(source_root: &Path) -> Result<()> {
959988
fs::create_dir_all(source_root.join("scripts/lib"))?;
960989
fs::create_dir_all(source_root.join("launcher"))?;
961990
fs::create_dir_all(source_root.join("packaging/linux"))?;
@@ -1003,8 +1032,18 @@ fi
10031032
)?;
10041033
fs::write(source_root.join("assets/codex.png"), b"png")?;
10051034
fs::write(source_root.join("assets/codex-linux.png"), b"linux png")?;
1035+
Ok(())
1036+
}
10061037

1007-
copy_builder_bundle(&source_root, &destination_root)?;
1038+
#[test]
1039+
fn bundle_copy_skips_missing_optional_package_scripts() -> Result<()> {
1040+
let temp = tempdir()?;
1041+
let source_root = temp.path().join("source");
1042+
let destination_root = temp.path().join("destination");
1043+
1044+
write_fake_fallback_bundle(&source_root)?;
1045+
1046+
copy_builder_bundle(&source_root, &destination_root, None)?;
10081047

10091048
assert!(destination_root.join("scripts/build-deb.sh").exists());
10101049
assert!(destination_root
@@ -1041,6 +1080,36 @@ fi
10411080
Ok(())
10421081
}
10431082

1083+
#[test]
1084+
fn fallback_bundle_copies_global_dictation_source_when_enabled() -> Result<()> {
1085+
let temp = tempdir()?;
1086+
let source_root = temp.path().join("source");
1087+
let destination_root = temp.path().join("destination");
1088+
let feature_config = temp.path().join("linux-features.json");
1089+
1090+
write_fake_fallback_bundle(&source_root)?;
1091+
fs::create_dir_all(source_root.join("global-dictation-linux/src"))?;
1092+
fs::write(
1093+
source_root.join("global-dictation-linux/Cargo.toml"),
1094+
b"[package]\nname = \"codex-global-dictation-linux\"\nversion = \"0.1.0\"\nedition = \"2021\"\n",
1095+
)?;
1096+
fs::write(
1097+
source_root.join("global-dictation-linux/src/main.rs"),
1098+
b"fn main() {}\n",
1099+
)?;
1100+
fs::write(&feature_config, b"{\"enabled\":[\"global-dictation\"]}\n")?;
1101+
1102+
copy_builder_bundle(&source_root, &destination_root, Some(&feature_config))?;
1103+
1104+
assert!(destination_root
1105+
.join("global-dictation-linux/Cargo.toml")
1106+
.exists());
1107+
assert!(destination_root
1108+
.join("global-dictation-linux/src/main.rs")
1109+
.exists());
1110+
Ok(())
1111+
}
1112+
10441113
#[test]
10451114
fn bundle_copy_prefers_packaged_update_builder_manifest() -> Result<()> {
10461115
let temp = tempdir()?;
@@ -1062,7 +1131,7 @@ fi
10621131
b"# generated\nassets/codex-linux.png\nrecord-replay-linux/Cargo.toml\n",
10631132
)?;
10641133

1065-
copy_builder_bundle(&source_root, &destination_root)?;
1134+
copy_builder_bundle(&source_root, &destination_root, None)?;
10661135

10671136
assert!(destination_root.join("assets/codex-linux.png").exists());
10681137
assert!(destination_root
@@ -1082,7 +1151,7 @@ fi
10821151
fs::create_dir_all(source_root.join(".codex-linux"))?;
10831152
fs::write(source_root.join(UPDATE_BUILDER_MANIFEST), b"../escape\n")?;
10841153

1085-
let error = copy_builder_bundle(&source_root, &destination_root)
1154+
let error = copy_builder_bundle(&source_root, &destination_root, None)
10861155
.expect_err("manifest parent path should be rejected");
10871156
assert!(error
10881157
.to_string()
@@ -1099,7 +1168,7 @@ fi
10991168
fs::create_dir_all(source_root.join(".codex-linux"))?;
11001169
fs::write(source_root.join(UPDATE_BUILDER_MANIFEST), b"/tmp/escape\n")?;
11011170

1102-
let error = copy_builder_bundle(&source_root, &destination_root)
1171+
let error = copy_builder_bundle(&source_root, &destination_root, None)
11031172
.expect_err("manifest absolute path should be rejected");
11041173
assert!(error
11051174
.to_string()

0 commit comments

Comments
 (0)