Change SDK/DartEditor versioning scheme to semantic versions.

This means that all components of the SDK (i.e. DartVM, dart2js, dartanalyzer,
pub) will have the same semantic version string when invoking them with
'--version'. The version string is also present in "dart-sdk/version".

The editor will have an eclipse compatible version which consists of
major.minor.patch.qualifier.

The SDK versions look like this on our three channels:
  - bleeding-edge: 1.1.0-edge.30857
  - dev:           1.1.0-dev.2.42
  - stable:        1.1.0
The SDK versions comply with the semantic versioning standard, see:
http://semver.org/.

The DartEditor versions look like this on our three channels:
  - bleeding-edge: 1.1.0.edge_030857
  - dev:           1.1.0.dev_02_42
  - stable:        1.1.0.release
The DartEditor versions comply with semantic eclipse versioning scheme.
(The leading zeros are necessary due to lexicographic ordering.)

From both version schemes, it becomes clear on which channel a user is on.

R=danrubel@google.com, kasperl@google.com, rnystrom@google.com

Review URL: https://codereview.chromium.org//104403005

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@30905 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
kustermann@google.com 2013-12-05 18:35:05 +00:00
parent 2e3b0fd8bf
commit 90c9463cc7
7 changed files with 104 additions and 96 deletions

View file

