import arg from 'arg';
import inquirer from 'inquirer';
import clear from 'clear';
import { title } from './common/common';
import { createProject } from './main';
/**
* Input taken directly from the user
* @param {String[]} rawArgs
*/
async function parseArgumentsIntoOptions(rawArgs) {
const args = arg(
{
'--name': String,
'--skip': Boolean,
'--git': Boolean,
'--clean': Boolean,
'--gitpod': Boolean,
'-n': '--name',
'-g': '--git',
'-p': '--gitpod',
'-s': '--skip',
'-c': '--clean',
},
{
argv: rawArgs.slice(2),
}
);
return {
name: args['--name'],
skipPrompts: args['--skip'] || false,
git: args['--git'] || false,
template: args._[0],
clean: args['--clean'] || false,
gitpod: args['--gitpod'] || false,
};
}
/**
*
* @param {Object} options
*/
async function promptForMissingOptions(options) {
const defaultTemplate = 'UCFD';
if (options.skipPrompts) {
return {
...options,
template: options.template.name || defaultTemplate,
clean: options.template || false,
};
}
const questions = [];
if (!options.name) {
questions.push({
type: 'input',
name: 'name',
message: 'What is the name of this amazing project: ',
validate: function (value) {
if (value.length) {
return true;
} else {
return 'Need to give your project a name';
}
},
});
}
if (!options.template) {
questions.push({
type: 'list',
name: 'template',
message: 'What milestone will you be working on?',
choices: [
{
name: 'User Centric Frontend (MS1)',
value: { name: 'frontend', python: false, django: false, flask: false, js: false },
},
{
name: 'Interactive Frontend (MS2)',
value: { name: 'frontend', python: false, django: false, flask: false, js: true },
},
{
name: 'Data Centric Development (MS3)',
value: { name: 'DCD', python: true, django: false, flask: true, js: true },
},
{
name: 'Full Stack Frameworks (MS4)',
value: { name: 'FSF', python: true, django: true, flask: false, js: true },
},
],
default: defaultTemplate,
});
}
if (!questions.gitpod) {
questions.push({
type: 'confirm',
name: 'gitpod',
message: 'Are you using Gitpod?',
default: false,
});
}
if (!options.git) {
questions.push({
type: 'confirm',
name: 'git',
message: 'Initialize a git repository?',
default: true,
});
}
const answers = await inquirer.prompt(questions);
return {
...options,
template: options.template || answers.template,
git: options.git || answers.git,
name: answers.name,
env: answers.env || false,
envName: answers.envName || 'env',
gitpod: answers.gitpod,
};
}
/**
* Checking if the user has created a virtual enviroment before
* @param {Object} options
*/
async function doesEnvExistForProject(options) {
const questions = [];
if (options.template.python && !options.gitpod) {
questions.push({
type: 'confirm',
name: 'env',
message: 'Have you created a virtual enviroment for your project',
default: false,
});
}
const answers = await inquirer.prompt(questions);
return {
...options,
env: answers.env,
};
}
/**
* Questions if the user wants us to create a virtual enviroment
* or if the user has one already what is the name of the folder.
* @param {Object} options
*/
async function envQuestions(options) {
const questions = [];
if (!options.env && options.template.python && !options.gitpod) {
questions.push({
type: 'confirm',
name: 'createENV',
message: 'Do you want us to create one for you?',
default: true,
});
}
if (options.env && !options.gitpod) {
questions.push({
type: 'input',
name: 'envName',
message: 'What is the name of the folder for your virtual enviroment',
validate: function (value) {
if (value.length) {
return true;
} else {
return 'We need to know your virtual enviroment folder name';
}
},
});
}
const answers = await inquirer.prompt(questions);
return {
...options,
envName: answers.envName,
createENV: answers.createENV,
};
}
/**
* Starting the main program
* @param {String[]} args
*/
export async function cli(args) {
clear();
title('Padawan', 'ANSI Shadow');
let options = parseArgumentsIntoOptions(args);
options = await promptForMissingOptions(options);
options = await doesEnvExistForProject(options);
options = await envQuestions(options);
await createProject(options);
}