import chalk from 'chalk';
import clear from 'clear';
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { title } from './common/common';
import Listr from 'listr';
import { generateRequirements } from './generate/generateRequirements';
import { createENVPy, createGitIgnore, createHTML, createMarkdown, createVSCodeSettings, createProcfile } from './tasks/createFiles';
import { createProjectDir, copyFiles } from './tasks/createStructure';
import { gitTasks } from './tasks/git';
import { installVirtualEnv, flaskApp, djangoApp } from './tasks/virtualenv';
const access = promisify(fs.access);
let errorToggle = false;
/**
* Main function to create a project
* @param {Object} options
*/
export async function createProject(options) {
options = {
...options,
targetDirectory: options.targetDirectory || process.cwd(),
};
const templateDir = path.resolve(__dirname, '../templates', options.template.name.toLowerCase());
const commonDir = path.resolve(__dirname, '../templates/common');
const backendDir = path.resolve(__dirname, '../templates/backend');
const frontendDir = path.resolve(__dirname, '../templates/frontend');
options.templateDirectory = templateDir;
options.commonDir = commonDir;
options.backendDir = backendDir;
options.frontendDir = frontendDir;
try {
await access(templateDir, fs.constants.R_OK);
await access(commonDir, fs.constants.R_OK);
await access(backendDir, fs.constants.R_OK);
await access(frontendDir, fs.constants.R_OK);
} catch (err) {
console.error('%s Invalid template name', chalk.red.bold('ERROR'));
process.exit(1);
}
const vsCodeTasks = new Listr([
{
title: `Creating ${options.name} Project`,
task: (ctx, task) => {
createProjectDir(options).catch((err) => {
if (err.code === 'EEXIST') {
options.error = true;
task.skip('Folder Already exists');
ctx.exists = true;
} else {
ctx.exists = false;
}
});
},
skip: () => options.gitpod,
},
{
title: `Copying Common files to ${options.name}`,
skip: (ctx) => ctx.exists,
task: () => copyFiles(options, 'common'),
enabled: () => !options.error,
},
{
title: `Creating Project files for ${options.name}`,
skip: (ctx) => ctx.exists,
task: () =>
//prettier-ignore
options.template.python ? copyFiles(options, "backend") : copyFiles(options, "frontend"),
enabled: () => !options.error,
},
{
title: `Copying Python settings ${options.name}`,
task: () => copyFiles(options, 'backend'),
skip: (ctx) =>
// prettier-ignore
ctx.exists || !options.template.python ? 'Not a Python Project 🚫🐍' : false,
enabled: () => options.template.python && !options.error,
},
{
title: `Copying template files to ${options.name}`,
task: () => copyFiles(options, 'templates'),
enabled: () => !options.error,
skip: (ctx) => ctx.exists,
},
{
title: 'Making Starting Templates',
task: () => createHTML(options),
enabled: () => !options.error,
skip: (ctx) => ctx.exists,
},
{
title: 'Creating README and TESTING.md 📢📑',
task: () => createMarkdown(options),
enabled: () => !options.error,
skip: (ctx) => ctx.exists,
},
{
title: 'Generating requirements.txt file',
task: () => generateRequirements(options),
skip: () =>
// prettier-ignore
options.gitpod || !options.template.python ? 'Not a Python Project 🚫🐍' : false,
enabled: () => !options.error,
},
{
title: 'Generating python env file',
task: () => createENVPy(options),
skip: () =>
// prettier-ignore
options.gitpod || !options.template.flask ? 'Not a Flask Project 🚫🐍' : false,
enabled: () => options.template.flask && !options.error,
},
{
title: 'Generating vscode settings',
task: (task) =>
createVSCodeSettings(options).catch((err) => {
task.skip(err.message);
}),
skip: (ctx) =>
// prettier-ignore
ctx.exists|| options.gitpod || !options.template.python ? 'Not a Python Project 🚫🐍' : false,
enabled: () => !options.error,
},
{
title: 'Configuring Procfile',
task: () => createProcfile(options),
enabled: () => (options.template.flask || options.template.django) && !options.error,
skip: (ctx) =>
// prettier-ignore
ctx.exists || options.gitpod,
},
{
title: 'Setting up git',
task: () => gitTasks(options),
enabled: () => options.git && !options.error,
skip: (ctx) => ctx.exists,
},
{
title: 'Setting up Virtual Enviroment',
task: () => installVirtualEnv(options),
enabled: () => options.createENV && !options.error,
skip: (ctx) => ctx.exists,
},
{
title: 'Setting Flask up',
task: () => flaskApp(),
enabled: () => options.template.flask && options.env && !options.error,
skip: (ctx) =>
// prettier-ignore
ctx.exists || !options.template.flask ? 'Not a Flask Project' : undefined || options.gitpod,
},
{
title: 'Setting Django up',
task: () => djangoApp(),
enabled: () => options.template.django && options.env && !options.error,
skip: (ctx) =>
// prettier-ignore
ctx.exists || !options.template.django ? 'Not a Django Project' : undefined || options.gitpod,
},
{
title: 'Configuring .gitignore',
task: () => createGitIgnore(options),
skip: (ctx) =>
// prettier-ignore
ctx.exists || !options.env ? 'No VirtualEnviroment created' : false || options.gitpod,
enabled: () => !options.error,
},
]);
if (!options.gitpod) {
await vsCodeTasks.run().catch(() => (errorToggle = true));
if (!errorToggle && !options.error) {
title(`${options.name}`, 'ANSI Shadow');
console.log('This tool was created by Eventyret');
console.log(`If you liked this tool please do say thank you in Slack or mention the tool in your Readme`);
return true;
}
if (options.error) {
clear();
title('Error', 'ANSI Shadow');
console.log(`${options.name} folder already exists`);
return false;
}
} else {
title('Oh noes!', 'ANSI Shadow');
console.log('Gitpod is not supported yet');
return false;
}
}