feat: add runtime build-ID management to increment and track application build numbers

- Implemented a new module for managing build IDs at runtime.
- Introduced functions to find the repository root, check for stale locks, and increment the build ID.
- Ensured atomic writes to the build ID file with proper locking mechanisms.
- The build version string is formatted as "0.1.0+build.{build_id}" for display purposes.
This commit is contained in:
2026-07-21 05:41:27 +03:00
parent cbe03f74a3
commit bc89eefa88
9 changed files with 417 additions and 115 deletions
+40 -1
View File
@@ -331,6 +331,8 @@ pub struct HcieIcedApp {
pub brush_category: crate::panels::brushes::BrushCategory,
/// Context menu screen position (x, y). None means closed.
pub canvas_context_menu: Option<(f32, f32)>,
/// Runtime build version string (e.g. `"0.1.0+build.992"`), incremented on each launch.
pub runtime_version: String,
/// Dirty flag set whenever fg/bg/recent colors change, so colors can be
/// persisted to disk (egui persists these under the `hcie_colors` key).
pub colors_dirty: bool,
@@ -507,6 +509,12 @@ pub struct IcedDocument {
/// Transformed vector shape being previewed during a drag (not yet committed
/// to the engine). Kept in the document so the overlay canvas can draw it.
pub vector_drag_preview: Option<hcie_engine_api::VectorShape>,
/// True while the user is holding Shift during a rotation drag (enables snap visual feedback).
pub rotation_snap_active: bool,
/// The snapped angle (radians) currently displayed in the snap indicator overlay.
pub rotation_snap_angle: f32,
/// True while the user is holding Shift during a resize drag (enables aspect-lock visual feedback).
pub resize_snap_active: bool,
/// Cached layer thumbnails keyed by layer ID — (thumb_w, thumb_h, RGBA pixels).
/// Regenerated only for dirty layers in `refresh_panel_caches()`.
pub layer_thumbnails: std::collections::HashMap<u64, (u32, u32, Vec<u8>)>,
@@ -1679,6 +1687,9 @@ impl HcieIcedApp {
vector_cycle_index: 0,
vector_edit_handle: hcie_engine_api::VectorEditHandle::None,
vector_drag_preview: None,
rotation_snap_active: false,
rotation_snap_angle: 0.0,
resize_snap_active: false,
layer_thumbnails: std::collections::HashMap::new(),
thumb_gen: 0,
};
@@ -1786,6 +1797,7 @@ impl HcieIcedApp {
show_dock_profile_dialog: false,
_language: i18n::Language::default(),
brush_category: crate::panels::brushes::BrushCategory::All,
runtime_version: crate::build_info::runtime_build_version(),
colors_dirty: false,
color_dragging: false,
pending_drag_color: None,
@@ -5270,6 +5282,9 @@ impl HcieIcedApp {
vector_cycle_index: 0,
vector_edit_handle: hcie_engine_api::VectorEditHandle::None,
vector_drag_preview: None,
rotation_snap_active: false,
rotation_snap_angle: 0.0,
resize_snap_active: false,
layer_thumbnails: std::collections::HashMap::new(),
thumb_gen: 0,
};
@@ -5769,7 +5784,7 @@ impl HcieIcedApp {
let radius = self.settings.tool_settings.vector_radius;
let points = self.settings.tool_settings.vector_points;
let sides = self.settings.tool_settings.vector_sides;
let fill_color = color;
let fill_color = self.bg_color;
let shape = match self.tool_state.active_tool {
Tool::VectorRect => Some(hcie_engine_api::VectorShape::Rect {
@@ -6411,6 +6426,24 @@ impl HcieIcedApp {
self.vector_drag_last_bounds = Some((x1, y1, x2, y2));
self.vector_drag_last_angle = Some(angle);
self.settings.tool_settings.vector_angle = angle.to_degrees();
// Track snap state for visual overlay feedback
let is_rotate = matches!(
session.handle,
hcie_engine_api::VectorEditHandle::Rotate
);
let is_resize = matches!(
session.handle,
hcie_engine_api::VectorEditHandle::TopLeft
| hcie_engine_api::VectorEditHandle::TopRight
| hcie_engine_api::VectorEditHandle::BottomLeft
| hcie_engine_api::VectorEditHandle::BottomRight
);
self.documents[self.active_doc].rotation_snap_active =
is_rotate && self.modifiers.shift();
self.documents[self.active_doc].rotation_snap_angle = angle;
self.documents[self.active_doc].resize_snap_active =
is_resize && self.modifiers.shift();
}
}
Message::VectorSelectDragEnd => {
@@ -6448,6 +6481,8 @@ impl HcieIcedApp {
self.documents[self.active_doc].vector_drag_preview = None;
self.documents[self.active_doc].vector_edit_handle =
hcie_engine_api::VectorEditHandle::None;
self.documents[self.active_doc].rotation_snap_active = false;
self.documents[self.active_doc].resize_snap_active = false;
self.refresh_composite_if_needed();
}
}
@@ -8076,6 +8111,9 @@ impl HcieIcedApp {
vector_cycle_index: 0,
vector_edit_handle: hcie_engine_api::VectorEditHandle::None,
vector_drag_preview: None,
rotation_snap_active: false,
rotation_snap_angle: 0.0,
resize_snap_active: false,
layer_thumbnails: std::collections::HashMap::new(),
thumb_gen: 0,
});
@@ -9237,6 +9275,7 @@ impl HcieIcedApp {
self.active_menu,
&self.title_search,
self.show_panel_list,
&self.runtime_version,
);
// Toolbox — 36px strip (single column) or 72px (2 columns) on the left edge