feat(rust): write the recommended PopupNotifications banner (runicnpc 9e, D327, D328)
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 2m5s
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 2m5s
install and update write PopupNotifications.json into the framework's config directory, as a banner across the top of the screen, only where the file is missing or every setting is still PopupNotifications 0.2.1's own default (the Version aside, numbers compared as numbers). A config with any setting changed, or one that does not parse, is kept whole. The file carries the plugin's Version, because PopupNotifications resets a config without one to its defaults on load. The plan prints a "popup look" row naming the case. Run against two scratch roots (a temporary local bypass of the RunicNPC check, since no published bundle carries RunicNPC yet): Oxide with no config got the banner; Carbon at the rig's defaults got the walk's banner file exactly; on update a hand-changed config and an existing banner were both kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -20,6 +20,7 @@ use anyhow::{bail, Context, Result};
|
||||
|
||||
use super::npc;
|
||||
use super::plugin::{self, ConfigView};
|
||||
use super::popup;
|
||||
use super::record::{ComponentRecord, DeployedFile, Instance, NpcRecord, RustRecord, SCHEMA};
|
||||
use super::server::{self, RustServer};
|
||||
use super::sidecar;
|
||||
@@ -49,6 +50,8 @@ struct Planned {
|
||||
retired_helpers: Vec<String>,
|
||||
/// RunicNPC, when the bundle carries it (D224): absent, identical or replaced.
|
||||
npc_action: Option<BinaryAction>,
|
||||
/// PopupNotifications' config: the banner where it is missing or the plugin's defaults (D327).
|
||||
popup: popup::State,
|
||||
game_port: u16,
|
||||
web_port: u16,
|
||||
config_path: PathBuf,
|
||||
@@ -395,6 +398,7 @@ pub fn deploy(cli: &Cli, mode: Mode) -> Result<()> {
|
||||
|| p.npc_action.is_some_and(|a| a.writes())
|
||||
|| p.helper_actions.iter().any(|a| a.writes())
|
||||
|| !p.retired_helpers.is_empty()
|
||||
|| p.popup.writes()
|
||||
})
|
||||
.count();
|
||||
if restored == 0 && !binary_action.writes() {
|
||||
@@ -537,10 +541,12 @@ fn plan_instance(
|
||||
Ok(_) => BinaryAction::Replace,
|
||||
},
|
||||
);
|
||||
let popup = popup::inspect(&server.framework.config_dir(&server.path).join(popup::FILE));
|
||||
let config_path = layout.rust_config(id);
|
||||
Ok(Planned {
|
||||
id: id.to_string(),
|
||||
running: server::is_running(&server.path),
|
||||
popup,
|
||||
config_exists: config_path.exists(),
|
||||
config_path,
|
||||
db_path: layout.rust_db(id),
|
||||
@@ -641,6 +647,18 @@ fn print_plan(
|
||||
if p.config_exists { "kept" } else { "written" }
|
||||
),
|
||||
);
|
||||
ui::row(
|
||||
"popup look",
|
||||
&format!(
|
||||
"{} {}",
|
||||
p.server
|
||||
.framework
|
||||
.config_dir(&p.server.path)
|
||||
.join(popup::FILE)
|
||||
.display(),
|
||||
p.popup.label()
|
||||
),
|
||||
);
|
||||
ui::row(
|
||||
"ports",
|
||||
&format!(
|
||||
@@ -703,6 +721,26 @@ fn deploy_instance(
|
||||
ui::ok(&format!("wrote {}", plugin_config_path.display()));
|
||||
}
|
||||
|
||||
// PopupNotifications' look (D327): the banner, only over nothing or over the plugin's own
|
||||
// defaults. Before the plugins, so a PopupNotifications that loads after them reads it; one
|
||||
// already loaded keeps its old look until it is reloaded.
|
||||
if let Some(banner) = popup::banner_for(plan.popup) {
|
||||
let dir = plan.server.framework.config_dir(&plan.server.path);
|
||||
std::fs::create_dir_all(&dir)
|
||||
.with_context(|| format!("cannot create {}", dir.display()))?;
|
||||
let path = dir.join(popup::FILE);
|
||||
write_atomic(&path, banner.as_bytes())?;
|
||||
ui::ok(&format!(
|
||||
"wrote the PopupNotifications banner {}{}",
|
||||
path.display(),
|
||||
if plan.running {
|
||||
" (takes effect when PopupNotifications next loads)"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
// The sidecar's config, once; the token is the sidecar's to generate.
|
||||
if !plan.config_exists {
|
||||
if let Some(parent) = plan.config_path.parent() {
|
||||
|
||||
Reference in New Issue
Block a user