diff --git a/.gitignore b/.gitignore index e21e7a09f..2b3cb8b31 100644 --- a/.gitignore +++ b/.gitignore @@ -39,8 +39,9 @@ libcef_dll tools /installer/mac/staging/ -/installer/linux/brackets.deb -/installer/linux/debian/usr/lib/ +/installer/linux/*.deb +/installer/linux/debian/package-root/opt/* +/installer/linux/debian/package-root/DEBIAN/control /installer/win/staging/ *.wixpdb *.wixobj diff --git a/Gruntfile.js b/Gruntfile.js index 63d886899..210f1b4cb 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,26 +27,39 @@ module.exports = function (grunt) { var common = require("./tasks/common")(grunt), resolve = common.resolve, + platform = common.platform(), staging; - - if (common.platform() === "mac") { + + if (platform === "mac") { staging = "installer/mac/staging/<%= build.name %>.app/Contents"; - } else if (common.platform() === "win") { + } else if (platform === "win") { staging = "installer/win/staging"; } else { - staging = "installer/linux/debian/usr/lib/brackets"; + staging = "installer/linux/debian/package-root/opt/brackets"; } grunt.initConfig({ "pkg": grunt.file.readJSON("package.json"), + "config-json": staging + "/www/config.json", "curl-dir": { - /* linux not supported yet */ - /* - linux: { - dest : "<%= cef_zip %>", - src : "https://docs.google.com/file/d/0B7as0diokeHxeTNqZFIyNWZKSWM/edit?usp=sharing" + /* linux */ + /* FIXME (jasonsanjose) no 32-bit 3.1547.1354, revert to cef.version variable for the next CEF upgrade */ + "cef-linux32": { + "dest" : "downloads/", + "src" : "http://dev.brackets.io/cef/cef_binary_3.1547.1357_linux32_release.zip" + }, + "cef-linux64": { + "dest" : "downloads/", + "src" : "http://dev.brackets.io/cef/cef_binary_<%= cef.version %>_linux64_release.zip" + }, + "node-linux32": { + "dest" : "downloads/", + "src" : "http://nodejs.org/dist/v<%= node.version %>/node-v<%= node.version %>-linux-x86.tar.gz" + }, + "node-linux64": { + "dest" : "downloads/", + "src" : "http://nodejs.org/dist/v<%= node.version %>/node-v<%= node.version %>-linux-x64.tar.gz" }, - */ /* mac */ "cef-mac": { "dest" : "downloads/", @@ -71,7 +84,7 @@ module.exports = function (grunt) { "downloads" : ["downloads"], "installer-mac" : ["installer/mac/*.dmg"], "installer-win" : ["installer/win/*.msi"], - "installer-linux" : ["installer/linux/brackets.deb"], + "installer-linux" : ["installer/linux/debian/*.deb"], "staging-mac" : ["installer/mac/staging"], "staging-win" : ["installer/win/staging"], "staging-linux" : ["<%= build.staging %>"], @@ -114,7 +127,7 @@ module.exports = function (grunt) { "files": [ { "expand" : true, - "cwd" : "out/Release", + "cwd" : "out/Release/", "src" : [ "lib/**", "locales/**", @@ -124,6 +137,14 @@ module.exports = function (grunt) { "devtools_resources.pak" ], "dest" : "<%= build.staging %>" + }, + { + "expand" : true, + "cwd" : "installer/linux/debian/", + "src" : [ + "brackets.desktop" + ], + "dest" : "<%= build.staging %>" } ] }, diff --git a/installer/linux/build_installer.sh b/installer/linux/build_installer.sh index 0e6dc626c..5b7159061 100755 --- a/installer/linux/build_installer.sh +++ b/installer/linux/build_installer.sh @@ -2,13 +2,16 @@ # grunt-contrib-copy doesn't preserve permissions # https://github.com/gruntjs/grunt/issues/615 -chmod 775 installer/linux/debian/usr/lib/brackets/Brackets +chmod 775 debian/package-root/opt/brackets/Brackets +chmod 755 debian/package-root/DEBIAN/prerm +chmod 755 debian/package-root/DEBIAN/postrm +chmod 755 debian/package-root/DEBIAN/postinst # set permissions on subdirectories -find installer/linux/debian -type d -exec chmod 755 {} \; +find debian -type d -exec chmod 755 {} \; # delete old package -rm -f installer/linux/brackets.deb +rm -f brackets.deb -fakeroot dpkg-deb --build installer/linux/debian -mv installer/linux/debian.deb installer/linux/brackets.deb +fakeroot dpkg-deb --build debian/package-root +mv debian/package-root.deb brackets.deb diff --git a/installer/linux/debian/usr/share/applications/brackets.desktop b/installer/linux/debian/brackets.desktop similarity index 58% rename from installer/linux/debian/usr/share/applications/brackets.desktop rename to installer/linux/debian/brackets.desktop index 9a8d8310a..69e2c3104 100644 --- a/installer/linux/debian/usr/share/applications/brackets.desktop +++ b/installer/linux/debian/brackets.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=Brackets Type=Application -Categories=Application -Exec=/usr/lib/brackets/Brackets %U +Categories=Development +Exec=/opt/brackets/Brackets %U Icon=brackets MimeType=text/html; diff --git a/installer/linux/debian/DEBIAN/control b/installer/linux/debian/control similarity index 73% rename from installer/linux/debian/DEBIAN/control rename to installer/linux/debian/control index 848d51565..78923dd35 100644 --- a/installer/linux/debian/DEBIAN/control +++ b/installer/linux/debian/control @@ -1,10 +1,10 @@ Package: brackets -Version: 0.27.0 -Section: base +Version: <%= version %> +Section: devel Priority: optional -Architecture: i386 -Installed-Size: 128819 -Depends: bash (>= 2.05a-11), libnss3-1d (>= 3.14.3), libnspr4-0d (>= 3.14.3) +Architecture: <%= arch %> +Installed-Size: <%= size %> +Depends: bash (>= 2.05a-11), libnss3-1d (>= 3.14.3), libnspr4-0d (>= 3.14.3), libudev0 (>= 147) | libudev1 (>= 198) Maintainer: Jason San Jose Description: Brackets Brackets is an open-source editor for web design and development diff --git a/installer/linux/debian/package-root/DEBIAN/postinst b/installer/linux/debian/package-root/DEBIAN/postinst new file mode 100755 index 000000000..db878c11c --- /dev/null +++ b/installer/linux/debian/package-root/DEBIAN/postinst @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Add icons to the system icons +XDG_ICON_RESOURCE="`which xdg-icon-resource 2> /dev/null`" +if [ ! -x "$XDG_ICON_RESOURCE" ]; then + echo "Error: Could not find xdg-icon-resource" >&2 + exit 1 +fi +for icon in "/opt/brackets/appshell"*.png; do + size="${icon##*/appshell}" + "$XDG_ICON_RESOURCE" install --novendor --size "${size%.png}" "$icon" "brackets" +done + +# Add an entry to the system menu +XDG_DESKTOP_MENU="`which xdg-desktop-menu 2> /dev/null`" +UPDATE_MENUS="`which update-menus 2> /dev/null`" +if [ ! -x "$XDG_DESKTOP_MENU" ]; then + echo "Error: Could not find xdg-desktop-menu" >&2 + exit 1 +fi +"$XDG_DESKTOP_MENU" install /opt/brackets/brackets.desktop --novendor + +if [ -x "$UPDATE_MENUS" ]; then + update-menus +fi + +DEFAULT_ARCH="`uname -m`" + +get_lib_dir() { + if [ "$DEFAULT_ARCH" = "i686" ]; then + LIBDIR=lib/i386-linux-gnu + elif [ "$DEFAULT_ARCH" = "x86_64" ]; then + LIBDIR=lib/x86_64-linux-gnu + else + echo Unknown CPU Architecture: "$DEFAULT_ARCH" + exit 1 + fi +} + +# Fedora 18 now has libudev.so.1. http://crbug.com/145160 +# Same for Ubuntu 13.04. http://crbug.com/226002 +LIBUDEV_0=libudev.so.0 +LIBUDEV_1=libudev.so.1 + +add_udev_symlinks() { + get_lib_dir + if [ -f "/$LIBDIR/$LIBUDEV_0" -o -f "/usr/$LIBDIR/$LIBUDEV_0" -o -f "/lib/$LIBUDEV_0" ]; then + return 0 + fi + + if [ -f "/$LIBDIR/$LIBUDEV_1" ]; then + ln -snf "/$LIBDIR/$LIBUDEV_1" "/opt/brackets/$LIBUDEV_0" + elif [ -f "/usr/$LIBDIR/$LIBUDEV_1" ]; + then + ln -snf "/usr/$LIBDIR/$LIBUDEV_1" "/opt/brackets/$LIBUDEV_0" + else + echo "$LIBUDEV_1" not found in "$LIBDIR" or "/usr/$LIBDIR". + exit 1 + fi +} + +remove_udev_symlinks() { + rm -rf "/opt/brackets/$LIBUDEV_0" +} + +remove_udev_symlinks +add_udev_symlinks diff --git a/installer/linux/debian/package-root/DEBIAN/postrm b/installer/linux/debian/package-root/DEBIAN/postrm new file mode 100755 index 000000000..213407342 --- /dev/null +++ b/installer/linux/debian/package-root/DEBIAN/postrm @@ -0,0 +1,2 @@ +#!/bin/sh +rm -rf "/opt/brackets/libudev.so.0" diff --git a/installer/linux/debian/package-root/DEBIAN/prerm b/installer/linux/debian/package-root/DEBIAN/prerm new file mode 100755 index 000000000..a35252601 --- /dev/null +++ b/installer/linux/debian/package-root/DEBIAN/prerm @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +action="$1" +if [ "$2" = "in-favour" ]; then + # Treat conflict remove as an upgrade. + action="upgrade" +fi +# Don't clean-up just for an upgrade.` +if [ "$action" = "upgrade" ] ; then + exit 0 +fi + +# Remove icons from the system icons +XDG_ICON_RESOURCE="`which xdg-icon-resource 2> /dev/null`" +if [ ! -x "$XDG_ICON_RESOURCE" ]; then + echo "Error: Could not find xdg-icon-resource" >&2 + exit 1 +fi +for icon in "/opt/brackets/appshell"*.png; do + size="${icon##*/appshell}" + "$XDG_ICON_RESOURCE" uninstall --size "${size%.png}" "brackets" +done + +# Remove the entry from the system menu +XDG_DESKTOP_MENU="`which xdg-desktop-menu 2> /dev/null`" +UPDATE_MENUS="`which update-menus 2> /dev/null`" +if [ ! -x "$XDG_DESKTOP_MENU" ]; then + echo "Error: Could not find xdg-desktop-menu" >&2 + exit 1 +fi +"$XDG_DESKTOP_MENU" uninstall /opt/brackets/brackets.desktop + +if [ -x "$UPDATE_MENUS" ]; then + update-menus +fi diff --git a/installer/linux/debian/package-root/usr/bin/brackets b/installer/linux/debian/package-root/usr/bin/brackets new file mode 100755 index 000000000..c1dad1aa9 --- /dev/null +++ b/installer/linux/debian/package-root/usr/bin/brackets @@ -0,0 +1,2 @@ +#!/bin/bash +/opt/brackets/Brackets diff --git a/installer/linux/debian/package-root/usr/share/doc/brackets/copyright b/installer/linux/debian/package-root/usr/share/doc/brackets/copyright new file mode 100644 index 000000000..eef9244ba --- /dev/null +++ b/installer/linux/debian/package-root/usr/share/doc/brackets/copyright @@ -0,0 +1,19 @@ +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. \ No newline at end of file diff --git a/installer/linux/debian/usr/share/icons/hicolor/scalable/apps/brackets.svg b/installer/linux/debian/package-root/usr/share/icons/hicolor/scalable/apps/brackets.svg similarity index 100% rename from installer/linux/debian/usr/share/icons/hicolor/scalable/apps/brackets.svg rename to installer/linux/debian/package-root/usr/share/icons/hicolor/scalable/apps/brackets.svg diff --git a/installer/linux/debian/package-root/usr/share/menu/brackets.menu b/installer/linux/debian/package-root/usr/share/menu/brackets.menu new file mode 100644 index 000000000..44c3313b1 --- /dev/null +++ b/installer/linux/debian/package-root/usr/share/menu/brackets.menu @@ -0,0 +1,6 @@ +?package(brackets):needs="x11" \ + section="Development" \ + hints="Code Editor" \ + title="Brackets" \ + icon="/opt/brackets/appshell32.png" \ + command="/usr/bin/brackets" diff --git a/installer/linux/debian/usr/bin/brackets b/installer/linux/debian/usr/bin/brackets deleted file mode 100755 index efdd3322d..000000000 --- a/installer/linux/debian/usr/bin/brackets +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -/usr/lib/brackets/Brackets \ No newline at end of file diff --git a/package.json b/package.json index cea75bb50..d93dfd8a6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,10 @@ "guid": "0.0.10", "grunt-curl": "0.5.0", "grunt-shell": "0.2.1", - "q": "0.9.2" + "q": "0.9.2", + "semver": "2.0.11" + }, + "scripts": { + "postinstall": "grunt" } -} \ No newline at end of file +} diff --git a/scripts/setup_linux_build.sh b/scripts/setup_linux_build.sh deleted file mode 100755 index 4fcad9c39..000000000 --- a/scripts/setup_linux_build.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -MACHINE_TYPE=`uname -m` - -# SYSTEM DEPENDENCIES -# install development dependencies -sudo apt-get install --assume-yes wget p7zip-full libnss3-1d libnspr4-0d gyp gtk+-2.0 - -# BUILD DEPENDENCIES - -mkdir deps -mkdir downloads -pushd downloads - - -# download Adobe CEF build -ZIPNAME="cef_binary_3.1453.1255_linux32" - -if [ ! -f cef.zip ]; then - wget -O cef.7z "https://drive.google.com/uc?export=download&id=0B7as0diokeHxMVpTOTM5NUJwemM" -fi - -# extract CEF -rm -rf ../deps/cef -7za x cef.7z -mv $ZIPNAME ../deps/cef - -# if 64bit platform, pull down 64bit CEF client and use 64bit CEF library. -# As www.magpcss.net/cef-downalds requires CAPTCHA, this will need to be done manually -# -#if [ ${MACHINE_TYPE} == 'x86_64' ]; then -# wget -O cef_binary_3.1453.1255_linux64_client.7z "http://www.magpcss.net/cef-downloads/index.php?file=cef_binary_3.1453.1255_linux64_client.7z" -# -#fi - -# download node binary - -if [ ${MACHINE_TYPE} == 'x86_64' ]; then - NODE_FILE='node-v0.8.20-linux-x64' -else - NODE_FILE='node-v0.8.20-linux-x86' -fi -wget "http://nodejs.org/dist/v0.8.20/$NODE_FILE.tar.gz" -tar xvzf $NODE_FILE.tar.gz -mv $NODE_FILE ../deps/node - -popd - - -# make symlinks to CEF -# Remove existing links -rm -f Debug include libcef_dll Release Resources tools - -# Make new links -# ln -s deps/cef/Debug/ Debug -ln -s deps/cef/include/ include -ln -s deps/cef/libcef_dll/ libcef_dll -ln -s deps/cef/Release/ Release -ln -s deps/cef/Resources/ Resources -# ln -s deps/cef/tools/ tools - -# CREATE MAKEFILE AND BUILD -# copy appshell.gyp -cp appshell.gyp.txt appshell.gyp - -gyp --depth . - - -# NB - After this script has completed successfully, -# -# - if 64bit, replace deps/cef/libcef.so with the 64bit libcef.so in the linux 64bit client.7z -# - in the brackets-shell directory, run 'make' -# - there should be a binary named 'Brackets' in out/Release. In the same directory, add -# symlinks to allow the appshell to find the cloned brackets directory -# -# ln -s /path/to/brackets dev -# ln -s /path/to/brackets/samples . diff --git a/tasks/build.js b/tasks/build.js index da3d385dc..3d0c48248 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -26,8 +26,10 @@ module.exports = function (grunt) { "use strict"; - var common = require("./common")(grunt), + var fs = require("fs"), + common = require("./common")(grunt), q = require("q"), + semver = require("semver"), spawn = common.spawn, resolve = common.resolve, platform = common.platform(), @@ -78,6 +80,18 @@ module.exports = function (grunt) { }); }); + // task: build-linux + grunt.registerTask("build-linux", "Build linux shell", function () { + var done = this.async(); + + spawn("make").then(function () { + done(); + }, function (err) { + grunt.log.error(err); + done(false); + }); + }); + // task: git grunt.registerMultiTask("git", "Pull specified repo branch from origin", function () { var repo = this.data.repo; @@ -93,6 +107,7 @@ module.exports = function (grunt) { var done = this.async(), promise = spawn([ + "git fetch origin", "git checkout " + this.data.branch, "git pull origin " + this.data.branch, "git submodule sync", @@ -117,10 +132,12 @@ module.exports = function (grunt) { spawn(["git status"], { cwd: wwwRepo }) .then(function (result) { - var branch = /On branch (.*)/.exec(result.stdout.trim())[1]; - - grunt.log.writeln("Build branch " + branch); - grunt.config("build.build-branch", branch); + var branch = /On branch (.*)/.exec(result.stdout.trim()); + + if (branch && branch[1]) { + grunt.log.writeln("Build branch " + branch); + grunt.config("build.build-branch", branch); + } done(); }, function (err) { @@ -195,6 +212,12 @@ module.exports = function (grunt) { grunt.task.run("copy:win"); }); + // task: stage-linux + grunt.registerTask("stage-linux", "Stage linux executable files", function () { + // stage platform-specific binaries, then package www files + grunt.task.run("copy:linux"); + }); + // task: package grunt.registerTask("package", "Package www files", function () { grunt.task.run(["clean:www", "copy:www", "copy:samples", "write-config"]); @@ -204,23 +227,26 @@ module.exports = function (grunt) { grunt.registerTask("write-config", "Update version data in www config.json payload", function () { grunt.task.requires(["build-num", "build-branch", "build-sha"]); - var configPath = grunt.config("build.staging") + "/www/config.json", - configJSON = grunt.file.readJSON(configPath); + var configJSON = grunt.file.readJSON(grunt.config("config-json")), + branch = grunt.config("build.build-branch"); configJSON.version = configJSON.version.substr(0, configJSON.version.lastIndexOf("-") + 1) + grunt.config("build.build-number"); - configJSON.repository.branch = grunt.config("build.build-branch"); configJSON.repository.SHA = grunt.config("build.build-sha"); + + if (branch) { + configJSON.repository.branch = branch; + } - common.writeJSON(configPath, configJSON); + common.writeJSON(grunt.config("config-json"), configJSON); }); - // task: installer + // task: build-installer grunt.registerTask("build-installer", "Build installer", function () { // TODO update brackets.config.json grunt.task.run(["clean:installer-" + platform, "build-installer-" + platform]); }); - // task: installer-mac + // task: build-installer-mac grunt.registerTask("build-installer-mac", "Build mac installer", function () { var done = this.async(); @@ -232,7 +258,7 @@ module.exports = function (grunt) { }); }); - // task: installer + // task: build-installer-win grunt.registerTask("build-installer-win", "Build windows installer", function () { var done = this.async(); @@ -243,4 +269,40 @@ module.exports = function (grunt) { done(false); }); }); -}; \ No newline at end of file + + // task: build-installer-linux + grunt.registerTask("build-installer-linux", "Build linux installer", function () { + grunt.task.requires(["package"]); + + var template = grunt.file.read("installer/linux/debian/control"), + templateData = {}, + content; + + // populate debian control template fields + templateData.version = grunt.file.readJSON(grunt.config("config-json")).version; + templateData.size = 0; + templateData.arch = (common.arch() === 64) ? "amd64" : "i386"; + + // uncompressed file size + grunt.file.recurse("installer/linux/debian/package-root", function (abspath) { + templateData.size += fs.statSync(abspath).size; + }); + templateData.size = Math.round(templateData.size / 1000); + + // write file + content = grunt.template.process(template, { data: templateData }); + grunt.file.write("installer/linux/debian/package-root/DEBIAN/control", content); + + var done = this.async(), + sprint = semver.parse(grunt.config("pkg").version).minor; + + spawn(["bash build_installer.sh"], { cwd: resolve("installer/linux"), env: getBracketsEnv() }).then(function () { + return common.rename("installer/linux/brackets.deb", "installer/linux/Brackets Sprint " + sprint + " " + common.arch() + "-bit.deb"); + }).then(function () { + done(); + }, function (err) { + grunt.log.error(err); + done(false); + }); + }); +}; diff --git a/tasks/common.js b/tasks/common.js index 95c69ede2..4481ad933 100644 --- a/tasks/common.js +++ b/tasks/common.js @@ -20,12 +20,13 @@ * DEALINGS IN THE SOFTWARE. * */ -/*jslint es5:true, vars: true, plusplus: true, regexp: true*/ +/*jslint es5:true, vars: true, plusplus: true, regexp: true, nomen: true*/ /*global module, require, process, Buffer*/ module.exports = function (grunt) { "use strict"; var q = require("q"), + fs = require("fs"), child_process = require("child_process"), path = require("path"), common = {}, @@ -187,7 +188,7 @@ module.exports = function (grunt) { code: code, stdout: stdout.toString(), stderr: stderr.toString(), - toString: function() { + toString: function () { if (code === 0) { return this.stdout; } else { @@ -234,6 +235,18 @@ module.exports = function (grunt) { return _platform; } + function arch() { + if (platform() === "linux") { + if (process.arch === "x64") { + return 64; + } else { + return 32; + } + } + + return ""; + } + function deleteFile(path, options) { if (grunt.file.exists(path)) { grunt.file.delete(path, options); @@ -249,8 +262,10 @@ module.exports = function (grunt) { common.spawn = spawn; common.resolve = resolve; common.platform = platform; + common.arch = arch; common.deleteFile = deleteFile; common.writeJSON = writeJSON; + common.rename = q.denodeify(fs.rename); return common; -}; \ No newline at end of file +}; diff --git a/tasks/setup.js b/tasks/setup.js index fb4222168..d39e37eb3 100644 --- a/tasks/setup.js +++ b/tasks/setup.js @@ -20,6 +20,7 @@ * DEALINGS IN THE SOFTWARE. * */ +/*jslint vars:true*/ /*global module, require, process*/ module.exports = function (grunt) { "use strict"; @@ -40,26 +41,23 @@ module.exports = function (grunt) { }, /* use promises instead of callbacks */ link, - rename = q.denodeify(fs.rename), + rename = common.rename, exec = common.exec; // cross-platform symbolic link link = (function () { - var symlink; + var typeArg, + symlink; if (process.platform === "win32") { - symlink = q.denodeify(fs.symlink); - - return function (srcpath, destpath) { - return symlink(srcpath, destpath, "junction"); - }; - } else { - symlink = q.denodeify(fs.link); - - return function (srcpath, destpath) { - return symlink(srcpath, destpath); - }; + typeArg = "junction"; } + + symlink = q.denodeify(fs.symlink); + + return function (srcpath, destpath) { + return symlink(srcpath, destpath, typeArg); + }; }()); function unzip(src, dest) { @@ -69,7 +67,7 @@ module.exports = function (grunt) { // task: cef grunt.registerTask("cef", "Download and setup CEF", function () { - var config = "cef-" + common.platform(), + var config = "cef-" + common.platform() + common.arch(), zipSrc = grunt.config("curl-dir." + config + ".src"), zipName = zipSrc.substr(zipSrc.lastIndexOf("/") + 1), zipDest = grunt.config("curl-dir." + config + ".dest") + zipName, @@ -86,12 +84,15 @@ module.exports = function (grunt) { // optionally download if CEF is not found if (!grunt.file.exists("deps/cef/" + txtName)) { + var cefTasks = ["cef-clean", "cef-extract", "cef-symlinks"]; + if (grunt.file.exists(zipDest)) { grunt.verbose.writeln("Found CEF download " + zipDest); - grunt.task.run(["cef-clean", "cef-extract", "cef-symlinks"]); } else { - grunt.task.run(["cef-download","cef-clean", "cef-extract", "cef-symlinks"]); + cefTasks.unshift("cef-download"); } + + grunt.task.run(cefTasks); } else { grunt.verbose.writeln("Skipping CEF download. Found deps/cef/" + txtName); } @@ -144,14 +145,14 @@ module.exports = function (grunt) { // rename version stamped name to cef return rename("deps/" + zipName, "deps/cef"); }).then(function () { - // write empty file with zip file - grunt.file.write("deps/cef/" + zipName + ".txt", ""); - - if (common.platform() !== "win") { + if (common.platform() === "mac") { // FIXME figure out how to use fs.chmod to only do additive mode u+x return exec("chmod u+x deps/cef/tools/*"); } + // write empty file with zip file + grunt.file.write("deps/cef/" + zipName + ".txt", ""); + // return a resolved promise return q.resolve(); }).then(function () { @@ -190,14 +191,14 @@ module.exports = function (grunt) { // task: node-download grunt.registerTask("node", "Download Node.js binaries and setup dependencies", function () { var platform = common.platform(), - config = "node-" + platform, + config = "node-" + platform + common.arch(), nodeSrc = grunt.config("curl-dir." + config + ".src"), nodeDest = [], dest = grunt.config("curl-dir." + config + ".dest"), - curlTask = "curl-dir:node-" + platform, + curlTask = "curl-dir:" + config, setupTask = "node-" + platform, - nodeVersion = grunt.config("node-version"), - npmVersion = grunt.config("npm-version"), + nodeVersion = grunt.config("node.version"), + npmVersion = grunt.config("npm.version"), txtName = "version-" + nodeVersion + ".txt", missingDest = false; @@ -230,7 +231,7 @@ module.exports = function (grunt) { function nodeWriteVersion() { // write empty file with node-version name - grunt.file.write("deps/node/version-" + grunt.config("node-version") + ".txt", ""); + grunt.file.write("deps/node/version-" + grunt.config("node.version") + ".txt", ""); } // task: node-win32 @@ -292,23 +293,35 @@ module.exports = function (grunt) { }); }); + // task: node-linux + grunt.registerTask("node-linux", ["node-mac"]); + // task: node-clean grunt.registerTask("node-clean", "Removes Node.js binaries", function () { common.deleteFile("deps/node", { force: true }); }); // task: create-project - grunt.registerTask("create-project", "Create Xcode/VisualStudio project", function () { + grunt.registerTask("create-project", "Create Xcode/VisualStudio/Makefile project", function () { var done = this.async(), - promise; + promise, + gypCommand; + + // TODO why doesn't gyp (in the repository) work for linux? + if (common.platform() === "linux") { + gypCommand = "gyp --depth ."; + } else { + gypCommand = "bash -c 'gyp/gyp appshell.gyp -I common.gypi --depth=.'"; + } grunt.log.writeln("Building project files"); // this is a hack to fix issues with node-gyp picking up this file during 'npm install' // see https://github.com/TooTallNate/node-gyp/issues/216 - promise = rename("appshell.gyp.txt", "appshell.gyp").then(function () { - return exec("bash -c 'gyp/gyp appshell.gyp -I common.gypi --depth=.'"); - }); + grunt.file.copy("appshell.gyp.txt", "appshell.gyp"); + + // Run gyp + promise = exec(gypCommand); if (common.platform() === "mac") { promise = promise.then(function () { @@ -318,8 +331,6 @@ module.exports = function (grunt) { } promise.then(function () { - return rename("appshell.gyp", "appshell.gyp.txt"); - }).then(function () { done(); }, function (err) { grunt.log.error(err);