UNPKG

generator-data-science

Version:

A generator to set-up a standardized project structure for any Data Science project.

174 lines (151 loc) 5.46 kB
const Generator = require('yeoman-generator'); const chalk = require('chalk'); const yosay = require('yosay'); const fs = require('fs') const promisify = require('util').promisify module.exports = class extends Generator { initializing() { /* Initialization actions for the generator. Checks if the current directory is empty. */ this.log(yosay( 'Welcome to the ' + chalk.red('Future Facts Data Science') + ' generator!' )); // Check if working directory is empty, if not raise return promisify(fs.readdir)(this.destinationRoot()) .then((files) => { if (files.length > 0) { this.env.error( 'Directory is not empty, cannot scafold project here.' ) } }) } _cleanUpOnFail() { // TODO: Method to clean up } _validateAnswers(answers) { // Post processing of answers // We do not support R for the moment if (answers.language === 'R') { this.env.error(yosay( `R? Really? Are you sure? Currently I don't have any support for scafolding R projects. Feel free to create a PR.` )) this._cleanUpOnFail() } else if (answers.language === 'Python') { this.log(yosay( 'Great choice of language!' )) } return answers } _storeAnswers(answers) { this.answers = answers return answers } prompting() { return this.prompt([ { type: 'input', name: 'creator', message: 'Who are you?', validate: answer => answer.length > 3, store: true }, { type: 'input', name: 'projectName', message: 'What is the name of this project, no whitespaces allowed?', validate: answer => answer.length > 3 && ! /\s/.test(answer) }, { type: 'list', name: 'language', message: 'What language will you be working in?', choices: ['R', 'Python'] }, { type: 'checkbox', name: 'additionalModules', message: 'What additional tools would you like installed?', choices: ['jupyter'], when: answers => answers.language === 'Python' } ]).then(this._validateAnswers.bind(this)) .then(this._storeAnswers.bind(this)) } writing() { // Copy the environment file for construction of the // conda this.fs.copyTpl( this.templatePath('python_project/conda_envs/env.yml'), this.destinationPath('env.yml'), { envName: this.answers.projectName, jupyter: this.answers.additionalModules.includes('jupyter') } ) // Copy readme file this.fs.copyTpl( this.templatePath('python_project/README.md'), this.destinationPath('README.md'), { projectName: this.answers.projectName, creator: this.answers.creator } ) // Copy .gitignore this.fs.copyTpl( this.templatePath('python_project/.gitignore.template'), this.destinationPath('.gitignore'), ) // Create project directory structure this.fs.copyTpl( this.templatePath('python_project/.gitkeep'), this.destinationPath('data/.gitkeep'), ) this.fs.copyTpl( this.templatePath('python_project/.gitkeep'), this.destinationPath('notebooks/.gitkeep'), ) this.fs.copyTpl( this.templatePath('python_project/__init__.py'), this.destinationPath('lib/load/__init__.py'), ) this.fs.copyTpl( this.templatePath('python_project/__init__.py'), this.destinationPath('lib/transform/__init__.py'), ) this.fs.copyTpl( this.templatePath('python_project/__init__.py'), this.destinationPath('lib/model/__init__.py'), ) this.fs.copyTpl( this.templatePath('python_project/bootstrap.py'), this.destinationPath('lib/bootstrap.py'), ) } install() { // Setup conda environment let installConda = this.spawnCommand( 'conda', ['env', 'create', '--file', this.destinationPath('env.yml')] ); // Add a listener for the conda installer, clean up if it fails installConda.on('close', (code) => { if (code != 0) { this.env.error('Could not create conda environment'); this._cleanUpOnFail() } }) // Set up git for this project this.composeWith( require.resolve('generator-git-init/generators/app'), { commit: "Initial commit" } ) } };