From 96e602965c301dcf03928f5f5d0c1f9b01454bcb Mon Sep 17 00:00:00 2001 From: Stanley Sathler Date: Tue, 9 Oct 2018 00:28:45 -0300 Subject: [PATCH 1/5] Added "theme" command to create a new theme folder structure --- lib/console/index.js | 8 +++++++ lib/console/theme.js | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 lib/console/theme.js diff --git a/lib/console/index.js b/lib/console/index.js index 1885086d..4d23fed5 100644 --- a/lib/console/index.js +++ b/lib/console/index.js @@ -17,5 +17,13 @@ module.exports = function(ctx) { ] }, require('./init')); + console.register('theme', 'Create a new theme folder structure.', { + desc: 'Create a new Hexo theme folder structure at the current directory.', + usage: '[name]', + arguments: [ + {name: 'name', desc: 'The name of your new theme'} + ] + }, require('./theme')); + console.register('version', 'Display version information.', {}, require('./version')); }; diff --git a/lib/console/theme.js b/lib/console/theme.js new file mode 100644 index 00000000..3b2f8a2a --- /dev/null +++ b/lib/console/theme.js @@ -0,0 +1,51 @@ +'use strict'; + +var Promise = require('bluebird'); +var fs = require('fs'); +var path = require('path'); + +var themeStructureFolders = [ + 'languages', + 'layout', + 'scripts', + 'source' +]; + +function parseArguments(args) { + return { name: args._[0] }; +} + +function addFolder(pathName) { + fs.mkdirSync(pathName); +} + +function addFile(directoryPath, fileName) { + fs.writeFileSync(path.join(directoryPath, fileName), ''); +} + +function themeConsole(args) { + var name = parseArguments(args).name; + var baseDirectory = this.base_dir; + var themeDirectory = path.join(baseDirectory, name); + + if (!name) + return Promise.reject(new Error('A theme name must be provided')); + + if (fs.existsSync(themeDirectory)) + return Promise.reject( + new Error('Seems you already have `' + name + '` in your directory') + ); + + addFolder(themeDirectory); + addFile(themeDirectory, 'config.yml'); + + themeStructureFolders.forEach(folderName => { + var folderPath = path.join(themeDirectory, folderName); + addFolder(folderPath); + addFile(folderPath, '.gitkeep'); + }); + + return Promise.resolve(); +}; + +module.exports = themeConsole; From c1db68faa8418f5ae6cffb5a2b1d83a0385137de Mon Sep 17 00:00:00 2001 From: Stanley Sathler Date: Tue, 9 Oct 2018 22:41:00 -0300 Subject: [PATCH 2/5] Fixed wrong error being thrown when theme's name is not given --- lib/console/theme.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/console/theme.js b/lib/console/theme.js index 3b2f8a2a..2da5389d 100644 --- a/lib/console/theme.js +++ b/lib/console/theme.js @@ -25,12 +25,13 @@ function addFile(directoryPath, fileName) { function themeConsole(args) { var name = parseArguments(args).name; - var baseDirectory = this.base_dir; - var themeDirectory = path.join(baseDirectory, name); if (!name) return Promise.reject(new Error('A theme name must be provided')); + var baseDirectory = this.base_dir; + var themeDirectory = path.join(baseDirectory, name); + if (fs.existsSync(themeDirectory)) return Promise.reject( new Error('Seems you already have `' + name + '` in your directory') From 217dc8d8b78f9858e82c3fe15ddf412d289de5ae Mon Sep 17 00:00:00 2001 From: Stanley Sathler Date: Tue, 9 Oct 2018 22:42:46 -0300 Subject: [PATCH 3/5] Added test in order to test error when the command is ran without a name --- test/index.js | 1 + test/scripts/theme.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 test/scripts/theme.js diff --git a/test/index.js b/test/index.js index 1f8933d5..d9d583b6 100644 --- a/test/index.js +++ b/test/index.js @@ -10,5 +10,6 @@ describe('hexo-cli', function() { require('./scripts/hexo'); require('./scripts/init'); require('./scripts/help'); + require('./scripts/theme'); require('./scripts/version'); }); diff --git a/test/scripts/theme.js b/test/scripts/theme.js new file mode 100644 index 00000000..00ee4bad --- /dev/null +++ b/test/scripts/theme.js @@ -0,0 +1,28 @@ +'use strict'; + +var should = require('chai').should(); // eslint-disable-line +var Context = require('../../lib/context'); + +describe('theme', function() { + let context; + let themeModule; + + beforeEach(function() { + context = new Context(); + themeModule = (require('../../lib/console/theme')); + }); + + it('throw error when folder already exists', function() { + var params = { _: [] }; + + themeModule + .call(context, params) + .catch(function(error) { + error.message.should.contain('A theme name must be provided'); + }); + }); + + it('create folder structure', function() { + // + }); +}); From 14e51440858ca56e1e0e69add2ac4c61f4db3077 Mon Sep 17 00:00:00 2001 From: Stanley Sathler Date: Wed, 10 Oct 2018 00:20:47 -0300 Subject: [PATCH 4/5] Added test to test theme folder structure creation --- test/scripts/theme.js | 47 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/test/scripts/theme.js b/test/scripts/theme.js index 00ee4bad..295d61a9 100644 --- a/test/scripts/theme.js +++ b/test/scripts/theme.js @@ -1,28 +1,63 @@ 'use strict'; var should = require('chai').should(); // eslint-disable-line +var fs = require('fs'); +var os = require('os'); +var path = require('path'); +var rewire = require('rewire'); +var sinon = require('sinon'); var Context = require('../../lib/context'); describe('theme', function() { - let context; - let themeModule; + var context; + var themeModule; beforeEach(function() { context = new Context(); - themeModule = (require('../../lib/console/theme')); + themeModule = require('../../lib/console/theme'); }); it('throw error when folder already exists', function() { var params = { _: [] }; - themeModule + return themeModule .call(context, params) .catch(function(error) { error.message.should.contain('A theme name must be provided'); }); }); - it('create folder structure', function() { - // + it('create theme initial structure', function() { + var params = { _: ['my-hexo-theme'] }; + var themeModule = rewire('../../lib/console/theme'); + var mkdirSpy = sinon.spy(); + var writeFileSpy = sinon.spy(); + var fsMock = { + mkdirSync: mkdirSpy, + writeFileSync: writeFileSpy, + }; + + return themeModule + .__with__({ fs: Object.assign(fs, fsMock) }) + (function() { + return themeModule.call(context, params); + }) + .then(function() { + mkdirSpy.args.should.eql([ + [path.join(context.base_dir, 'my-hexo-theme')], + [path.join(context.base_dir, 'my-hexo-theme/languages')], + [path.join(context.base_dir, 'my-hexo-theme/layout')], + [path.join(context.base_dir, 'my-hexo-theme/scripts')], + [path.join(context.base_dir, 'my-hexo-theme/source')], + ]); + + writeFileSpy.args.should.eql([ + [path.join(context.base_dir, 'my-hexo-theme/config.yml'), ''], + [path.join(context.base_dir, 'my-hexo-theme/languages/.gitkeep'), ''], + [path.join(context.base_dir, 'my-hexo-theme/layout/.gitkeep'), ''], + [path.join(context.base_dir, 'my-hexo-theme/scripts/.gitkeep'), ''], + [path.join(context.base_dir, 'my-hexo-theme/source/.gitkeep'), ''], + ]); + }); }); }); From 76f1f85cd28d2dc694f345e23d3b2fea54156fc7 Mon Sep 17 00:00:00 2001 From: Stanley Sathler Date: Wed, 10 Oct 2018 00:47:38 -0300 Subject: [PATCH 5/5] Fixed ESLint errors --- lib/console/theme.js | 8 +++++--- test/scripts/theme.js | 15 +++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/console/theme.js b/lib/console/theme.js index 2da5389d..989b8f3b 100644 --- a/lib/console/theme.js +++ b/lib/console/theme.js @@ -26,16 +26,18 @@ function addFile(directoryPath, fileName) { function themeConsole(args) { var name = parseArguments(args).name; - if (!name) + if (!name) { return Promise.reject(new Error('A theme name must be provided')); + } var baseDirectory = this.base_dir; var themeDirectory = path.join(baseDirectory, name); - if (fs.existsSync(themeDirectory)) + if (fs.existsSync(themeDirectory)) { return Promise.reject( new Error('Seems you already have `' + name + '` in your directory') ); + } addFolder(themeDirectory); addFile(themeDirectory, 'config.yml'); @@ -47,6 +49,6 @@ function themeConsole(args) { }); return Promise.resolve(); -}; +} module.exports = themeConsole; diff --git a/test/scripts/theme.js b/test/scripts/theme.js index 295d61a9..9157e8cb 100644 --- a/test/scripts/theme.js +++ b/test/scripts/theme.js @@ -2,15 +2,13 @@ var should = require('chai').should(); // eslint-disable-line var fs = require('fs'); -var os = require('os'); var path = require('path'); var rewire = require('rewire'); var sinon = require('sinon'); var Context = require('../../lib/context'); describe('theme', function() { - var context; - var themeModule; + var context, themeModule; beforeEach(function() { context = new Context(); @@ -34,12 +32,13 @@ describe('theme', function() { var writeFileSpy = sinon.spy(); var fsMock = { mkdirSync: mkdirSpy, - writeFileSync: writeFileSpy, + writeFileSync: writeFileSpy }; return themeModule - .__with__({ fs: Object.assign(fs, fsMock) }) - (function() { + .__with__({ + fs: Object.assign(fs, fsMock) + })(function() { return themeModule.call(context, params); }) .then(function() { @@ -48,7 +47,7 @@ describe('theme', function() { [path.join(context.base_dir, 'my-hexo-theme/languages')], [path.join(context.base_dir, 'my-hexo-theme/layout')], [path.join(context.base_dir, 'my-hexo-theme/scripts')], - [path.join(context.base_dir, 'my-hexo-theme/source')], + [path.join(context.base_dir, 'my-hexo-theme/source')] ]); writeFileSpy.args.should.eql([ @@ -56,7 +55,7 @@ describe('theme', function() { [path.join(context.base_dir, 'my-hexo-theme/languages/.gitkeep'), ''], [path.join(context.base_dir, 'my-hexo-theme/layout/.gitkeep'), ''], [path.join(context.base_dir, 'my-hexo-theme/scripts/.gitkeep'), ''], - [path.join(context.base_dir, 'my-hexo-theme/source/.gitkeep'), ''], + [path.join(context.base_dir, 'my-hexo-theme/source/.gitkeep'), ''] ]); }); });