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..989b8f3b --- /dev/null +++ b/lib/console/theme.js @@ -0,0 +1,54 @@ +'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; + + 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') + ); + } + + 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; 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..9157e8cb --- /dev/null +++ b/test/scripts/theme.js @@ -0,0 +1,62 @@ +'use strict'; + +var should = require('chai').should(); // eslint-disable-line +var fs = require('fs'); +var path = require('path'); +var rewire = require('rewire'); +var sinon = require('sinon'); +var Context = require('../../lib/context'); + +describe('theme', function() { + var context, themeModule; + + beforeEach(function() { + context = new Context(); + themeModule = require('../../lib/console/theme'); + }); + + it('throw error when folder already exists', function() { + var params = { _: [] }; + + return themeModule + .call(context, params) + .catch(function(error) { + error.message.should.contain('A theme name must be provided'); + }); + }); + + 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'), ''] + ]); + }); + }); +});