Skip to content

Instantly share code, notes, and snippets.

@cliftonc
Created September 13, 2015 12:28
Show Gist options
  • Save cliftonc/46661fdd9583f0111234 to your computer and use it in GitHub Desktop.
Save cliftonc/46661fdd9583f0111234 to your computer and use it in GitHub Desktop.
Theme.js assuming using npm install of themese
'use strict';
import when from 'when';
import Path from 'path';
import _ from 'lodash';
import File from 'fs-extra';
import fs from 'fs';
import del from 'del';
import 'source-map-support/register';
import elegantSpinner from 'elegant-spinner';
import logUpdate from 'log-update';
let frame = elegantSpinner();
/**
* The class that installs themes.
* @class Theme
*/
class Theme {
constructor(options) {
let theme = this.locateTheme(options.theme);
this.options = {
theme: {
name: theme.theme,
path: theme.path,
target: {
path: options.target
}
},
template: {
path: options.template.path,
isEnabled: () => {
return !!options.template.path;
}
}
};
}
locateTheme(theme) {
const DEFAULT_THEME = 'doxx-theme-default';
const doxxBasePath = Path.resolve(__dirname, '..');
const projectBasePath = Path.resolve(__dirname, '../../..');
const doxxBaseModulePath = Path.join(doxxBasePath,
'node_modules',
theme);
const projectBaseModulePath = Path.join(projectBasePath,
'node_modules',
theme);
const defaultThemePath = Path.join(doxxBasePath,
'node_modules',
DEFAULT_THEME);
let exists = fs.existsSync(doxxBaseModulePath);
if (exists) {
console.log('EXISTS ' + doxxBaseModulePath);
return {
theme: theme,
path: doxxBaseModulePath
};
}
exists = fs.existsSync(projectBaseModulePath);
if (exists) {
console.log('EXISTS ' + projectBaseModulePath);
return {
theme: theme,
path: projectBaseModulePath
};
}
console.log('WARNING: theme "' +
theme +
'" not found, reverting to default.');
return {
theme: DEFAULT_THEME,
path: defaultThemePath
};
}
/**
* Installs the theme and its assets
* @return {Function} The promise
*/
copyAssets() {
let final = when.defer();
/**
* The commands to install the theme
* @type {object}
*/
let commands = {
showProgress: (command) => {
var count = 0;
while (count < 200) {
logUpdate('doxx: ' + frame() + ' ' + command);
count++;
}
},
/**
* Create necessary paths to
* process the commands
* @return {Function} The promise
*/
preProcess: () => {
let d = when.defer();
let theme = this.options.theme.name;
// Create short-hands for paths
// Sources
var src = {
theme: {
path: this.options.theme.path
}
};
// Destinations
var dest = {
theme: {
path: this.options.theme.target.path
}
};
// Assets dir
let assets = {
path: Path.join(src.theme.path, '/assets/')
};
// Template dir
let template = {
path: Path.join(src.theme.path, '/template/')
};
// The css dir within assets dir
_.extend(src, {
css: {
path: Path.join(assets.path, 'css/')
}
});
_.extend(dest, {
css: {
path: Path.join(dest.theme.path, 'css/')
}
});
// The js dir within assets dir
_.extend(src, {
js: {
path: Path.join(assets.path, 'js/')
}
});
_.extend(dest, {
js: {
path: Path.join(dest.theme.path, 'js/')
}
});
// The bower template dir within assets dir
_.extend(src, {
template
});
_.extend(dest, {
template: {
path: Path.join(dest.theme.path, 'template/')
}
});
d.resolve({
theme, src, dest
});
return d.promise;
},
/**
* Copies the css dir from the assets dir
* to the target dir
* @param {object} result The result
* @return {Function} The promise
*/
copyAssetCSS: (result) => {
let d = when.defer();
var {
src, dest
} = result;
File.copy(src.css.path, dest.css.path, {
clobber: true
}, error => {
if (error) d.reject(error);
else {
d.resolve(result);
}
});
return d.promise;
},
/**
* Copies the js dir from the assets dir
* to the target dir
* @param {object} result The result
* @return {Function} The promise
*/
copyAssetJS: (result) => {
let d = when.defer();
var {
src, dest
} = result;
File.copy(src.js.path, dest.js.path, {
clobber: true
}, error => {
if (error) d.reject(error);
else {
d.resolve(result);
}
});
return d.promise;
},
/**
* Copies the template dir from the assets dir
* to the target dir
* @param {object} result The result
* @return {Function} The promise
*/
copyTemplate: (result) => {
let d = when.defer();
var {
src, dest
} = result;
File.copy(src.template.path, dest.template.path, {
clobber: true
}, error => {
if (error) d.reject(error);
else {
d.resolve(result);
}
});
return d.promise;
},
/**
* Reads the template and strigifies it.
* @param {object} result The result
* @return {Function} The promise
*/
stringifyTemplate: (result) => {
let d = when.defer();
var {
dest, src, theme
} = result;
let file = dest.template.path + 'index.jade';
File.readFile(file, (error, data) => {
if (error) d.reject(error);
else d.resolve({
dest, src, theme,
template: data.toString()
});
});
return d.promise;
},
/**
* Removes the template dir from
* the target dir
* @param {object} result The result
* @return {Function} The promise
*/
deleteTemplateDir: (result) => {
let d = when.defer();
var {
dest
} = result;
del([dest.template.path]).then(() => {
d.resolve(result);
});
return d.promise;
}
};
// Check if the template is enabled (legacy)
if (this.options.template.isEnabled()) {
final.resolve({
template: File.readFileSync(
Path.resolve(__dirname,
this.options.template.path)).toString()
});
} else {
((notify) => {
// Preprocess the commands
return commands.preProcess()
.tap(() => {
notify('Preparing to copy theme assets');
})
// Copy css dir files
.then(commands.copyAssetCSS)
.tap(() => {
return notify('Copying css directory');
})
// Copy the js dir & files
.then(commands.copyAssetJS)
.tap(() => {
return notify('Copying js directory');
})
// Copy the template dir & file
.then(commands.copyTemplate)
.tap(() => {
return notify('Copying template directory');
})
// Convert the template to a string
.then(commands.stringifyTemplate)
.tap(() => {
return notify('Rendering the template');
})
// Delete the template dir
.then(commands.deleteTemplateDir)
.tap(() => {
return notify('Removing the template directory');
})
.then(final.resolve);
})(commands.showProgress);
}
return final.promise;
}
}
export default (theme) => {
return new Theme(theme);
};
@cliftonc
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment