diff --git a/Gruntfile.coffee b/build/Gruntfile.coffee similarity index 96% rename from Gruntfile.coffee rename to build/Gruntfile.coffee index 024c01e48..831f18a15 100644 --- a/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -5,7 +5,7 @@ os = require 'os' fm = require 'json-front-matter' _ = require 'underscore-plus' -packageJson = require './package.json' +packageJson = require '../package.json' # OAuth token for atom-bot # TODO Remove once all repositories are public @@ -16,6 +16,20 @@ process.env.ATOM_ACCESS_TOKEN ?= '362295be4c5258d3f7b967bbabae662a455ca2a7' _.extend(global, require('harmony-collections')) unless global.WeakMap? module.exports = (grunt) -> + grunt.loadNpmTasks('grunt-coffeelint') + grunt.loadNpmTasks('grunt-lesslint') + grunt.loadNpmTasks('grunt-cson') + grunt.loadNpmTasks('grunt-contrib-csslint') + grunt.loadNpmTasks('grunt-contrib-coffee') + grunt.loadNpmTasks('grunt-contrib-less') + grunt.loadNpmTasks('grunt-markdown') + grunt.loadNpmTasks('grunt-shell') + grunt.loadNpmTasks('grunt-download-atom-shell') + grunt.loadTasks('tasks') + + # This allows all subsequent paths to the relative to the root of the repo + grunt.file.setBase(path.resolve('..')) + if not grunt.option('verbose') grunt.log.writeln = (args...) -> grunt.log grunt.log.write = (args...) -> grunt.log @@ -193,21 +207,10 @@ module.exports = (grunt) -> stderr: false failOnError: false - grunt.loadNpmTasks('grunt-coffeelint') - grunt.loadNpmTasks('grunt-lesslint') - grunt.loadNpmTasks('grunt-cson') - grunt.loadNpmTasks('grunt-contrib-csslint') - grunt.loadNpmTasks('grunt-contrib-coffee') - grunt.loadNpmTasks('grunt-contrib-less') - grunt.loadNpmTasks('grunt-markdown') - grunt.loadNpmTasks('grunt-download-atom-shell') - grunt.loadNpmTasks('grunt-shell') - grunt.loadTasks('tasks') - grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson']) grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint']) grunt.registerTask('test', ['shell:kill-atom', 'run-specs']) - grunt.registerTask('ci', ['download-atom-shell', 'build', 'set-development-version', 'lint', 'test']) + grunt.registerTask('ci', ['download-atom-shell', 'build', 'set-development-version', 'lint', 'test', 'publish-build']) grunt.registerTask('deploy', ['partial-clean', 'download-atom-shell', 'build', 'codesign']) grunt.registerTask('docs', ['markdown:guides', 'build-docs']) grunt.registerTask('default', ['download-atom-shell', 'build', 'set-development-version', 'install']) diff --git a/build/README.md b/build/README.md new file mode 100644 index 000000000..4ada056f1 --- /dev/null +++ b/build/README.md @@ -0,0 +1,10 @@ +# Atom Build + +This folder contains the grunt configuration and tasks to build Atom. + +It was moved from the root of the repository so that any native modules used +would be compiled against node's v8 headers since anything stored in +`node_modules` at the root of the repo is compiled against atom's v8 headers. + +New build dependencies should be added to the `package.json` file located in +this folder. diff --git a/build/package.json b/build/package.json new file mode 100644 index 000000000..221dc69c2 --- /dev/null +++ b/build/package.json @@ -0,0 +1,33 @@ +{ + "name": "atom-build", + "description": "Atom build", + "repository": { + "type": "git", + "url": "https://github.com/atom/atom.git" + }, + "dependencies": { + "biscotto": "0.0.17", + "first-mate": "~0.10.0", + "formidable": "~1.0.14", + "github-releases": "~0.2.0", + "grunt": "~0.4.1", + "grunt-cli": "~0.1.9", + "grunt-coffeelint": "git://github.com/atom/grunt-coffeelint.git", + "grunt-contrib-csslint": "~0.1.2", + "grunt-contrib-coffee": "~0.7.0", + "grunt-contrib-less": "~0.8.0", + "grunt-cson": "0.5.0", + "grunt-download-atom-shell": "git+https://atom-bot:362295be4c5258d3f7b967bbabae662a455ca2a7@github.com/atom/grunt-download-atom-shell#v0.5.0", + "grunt-lesslint": "0.13.0", + "grunt-markdown": "~0.4.0", + "grunt-shell": "~0.3.1", + "harmony-collections": "~0.3.8", + "js-yaml": "~2.1.0", + "json-front-matter": "~0.1.3", + "rcedit": "~0.1.2", + "request": "~2.27.0", + "rimraf": "~2.2.2", + "unzip": "~0.1.9", + "walkdir": "0.0.7" + } +} diff --git a/tasks/build-task.coffee b/build/tasks/build-task.coffee similarity index 100% rename from tasks/build-task.coffee rename to build/tasks/build-task.coffee diff --git a/tasks/clean-task.coffee b/build/tasks/clean-task.coffee similarity index 100% rename from tasks/clean-task.coffee rename to build/tasks/clean-task.coffee diff --git a/tasks/codesign-task.coffee b/build/tasks/codesign-task.coffee similarity index 100% rename from tasks/codesign-task.coffee rename to build/tasks/codesign-task.coffee diff --git a/tasks/convert-theme.coffee b/build/tasks/convert-theme.coffee similarity index 100% rename from tasks/convert-theme.coffee rename to build/tasks/convert-theme.coffee diff --git a/tasks/copy-info-plist-task.coffee b/build/tasks/copy-info-plist-task.coffee similarity index 100% rename from tasks/copy-info-plist-task.coffee rename to build/tasks/copy-info-plist-task.coffee diff --git a/tasks/docs-task.coffee b/build/tasks/docs-task.coffee similarity index 97% rename from tasks/docs-task.coffee rename to build/tasks/docs-task.coffee index ac034818f..42856f8ee 100644 --- a/tasks/docs-task.coffee +++ b/build/tasks/docs-task.coffee @@ -3,7 +3,7 @@ fs = require 'fs' module.exports = (grunt) -> cmd = path.join('node_modules', '.bin', 'coffee') - commonArgs = [path.join('node_modules', '.bin', 'biscotto'), '--'] + commonArgs = [path.join('build', 'node_modules', '.bin', 'biscotto'), '--'] opts = stdio: 'inherit' diff --git a/tasks/install-task.coffee b/build/tasks/install-task.coffee similarity index 100% rename from tasks/install-task.coffee rename to build/tasks/install-task.coffee diff --git a/tasks/nof-task.coffee b/build/tasks/nof-task.coffee similarity index 100% rename from tasks/nof-task.coffee rename to build/tasks/nof-task.coffee diff --git a/tasks/prebuild-less-task.coffee b/build/tasks/prebuild-less-task.coffee similarity index 100% rename from tasks/prebuild-less-task.coffee rename to build/tasks/prebuild-less-task.coffee diff --git a/script/upload-release b/build/tasks/publish-build-task.coffee old mode 100755 new mode 100644 similarity index 66% rename from script/upload-release rename to build/tasks/publish-build-task.coffee index 1227f94d5..0c0f9c1fc --- a/script/upload-release +++ b/build/tasks/publish-build-task.coffee @@ -1,7 +1,3 @@ -#!/usr/bin/env coffee - -return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master' - child_process = require 'child_process' path = require 'path' @@ -19,16 +15,35 @@ defaultHeaders = Authorization: "token #{token}" 'User-Agent': 'Atom' +module.exports = (grunt) -> + grunt.registerTask 'publish-build', 'Publish the built app', -> + return unless process.platform is 'darwin' + return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master' + + done = @async() + + createRelease (error, release) -> + return done(error) if error? + zipApp (error) -> + return done(error) if error? + uploadAsset release, (error) -> + return done(error) if error? + publishRelease release (error) -> + done(error) + +logError = (message, error, details) -> + grunt.log.error(message) + grunt.log.error(error.message ? error) if error? + grunt.log.error(details) if details + zipApp = (callback) -> fs.removeSync(assetPath) options = {cwd: path.dirname(assetPath), maxBuffer: Infinity} child_process.exec "zip -r --symlinks #{assetName} Atom.app", options, (error, stdout, stderr) -> if error? - console.error('Zipping Atom.app failed', error, stderr) - process.exit(1) - else - callback() + logError('Zipping Atom.app failed', error, stderr) + callback(error) getRelease = (callback) -> options = @@ -38,14 +53,14 @@ getRelease = (callback) -> json: true request options, (error, response, releases=[]) -> if error? or response.statusCode isnt 200 - console.error('Fetching releases failed', error, releases) - process.exit(1) + logError('Fetching releases failed', error, releases) + callback(error ? new Error(response.statusCode)) else if releases.length > maxReleases deleteRelease(release) for release in releases[maxReleases..] for release in releases when release.name is commitSha - callback(release) + callback(null, release) return callback() @@ -57,7 +72,7 @@ deleteRelease = (release) -> json: true request options, (error, response, body='') -> if error? or response.statusCode isnt 204 - console.error('Deleting release failed', error, body) + logError('Deleting release failed', error, body) deleteExistingAsset = (release, callback) -> for asset in release.assets when asset.name is assetName @@ -67,8 +82,8 @@ deleteExistingAsset = (release, callback) -> headers: defaultHeaders request options, (error, response, body='') -> if error? or response.statusCode isnt 204 - console.error('Deleting existing release asset failed', error, body) - process.exit(1) + logError('Deleting existing release asset failed', error, body) + callback(error ? new Error(response.statusCode)) else callback() @@ -77,7 +92,11 @@ deleteExistingAsset = (release, callback) -> callback() createRelease = (callback) -> - getRelease (release) -> + getRelease (error, release) -> + if error? + callback(error) + return + if release? deleteExistingAsset release, -> callback(release) @@ -96,10 +115,10 @@ createRelease = (callback) -> prerelease: true request options, (error, response, release={}) -> if error? or response.statusCode isnt 201 - console.error('Creating release failed', error, release) - process.exit(1) + logError('Creating release failed', error, release) + callback(error ? new Error(response.statusCode)) else - callback(release) + callback(null, release) uploadAsset = (release, callback) -> options = @@ -112,10 +131,10 @@ uploadAsset = (release, callback) -> assetRequest = request options, (error, response, body='') -> if error? or response.statusCode >= 400 - console.error('Upload release asset failed', error, body) - process.exit(1) + logError('Upload release asset failed', error, body) + callback(error ? new Error(response.statusCode)) else - callback(release) + callback(null, release) fs.createReadStream(assetPath).pipe(assetRequest) @@ -128,10 +147,7 @@ publishRelease = (release) -> draft: false request options, (error, response, body={}) -> if error? or response.statusCode isnt 200 - console.error('Creating release failed', error, body) - process.exit(1) - -createRelease (release) -> - zipApp -> - uploadAsset release, -> - publishRelease release + logError('Creating release failed', error, body) + callback(error ? new Error(response.statusCode)) + else + callback() diff --git a/tasks/publish-packages.coffee b/build/tasks/publish-packages.coffee similarity index 100% rename from tasks/publish-packages.coffee rename to build/tasks/publish-packages.coffee diff --git a/tasks/set-development-version-task.coffee b/build/tasks/set-development-version-task.coffee similarity index 100% rename from tasks/set-development-version-task.coffee rename to build/tasks/set-development-version-task.coffee diff --git a/tasks/set-exe-icon-task.coffee b/build/tasks/set-exe-icon-task.coffee similarity index 80% rename from tasks/set-exe-icon-task.coffee rename to build/tasks/set-exe-icon-task.coffee index 09bc2b67b..0d9e2c0f6 100644 --- a/tasks/set-exe-icon-task.coffee +++ b/build/tasks/set-exe-icon-task.coffee @@ -6,7 +6,7 @@ module.exports = (grunt) -> shellAppDir = grunt.config.get('atom.shellAppDir') shellExePath = path.join(shellAppDir, 'atom.exe') - iconPath = path.resolve(__dirname, '..', 'resources', 'win', 'atom.ico') + iconPath = path.resolve('resources', 'win', 'atom.ico') rcedit = require('rcedit') rcedit(shellExePath, {'icon': iconPath}, done) diff --git a/tasks/spec-task.coffee b/build/tasks/spec-task.coffee similarity index 100% rename from tasks/spec-task.coffee rename to build/tasks/spec-task.coffee diff --git a/tasks/task-helpers.coffee b/build/tasks/task-helpers.coffee similarity index 100% rename from tasks/task-helpers.coffee rename to build/tasks/task-helpers.coffee diff --git a/package.json b/package.json index f15021933..2712c40c0 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,13 @@ "emissary": "0.19.0", "first-mate": "0.10.0", "fs-plus": "0.13.0", + "fstream": "0.1.24", "fuzzaldrin": "0.1.0", "git-utils": "0.29.0", "guid": "0.0.10", "jasmine-focused": "~0.15.0", + "jasmine-node": "git://github.com/kevinsawicki/jasmine-node.git#short-stacks", + "jasmine-tagged": "0.2.0", "mkdirp": "0.3.5", "keytar": "0.13.0", "less-cache": "0.10.0", @@ -48,32 +51,6 @@ "temp": "0.5.0", "underscore-plus": "0.6.1" }, - "devDependencies": { - "biscotto": "0.0.17", - "formidable": "~1.0.14", - "fstream": "0.1.24", - "grunt": "~0.4.1", - "grunt-cli": "~0.1.9", - "grunt-coffeelint": "git://github.com/atom/grunt-coffeelint.git", - "grunt-lesslint": "0.13.0", - "grunt-cson": "0.5.0", - "grunt-contrib-csslint": "~0.1.2", - "grunt-contrib-coffee": "~0.7.0", - "grunt-contrib-less": "~0.8.0", - "walkdir": "0.0.7", - "js-yaml": "~2.1.0", - "grunt-markdown": "~0.4.0", - "json-front-matter": "~0.1.3", - "grunt-shell": "~0.3.1", - "jasmine-node": "git://github.com/kevinsawicki/jasmine-node.git#short-stacks", - "jasmine-tagged": "0.2.0", - "request": "~2.27.0", - "unzip": "~0.1.9", - "rcedit": "~0.1.2", - "rimraf": "~2.2.2", - "github-releases": "~0.2.0", - "harmony-collections": "~0.3.8" - }, "packageDependencies": { "atom-dark-syntax": "0.10.0", "atom-dark-ui": "0.18.0", @@ -156,8 +133,7 @@ "language-todo": "0.2.0", "language-toml": "0.7.0", "language-xml": "0.2.0", - "language-yaml": "0.1.0", - "grunt-download-atom-shell": "0.4.0" + "language-yaml": "0.1.0" }, "private": true, "scripts": { diff --git a/script/bootstrap b/script/bootstrap index 87c18f88b..2154a1ef4 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -35,6 +35,7 @@ var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo'; var commands = [ 'git submodule --quiet sync', 'git submodule --quiet update --recursive --init', + {command: 'npm install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}}, {command: 'npm install --quiet', options: {cwd: apmVendorPath, ignoreStdout: true}}, {command: 'npm install --quiet ' + apmVendorPath, options: {cwd: apmInstallPath, ignoreStdout: true}}, {command: 'npm install --quiet ' + apmVendorPath, options: {ignoreStdout: true}}, diff --git a/script/build b/script/build index b2022c6ae..19e38f818 100755 --- a/script/build +++ b/script/build @@ -5,7 +5,9 @@ var path = require('path'); process.chdir(path.dirname(__dirname)); cp.safeExec('node script/bootstrap', function() { - // node_modules/.bin/grunt "$@" - var gruntPath = path.join('node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : ''); - cp.safeSpawn(gruntPath, process.argv.slice(2), process.exit); + // build/node_modules/.bin/grunt "$@" + var gruntPath = path.join('build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : ''); + var args = [gruntPath, '--gruntfile', path.resolve('build', 'Gruntfile.coffee')]; + args = args.concat(process.argv.slice(2)); + cp.safeSpawn(process.execPath, args, process.exit); }); diff --git a/script/cibuild b/script/cibuild index 8999f0af9..c5b1a0423 100755 --- a/script/cibuild +++ b/script/cibuild @@ -28,16 +28,13 @@ readEnvironmentVariables(); cp.safeExec.bind(global, 'node script/bootstrap', function(error) { if (error) process.exit(1); + require('fs-plus').removeSync.bind(global, path.join(homeDir, '.atom')) var async = require('async'); - var gruntPath = path.join('node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : ''); + var gruntPath = path.join('build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : ''); var tasks = [ - require('rimraf').bind(global, path.join(homeDir, '.atom')), cp.safeExec.bind(global, 'git clean -dff'), - cp.safeExec.bind(global, gruntPath + ' ci --stack --no-color'), + cp.safeExec.bind(global, gruntPath + ' ci --gruntfile build/Gruntfile.coffee --stack --no-color'), ] - if (process.platform === 'darwin') { - tasks.push(cp.safeExec.bind(global, 'node_modules/.bin/coffee script/upload-release')) - } async.series(tasks, function(error) { process.exit(error ? 1 : 0); }); diff --git a/script/clean b/script/clean index 1c6590ae3..d0c7c93ea 100755 --- a/script/clean +++ b/script/clean @@ -16,6 +16,7 @@ var killatom = process.platform === 'win32' ? 'START taskkill /F /IM ' + product var commands = [ killatom, [__dirname, '..', 'node_modules'], + [__dirname, '..', 'build', 'node_modules'], [__dirname, '..', 'atom-shell'], [home, '.atom', '.node-gyp'], [home, '.atom', 'storage'], diff --git a/script/constructicon/build b/script/constructicon/build index 6bb049759..647108d85 100755 --- a/script/constructicon/build +++ b/script/constructicon/build @@ -9,7 +9,7 @@ cd "$(dirname "$0")/../.." rm -fr node_modules rm -fr vendor/apm/node_modules ./script/bootstrap --no-color -./node_modules/.bin/grunt --no-color --build-dir="$BUILT_PRODUCTS_DIR" deploy +./build/node_modules/.bin/grunt --no-color --build-dir="$BUILT_PRODUCTS_DIR" deploy echo "TARGET_BUILD_DIR=$BUILT_PRODUCTS_DIR" echo "FULL_PRODUCT_NAME=Atom.app" diff --git a/script/grunt b/script/grunt new file mode 100755 index 000000000..3f8516512 --- /dev/null +++ b/script/grunt @@ -0,0 +1,9 @@ +#!/usr/bin/env node --harmony_collections +var cp = require('./utils/child-process-wrapper.js'); +var path = require('path'); + +// node build/node_modules/grunt-cli/bin/grunt "$@" +var gruntPath = path.resolve(__dirname, '..', 'build', 'node_modules', 'grunt-cli', 'bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : ''); +var args = [gruntPath, '--gruntfile', path.resolve('build', 'Gruntfile.coffee')]; +args = args.concat(process.argv.slice(2)); +cp.safeSpawn(process.execPath, args, process.exit); diff --git a/src/package-manager.coffee b/src/package-manager.coffee index a85e51e43..e94a69785 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -226,10 +226,6 @@ class PackageManager {@packageDependencies} = JSON.parse(fs.readFileSync(metadataPath)) ? {} @packageDependencies ?= {} - # Temporarily ignore 'grunt-download-atom-shell' here, should remove this - # when it became a public npm module. - delete @packageDependencies['grunt-download-atom-shell'] - @packageDependencies # Public: Get an array of all the available package paths.