mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-17 12:16:59 +00:00
feat(bar): show running app version in the panel header
A right-aligned v{CFBundleShortVersionString} label fills the unused
header space next to the CCS name, styled like the subtitle and hidden
when no bundle version is available (e.g. swift run). The display
logic lives in CCSBarCore as a pure helper with ccs-bar-check
coverage, making the on-screen build identifiable after reinstalls.
This commit is contained in:
@@ -192,6 +192,11 @@ struct BarMenuView: View {
|
||||
Text("usage & accounts").font(.caption2).foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
if let v = BarVersionDisplay.string() {
|
||||
Text(v)
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
if viewModel.isRefreshing {
|
||||
ProgressView().controlSize(.small)
|
||||
}
|
||||
|
||||
@@ -1436,6 +1436,15 @@ do {
|
||||
check(selectedIdx == 1, "screenPicker: exact hit selects right screen (index 1) for #1502 anchor")
|
||||
}
|
||||
|
||||
// MARK: BarVersionDisplay — pure display-string helper
|
||||
|
||||
check(BarVersionDisplay.displayString(for: nil) == nil, "version nil raw -> nil (no dangling 'v')")
|
||||
check(BarVersionDisplay.displayString(for: "") == nil, "version empty raw -> nil (no dangling 'v')")
|
||||
check(BarVersionDisplay.displayString(for: "1.5.0") == "v1.5.0", "version '1.5.0' -> 'v1.5.0'")
|
||||
check(BarVersionDisplay.displayString(for: "2.0.0") == "v2.0.0", "version '2.0.0' -> 'v2.0.0'")
|
||||
// Outside a bundle, string() must not crash and returns nil (no assertion on value — bundle absent).
|
||||
let _ = BarVersionDisplay.string()
|
||||
|
||||
// cleanup
|
||||
try? FileManager.default.removeItem(atPath: tmp)
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import Foundation
|
||||
|
||||
/// Pure helper for the version string shown in the bar panel header.
|
||||
///
|
||||
/// Kept tiny so it can be tested in CCSBarCheck without a bundle present:
|
||||
/// the display-string logic is pure-Foundation and has no AppKit dependency.
|
||||
public enum BarVersionDisplay {
|
||||
|
||||
/// Converts a raw version string to a "v{version}" display string.
|
||||
///
|
||||
/// - Returns: `"v\(raw)"` when `raw` is non-nil and non-empty; `nil` otherwise.
|
||||
///
|
||||
/// This is the logic under test. The actual `Bundle.main` lookup is in `string()`.
|
||||
public static func displayString(for raw: String?) -> String? {
|
||||
guard let v = raw, !v.isEmpty else { return nil }
|
||||
return "v\(v)"
|
||||
}
|
||||
|
||||
/// Returns the display string for the running app's bundle version, or `nil`
|
||||
/// when the key is absent (e.g. `swift run` outside a bundle).
|
||||
///
|
||||
/// Never produces a dangling "v" prefix: if `CFBundleShortVersionString` is
|
||||
/// missing or empty, returns `nil` so the caller can omit the label entirely.
|
||||
public static func string() -> String? {
|
||||
let raw = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
|
||||
return displayString(for: raw)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user