| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * This file contains functionality for getting dart version numbers using | |
| 7 * our standard version construction method. Systems that does not include this | |
| 8 * file should emulate the structure for revision numbers that we have here. | |
| 9 * | |
| 10 * The version number of a dart build is constructed as follows: | |
| 11 * 1. The major, minor, build and patch numbers are extracted from the VERSION | |
| 12 * file in the root directory. We call these MAJOR, MINOR, BUILD and PATCH. | |
| 13 * 2. The svn revision number for the current checkout is extracted from the | |
| 14 * source control system that is used in the current checkout. We call this | |
| 15 * REVISION. | |
| 16 * 3. If this is _not_ a official build, i.e., this is not build by our | |
| 17 * buildbot infrastructure, we extract the user-name of the logged in | |
| 18 * person from the operating system. We call this USERNAME. | |
| 19 * 4. The version number is constructed as follows: | |
| 20 * MAJOR.MINOR.BUILD.PATCH_rREVISION_USERNAME | |
| 21 */ | |
| 22 | |
| 23 library version; | |
| 24 import "dart:io"; | |
| 25 | |
| 26 /** | |
| 27 * Generates version information for builds. | |
| 28 */ | |
| 29 class Version { | |
| 30 String _versionFileName; | |
| 31 String USERNAME; | |
| 32 int REVISION; | |
| 33 int MAJOR; | |
| 34 int MINOR; | |
| 35 int BUILD; | |
| 36 int PATCH; | |
| 37 | |
| 38 Version(Path versionFile) { | |
| 39 _versionFileName = versionFile.toNativePath(); | |
| 40 } | |
| 41 | |
| 42 /** | |
| 43 * Get the version number for this specific build using the version info | |
| 44 * from the VERSION file in the root directory and the revision info | |
| 45 * from the source control system of the current checkout. | |
| 46 */ | |
| 47 Future<String> getVersion() { | |
| 48 File f = new File(_versionFileName); | |
| 49 Completer c = new Completer(); | |
| 50 f.exists().then((existed) { | |
| 51 if (!existed) { | |
| 52 c.completeException("No VERSION file"); | |
| 53 return; | |
| 54 } | |
| 55 StringInputStream input = new StringInputStream(f.openInputStream()); | |
| 56 input.onLine = () { | |
| 57 var line = input.readLine(); | |
| 58 if (line == null) { | |
| 59 c.completeException( | |
| 60 "VERSION input file seems to be in the wrong format"); | |
| 61 return; | |
| 62 } | |
| 63 var values = line.split(" "); | |
| 64 if (values.length != 2) { | |
| 65 c.completeException( | |
| 66 "VERSION input file seems to be in the wrong format"); | |
| 67 return; | |
| 68 } | |
| 69 var number = 0; | |
| 70 try { | |
| 71 number = int.parse(values[1]); | |
| 72 } catch (e) { | |
| 73 c.completeException("Can't parse version numbers, not an int"); | |
| 74 return; | |
| 75 } | |
| 76 switch (values[0]) { | |
| 77 case "MAJOR": | |
| 78 MAJOR = number; | |
| 79 break; | |
| 80 case "MINOR": | |
| 81 MINOR = number; | |
| 82 break; | |
| 83 case "BUILD": | |
| 84 BUILD = number; | |
| 85 break; | |
| 86 case "PATCH": | |
| 87 PATCH = number; | |
| 88 break; | |
| 89 default: | |
| 90 c.completeException("Wrong format in VERSION file, line does not " | |
| 91 "contain one of {MAJOR, MINOR, BUILD, PATCH}"); | |
| 92 return; | |
| 93 } | |
| 94 }; | |
| 95 input.onClosed = () { | |
| 96 // Only complete if we did not already complete with a failure. | |
| 97 if (!c.future.isComplete) { | |
| 98 getRevision().then((revision) { | |
| 99 REVISION = revision; | |
| 100 USERNAME = getUserName(); | |
| 101 var userNameString = ""; | |
| 102 if (USERNAME != '') userNameString = "_$USERNAME"; | |
| 103 var revisionString = ""; | |
| 104 if (revision != 0) revisionString = "_r$revision"; | |
| 105 c.complete( | |
| 106 "$MAJOR.$MINOR.$BUILD.$PATCH$revisionString$userNameString"); | |
| 107 return; | |
| 108 }); | |
| 109 } | |
| 110 }; | |
| 111 }); | |
| 112 return c.future; | |
| 113 } | |
| 114 | |
| 115 String getExecutableSuffix() { | |
| 116 if (Platform.operatingSystem == 'windows') { | |
| 117 return '.bat'; | |
| 118 } | |
| 119 return ''; | |
| 120 } | |
| 121 | |
| 122 Future<int> getRevision() { | |
| 123 if (repositoryType == RepositoryType.UNKNOWN) { | |
| 124 return new Future.immediate(0); | |
| 125 } | |
| 126 var isSvn = repositoryType == RepositoryType.SVN; | |
| 127 var command = isSvn ? "svn" : "git"; | |
| 128 command = "$command${getExecutableSuffix()}"; | |
| 129 var arguments = isSvn ? ["info"] : ["svn", "info"]; | |
| 130 return Process.run(command, arguments).transform((result) { | |
| 131 if (result.exitCode != 0) { | |
| 132 return 0; | |
| 133 } | |
| 134 // If anything goes wrong parsing the revision we simply return 0. | |
| 135 try { | |
| 136 // Extract the revision. It's located at the 8th line, | |
| 137 // 18 characters in. | |
| 138 String revisionString = result.stdout.split("\n")[8].substring(18); | |
| 139 return int.parse(revisionString); | |
| 140 } catch (e) { | |
| 141 return 0; | |
| 142 } | |
| 143 }); | |
| 144 } | |
| 145 | |
| 146 String getUserName() { | |
| 147 // TODO(ricow): Don't add this on the buildbot. | |
| 148 var key = "USER"; | |
| 149 if (Platform.operatingSystem == 'windows') { | |
| 150 key = "USERNAME"; | |
| 151 } | |
| 152 if (!Platform.environment.containsKey(key)) return ""; | |
| 153 return Platform.environment[key]; | |
| 154 } | |
| 155 | |
| 156 RepositoryType get repositoryType { | |
| 157 if (new Directory(".svn").existsSync()) return RepositoryType.SVN; | |
| 158 if (new Directory(".git").existsSync()) return RepositoryType.GIT; | |
| 159 return RepositoryType.UNKNOWN; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 class RepositoryType { | |
| 164 static final RepositoryType SVN = const RepositoryType("SVN"); | |
| 165 static final RepositoryType GIT = const RepositoryType("GIT"); | |
| 166 static final RepositoryType UNKNOWN = const RepositoryType("UNKNOWN"); | |
| 167 | |
| 168 const RepositoryType(String this.name); | |
| 169 | |
| 170 static RepositoryType guessType() { | |
| 171 if (new Directory(".svn").existsSync()) return RepositoryType.SVN; | |
| 172 if (new Directory(".git").existsSync()) return RepositoryType.GIT; | |
| 173 return RepositoryType.UNKNOWN; | |
| 174 } | |
| 175 | |
| 176 String toString() => name; | |
| 177 | |
| 178 final String name; | |
| 179 } | |
| OLD | NEW |