From c8998a11f4f25b1261d3faba50c5de1a89d4733c Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Mon, 23 Nov 2015 18:25:22 +0800 Subject: [PATCH 1/9] add build option 'symlink' --- lib/option/build.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/option/build.js b/lib/option/build.js index c0969bc9..152df687 100644 --- a/lib/option/build.js +++ b/lib/option/build.js @@ -79,6 +79,13 @@ exports.options = { default: false }, + 'symlink': { + enumerable: false, + type: Boolean, + info: 'create symbolic links, instead of copying css files and directories', + default: false + }, + prerelease: { enumerable: false, info: 'build as a pre-release package.' From 25bbe0954ded68d3a2a03b3419a0ee841b0d2c75 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Tue, 24 Nov 2015 10:45:41 +0800 Subject: [PATCH 2/9] create symlink instead of copying directories --- lib/command/build.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/command/build.js b/lib/command/build.js index e4ab637d..a1c5ad32 100644 --- a/lib/command/build.js +++ b/lib/command/build.js @@ -674,6 +674,7 @@ build.copy_directories = function(options, callback) { var to = options.to; var file = options.file; var build_type = options.build_type; + var symlink = options.symlink; if(!this._is_type(build_type, 'dir')){ return callback(null); @@ -701,6 +702,15 @@ build.copy_directories = function(options, callback) { async.eachSeries(tasks, function (name, done) { var dir = directories[name]; + + if (symlink) { + var linkTo = node_path.join(cwd, dir); + var linkFrom = node_path.join(to, dir); + + self.symlink(linkFrom, linkTo, done); + return; + } + self.copy(cwd, to, dir, function (err) { if (err && err.code === 'SRC_NOT_FOUND') { err = { @@ -718,6 +728,19 @@ build.copy_directories = function(options, callback) { }, callback); }; +// Creates a symlink from `from` to `to`. +build.symlink = function(from, to, callback) { + var self = this; + + fs.lstat(to, function(err, stats) { + if (err) { + return callback(err); + } + + self.logger.info(' {{cyan link}} ' + from + ' -> ' + to); + ln.link(from, to, callback); + }); +} // Copy item from `from` to `to` // @param {String=} item If is undefined, will copy `from` to `to` From 4c4d73a632fbb2922ddd27a0588821dbc95a79a4 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Tue, 24 Nov 2015 14:30:38 +0800 Subject: [PATCH 3/9] only link css files if they are in the same subdirectory of cwd --- lib/command/build.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/command/build.js b/lib/command/build.js index a1c5ad32..3116a3e4 100644 --- a/lib/command/build.js +++ b/lib/command/build.js @@ -562,6 +562,9 @@ build._is_type = function(build_type, type){ build.copy_csses = function (options, callback) { var css = options.pkg.css; var build_type = options.build_type; + var symlink = options.symlink; + var common_root; + if (!css) { return callback(null); } @@ -575,6 +578,12 @@ build.copy_csses = function (options, callback) { if(build_type == 'css'){ css = [node_path.relative(options.cwd, options.file)]; + } else if (symlink && (common_root = self.parse_common_root(css))) { + var linkFrom = node_path.join(options.to, common_root); + var linkTo = node_path.join(options.cwd, common_root); + + self.symlink(linkFrom, linkTo, callback); + return; } async.eachSeries(css, function (path, done) { @@ -625,6 +634,32 @@ build.copy_csses = function (options, callback) { }, callback); }; +// Accept a file list and return their longest common prefix +// NOTICE: +// every file path should be relative to cwd and not beyond cwd +// if no common path except cwd, return undefined +build.parse_common_root = function(files) { + var all_paths = files.filter(function(file) { + return file.indexOf('.' + node_path.sep) == 0; + }); + + if (!all_paths.length) {return;} + + all_paths = all_paths.map(function(file) { + return file.split(node_path.sep); + }); + + var i, len, is_common; + for (i = 0, len = all_paths[0].length; i < len; i++) { + is_common = all_paths.every(function(paths) { + return paths.length > i && paths[i] == all_paths[0][i]; + }); + if (!is_common) break; + } + + return i ? all_paths[0].slice(0, i).join(node_path.sep) : ''; +}; + build.parse_css_images = function(csspath, done){ var self = this; From 968a375fc248e925dbe66a3db46bbd66058c7e6b Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Mon, 30 Nov 2015 14:35:36 +0800 Subject: [PATCH 4/9] add --symlink for 'cortex watch' --- lib/command/watch.js | 5 +++++ lib/option/watch.js | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/lib/command/watch.js b/lib/command/watch.js index 23e03a24..dd5d7b91 100644 --- a/lib/command/watch.js +++ b/lib/command/watch.js @@ -225,6 +225,11 @@ watch._rebuild = function(options, cwd, init) { argv.push("--prerelease", prerelease); } + var symlink = options.symlink; + if (symlink) { + argv.push("--symlink", symlink); + } + var commander = self.commander; var parsed = commander.parse(argv, function(err, result, details) { if (err) { diff --git a/lib/option/watch.js b/lib/option/watch.js index c60f9874..b1d3ac26 100644 --- a/lib/option/watch.js +++ b/lib/option/watch.js @@ -54,6 +54,13 @@ exports.options = { info: 'whether cortex should build the project when begins to watch.', default: true }, + + 'symlink': { + enumerable: false, + type: Boolean, + info: 'create symbolic links, instead of copying css files and directories', + default: false + }, prerelease: { enumerable: false, From 7aa9fd592c63495bb96fa865a4eb5c90703f4525 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Mon, 30 Nov 2015 17:58:22 +0800 Subject: [PATCH 5/9] fix parsed args to be string --- lib/command/watch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/command/watch.js b/lib/command/watch.js index dd5d7b91..59a9ec5f 100644 --- a/lib/command/watch.js +++ b/lib/command/watch.js @@ -222,12 +222,12 @@ watch._rebuild = function(options, cwd, init) { var prerelease = options.prerelease; if (prerelease) { - argv.push("--prerelease", prerelease); + argv.push("--prerelease", "true"); } var symlink = options.symlink; if (symlink) { - argv.push("--symlink", symlink); + argv.push("--symlink", "true"); } var commander = self.commander; From ea19e0614b0c362507d5a394e5856aeda33f5bf4 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Mon, 7 Dec 2015 17:59:00 +0800 Subject: [PATCH 6/9] remove quote signs --- lib/option/build.js | 2 +- lib/option/watch.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/option/build.js b/lib/option/build.js index 152df687..54e24ffa 100644 --- a/lib/option/build.js +++ b/lib/option/build.js @@ -79,7 +79,7 @@ exports.options = { default: false }, - 'symlink': { + symlink: { enumerable: false, type: Boolean, info: 'create symbolic links, instead of copying css files and directories', diff --git a/lib/option/watch.js b/lib/option/watch.js index b1d3ac26..75438b4f 100644 --- a/lib/option/watch.js +++ b/lib/option/watch.js @@ -55,7 +55,7 @@ exports.options = { default: true }, - 'symlink': { + symlink: { enumerable: false, type: Boolean, info: 'create symbolic links, instead of copying css files and directories', From b316fccc41e81dc53e58acc443af9855068e009b Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Mon, 7 Dec 2015 18:55:23 +0800 Subject: [PATCH 7/9] handle copying between identical files --- lib/command/build.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/command/build.js b/lib/command/build.js index 3116a3e4..c93d7d1d 100644 --- a/lib/command/build.js +++ b/lib/command/build.js @@ -782,10 +782,6 @@ build.symlink = function(from, to, callback) { // @param {Boolean} strict build.copy = function(from, to, item, callback, strict) { var self = this; - if (from === to) { - callback(null); - return; - } if (item) { if (item != item.toLowerCase()) { @@ -797,6 +793,16 @@ build.copy = function(from, to, item, callback, strict) { to = node_path.join(to, item); } + // after fs-extra #198 is solved, can delete this check + try{ + var fromStats = fs.lstatSync(from); + var toStats = fs.lstatSync(to); + if (fromStats && toStats && fromStats.ino === toStats.ino) { + callback(null); + return; + } + } catch(e) {} + fs.exists(from, function (exists) { if (!exists) { // if strict and the source is not found, an error will throw. From 93c0da453f212e7efcf8219c9d287cfba721bc01 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Thu, 19 May 2016 15:24:11 +0800 Subject: [PATCH 8/9] fix the wrong `prerelease` option --- lib/command/watch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/command/watch.js b/lib/command/watch.js index 59a9ec5f..97b2878c 100644 --- a/lib/command/watch.js +++ b/lib/command/watch.js @@ -222,7 +222,7 @@ watch._rebuild = function(options, cwd, init) { var prerelease = options.prerelease; if (prerelease) { - argv.push("--prerelease", "true"); + argv.push("--prerelease", prerelease); } var symlink = options.symlink; From de95d11fba8254a27dbcf2f5d8e4a9052e1596b1 Mon Sep 17 00:00:00 2001 From: chinesedfan Date: Tue, 16 Aug 2016 15:02:20 +0800 Subject: [PATCH 9/9] fix the identical check --- lib/command/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/command/build.js b/lib/command/build.js index c93d7d1d..b7a0e61e 100644 --- a/lib/command/build.js +++ b/lib/command/build.js @@ -795,8 +795,8 @@ build.copy = function(from, to, item, callback, strict) { // after fs-extra #198 is solved, can delete this check try{ - var fromStats = fs.lstatSync(from); - var toStats = fs.lstatSync(to); + var fromStats = fs.statSync(from); + var toStats = fs.statSync(to); if (fromStats && toStats && fromStats.ino === toStats.ino) { callback(null); return;