move backup files/dirs into temp dir to prevent size mismatch error
This commit is contained in:
parent
62a8da129a
commit
00b886740d
226
index.js
226
index.js
|
@ -8,7 +8,9 @@ const ora = require('ora');
|
||||||
const BackupArchive = require('./archiver');
|
const BackupArchive = require('./archiver');
|
||||||
const mysqldump = require('mysqldump');
|
const mysqldump = require('mysqldump');
|
||||||
|
|
||||||
const CURRENT_FOLDER = __dirname.startsWith('/snapshot') ? path.dirname(process.env._) : __dirname;
|
const CURRENT_FOLDER = __dirname.startsWith('/snapshot') ?
|
||||||
|
path.dirname(process.env._) :
|
||||||
|
__dirname;
|
||||||
const TASKS_DIRECTORY = path.join(CURRENT_FOLDER, 'tasks');
|
const TASKS_DIRECTORY = path.join(CURRENT_FOLDER, 'tasks');
|
||||||
const BACKUPS_DIRECTORY = path.join(CURRENT_FOLDER, 'backups');
|
const BACKUPS_DIRECTORY = path.join(CURRENT_FOLDER, 'backups');
|
||||||
const TEMP_DIR = path.join(CURRENT_FOLDER, '.temp');
|
const TEMP_DIR = path.join(CURRENT_FOLDER, '.temp');
|
||||||
|
@ -19,9 +21,10 @@ const run = async (programArgs) => {
|
||||||
case 'exit':
|
case 'exit':
|
||||||
logger.info('exiting...');
|
logger.info('exiting...');
|
||||||
break;
|
break;
|
||||||
case 'createcrontab': {
|
case 'createcrontab':
|
||||||
logger.info('not added yet.');
|
{
|
||||||
}
|
logger.info('not added yet.');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'backup': {
|
case 'backup': {
|
||||||
let taskName = programArgs.filename ? programArgs.filename + '.json' : '';
|
let taskName = programArgs.filename ? programArgs.filename + '.json' : '';
|
||||||
|
@ -44,7 +47,10 @@ const run = async (programArgs) => {
|
||||||
name: 'filename',
|
name: 'filename',
|
||||||
message: 'Select a Task file to use',
|
message: 'Select a Task file to use',
|
||||||
choices: AUTO_COMPLETE_ARRAY,
|
choices: AUTO_COMPLETE_ARRAY,
|
||||||
validate: (value) => FILES.includes(value + '.json') ? true : 'Task file does not exist, please specify a valid task file.',
|
validate: (value) =>
|
||||||
|
FILES.includes(value + '.json') ?
|
||||||
|
true :
|
||||||
|
'Task file does not exist, please specify a valid task file.',
|
||||||
});
|
});
|
||||||
|
|
||||||
taskName = PROMPT.filename;
|
taskName = PROMPT.filename;
|
||||||
|
@ -59,25 +65,57 @@ const run = async (programArgs) => {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TASK_FILE_CONTENTS = JSON.parse(fs.readFileSync(path.join(TASKS_DIRECTORY, taskName), 'utf8'));
|
const TASK_FILE_CONTENTS = JSON.parse(
|
||||||
|
fs.readFileSync(path.join(TASKS_DIRECTORY, taskName), 'utf8'),
|
||||||
|
);
|
||||||
const VALID_TASK_FILE = validate(TASK_FILE_CONTENTS);
|
const VALID_TASK_FILE = validate(TASK_FILE_CONTENTS);
|
||||||
if (VALID_TASK_FILE.length > 0) {
|
if (VALID_TASK_FILE.length > 0) {
|
||||||
logger.error('task file is not valid, ' + VALID_TASK_FILE.length + ' errors found');
|
logger.error(
|
||||||
logger.info('check with \'' + process.argv0 + ' checkTaskConf ' + path.parse(taskName).name + '\'');
|
'task file is not valid, ' + VALID_TASK_FILE.length + ' errors found',
|
||||||
|
);
|
||||||
|
logger.info(
|
||||||
|
'check with \'' +
|
||||||
|
process.argv0 +
|
||||||
|
' checkTaskConf ' +
|
||||||
|
path.parse(taskName).name +
|
||||||
|
'\'',
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
logger.success('task file is valid');
|
logger.success('task file is valid');
|
||||||
const TIMER = new (require('./timer'))().startTimer();
|
const TIMER = new (require('./timer'))().startTimer();
|
||||||
const SPINNER = ora('initialization...').start();
|
const SPINNER = ora('preparing backup... please wait.').start();
|
||||||
if (!fs.existsSync(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name))) {
|
|
||||||
await fs.promises.mkdir(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name));
|
const FILE_PATHS = [];
|
||||||
|
const fsExtra = require('fs-extra');
|
||||||
|
|
||||||
|
await Promise.all(TASK_FILE_CONTENTS.filesystem.targets.map(async (file) => {
|
||||||
|
if (fs.existsSync(file)) {
|
||||||
|
const newPath = path.join(TEMP_DIR, path.parse(file).name);
|
||||||
|
FILE_PATHS.push(newPath);
|
||||||
|
await fsExtra.copySync(file, newPath);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (
|
||||||
|
!fs.existsSync(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name))
|
||||||
|
) {
|
||||||
|
await fs.promises.mkdir(
|
||||||
|
path.join(BACKUPS_DIRECTORY, path.parse(taskName).name),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (TASK_FILE_CONTENTS.vacuum.enabled) {
|
if (TASK_FILE_CONTENTS.vacuum.enabled) {
|
||||||
SPINNER.text = 'cleaning up old backups...';
|
SPINNER.text = 'cleaning up old backups...';
|
||||||
const ALL_FILES = fs.readdirSync(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name));
|
const ALL_FILES = fs.readdirSync(
|
||||||
|
path.join(BACKUPS_DIRECTORY, path.parse(taskName).name),
|
||||||
|
);
|
||||||
const CURRENT_DATE = Date.now();
|
const CURRENT_DATE = Date.now();
|
||||||
for (const FILE of ALL_FILES) {
|
for (const FILE of ALL_FILES) {
|
||||||
const FILE_DATE = new Date(fs.statSync(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name, FILE)).birthtime).getTime();
|
const FILE_DATE = new Date(
|
||||||
|
fs.statSync(
|
||||||
|
path.join(BACKUPS_DIRECTORY, path.parse(taskName).name, FILE),
|
||||||
|
).birthtime,
|
||||||
|
).getTime();
|
||||||
let timeAdd = 0;
|
let timeAdd = 0;
|
||||||
switch (TASK_FILE_CONTENTS.vacuum.unit) {
|
switch (TASK_FILE_CONTENTS.vacuum.unit) {
|
||||||
case 'DAYS':
|
case 'DAYS':
|
||||||
|
@ -92,22 +130,34 @@ const run = async (programArgs) => {
|
||||||
}
|
}
|
||||||
const DELETE_DATE = new Date(FILE_DATE + timeAdd);
|
const DELETE_DATE = new Date(FILE_DATE + timeAdd);
|
||||||
if (DELETE_DATE.getTime() < CURRENT_DATE) {
|
if (DELETE_DATE.getTime() < CURRENT_DATE) {
|
||||||
await fs.unlinkSync(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name, FILE));
|
await fs.unlinkSync(
|
||||||
|
path.join(BACKUPS_DIRECTORY, path.parse(taskName).name, FILE),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const UNREPLACED_FILENAME = TASK_FILE_CONTENTS.general.outputFile;
|
const UNREPLACED_FILENAME = TASK_FILE_CONTENTS.general.outputFile;
|
||||||
const REPLACED_FILENAME = UNREPLACED_FILENAME.replace('{date}', require('moment')().format(TASK_FILE_CONTENTS.general.dateFormat))
|
const REPLACED_FILENAME = UNREPLACED_FILENAME.replace(
|
||||||
.replace('{taskName}', path.parse(taskName).name);
|
'{date}',
|
||||||
|
require('moment')().format(TASK_FILE_CONTENTS.general.dateFormat),
|
||||||
|
).replace('{taskName}', path.parse(taskName).name);
|
||||||
|
|
||||||
const DB_FILE = path.join(TEMP_DIR, require('crypto').randomBytes(16).toString('hex') + '.sql');
|
const DB_FILE = path.join(
|
||||||
const ARCHIVE = new BackupArchive(path.join(BACKUPS_DIRECTORY, path.parse(taskName).name,
|
TEMP_DIR,
|
||||||
REPLACED_FILENAME + '.tar.gz'),
|
require('crypto').randomBytes(16).toString('hex') + '.sql',
|
||||||
TASK_FILE_CONTENTS.filesystem.targets,
|
);
|
||||||
TASK_FILE_CONTENTS.general.gzip,
|
const ARCHIVE = new BackupArchive(
|
||||||
TASK_FILE_CONTENTS.general.gzipLevel);
|
path.join(
|
||||||
|
BACKUPS_DIRECTORY,
|
||||||
|
path.parse(taskName).name,
|
||||||
|
REPLACED_FILENAME + '.tar.gz',
|
||||||
|
),
|
||||||
|
FILE_PATHS,
|
||||||
|
TASK_FILE_CONTENTS.general.gzip,
|
||||||
|
TASK_FILE_CONTENTS.general.gzipLevel,
|
||||||
|
);
|
||||||
|
|
||||||
ARCHIVE.eventEmitter.on('progress', (progressInfo) => {
|
ARCHIVE.eventEmitter.on('progress', (progressInfo) => {
|
||||||
const TOTAL = ARCHIVE.totalFiles;
|
const TOTAL = ARCHIVE.totalFiles;
|
||||||
|
@ -117,10 +167,12 @@ const run = async (programArgs) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
ARCHIVE.eventEmitter.on('finish', async () => {
|
ARCHIVE.eventEmitter.on('finish', async () => {
|
||||||
if (TASK_FILE_CONTENTS.mysql.enabled) {
|
SPINNER.text = 'Cleaning up temporary files...';
|
||||||
if (DB_FILE !== undefined && fs.existsSync(DB_FILE)) {
|
if (fs.existsSync(DB_FILE)) {
|
||||||
await fs.unlinkSync(DB_FILE);
|
await fs.unlinkSync(DB_FILE);
|
||||||
}
|
}
|
||||||
|
for (const FILE of FILE_PATHS) {
|
||||||
|
await fsExtra.removeSync(FILE);
|
||||||
}
|
}
|
||||||
SPINNER.succeed('backup complete, took ' + TIMER.endTimer());
|
SPINNER.succeed('backup complete, took ' + TIMER.endTimer());
|
||||||
});
|
});
|
||||||
|
@ -178,7 +230,10 @@ const run = async (programArgs) => {
|
||||||
name: 'filename',
|
name: 'filename',
|
||||||
message: 'Select a Task file to check',
|
message: 'Select a Task file to check',
|
||||||
choices: AUTO_COMPLETE_ARRAY,
|
choices: AUTO_COMPLETE_ARRAY,
|
||||||
validate: (value) => FILES.includes(value + '.json') ? true : 'Task file does not exist, please specify a valid task file.',
|
validate: (value) =>
|
||||||
|
FILES.includes(value + '.json') ?
|
||||||
|
true :
|
||||||
|
'Task file does not exist, please specify a valid task file.',
|
||||||
});
|
});
|
||||||
|
|
||||||
taskName = PROMPT.filename;
|
taskName = PROMPT.filename;
|
||||||
|
@ -198,7 +253,11 @@ const run = async (programArgs) => {
|
||||||
|
|
||||||
const VALIDATION_ERRORS = validate(TASK_FILE_TO_CHECK);
|
const VALIDATION_ERRORS = validate(TASK_FILE_TO_CHECK);
|
||||||
if (VALIDATION_ERRORS.length > 0) {
|
if (VALIDATION_ERRORS.length > 0) {
|
||||||
logger.error('task file is not valid, ' + VALIDATION_ERRORS.length + ' errors found');
|
logger.error(
|
||||||
|
'task file is not valid, ' +
|
||||||
|
VALIDATION_ERRORS.length +
|
||||||
|
' errors found',
|
||||||
|
);
|
||||||
for (const ERROR of VALIDATION_ERRORS) logger.error(ERROR);
|
for (const ERROR of VALIDATION_ERRORS) logger.error(ERROR);
|
||||||
} else {
|
} else {
|
||||||
logger.success('Task file is valid!');
|
logger.success('Task file is valid!');
|
||||||
|
@ -214,7 +273,10 @@ const run = async (programArgs) => {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'filename',
|
name: 'filename',
|
||||||
message: 'Define a name for the new task file',
|
message: 'Define a name for the new task file',
|
||||||
validate: (value) => value.length <= 0 || value == '' ? 'Please specify a valid file name' : true,
|
validate: (value) =>
|
||||||
|
value.length <= 0 || value == '' ?
|
||||||
|
'Please specify a valid file name' :
|
||||||
|
true,
|
||||||
});
|
});
|
||||||
|
|
||||||
taskName = PROMPT.filename;
|
taskName = PROMPT.filename;
|
||||||
|
@ -224,7 +286,8 @@ const run = async (programArgs) => {
|
||||||
const PROMPT_2 = await prompts({
|
const PROMPT_2 = await prompts({
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
name: 'overwrite',
|
name: 'overwrite',
|
||||||
message: 'A task file with the same name already exists. Do you want to overwrite it?',
|
message:
|
||||||
|
'A task file with the same name already exists. Do you want to overwrite it?',
|
||||||
active: 'yes',
|
active: 'yes',
|
||||||
inactive: 'no',
|
inactive: 'no',
|
||||||
initial: false,
|
initial: false,
|
||||||
|
@ -244,38 +307,37 @@ const run = async (programArgs) => {
|
||||||
const TASK_FILE_PATH = path.join(TASKS_DIRECTORY, taskName + '.json');
|
const TASK_FILE_PATH = path.join(TASKS_DIRECTORY, taskName + '.json');
|
||||||
|
|
||||||
const TASK_CONFIG = {
|
const TASK_CONFIG = {
|
||||||
'general': {
|
general: {
|
||||||
'dateFormat': 'yyyy-MM-DD HH-mm-ss',
|
dateFormat: 'yyyy-MM-DD HH-mm-ss',
|
||||||
'outputFile': '{date} - {taskName}',
|
outputFile: '{date} - {taskName}',
|
||||||
'gzip': true,
|
gzip: true,
|
||||||
'gzipLevel': 6,
|
gzipLevel: 6,
|
||||||
},
|
},
|
||||||
'vacuum': {
|
vacuum: {
|
||||||
'enabled': true,
|
enabled: true,
|
||||||
'unit': 'DAYS',
|
unit: 'DAYS',
|
||||||
'time': 7,
|
time: 7,
|
||||||
},
|
},
|
||||||
'mysql': {
|
mysql: {
|
||||||
'enabled': true,
|
enabled: true,
|
||||||
'host': 'localhost',
|
host: 'localhost',
|
||||||
'port': 3306,
|
port: 3306,
|
||||||
'user': '',
|
user: '',
|
||||||
'password': '',
|
password: '',
|
||||||
'database': '',
|
database: '',
|
||||||
},
|
},
|
||||||
'filesystem': {
|
filesystem: {
|
||||||
'enabled': true,
|
enabled: true,
|
||||||
'targets': [
|
targets: ['/home/magento/', '/home/test/testfile.txt'],
|
||||||
'/home/magento/',
|
|
||||||
'/home/test/testfile.txt',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const SAVE_FILE = fs.createWriteStream(TASK_FILE_PATH);
|
const SAVE_FILE = fs.createWriteStream(TASK_FILE_PATH);
|
||||||
SAVE_FILE.write(JSON.stringify(TASK_CONFIG, null, 4));
|
SAVE_FILE.write(JSON.stringify(TASK_CONFIG, null, 4));
|
||||||
SAVE_FILE.end();
|
SAVE_FILE.end();
|
||||||
logger.success('Task file "' + path.basename(TASK_FILE_PATH) + '" saved successfully');
|
logger.success(
|
||||||
|
'Task file "' + path.basename(TASK_FILE_PATH) + '" saved successfully',
|
||||||
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
}
|
}
|
||||||
|
@ -292,27 +354,39 @@ const validate = (taskConfig) => {
|
||||||
const ERRORS = [];
|
const ERRORS = [];
|
||||||
|
|
||||||
if (taskConfig.general && typeof taskConfig.general === 'object') {
|
if (taskConfig.general && typeof taskConfig.general === 'object') {
|
||||||
if (taskConfig.general.dateFormat && typeof taskConfig.general.dateFormat === 'string') {
|
if (
|
||||||
|
taskConfig.general.dateFormat &&
|
||||||
|
typeof taskConfig.general.dateFormat === 'string'
|
||||||
|
) {
|
||||||
const DATE_FORMAT = taskConfig.general.dateFormat;
|
const DATE_FORMAT = taskConfig.general.dateFormat;
|
||||||
const DATE_FORMAT_REGEX = /d{1,4}|D{3,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|W{1,2}|[LlopSZN]|"[^"]*"|'[^']*'/g;
|
const DATE_FORMAT_REGEX =
|
||||||
|
/d{1,4}|D{3,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|W{1,2}|[LlopSZN]|"[^"]*"|'[^']*'/g;
|
||||||
if (!DATE_FORMAT_REGEX.test(DATE_FORMAT)) {
|
if (!DATE_FORMAT_REGEX.test(DATE_FORMAT)) {
|
||||||
ERRORS.push('general.dateFormat is not a valid date format');
|
ERRORS.push('general.dateFormat is not a valid date format');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERRORS.push('general.dateFormat is not defined or is not a string');
|
ERRORS.push('general.dateFormat is not defined or is not a string');
|
||||||
}
|
}
|
||||||
if (taskConfig.general.outputFile && typeof taskConfig.general.outputFile === 'string') {
|
if (
|
||||||
|
taskConfig.general.outputFile &&
|
||||||
|
typeof taskConfig.general.outputFile === 'string'
|
||||||
|
) {
|
||||||
const OUTPUT_FILE = taskConfig.general.outputFile;
|
const OUTPUT_FILE = taskConfig.general.outputFile;
|
||||||
const OUTPUT_FILE_REGEX = /^([^.]+)$/g;
|
const OUTPUT_FILE_REGEX = /^([^.]+)$/g;
|
||||||
if (!OUTPUT_FILE_REGEX.test(OUTPUT_FILE)) {
|
if (!OUTPUT_FILE_REGEX.test(OUTPUT_FILE)) {
|
||||||
ERRORS.push('general.outputFile is not a valid output file name, maybe you added a file extension?');
|
ERRORS.push(
|
||||||
|
'general.outputFile is not a valid output file name, maybe you added a file extension?',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERRORS.push('general.outputFile is not defined or is not a string');
|
ERRORS.push('general.outputFile is not defined or is not a string');
|
||||||
}
|
}
|
||||||
if (typeof taskConfig.general.gzip === 'boolean') {
|
if (typeof taskConfig.general.gzip === 'boolean') {
|
||||||
if (taskConfig.general.gzip) {
|
if (taskConfig.general.gzip) {
|
||||||
if (!taskConfig.general.gzipLevel && typeof taskConfig.general.gzipLevel !== 'number') {
|
if (
|
||||||
|
!taskConfig.general.gzipLevel &&
|
||||||
|
typeof taskConfig.general.gzipLevel !== 'number'
|
||||||
|
) {
|
||||||
ERRORS.push('general.gzipLevel is not defined or is not a number');
|
ERRORS.push('general.gzipLevel is not defined or is not a number');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,19 +404,29 @@ const validate = (taskConfig) => {
|
||||||
if (typeof taskConfig.vacuum.enabled !== 'boolean') {
|
if (typeof taskConfig.vacuum.enabled !== 'boolean') {
|
||||||
ERRORS.push('vacuum.enabled is not defined or is not a boolean');
|
ERRORS.push('vacuum.enabled is not defined or is not a boolean');
|
||||||
} else if (taskConfig.vacuum.enabled) {
|
} else if (taskConfig.vacuum.enabled) {
|
||||||
if (taskConfig.vacuum.unit && typeof taskConfig.vacuum.unit === 'string') {
|
if (
|
||||||
|
taskConfig.vacuum.unit &&
|
||||||
|
typeof taskConfig.vacuum.unit === 'string'
|
||||||
|
) {
|
||||||
const UNIT = taskConfig.vacuum.unit;
|
const UNIT = taskConfig.vacuum.unit;
|
||||||
const UNIT_REGEX = /^(DAYS|HOURS|MINUTES)$/g;
|
const UNIT_REGEX = /^(DAYS|HOURS|MINUTES)$/g;
|
||||||
if (!UNIT_REGEX.test(UNIT)) {
|
if (!UNIT_REGEX.test(UNIT)) {
|
||||||
ERRORS.push('vacuum.unit is not a valid unit, please use DAYS, HOURS or MINUTES');
|
ERRORS.push(
|
||||||
|
'vacuum.unit is not a valid unit, please use DAYS, HOURS or MINUTES',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERRORS.push('vacuum.unit is not defined or is not a string');
|
ERRORS.push('vacuum.unit is not defined or is not a string');
|
||||||
}
|
}
|
||||||
if (taskConfig.vacuum.time && typeof taskConfig.vacuum.time === 'number') {
|
if (
|
||||||
|
taskConfig.vacuum.time &&
|
||||||
|
typeof taskConfig.vacuum.time === 'number'
|
||||||
|
) {
|
||||||
const TIME = taskConfig.vacuum.time;
|
const TIME = taskConfig.vacuum.time;
|
||||||
if (TIME < 1) {
|
if (TIME < 1) {
|
||||||
ERRORS.push('vacuum.time is not a valid time, please use a number greater than 0');
|
ERRORS.push(
|
||||||
|
'vacuum.time is not a valid time, please use a number greater than 0',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERRORS.push('vacuum.time is not defined or is not a number');
|
ERRORS.push('vacuum.time is not defined or is not a number');
|
||||||
|
@ -371,7 +455,10 @@ const validate = (taskConfig) => {
|
||||||
if (typeof taskConfig.mysql.password !== 'string') {
|
if (typeof taskConfig.mysql.password !== 'string') {
|
||||||
ERRORS.push('mysql.password is not defined or is not a string');
|
ERRORS.push('mysql.password is not defined or is not a string');
|
||||||
}
|
}
|
||||||
if (!taskConfig.mysql.database || typeof taskConfig.mysql.database !== 'string') {
|
if (
|
||||||
|
!taskConfig.mysql.database ||
|
||||||
|
typeof taskConfig.mysql.database !== 'string'
|
||||||
|
) {
|
||||||
ERRORS.push('mysql.database is not defined or is not a string');
|
ERRORS.push('mysql.database is not defined or is not a string');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,14 +475,19 @@ const validate = (taskConfig) => {
|
||||||
if (typeof taskConfig.filesystem.enabled !== 'boolean') {
|
if (typeof taskConfig.filesystem.enabled !== 'boolean') {
|
||||||
ERRORS.push('filesystem.enabled is not defined or is not a boolean');
|
ERRORS.push('filesystem.enabled is not defined or is not a boolean');
|
||||||
} else if (taskConfig.filesystem.enabled) {
|
} else if (taskConfig.filesystem.enabled) {
|
||||||
if (taskConfig.filesystem.targets && typeof taskConfig.filesystem.targets === 'object') {
|
if (
|
||||||
|
taskConfig.filesystem.targets &&
|
||||||
|
typeof taskConfig.filesystem.targets === 'object'
|
||||||
|
) {
|
||||||
const TARGETS = taskConfig.filesystem.targets;
|
const TARGETS = taskConfig.filesystem.targets;
|
||||||
if (TARGETS.length < 1) {
|
if (TARGETS.length < 1) {
|
||||||
ERRORS.push('filesystem.targets is not defined or is not an array');
|
ERRORS.push('filesystem.targets is not defined or is not an array');
|
||||||
} else {
|
} else {
|
||||||
for (const target of TARGETS) {
|
for (const target of TARGETS) {
|
||||||
if (!target || typeof target !== 'string') {
|
if (!target || typeof target !== 'string') {
|
||||||
ERRORS.push('filesystem.targets[] is not defined or is not a valid path');
|
ERRORS.push(
|
||||||
|
'filesystem.targets[] is not defined or is not a valid path',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +526,8 @@ const cli = async (forcePrompt) => {
|
||||||
const PROMPT = await prompts({
|
const PROMPT = await prompts({
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
name: 'createTask',
|
name: 'createTask',
|
||||||
message: 'This is the first time you run this script, do you want to create a new task?',
|
message:
|
||||||
|
'This is the first time you run this script, do you want to create a new task?',
|
||||||
active: 'yes',
|
active: 'yes',
|
||||||
inactive: 'no',
|
inactive: 'no',
|
||||||
initial: false,
|
initial: false,
|
||||||
|
@ -474,4 +567,3 @@ const cli = async (forcePrompt) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
cli(false);
|
cli(false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user