@ -94,15 +94,6 @@ class LishCommand extends PubCommand {
}
Future onRun() {
// Sanity check. Don't push to the production server when running tests or
// developing on pub.
if (sdk.isBleedingEdge &&
server.toString() == HostedSource.defaultUrl &&
!dryRun) {
log.error('Cannot publish to $server from bleeding edge pub!');
return null;
}
if (force && dryRun) {
log.error('Cannot use both --force and --dry-run.');
this.printUsage();

View file

@ -12,11 +12,6 @@ import 'package:path/path.dart' as path;
import 'io.dart';
import 'version.dart';
/// Matches an Eclipse-style SDK version number. This is four dotted numbers
/// (major, minor, patch, build) with an optional suffix attached to the build
/// number.
final _versionPattern = new RegExp(r'^(\d+)\.(\d+)\.(\d+)\.(\d+.*)$');
/// Gets the path to the root directory of the SDK.
String get rootDirectory {
// Assume the Dart executable is always coming from the SDK.
@ -29,30 +24,6 @@ String get rootDirectory {
/// different SDK versions.
Version version = _getVersion();
/// Is `true` if the current SDK is an unreleased bleeding edge version.
bool get isBleedingEdge {
// The live build is locked to the magical old number "0.1.2+<stuff>".
return version.major == 0 && version.minor == 1 && version.patch == 2;
}
/// Parse an Eclipse-style version number using the SDK's versioning convention.
Version parseVersion(String version) {
// Given a version file like: 0.1.2.0_r17495
// We create a semver like: 0.1.2+0.r17495
var match = _versionPattern.firstMatch(version);
if (match == null) {
throw new FormatException("The Dart SDK's 'version' file was not in a "
"format pub could recognize. Found: $version");
}
// Semantic versions cannot use "_".
var build = match[4].replaceAll('_', '.');
return new Version(
int.parse(match[1]), int.parse(match[2]), int.parse(match[3]),
build: build);
}
/// Determine the SDK's version number.
Version _getVersion() {
// Some of the pub integration tests require an SDK version number, but the
@ -64,5 +35,5 @@ Version _getVersion() {
// Read the "version" file.
var revisionPath = path.join(rootDirectory, "version");
var version = readTextFile(revisionPath).trim();
return parseVersion(version);
return new Version.parse(version);
}

View file

@ -630,12 +630,6 @@ class Traverser {
/// Ensures that if [pubspec] has an SDK constraint, then it is compatible
/// with the current SDK. Throws a [SolveFailure] if not.
void _validateSdkConstraint(Pubspec pubspec) {
// If the user is running a continouous build of the SDK, just disable SDK
// constraint checking entirely. The actual version number you get is
// impossibly old and not correct. We'll just assume users on continuous
// know what they're doing.
if (sdk.isBleedingEdge) return;
if (pubspec.environment.sdkVersion.allows(sdk.version)) return;
throw new BadSdkVersionException(pubspec.name,

View file

@ -1,5 +1,31 @@
# This file is used by tools/utils.py to generate version strings.
# The numbers are changed as follows:
#
# * New release cycle has begun (i.e. stable release was just made):
# - increase MINOR by 1
# - set "PATCH 0"
# - set "PRERELEASE 0"
# - set "PRERELEASE_PATCH 0"
#
# * Doing a push-to-trunk from bleeding_edge:
# (The first push-to-trunk in the release cycle will set PRERELEASE to 1)
# - increase PRERELEASE by 1
# - set "PRERELEASE_PATCH 0"
#
# * Doing a cherry-pick to trunk:
# - increase PRERELEASE_PATCH by 1
#
# * Making a stable release (i.e. new stable branch):
# - set "PRERELEASE 0"
# - set "PRERELEASE_PATCH 0"
# The new stable release version will sort higher than the prereleases.
#
# * Making cherry-picks to stable channel
# - increase PATCH by 1
#
CHANNEL be
MAJOR 0
MAJOR 1
MINOR 1
BUILD 2
PATCH 0
PRERELEASE 0
PRERELEASE_PATCH 0

View file

@ -187,14 +187,15 @@ def Main():
join('third_party', 'bzip2', 'bzip2.jar'),
'-Dbuild.out=' + OUTPUT,
'-Dbuild.configs=' + buildConfig,
'-Dbuild.revision=' + utils.GetSVNRevision(),
'-Ddart.version.full=' + utils.GetVersion(),
'-Dbuild.root=' + GetEclipseBuildRoot(),
'-Dbuild.downloads=' + GetDownloadCache(),
'-Dbuild.source=' + os.path.abspath('editor'),
'-Dbuild.dart.sdk=' + GetSdkPath(),
'-Dbuild.no.properties=true',
'-Dbuild.channel=' + utils.GetChannel(),
'-Dbuild.revision=' + utils.GetSVNRevision(),
'-Dbuild.version.qualifier=' + utils.GetEclipseVersionQualifier(),
'-Ddart.version.full=' + utils.GetVersion(),
'-buildfile',
buildScript]
print build_cmd

View file

@ -83,24 +83,29 @@ def GetInputDirectory(options, temp_dir):
# In addition to that, the limits on the size are:
# Major: 256
# Minor: 256
# Build: 65536
# Patch: 65536
# To circumvent this we create the version like this:
# Major.Minor.X
# where X is Build<<9 + Patch
# Example version 1.2.4.14 will go to 1.2.2062
# from "major.minor.patch-prerelease.prerelease_patch"
# where X is "patch<<10 + prerelease<<5 + prerelease_patch"
# Example version 1.2.4-dev.2.3 will go to 1.2.4163
def GetMicrosoftProductVersion(version):
version_parts = version.split('.')
if len(version_parts) is not 4:
if len(version_parts) is not 5:
raise Exception(
"Version string (%s) does not follow specification" % version)
(major, minor, build, patch) = map(int, version_parts)
(major, minor, patch, prerelease, prerelease_patch) = map(int, version_parts)
if build > 127 or patch > 511:
raise Exception('Build/Patch can not be above 127/511')
if major > 255 or minor > 255:
raise Exception('Major/Minor can not be above 256')
if patch > 63:
raise Exception('Patch can not be above 63')
if prerelease > 31:
raise Exception('Prerelease can not be above 31')
if prerelease_patch > 31:
raise Exception('PrereleasePatch can not be above 31')
combined = (build << 9) + patch
combined = (patch << 10) + (prerelease << 5) + prerelease_patch
return '%s.%s.%s' % (major, minor, combined)
# Append using the current indentation level

View file

@ -14,6 +14,15 @@ import subprocess
import sys
import tempfile
class Version(object):
def __init__(self, channel, major, minor, patch, prerelease,
prerelease_patch):
self.channel = channel
self.major = major
self.minor = minor
self.patch = patch
self.prerelease = prerelease
self.prerelease_patch = prerelease_patch
# Try to guess the host operating system.
def GuessOS():
@ -231,40 +240,47 @@ def GetBuildRoot(host_os, mode=None, arch=None, target_os=None):
def GetBaseDir():
return BASE_DIR
# Return the base part of the version, Major.Minor.Build.Patch,
# without the _revision addition
def GetShortVersion():
(channel, major, minor, build, patch) = ReadVersionFile()
# TODO(kustermann/ricow): Add the channel to the version string.
return '%s.%s.%s.%s' % (major, minor, build, patch)
version = ReadVersionFile()
return ('%s.%s.%s.%s.%s' % (
version.major, version.minor, version.patch, version.prerelease,
version.prerelease_patch))
def GetVersion():
version_tuple = ReadVersionFile()
if not version_tuple:
def GetSemanticSDKVersion():
version = ReadVersionFile()
if not version:
return None
(channel, major, minor, build, patch) = version_tuple
revision = GetSVNRevision()
user = GetUserName()
# We don't add username to release builds (or any builds on the bots)
if user == 'chrome-bot':
user = ''
if version.channel == 'be':
postfix = '-edge.%s' % GetSVNRevision()
elif version.channel == 'dev':
postfix = '-dev.%s.%s' % (version.prerelease, version.prerelease_patch)
else:
assert version.channel == 'stable'
postfix = ''
user_string = ''
revision_string = ''
if user:
user_string = '_%s' % user
if revision:
revision_string = '_r%s' % revision
return '%s.%s.%s%s' % (version.major, version.minor, version.patch, postfix)
# TODO(kustermann/ricow): Add the channel to the version string.
return ("%s.%s.%s.%s%s%s" %
(major, minor, build, patch, revision_string, user_string))
def GetEclipseVersionQualifier():
def pad(number, num_digits):
number_str = str(number)
return '0' * max(0, num_digits - len(number_str)) + number_str
version = ReadVersionFile()
if version.channel == 'be':
return 'edge_%s' % pad(GetSVNRevision(), 6)
elif version.channel == 'dev':
return 'dev_%s_%s' % (pad(version.prerelease, 2),
pad(version.prerelease_patch, 2))
else:
return 'release'
def GetVersion():
return GetSemanticSDKVersion()
def GetChannel():
(channel, _, _, _, _) = ReadVersionFile()
return channel
version = ReadVersionFile()
return version.channel
def GetUserName():
key = 'USER'
@ -273,6 +289,12 @@ def GetUserName():
return os.environ.get(key, '')
def ReadVersionFile():
def match_against(pattern, content):
match = re.search(pattern, content, flags=re.MULTILINE)
if match:
return match.group(1)
return None
version_file = os.path.join(DART_DIR, 'tools', 'VERSION')
try:
fd = open(version_file)
@ -281,19 +303,17 @@ def ReadVersionFile():
except:
print "Warning: Couldn't read VERSION file (%s)" % version_file
return None
channel_match = re.search(
'^CHANNEL ([A-Za-z0-9]+)$', content, flags=re.MULTILINE)
major_match = re.search('^MAJOR (\d+)$', content, flags=re.MULTILINE)
minor_match = re.search('^MINOR (\d+)$', content, flags=re.MULTILINE)
build_match = re.search('^BUILD (\d+)$', content, flags=re.MULTILINE)
patch_match = re.search('^PATCH (\d+)$', content, flags=re.MULTILINE)
if (channel_match and
major_match and
minor_match and
build_match and
patch_match):
return (channel_match.group(1), major_match.group(1), minor_match.group(1),
build_match.group(1), patch_match.group(1))
channel = match_against('^CHANNEL ([A-Za-z0-9]+)$', content)
major = match_against('^MAJOR (\d+)$', content)
minor = match_against('^MINOR (\d+)$', content)
patch = match_against('^PATCH (\d+)$', content)
prerelease = match_against('^PRERELEASE (\d+)$', content)
prerelease_patch = match_against('^PRERELEASE_PATCH (\d+)$', content)
if channel and major and minor and prerelease and prerelease_patch:
return Version(
channel, major, minor, patch, prerelease, prerelease_patch)
else:
print "Warning: VERSION file (%s) has wrong format" % version_file
return None