tv-anarchy/Sources/TVAnarchyCore/AppVersion.swift
Natalie 92b38b1bae refactor(tv-anarchy): rename PlumTV→TVAnarchy and land session work
Renames Sources/PlumTV→TVAnarchy and PlumTVCore→TVAnarchyCore (the rename
the auto-commit service couldn't stage — it git-add'd the old, now-gone
paths and aborted every cycle), and commits the accumulated work:

- Library: black-built index fast path (LibraryIndex + scanFromIndex) with
  NFS-walk fallback; incremental --add on download-complete; mtime staleness
  gate; loose-file series-collapse fix; determinate scan/index progress.
- Cover art: keyless TVmaze cartoon-vs-live-action disambiguation (type/year).
- Player: sleep timer (timed + end-of-episode); visibility-gated polling.
- Home: Continue Watching cover art + live refresh; Recently Added; adult gate.
- Logs: multi-line selection + copy; truncated giant tx-list errors.
- Hover previews (opt-in) via black ffmpeg + scp.

Also gitignores foreign project trees (governor/mcp/fleet/recommender) that
sit in this directory but belong to their own repos.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 22:04:22 -07:00

34 lines
1.6 KiB
Swift

import Foundation
/// Reads the build identity stamped onto the app bundle's Info.plist at build
/// time (see the "Stamp version" phase in project.yml). `Bundle.main` is the
/// running .app even though this lives in the framework, so the values reflect
/// the app you actually launched which is exactly how you tell a fresh build
/// from a stale one you forgot to relaunch.
public enum AppVersion {
/// Human version, e.g. "1.1.0" from MARKETING_VERSION, baked into the
/// Info.plist by XcodeGen (reliable; unlike the dynamic stamp it never moves
/// between builds of the same release).
public static var marketing: String { info("CFBundleShortVersionString") ?? "?" }
/// Monotonic build number = git commit count, e.g. "212".
public static var build: String { String(BuildStamp.commitCount) }
/// Short git SHA, with a "-dirty" suffix when built from an uncommitted tree.
public static var sha: String { BuildStamp.sha }
/// Build timestamp, "yyyy-MM-dd HH:mm:ss".
public static var buildTime: String { BuildStamp.buildTime }
/// Glanceable one-liner for chrome (sidebar / title): "v1.1.0 · a1b2c3d · 14:32".
public static var short: String {
let clock = buildTime.split(separator: " ").last.map(String.init) ?? buildTime
return "v\(marketing) · \(sha) · \(clock)"
}
/// Full identity for an about/settings line.
public static var full: String {
"TVAnarchy v\(marketing) (build \(build)) · \(sha) · built \(buildTime)"
}
private static func info(_ key: String) -> String? {
Bundle.main.infoDictionary?[key] as? String
}
}