fs = require 'fs' path = require 'path' _ = require 'underscore' module.exports = (grunt) -> {cp, isNylasPackage, mkdir, rm} = require('./task-helpers')(grunt) escapeRegExp = (string) -> if string return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') else return '' grunt.registerTask 'copy-files-for-build', 'Copy files for build', -> shellAppDir = grunt.config.get('nylasGruntConfig.shellAppDir') buildDir = grunt.config.get('nylasGruntConfig.buildDir') appDir = grunt.config.get('nylasGruntConfig.appDir') rm shellAppDir rm path.join(buildDir, 'installer') mkdir path.dirname(buildDir) if process.platform is 'darwin' cp 'electron/Electron.app', shellAppDir, filter: /default_app/ cp(path.join(shellAppDir, 'Contents', 'MacOS', 'Electron'), path.join(shellAppDir, 'Contents', 'MacOS', 'Nylas')) rm path.join(shellAppDir, 'Contents', 'MacOS', 'Electron') # Create locale directories that were skipped because they were empty. # Otherwise, `navigator.language` always returns `English`. resourcesDir = 'electron/Electron.app/Contents/Resources' filenames = fs.readdirSync(resourcesDir) for filename in filenames continue unless fs.statSync(path.join(resourcesDir, filename)).isDirectory() continue unless path.extname(filename) is '.lproj' destination = path.join(shellAppDir, 'Contents', 'Resources', filename) continue if fs.existsSync(destination) grunt.file.mkdir(destination) else if process.platform is 'win32' cp 'electron', shellAppDir, filter: /default_app/ cp path.join(shellAppDir, 'electron.exe'), path.join(shellAppDir, 'nylas.exe') rm path.join(shellAppDir, 'electron.exe') else cp 'electron', shellAppDir, filter: /default_app/ cp path.join(shellAppDir, 'electron'), path.join(shellAppDir, 'nylas') rm path.join(shellAppDir, 'electron') mkdir appDir if process.platform isnt 'win32' cp 'N1.sh', path.resolve(appDir, '..', 'new-app', 'N1.sh') cp 'package.json', path.join(appDir, 'package.json') cp path.join('build', 'resources', 'nylas.png'), path.join(appDir, 'nylas.png') packageNames = [] packageDirectories = [] nonPackageDirectories = [ 'dot-nylas' ] {devDependencies} = grunt.file.readJSON('package.json') for packageFolder in ['node_modules', 'internal_packages'] for child in fs.readdirSync(packageFolder) directory = path.join(packageFolder, child) if isNylasPackage(directory) packageDirectories.push(directory) packageNames.push(child) else nonPackageDirectories.push(directory) # Put any paths here that shouldn't end up in the built Electron.app # so that it doesn't becomes larger than it needs to be. ignoredPaths = [ path.join('less', 'dist') path.join('npm', 'doc') path.join('npm', 'html') path.join('npm', 'man') path.join('npm', 'node_modules', '.bin', 'beep') path.join('npm', 'node_modules', '.bin', 'clear') path.join('npm', 'node_modules', '.bin', 'starwars') path.join('pegjs', 'examples') path.join('jasmine-reporters', 'ext') path.join('jasmine-node', 'node_modules', 'gaze') path.join('jasmine-node', 'spec') path.join('node_modules', 'nan') path.join('build', 'binding.Makefile') path.join('build', 'config.gypi') path.join('build', 'gyp-mac-tool') path.join('build', 'Makefile') path.join('build', 'Release', 'obj.target') path.join('build', 'Release', 'obj') path.join('build', 'Release', '.deps') path.join('build', 'resources') path.join('build', 'resources', 'linux') path.join('build', 'resources', 'mac') path.join('build', 'resources', 'win') path.join('vendor', 'apm') # These are only require in dev mode when the grammar isn't precompiled path.join('snippets', 'node_modules', 'loophole') path.join('snippets', 'node_modules', 'pegjs') path.join('snippets', 'node_modules', '.bin', 'pegjs') # These aren't needed since WeakMap is built-in path.join('emissary', 'node_modules', 'es6-weak-map') path.join('property-accessors', 'node_modules', 'es6-weak-map') '.DS_Store' '.jshintrc' '.npmignore' '.pairs' '.travis.yml' 'appveyor.yml' '.idea' '.editorconfig' '.lint' '.lintignore' '.eslintrc' '.jshintignore' '.gitattributes' '.gitkeep' ] ignoredPaths = ignoredPaths.map (ignoredPath) -> escapeRegExp(ignoredPath) # Add .* to avoid matching hunspell_dictionaries. ignoredPaths.push "#{escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*" ignoredPaths.push "#{escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb" # Ignore *.cc and *.h files from native modules ignoredPaths.push "#{escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('pathwatcher', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('runas', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('scrollbar-style', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{escapeRegExp(path.join('spellchecker', 'src') + path.sep)}.*\\.(cc|h)*" # Ignore build files ignoredPaths.push "#{escapeRegExp(path.sep)}binding\\.gyp$" ignoredPaths.push "#{escapeRegExp(path.sep)}.+\\.target.mk$" ignoredPaths.push "#{escapeRegExp(path.sep)}linker\\.lock$" ignoredPaths.push "#{escapeRegExp(path.join('build', 'Release') + path.sep)}.+\\.node\\.dSYM" # Hunspell dictionaries are only not needed on OS X. if process.platform is 'darwin' ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries') ignoredPaths = ignoredPaths.map (ignoredPath) -> "(#{ignoredPath})" testFolderPattern = new RegExp("#{escapeRegExp(path.sep)}te?sts?#{escapeRegExp(path.sep)}") exampleFolderPattern = new RegExp("#{escapeRegExp(path.sep)}examples?#{escapeRegExp(path.sep)}") nodeModulesFilter = new RegExp(ignoredPaths.join('|')) filterNodeModule = (pathToCopy) -> pathToCopy = path.resolve(pathToCopy) nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy) packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee|cjsx|jsx)$)") filterPackage = (pathToCopy) -> pathToCopy = path.resolve(pathToCopy) packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy) for directory in nonPackageDirectories cp directory, path.join(appDir, directory), filter: filterNodeModule for directory in packageDirectories cp directory, path.join(appDir, directory), filter: filterPackage cp 'spec', path.join(appDir, 'spec') cp 'examples', path.join(appDir, 'examples') cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee|cjsx|jsx)$/ cp 'static', path.join(appDir, 'static') # Move all of the node modules inside /apm/node_modules to new-app/apm/node_modules apmInstallDir = path.resolve(appDir, '..', 'new-app', 'apm') mkdir apmInstallDir cp path.join('apm', 'node_modules'), path.resolve(apmInstallDir, 'node_modules'), filter: filterNodeModule # Move /apm/node_modules/atom-package-manager to new-app/apm. We're essentially # pulling the atom-package-manager module up outside of the node_modules folder, # which is necessary because npmV3 installs nested dependencies in the same dir. apmPackageDir = path.join(apmInstallDir, 'node_modules', 'atom-package-manager') for name in fs.readdirSync(apmPackageDir) fs.renameSync path.join(apmPackageDir, name), path.join(apmInstallDir, name) fs.unlinkSync(path.join(apmInstallDir, 'node_modules', '.bin', 'apm')) fs.rmdirSync(apmPackageDir) if process.platform is 'darwin' grunt.file.recurse path.join('build', 'resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) -> unless /.+\.plist/.test(sourcePath) grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename)) if process.platform is 'win32' cp path.join('build', 'resources', 'win', 'N1.cmd'), path.join(shellAppDir, 'resources', 'cli', 'N1.cmd') cp path.join('build', 'resources', 'win', 'N1.sh'), path.join(shellAppDir, 'resources', 'cli', 'N1.sh') cp path.join('build', 'resources', 'win', 'nylas-win-bootup.js'), path.join(shellAppDir, 'resources', 'cli', 'nylas-win-bootup.js') cp path.join('build', 'resources', 'win', 'apm.sh'), path.join(shellAppDir, 'resources', 'cli', 'apm.sh') if process.platform is 'linux' cp path.join('build', 'resources', 'linux', 'icons'), path.join(buildDir, 'icons')