myt/myvc-version.js

189 lines
4.5 KiB
JavaScript

const MyVC = require('./myvc');
const fs = require('fs-extra');
/**
* Creates a new version.
*/
class Version {
mainOpt = 'name';
get localOpts() {
return {
operand: 'name',
name: {
name: 'n'
},
default: {
remote: 'production'
}
};
}
async run(myvc, opts) {
const verionsDir =`${opts.workspace}/versions`;
let versionDir;
let versionName = opts.name;
// Fetch last version number
const conn = await myvc.dbConnect();
const version = await myvc.fetchDbVersion() || {};
try {
await conn.query('START TRANSACTION');
const [[row]] = await conn.query(
`SELECT lastNumber FROM version WHERE code = ? FOR UPDATE`,
[opts.code]
);
const lastVersion = row && row.lastNumber;
console.log(
`Database information:`
+ `\n -> Version: ${version.number}`
+ `\n -> Last version: ${lastVersion}`
);
let newVersion = lastVersion ? parseInt(lastVersion) + 1 : 1;
newVersion = String(newVersion).padStart(opts.versionDigits, '0');
// Get version name
const versionNames = new Set();
const versionDirs = await fs.readdir(verionsDir);
for (const versionNameDir of versionDirs) {
const split = versionNameDir.split('-');
const versionName = split[1];
if (versionName) versionNames.add(versionName);
}
if (!versionName) {
let attempts;
const maxAttempts = 1000;
for (attempts = 0; attempts < maxAttempts; attempts++) {
versionName = randomName();
if (!versionNames.has(versionName)) break;
}
if (attempts === maxAttempts)
throw new Error(`Cannot create a unique version name after ${attempts} attempts`);
} else {
const isNameValid = typeof versionName === 'string'
&& /^[a-zA-Z0-9]+$/.test(versionName);
if (!isNameValid)
throw new Error('Version name can only contain letters or numbers');
if (versionNames.has(versionName))
throw new Error('Version with same name already exists');
}
// Create version
const versionFolder = `${newVersion}-${versionName}`;
versionDir = `${verionsDir}/${versionFolder}`;
await conn.query(
`UPDATE version SET lastNumber = ? WHERE code = ?`,
[newVersion, opts.code]
);
await fs.mkdir(versionDir);
console.log(`New version folder created: ${versionFolder}`);
await conn.query('COMMIT');
} catch (err) {
await conn.query('ROLLBACK');
if (versionDir && await fs.pathExists(versionDir))
await fs.remove(versionDir, {recursive: true});
throw err;
}
}
}
function randomName() {
const color = random(colors);
let plant = random(plants);
plant = plant.charAt(0).toUpperCase() + plant.slice(1);
return color + plant;
}
function random(array) {
return array[Math.floor(Math.random() * array.length)];
}
const colors = [
'aqua',
'azure',
'black',
'blue',
'bronze',
'brown',
'chocolate',
'crimson',
'golden',
'gray',
'green',
'lime',
'maroon',
'navy',
'orange',
'pink',
'purple',
'red',
'salmon',
'silver',
'teal',
'turquoise',
'yellow',
'wheat',
'white'
];
const plants = [
'anthurium',
'aralia',
'arborvitae',
'asparagus',
'aspidistra',
'bamboo',
'birch',
'carnation',
'camellia',
'cataractarum',
'chico',
'chrysanthemum',
'cordyline',
'cyca',
'cymbidium',
'dendro',
'dracena',
'erica',
'eucalyptus',
'fern',
'galax',
'gerbera',
'hydrangea',
'ivy',
'laurel',
'lilium',
'mastic',
'medeola',
'monstera',
'moss',
'oak',
'orchid',
'palmetto',
'paniculata',
'phormium',
'raphis',
'roebelini',
'rose',
'ruscus',
'salal',
'tulip'
];
module.exports = Version;
if (require.main === module)
new MyVC().run(Version);