diff --git a/.gitignore b/.gitignore index 7525d3768..cf7409603 100644 --- a/.gitignore +++ b/.gitignore @@ -40,8 +40,13 @@ tools /installer/mac/staging/ /installer/linux/*.deb -/installer/linux/debian/package-root/opt/* -/installer/linux/debian/package-root/DEBIAN/control +/installer/linux/*.pkg.tar* +/installer/linux/linux/INFO +/installer/linux/arch/PKGBUILD +/installer/linux/arch/*/ +/installer/linux/ubuntu/control +/installer/linux/ubuntu/*/ +/installer/linux/staging/ /installer/win/staging/ *.wixpdb *.wixobj diff --git a/Gruntfile.js b/Gruntfile.js index 6650a69f3..3c8a44c75 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -35,7 +35,7 @@ module.exports = function (grunt) { } else if (platform === "win") { staging = "installer/win/staging"; } else { - staging = "installer/linux/debian/package-root/opt/brackets"; + staging = "installer/linux/staging"; } grunt.initConfig({ @@ -84,7 +84,8 @@ module.exports = function (grunt) { "downloads" : ["downloads"], "installer-mac" : ["installer/mac/*.dmg"], "installer-win" : ["installer/win/*.msi"], - "installer-linux" : ["installer/linux/debian/*.deb"], + "installer-linux" : ["installer/linux/*.deb", + "installer/linux/*.pkg.tar*"], "staging-mac" : ["installer/mac/staging"], "staging-win" : ["installer/win/staging"], "staging-linux" : ["<%= build.staging %>"], @@ -142,7 +143,7 @@ module.exports = function (grunt) { }, { "expand" : true, - "cwd" : "installer/linux/debian/", + "cwd" : "installer/linux/linux/", "src" : [ "brackets.desktop", "brackets" diff --git a/installer/linux/arch/PKGBUILD.template b/installer/linux/arch/PKGBUILD.template new file mode 100644 index 000000000..c61866894 --- /dev/null +++ b/installer/linux/arch/PKGBUILD.template @@ -0,0 +1,104 @@ +# Maintainer: Brackets Team +pkgname=brackets +pkgver= +pkgrel=1 +pkgdesc="A code editor for HTML, CSS and JavaScript. " +arch=("i686" "x86_64") +url="http://brackets.io" +license=("MIT") +depends=("brackets-lib" "gconf" "nodejs" "nspr" "systemd") +makedepends=("prelink") +optdepends=( + "alsa-lib: " + "chromium: to enable Live Preview" + "gnuplot: to enable node benchmarking" + "gtk2: to enable native UI" + "ruby: to enable LiveDevelopment Inspector" + "desktop-file-utils: for update-desktop-database" + "hicolor-icon-theme: for hicolor theme hierarchy" +) +provides=("brackets" "adobe-brackets") +conflicts=("brackets-git") +replaces=() +backup=() +options=() +install=${pkgname}.install + +source=() + + +prepare() { + cd "$srcdir" + + echo " -> Fixing executable stack..." + execstack -c "Brackets" +} + +package() { + cd ${srcdir} + + echo " -> Installing program..." + install -dm755 "${pkgdir}/usr/bin" + install -Dm755 \ + "Brackets" \ + "${pkgdir}/opt/${pkgname}/Brackets" + + install -Dm755 \ + "brackets" \ + "${pkgdir}/opt/${pkgname}/brackets" + + ln -s "/opt/${pkgname}/brackets" "${pkgdir}/usr/bin/brackets" + + for _file in *.pak; do + install -Dm644 \ + "${_file}" \ + "${pkgdir}/opt/${pkgname}/${_file}" + done + + for _file in "lib/"*; do + local _filename="${_file##*/}" + install -Dm755 \ + "${_file}" \ + "${pkgdir}/usr/lib/${_filename}" + done + + for _file in "locales/"*; do + install -Dm644 \ + "${_file}" \ + "${pkgdir}/opt/${pkgname}/${_file}" + done + + cp -dpr --no-preserve=ownership \ + "www" \ + "${pkgdir}/opt/${pkgname}/www" + + cp -dpr --no-preserve=ownership \ + "samples" \ + "${pkgdir}/opt/${pkgname}/samples" + + + echo " -> Installing icons..." + local _icon_dir="usr/share/icons/hicolor" + install -Dm644 \ + "${pkgname}.svg" \ + "${pkgdir}/${_icon_dir}/scalable/apps/${pkgname}.svg" + for _icon in "appshell"*.png; do + local _icon_size="${_icon##*appshell}" + install -Dm644 \ + "${_icon}" \ + "${pkgdir}/${_icon_dir}/${_icon_size%.png}x${_icon_size%.png}/apps/${pkgname}.png" + done + + + echo " -> Installing .desktop file..." + install -Dm755 \ + "${pkgname}.desktop" \ + "${pkgdir}/usr/share/applications/${pkgname}.desktop" + + + echo " -> Installing license..." + install -Dm644 \ + "license" \ + "${pkgdir}/usr/share/licenses/${pkgname}/license" + +} diff --git a/installer/linux/arch/brackets.install b/installer/linux/arch/brackets.install new file mode 100644 index 000000000..a1317a818 --- /dev/null +++ b/installer/linux/arch/brackets.install @@ -0,0 +1,17 @@ +post_install() { + xdg-icon-resource forceupdate --theme hicolor &> /dev/null + update-desktop-database -q + update-mime-database usr/share/mime + echo "==> Linux version doesn't always run as expected. See: https://github.com/adobe/brackets/wiki/Linux-Version#known-issues" + echo "==> To use Live Preview with chromium do: # ln -s /usr/bin/chromium /usr/bin/google-chrome" +} + +post_upgrade() { + post_install +} + +post_remove() { + xdg-icon-resource forceupdate --theme hicolor &> /dev/null + update-desktop-database -q + update-mime-database usr/share/mime +} diff --git a/installer/linux/arch_builder.sh b/installer/linux/arch_builder.sh new file mode 100644 index 000000000..730e307a3 --- /dev/null +++ b/installer/linux/arch_builder.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# +# Package builder for Arch Linux +# + +# +# GLOBAL VARIABLES +# + +# brackets version number +VERSION=`. linux/INFO; echo ${MINOR_VERSION}` + + +# +# FUNCTIONS +# + +# create build filesystem +prepare() { + cp -dpr --no-preserve=ownership \ + "../staging/" \ + "src" + cp -dpr --no-preserve=ownership \ + "../linux/." \ + "src" + + # update pkgbuild file + pkgbuild + + # delete old package + rm -f *pkg.tar* +} + +# postbuild clean +clean() { + mv *pkg.tar* ../ + rm -rf src + rm -rf pkg + rm -f PKGBUILD +} + +# update pkgbuild file +pkgbuild() { + awk -v ver=${VERSION} \ + 'BEGIN{FS="=";OFS="="} {\ + sub(/^pkgver=.*/, $1"=sprint"'ver'); \ + print}' PKGBUILD.template > PKGBUILD +} + + +# +# MAIN +# +cd "arch" +prepare +makepkg +clean diff --git a/installer/linux/build_installer.sh b/installer/linux/build_installer.sh index 7901b543a..4e534c0b9 100755 --- a/installer/linux/build_installer.sh +++ b/installer/linux/build_installer.sh @@ -1,19 +1,30 @@ #!/bin/bash +# +# Build installer for linux +# +# When add new distro check other possible release files: +# http://linuxmafia.com/faq/Admin/release-files.html -# grunt-contrib-copy doesn't preserve permissions -# https://github.com/gruntjs/grunt/issues/615 -chmod 755 debian/package-root/opt/brackets/brackets -chmod 755 debian/package-root/opt/brackets/Brackets -chmod 755 debian/package-root/opt/brackets/Brackets-node -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 debian -type d -exec chmod 755 {} \; +DISTRO="unknown" -# delete old package -rm -f brackets.deb -fakeroot dpkg-deb --build debian/package-root -mv debian/package-root.deb brackets.deb +# get distribution name from /etc/*release file +if [[ -f /etc/os-release ]]; then + . /etc/os-release; DISTRO=$ID +elif [[ -f /etc/lsb_release ]]; then + . /etc/lsb_release; DISTRO=$DISTRIB_ID +else + echo "Error: non-standard /etc/*release files are currently not supported" 2>&1 + exit 1 +fi; + + +# run distro-specified builder +if [[ -f ${DISTRO}_builder.sh ]]; then + bash ${DISTRO}_builder.sh +else + echo "Error: ${DISTRO}_builder.sh not found" 2>&1 + echo " Can't build package for distribution \"${DISTRO}\"" 2>&1 + exit 1 +fi; diff --git a/installer/linux/debian/package-root/usr/bin/brackets b/installer/linux/debian/package-root/usr/bin/brackets deleted file mode 120000 index 6970ddfae..000000000 --- a/installer/linux/debian/package-root/usr/bin/brackets +++ /dev/null @@ -1 +0,0 @@ -/opt/brackets/brackets \ No newline at end of file diff --git a/installer/linux/linux/INFO.template b/installer/linux/linux/INFO.template new file mode 100644 index 000000000..645641dff --- /dev/null +++ b/installer/linux/linux/INFO.template @@ -0,0 +1,2 @@ +VERSION=<%= version %> +MINOR_VERSION=<%= minorVersion %> diff --git a/installer/linux/debian/brackets b/installer/linux/linux/brackets similarity index 100% rename from installer/linux/debian/brackets rename to installer/linux/linux/brackets diff --git a/installer/linux/debian/brackets.desktop b/installer/linux/linux/brackets.desktop similarity index 100% rename from installer/linux/debian/brackets.desktop rename to installer/linux/linux/brackets.desktop diff --git a/installer/linux/debian/package-root/usr/share/menu/brackets.menu b/installer/linux/linux/brackets.menu similarity index 100% rename from installer/linux/debian/package-root/usr/share/menu/brackets.menu rename to installer/linux/linux/brackets.menu diff --git a/installer/linux/debian/package-root/usr/share/icons/hicolor/scalable/apps/brackets.svg b/installer/linux/linux/brackets.svg similarity index 100% rename from installer/linux/debian/package-root/usr/share/icons/hicolor/scalable/apps/brackets.svg rename to installer/linux/linux/brackets.svg diff --git a/installer/linux/debian/package-root/usr/share/doc/brackets/copyright b/installer/linux/linux/license similarity index 100% rename from installer/linux/debian/package-root/usr/share/doc/brackets/copyright rename to installer/linux/linux/license diff --git a/installer/linux/debian/control b/installer/linux/ubuntu/control.template similarity index 93% rename from installer/linux/debian/control rename to installer/linux/ubuntu/control.template index 410cc1ee4..7dfd34029 100644 --- a/installer/linux/debian/control +++ b/installer/linux/ubuntu/control.template @@ -1,9 +1,9 @@ Package: brackets -Version: <%= version %> +Version: Section: devel Priority: optional -Architecture: <%= arch %> -Installed-Size: <%= size %> +Architecture: +Installed-Size: Pre-Depends: dpkg (>= 1.14.0) Depends: gconf-service, libasound2 (>= 1.0.23), libatk1.0-0 (>= 1.12.4), libc6 (>= 2.11), libcairo2 (>= 1.6.0), libcups2 (>= 1.4.0), libdbus-1-3 (>= 1.2.14), libexpat1 (>= 1.95.8), libfontconfig1 (>= 2.8.0), libfreetype6 (>= 2.3.9), libgcc1 (>= 1:4.1.1), libgconf-2-4 (>= 2.31.1), libgcrypt11 (>= 1.4.5), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.18.0), libgtk2.0-0 (>= 2.24.0), libnspr4 (>= 1.8.0.10), libnss3 (>= 3.12.6), libpango1.0-0 (>= 1.22.0), libstdc++6 (>= 4.6), libudev0 (>= 147) | libudev1 (>= 198), libx11-6 (>= 2:1.4.99.1), libxcomposite1 (>= 1:0.3-1), libxdamage1 (>= 1:1.1), libxext6, libxfixes3, libxrandr2 (>= 2:1.2.0), libxrender1, ca-certificates, libcurl3, lsb-base (>= 3.2), xdg-utils (>= 1.0.2), wget Maintainer: Brackets Team diff --git a/installer/linux/debian/package-root/DEBIAN/postinst b/installer/linux/ubuntu/postinst similarity index 100% rename from installer/linux/debian/package-root/DEBIAN/postinst rename to installer/linux/ubuntu/postinst diff --git a/installer/linux/debian/package-root/DEBIAN/postrm b/installer/linux/ubuntu/postrm similarity index 100% rename from installer/linux/debian/package-root/DEBIAN/postrm rename to installer/linux/ubuntu/postrm diff --git a/installer/linux/debian/package-root/DEBIAN/prerm b/installer/linux/ubuntu/prerm similarity index 100% rename from installer/linux/debian/package-root/DEBIAN/prerm rename to installer/linux/ubuntu/prerm diff --git a/installer/linux/ubuntu_builder.sh b/installer/linux/ubuntu_builder.sh new file mode 100644 index 000000000..dbc4a4eec --- /dev/null +++ b/installer/linux/ubuntu_builder.sh @@ -0,0 +1,126 @@ +#!/bin/bash +# +# Package builder for Ubuntu +# + + +# +# GLOBAL VARIABLES +# + +# current architecture +if [[ `uname -m` == "x86_64" ]]; then + ARCH="amd64" +else + ARCH="i386" +fi; +# brackets version number +VERSION=`. linux/INFO; echo ${MINOR_VERSION}` +# deb package name +PKG_NAME="brackets-sprint${VERSION}-0ubuntu1-${ARCH}.deb" + + +# +# FUNCTIONS +# + +# create build filesystem +prepare() { + rm -rf package-root + # create dirs + mkdir -p package-root/DEBIAN + mkdir -p package-root/opt + mkdir -p package-root/usr/bin + mkdir -p package-root/usr/share/menu + mkdir -p package-root/usr/share/icons/hicolor/scalable/apps + mkdir -p package-root/usr/share/doc/brackets + + # copy package files + cp -dpr --no-preserve=ownership \ + "control.template" \ + "package-root/DEBIAN/control.template" + cp -dpr --no-preserve=ownership \ + "postinst" \ + "package-root/DEBIAN/postinst" + cp -dpr --no-preserve=ownership \ + "prerm" \ + "package-root/DEBIAN/prerm" + cp -dpr --no-preserve=ownership \ + "postrm" \ + "package-root/DEBIAN/postrm" + + # copy staging directory + cp -dpr --no-preserve=ownership \ + "../staging" \ + "package-root/opt/brackets" + + # copy files from resource directory + cp -dpr --no-preserve=ownership \ + "../linux/brackets" \ + "package-root/opt/brackets/brackets" + ln -s "/opt/brackets/brackets" "package-root/usr/bin/brackets" + cp -dpr --no-preserve=ownership \ + "../linux/brackets.desktop" \ + "package-root/opt/brackets/brackets.desktop" + cp -dpr --no-preserve=ownership \ + "../linux/brackets.menu" \ + "package-root/usr/share/menu/brackets.menu" + cp -dpr --no-preserve=ownership \ + "../linux/brackets.svg" \ + "package-root/usr/share/icons/hicolor/scalable/apps/brackets.svg" + cp -dpr --no-preserve=ownership \ + "../linux/license" \ + "package-root/usr/share/doc/brackets/copyright" + + # grunt-contrib-copy doesn't preserve permissions + # https://github.com/gruntjs/grunt/issues/615 + chmod 755 package-root/opt/brackets/brackets + chmod 755 package-root/opt/brackets/Brackets + chmod 755 package-root/opt/brackets/Brackets-node + chmod 755 package-root/DEBIAN/prerm + chmod 755 package-root/DEBIAN/postrm + chmod 755 package-root/DEBIAN/postinst + + # set permissions on subdirectories + find . -type d -exec chmod 755 {} \; + + # update control file + control + + # delete old package + rm -f ../$PKG_NAME +} + +# postbuild clean +clean() { + mv package-root.deb ../$PKG_NAME + rm -rf package-root +} + +# update control file +control() { + # size of all files in opt dir (in kB) + local _SIZE=`du -shb package-root/opt/ | \ + awk '{printf "%.0f\n", $1 / 1000}'` + # update control file + cd "package-root/DEBIAN" + awk -v arch=${ARCH} -v ver=${VERSION} -v size=${_SIZE} \ + 'BEGIN{FS=":";OFS=":"}{ \ + sub(/^Version:.*/, $1": "'ver'); \ + sub(/^Architecture:.*/, $1": "'arch'); \ + sub(/^Installed-Size:.*/, $1": "'size'); \ + print}' control.template > control + rm -f control.template + + cd ../.. +} + + +# +# MAIN +# + +cd "ubuntu" +prepare +fakeroot dpkg-deb --build package-root +clean diff --git a/tasks/build.js b/tasks/build.js index f10cb4749..52e931081 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -273,32 +273,18 @@ module.exports = function (grunt) { // 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"), + + // INFO file + var template = grunt.file.read("installer/linux/linux/INFO.template"), 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/opt", function (abspath) { - templateData.size += fs.statSync(abspath).size; - }); - templateData.size = Math.round(templateData.size / 1000); - - // write file + templateData.version = grunt.config("pkg").version; + templateData.minorVersion = semver.parse(grunt.config("pkg").version).minor; 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; - + grunt.file.write("installer/linux/linux/INFO", content); + + var done = this.async(); 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);