66 lines
2.4 KiB
Dart
66 lines
2.4 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
|
|
/// Single source of truth for the app's identity shown inside the running app.
|
|
///
|
|
/// **Source of truth** for the version numbers is the `version:` field in
|
|
/// `pubspec.yaml` (e.g. `1.0.0+1`). At runtime we read that value via
|
|
/// `package_info_plus`, which Flutter populates from `pubspec.yaml` *unless*
|
|
/// overridden at build time with `--build-name` / `--build-number`.
|
|
///
|
|
/// If `package_info_plus` cannot resolve the values (e.g. running in a unit
|
|
/// test that hasn't initialised the plugin platform), we fall back to the
|
|
/// [fallbackVersion] constant. Keep that constant in sync with `pubspec.yaml`
|
|
/// when you bump versions; the release process described in
|
|
/// `docs/RELEASING.md` owns that update.
|
|
class AppInfo {
|
|
AppInfo._();
|
|
|
|
/// Hard-coded fallback. Must mirror the `version:` field in `pubspec.yaml`.
|
|
/// Format: `MAJOR.MINOR.PATCH+BUILD`.
|
|
static const String fallbackVersion = '1.0.0+1';
|
|
|
|
/// Cached result so we only hit the platform once.
|
|
static PackageInfo? _cached;
|
|
|
|
/// Asynchronously loads the package info, caching the result.
|
|
static Future<PackageInfo> _load() async {
|
|
return _cached ??= await PackageInfo.fromPlatform();
|
|
}
|
|
|
|
/// Resolves the build version in the form `MAJOR.MINOR.PATCH+BUILD`
|
|
/// (e.g. `1.0.0+1`). Falls back to [fallbackVersion] on error.
|
|
static Future<String> versionString() async {
|
|
try {
|
|
final info = await _load();
|
|
final name = info.version.isEmpty ? '0.0.0' : info.version;
|
|
final build = info.buildNumber.isEmpty ? '0' : info.buildNumber;
|
|
return '$name+$build';
|
|
} catch (e, st) {
|
|
debugPrint('AppInfo.versionString() fell back to constant: $e\n$st');
|
|
return fallbackVersion;
|
|
}
|
|
}
|
|
|
|
/// The user-facing `MAJOR.MINOR.PATCH` portion (e.g. `1.0.0`).
|
|
static Future<String> versionName() async {
|
|
try {
|
|
final info = await _load();
|
|
return info.version.isEmpty ? '0.0.0' : info.version;
|
|
} catch (_) {
|
|
// Extract the part before the '+' from the fallback.
|
|
return fallbackVersion.split('+').first;
|
|
}
|
|
}
|
|
|
|
/// The monotonically increasing `+BUILD` portion (e.g. `1`).
|
|
static Future<String> buildNumber() async {
|
|
try {
|
|
final info = await _load();
|
|
return info.buildNumber.isEmpty ? '0' : info.buildNumber;
|
|
} catch (_) {
|
|
return fallbackVersion.split('+').last;
|
|
}
|
|
}
|
|
}
|