diff --git a/src/brackets.js b/src/brackets.js index a4e5ce646..39e30b288 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -60,6 +60,7 @@ define(function (require, exports, module) { KeyMap = require("command/KeyMap"), Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), + BuildInfoUtils = require("utils/BuildInfoUtils"), CodeHintManager = require("editor/CodeHintManager"), JSLintUtils = require("language/JSLintUtils"), PerfUtils = require("utils/PerfUtils"), @@ -160,7 +161,20 @@ define(function (require, exports, module) { DocumentCommandHandlers.init($("#main-toolbar")); + // About dialog CommandManager.register(Commands.HELP_ABOUT, function () { + // If we've successfully determined a "build number" via .git metadata, add it to dialog + var bracketsSHA = BuildInfoUtils.getBracketsSHA(), + bracketsAppSHA = BuildInfoUtils.getBracketsAppSHA(), + versionLabel = ""; + if (bracketsSHA) { + versionLabel += " (" + bracketsSHA.substr(0, 7) + ")"; + } + if (bracketsAppSHA) { + versionLabel += " (shell " + bracketsAppSHA.substr(0, 7) + ")"; + } + $("#about-build-number").text(versionLabel); + Dialogs.showModalDialog(Dialogs.DIALOG_ID_ABOUT); }); } @@ -263,6 +277,10 @@ define(function (require, exports, module) { initKeyBindings(); Menus.init(); // key bindings should be initialized first initWindowListeners(); + + // Read "build number" SHAs off disk at the time the matching Brackets JS code is being loaded, instead + // of later, when they may have been updated to a different version + BuildInfoUtils.init(); // Load extensions diff --git a/src/index.html b/src/index.html index ba16dfe55..3f2b6bc3d 100644 --- a/src/index.html +++ b/src/index.html @@ -287,7 +287,7 @@

Brackets

-

sprint 8 experimental build

+

sprint 8 experimental build

Copyright 2012 Adobe Systems Incorporated and its licensors. All rights reserved.

Notices, terms and conditions pertaining to third party software are located at http://www.adobe.com/go/thirdparty/ and incorporated by reference herein.

Documentation and source at https://github.com/adobe/brackets/

diff --git a/src/styles/brackets_patterns_override.less b/src/styles/brackets_patterns_override.less index 986c1ce5d..90cd308e3 100644 --- a/src/styles/brackets_patterns_override.less +++ b/src/styles/brackets_patterns_override.less @@ -316,6 +316,10 @@ .about-text { // Icon is 120px, so we need at least that much left padding/margin to avoid overlap margin: 0 10px 0 123px; + + #about-build-number { + color: #b0b0b0; + } } h2 { diff --git a/src/utils/BuildInfoUtils.js b/src/utils/BuildInfoUtils.js new file mode 100644 index 000000000..987b59eed --- /dev/null +++ b/src/utils/BuildInfoUtils.js @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + + +/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ +/*global define, $ */ + +/** + * Utilities for determining the current "build number" / version + */ +define(function (require, exports, module) { + 'use strict'; + + var NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem, + FileUtils = require("file/FileUtils"); + + + var _bracketsSHA = null; + var _bracketsAppSHA = null; + + /** + * @return {?string} the Git SHA of the brackets submodule at the time when Brackets launched, + * or null if no Git metadata was found on disk. + */ + function getBracketsSHA() { + return _bracketsSHA; + } + + /** + * @return {?string} the Git SHA of the brackets-app module at the time when Brackets launched, + * or null if no Git metadata was found on disk. + */ + function getBracketsAppSHA() { + return _bracketsAppSHA; + } + + + /** + * Loads a SHA from Git metadata file. If the file contains a symbolic ref name, follows the ref + * and loads the SHA from that file in turn. + */ + function _loadSHA(path, callback) { + var fileEntry = new NativeFileSystem.FileEntry(path); + var reader = new NativeFileSystem.FileReader(); + + var result = new $.Deferred(); + + // HEAD contains a SHA in detached-head mode; otherwise it contains a relative path + // to a file in /refs which in turn contains the SHA + fileEntry.file(function (file) { + reader.onload = function (event) { + var text = event.target.result; + + if (text.indexOf("ref: ") === 0) { + var basePath = path.substr(0, path.lastIndexOf("/")); + var refRelPath = text.substr(5).trim(); + _loadSHA(basePath + "/" + refRelPath, callback) + .pipe(result.resolve, result.reject); + } else { + result.resolve(text); + } + }; + reader.onerror = function (event) { + result.reject(); + }; + + reader.readAsText(file, "utf8"); + }); + + return result.promise(); + } + + function init() { + // Look for Git metadata on disk to load the SHAs for 'brackets' and 'brackets-app'. Done on + // startup instead of on demand because the version that's currently running is what was + // loaded at startup (the src on disk may be updated to a different version later). + // Git metadata may be missing (e.g. in the per-sprint ZIP builds) - silently ignore if so. + var bracketsSrc = FileUtils.getNativeBracketsDirectoryPath(); + var bracketsGitRoot = bracketsSrc + "/../../.git/"; + var bracketsSubmoduleRoot_inParent = bracketsGitRoot + "modules/brackets/"; + var bracketsSubmoduleRoot_inSubmodule = bracketsSrc + "/../.git/"; + + _loadSHA(bracketsGitRoot + "HEAD") + .done(function (text) { + _bracketsAppSHA = text; + }); + + // brackets submodule metadata may be in brackets/.git OR a subfolder of brackets-app/.git, + // so try both locations + _loadSHA(bracketsSubmoduleRoot_inSubmodule + "HEAD") + .done(function (text) { + _bracketsSHA = text; + }) + .fail(function () { + _loadSHA(bracketsSubmoduleRoot_inParent + "HEAD") + .done(function (text) { + _bracketsSHA = text; + }); + }); + } + + + // Define public API + exports.init = init; + exports.getBracketsSHA = getBracketsSHA; + exports.getBracketsAppSHA = getBracketsAppSHA; +}); \ No newline at end of file