| 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(String this._versionFileName); |
| 39 |
| 40 /** |
| 41 * Get the version number for this specific build using the version info |
| 42 * from the VERSION file in the root directory and the revision info |
| 43 * from the source control system of the current checkout. |
| 44 */ |
| 45 Future<String> getVersion() { |
| 46 File f = new File(_versionFileName); |
| 47 Completer c = new Completer(); |
| 48 f.exists().then((existed) { |
| 49 if (!existed) { |
| 50 c.completeException("No VERSION file"); |
| 51 return; |
| 52 } |
| 53 StringInputStream input = new StringInputStream(f.openInputStream()); |
| 54 input.onLine = () { |
| 55 var line = input.readLine(); |
| 56 if (line == null) { |
| 57 c.completeException( |
| 58 "VERSION input file seems to be in the wrong format"); |
| 59 return; |
| 60 } |
| 61 var values = line.split(" "); |
| 62 if (values.length != 2) { |
| 63 c.completeException( |
| 64 "VERSION input file seems to be in the wrong format"); |
| 65 return; |
| 66 } |
| 67 var number = 0; |
| 68 try { |
| 69 number = int.parse(values[1]); |
| 70 } catch (e) { |
| 71 c.completeException("Can't parse version numbers, not an int"); |
| 72 return; |
| 73 } |
| 74 switch (values[0]) { |
| 75 case "MAJOR": |
| 76 MAJOR = number; |
| 77 break; |
| 78 case "MINOR": |
| 79 MINOR = number; |
| 80 break; |
| 81 case "BUILD": |
| 82 BUILD = number; |
| 83 break; |
| 84 case "PATCH": |
| 85 PATCH = number; |
| 86 break; |
| 87 default: |
| 88 c.completeException("Wrong format in VERSION file, line does not " |
| 89 "contain one of {MAJOR, MINOR, BUILD, PATCH}"); |
| 90 return; |
| 91 } |
| 92 }; |
| 93 input.onClosed = () { |
| 94 // Only complete if we did not already complete with a failure. |
| 95 if (!c.future.isComplete) { |
| 96 getRevision().then((revision) { |
| 97 REVISION = revision; |
| 98 getUserName().then((username) { |
| 99 USERNAME = username; |
| 100 if (username != '') username = "_$username"; |
| 101 var revisionString = ""; |
| 102 if (revision != 0) revisionString = "_r$revision"; |
| 103 c.complete("$MAJOR.$MINOR.$BUILD.$PATCH$revisionString$username"); |
| 104 return; |
| 105 }); |
| 106 }); |
| 107 } |
| 108 }; |
| 109 }); |
| 110 return c.future; |
| 111 } |
| 112 |
| 113 Future<int> getRevision() { |
| 114 if (repositoryType == RepositoryType.UNKNOWN) { |
| 115 return new Future.immediate(0); |
| 116 } |
| 117 var isSvn = repositoryType == RepositoryType.SVN; |
| 118 var command = isSvn ? "svn" : "git"; |
| 119 var arguments = isSvn ? ["info"] : ["svn", "info"]; |
| 120 return Process.run(command, arguments).transform((result) { |
| 121 if (result.exitCode != 0) { |
| 122 return 0; |
| 123 } |
| 124 // If anything goes wrong parsing the revision we simply return 0. |
| 125 try { |
| 126 // Extract the revision. It's located at the 8th line, |
| 127 // 18 characters in. |
| 128 String revisionString = result.stdout.split("\n")[8].substring(18); |
| 129 return int.parse(revisionString); |
| 130 } catch (e) { |
| 131 return 0; |
| 132 } |
| 133 }); |
| 134 } |
| 135 |
| 136 Future<String> getUserName() { |
| 137 // TODO(ricow): Don't add this on the buildbot. |
| 138 // If we can't get the username simple return "" (e.g. on windows). |
| 139 return Process.run("whoami", []).transform((result) { |
| 140 if (result.exitCode != 0) { |
| 141 return ""; |
| 142 } |
| 143 return result.stdout; |
| 144 }).transformException((e) { |
| 145 return ""; |
| 146 }); |
| 147 } |
| 148 |
| 149 RepositoryType get repositoryType { |
| 150 if (new Directory(".svn").existsSync()) return RepositoryType.SVN; |
| 151 if (new Directory(".git").existsSync()) return RepositoryType.GIT; |
| 152 return RepositoryType.UNKNOWN; |
| 153 } |
| 154 } |
| 155 |
| 156 class RepositoryType { |
| 157 static final RepositoryType SVN = const RepositoryType("SVN"); |
| 158 static final RepositoryType GIT = const RepositoryType("GIT"); |
| 159 static final RepositoryType UNKNOWN = const RepositoryType("UNKNOWN"); |
| 160 |
| 161 const RepositoryType(String this.name); |
| 162 |
| 163 static RepositoryType guessType() { |
| 164 if (new Directory(".svn").existsSync()) return RepositoryType.SVN; |
| 165 if (new Directory(".git").existsSync()) return RepositoryType.GIT; |
| 166 return RepositoryType.UNKNOWN; |
| 167 } |
| 168 |
| 169 String toString() => name; |
| 170 |
| 171 final String name; |
| 172 } |
| OLD | NEW |