• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5class Version implements Comparable<Version> {
6  /// Creates a new [Version] object.
7  factory Version(int major, int minor, int patch, {String text}) {
8    if (text == null) {
9      text = major == null ? '0' : '$major';
10      if (minor != null)
11        text = '$text.$minor';
12      if (patch != null)
13        text = '$text.$patch';
14    }
15
16    return Version._(major ?? 0, minor ?? 0, patch ?? 0, text);
17  }
18
19  Version._(this.major, this.minor, this.patch, this._text) {
20    if (major < 0)
21      throw ArgumentError('Major version must be non-negative.');
22    if (minor < 0)
23      throw ArgumentError('Minor version must be non-negative.');
24    if (patch < 0)
25      throw ArgumentError('Patch version must be non-negative.');
26  }
27
28  /// Creates a new [Version] by parsing [text].
29  factory Version.parse(String text) {
30    final Match match = versionPattern.firstMatch(text ?? '');
31    if (match == null) {
32      return null;
33    }
34
35    try {
36      final int major = int.parse(match[1] ?? '0');
37      final int minor = int.parse(match[3] ?? '0');
38      final int patch = int.parse(match[5] ?? '0');
39      return Version._(major, minor, patch, text);
40    } on FormatException {
41      return null;
42    }
43  }
44
45  /// Returns the primary version out of a list of candidates.
46  ///
47  /// This is the highest-numbered stable version.
48  static Version primary(List<Version> versions) {
49    Version primary;
50    for (Version version in versions) {
51      if (primary == null || (version > primary)) {
52        primary = version;
53      }
54    }
55    return primary;
56  }
57
58
59  static Version get unknown => Version(0, 0, 0, text: 'unknown');
60
61  /// The major version number: "1" in "1.2.3".
62  final int major;
63
64  /// The minor version number: "2" in "1.2.3".
65  final int minor;
66
67  /// The patch version number: "3" in "1.2.3".
68  final int patch;
69
70  /// The original string representation of the version number.
71  ///
72  /// This preserves textual artifacts like leading zeros that may be left out
73  /// of the parsed version.
74  final String _text;
75
76  static final RegExp versionPattern =
77      RegExp(r'^(\d+)(\.(\d+)(\.(\d+))?)?');
78
79  /// Two [Version]s are equal if their version numbers are. The version text
80  /// is ignored.
81  @override
82  bool operator ==(dynamic other) {
83    if (other is! Version)
84      return false;
85    return major == other.major && minor == other.minor && patch == other.patch;
86  }
87
88  @override
89  int get hashCode => major ^ minor ^ patch;
90
91  bool operator <(Version other) => compareTo(other) < 0;
92  bool operator >(Version other) => compareTo(other) > 0;
93  bool operator <=(Version other) => compareTo(other) <= 0;
94  bool operator >=(Version other) => compareTo(other) >= 0;
95
96  @override
97  int compareTo(Version other) {
98    if (major != other.major)
99      return major.compareTo(other.major);
100    if (minor != other.minor)
101      return minor.compareTo(other.minor);
102    return patch.compareTo(other.patch);
103  }
104
105  @override
106  String toString() => _text;
107}
108