Derive the version from the Cargo/pubspec manifests

The version string was duplicated across six places. Collapse it to two
ecosystem sources of truth and derive the rest:

- backend/src/web_server.rs: omit the OpenAPI info.version so utoipa fills
  it from CARGO_PKG_VERSION (backend/Cargo.toml); add a test pinning this.
- nix/package.nix: read the version from backend/Cargo.toml via fromTOML.
- nix/frontend.nix: read the version from frontend/pubspec.yaml by splitting
  into lines (a whole-file regex triggers catastrophic backtracking in Nix's
  regex engine).
- frontend/lib/about/about.dart: read the version at runtime via
  package_info_plus instead of a hardcoded constant.

Also drop frontend/pubspec.lock.json: it is unreferenced (Nix's
autoPubspecLock generates its own JSON from pubspec.lock) and was going stale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-06-02 16:49:52 -04:00
co-authored by Claude Opus 4.8
parent dd089a9cbc
commit 4a1fe60ec3
8 changed files with 75 additions and 19 deletions
+17 -6
View File
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
const _version = '0.1.0';
// The version is read at runtime from the bundled package metadata
// (frontend/pubspec.yaml), so it never needs to be hand-edited here.
const _releaseDate = 'May 28, 2026';
const _repoUrl = 'https://github.com/rzuasti/oott';
const _licenseUrl = 'https://www.gnu.org/licenses/agpl-3.0.html';
@@ -28,11 +30,20 @@ class About extends StatelessWidget {
style: textTheme.bodyLarge,
),
const SizedBox(height: 8),
Text(
'v$_version - released $_releaseDate',
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
FutureBuilder<PackageInfo>(
future: PackageInfo.fromPlatform(),
builder: (context, snapshot) {
final version = snapshot.data?.version;
final label = version == null
? 'Released $_releaseDate'
: 'v$version - released $_releaseDate';
return Text(
label,
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
);
},
),
const SizedBox(height: 24),
_SurfaceContainer(
@@ -7,12 +7,14 @@ import Foundation
import connectivity_plus
import encrypter
import package_info_plus
import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
EncrypterPlugin.register(with: registry.registrar(forPlugin: "EncrypterPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
+24
View File
@@ -384,6 +384,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
package_info_plus:
dependency: "direct main"
description:
name: package_info_plus
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
url: "https://pub.dev"
source: hosted
version: "8.3.1"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
path:
dependency: transitive
description:
@@ -701,6 +717,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.1"
win32:
dependency: transitive
description:
name: win32
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.15.0"
xdg_directories:
dependency: transitive
description:
File diff suppressed because one or more lines are too long
+1
View File
@@ -20,6 +20,7 @@ dependencies:
fl_chart: ^1.2.0
google_fonts: ^6.2.1
url_launcher: ^6.3.0
package_info_plus: ^8.0.0
dev_dependencies:
flutter_test: