FlutterVersion.parse constructor

FlutterVersion.parse(
  1. String version
)

Implementation

factory FlutterVersion.parse(String version) {
  // Match pattern: [fork/]version[@channel]
  final pattern = RegExp(
    r'^(?:(?<fork>[^/]+)/)?(?<version>[^@]+)(?:@(?<channel>\w+))?$',
  );
  final match = pattern.firstMatch(version);

  if (match == null) {
    throw FormatException('Invalid version format: $version');
  }

  // Extract components
  final forkName = match.namedGroup('fork');
  final versionPart = match.namedGroup('version')!;
  final channelPart = match.namedGroup('channel');

  // Handle custom versions
  if (versionPart.startsWith('custom_')) {
    if (forkName != null || channelPart != null) {
      throw FormatException(
        'Custom versions cannot have fork or channel specifications',
      );
    }

    return FlutterVersion.custom(versionPart);
  }

  // Handle channel versions
  if (isFlutterChannel(versionPart)) {
    return FlutterVersion.channel(versionPart, fork: forkName);
  }

  // Handle release versions with channel
  if (channelPart != null) {
    if (!isFlutterChannel(channelPart)) {
      throw FormatException('Invalid channel: $channelPart');
    }

    final nameToUse = '$versionPart@$channelPart';

    return FlutterVersion.release(
      nameToUse,
      releaseChannel: FlutterChannel.fromValue(channelPart),
      fork: forkName,
    );
  }

  // Try to parse as semantic version
  try {
    // Create a version to check for validation only
    String checkVersion = versionPart;
    if (versionPart.startsWith('v')) {
      // Strip 'v' only for validation check
      checkVersion = versionPart.substring(1);
    }

    // Validate format - Version.parse throws FormatException on invalid input
    // ignore: avoid-unused-instances
    Version.parse(checkVersion);

    // Use the original version string (preserving v if present)
    return FlutterVersion.release(versionPart, fork: forkName);
  } catch (e) {
    // Not a valid semver, treat as git reference
    return FlutterVersion.gitReference(versionPart, fork: forkName);
  }
}