@adinsure-ops/ops-cli 4.0.0-rc6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOGS.md +55 -0
- package/LICENSE +1 -0
- package/README.md +576 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/lib/command.base.d.ts +17 -0
- package/lib/command.base.jira.d.ts +11 -0
- package/lib/command.base.jira.js +37 -0
- package/lib/command.base.js +73 -0
- package/lib/commands/doctor.d.ts +54 -0
- package/lib/commands/doctor.js +311 -0
- package/lib/commands/download/client.d.ts +18 -0
- package/lib/commands/download/client.js +72 -0
- package/lib/commands/download/identity-server.d.ts +18 -0
- package/lib/commands/download/identity-server.js +72 -0
- package/lib/commands/download/platform.d.ts +18 -0
- package/lib/commands/download/platform.js +72 -0
- package/lib/commands/download/scheduler.d.ts +18 -0
- package/lib/commands/download/scheduler.js +72 -0
- package/lib/commands/download/server.d.ts +18 -0
- package/lib/commands/download/server.js +72 -0
- package/lib/commands/download/studio.d.ts +20 -0
- package/lib/commands/download/studio.js +89 -0
- package/lib/commands/gitlab/next-nightly-tag.d.ts +30 -0
- package/lib/commands/gitlab/next-nightly-tag.js +171 -0
- package/lib/commands/jira/issue.d.ts +17 -0
- package/lib/commands/jira/issue.js +31 -0
- package/lib/commands/jira/labels.d.ts +22 -0
- package/lib/commands/jira/labels.js +70 -0
- package/lib/commands/log/add.d.ts +17 -0
- package/lib/commands/log/add.js +107 -0
- package/lib/commands/log/generate.d.ts +22 -0
- package/lib/commands/log/generate.js +155 -0
- package/lib/commands/log/validate.d.ts +11 -0
- package/lib/commands/log/validate.js +58 -0
- package/lib/commands/login.d.ts +23 -0
- package/lib/commands/login.js +144 -0
- package/lib/commands/npm/check.publish.d.ts +17 -0
- package/lib/commands/npm/check.publish.js +78 -0
- package/lib/commands/npm/publish.d.ts +23 -0
- package/lib/commands/npm/publish.js +163 -0
- package/lib/commands/prepare-content.d.ts +29 -0
- package/lib/commands/prepare-content.js +386 -0
- package/lib/commands/sql.d.ts +24 -0
- package/lib/commands/sql.js +147 -0
- package/lib/commands/translate.d.ts +37 -0
- package/lib/commands/translate.js +149 -0
- package/lib/commands/version.d.ts +48 -0
- package/lib/commands/version.js +267 -0
- package/lib/config.d.ts +7 -0
- package/lib/config.js +9 -0
- package/lib/hooks/init/version-override.d.ts +2 -0
- package/lib/hooks/init/version-override.js +15 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -0
- package/lib/lib/command.d.ts +9 -0
- package/lib/lib/command.js +71 -0
- package/lib/lib/npm.d.ts +15 -0
- package/lib/lib/npm.js +79 -0
- package/lib/lib/npmrc.d.ts +17 -0
- package/lib/lib/npmrc.js +44 -0
- package/lib/security/cache.d.ts +7 -0
- package/lib/security/cache.js +33 -0
- package/lib/security/context.d.ts +58 -0
- package/lib/security/context.js +224 -0
- package/lib/types/changelog.types.d.ts +6 -0
- package/lib/types/changelog.types.js +2 -0
- package/lib/types/npm.types.d.ts +34 -0
- package/lib/types/npm.types.js +2 -0
- package/oclif.manifest.json +1 -0
- package/package.json +118 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import CommandBase from '../command.base';
|
|
3
|
+
export default class Sql extends CommandBase {
|
|
4
|
+
static description: string;
|
|
5
|
+
static usage: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static args: {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
options: string[];
|
|
11
|
+
}[];
|
|
12
|
+
static flags: {
|
|
13
|
+
version: flags.IOptionFlag<string | undefined>;
|
|
14
|
+
layer: flags.IOptionFlag<string | undefined>;
|
|
15
|
+
};
|
|
16
|
+
private readonly _moduleTypes;
|
|
17
|
+
private readonly _dbmsType;
|
|
18
|
+
/**
|
|
19
|
+
* Get unique scriptID by specified version
|
|
20
|
+
*/
|
|
21
|
+
getScriptId(version: string): Promise<string>;
|
|
22
|
+
handleLayer(scriptDbmsFolder: string, scriptLayer: string, scriptType: string, dbmsFormat: string): Promise<string>;
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const inquirer = require("inquirer");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const request = require("request-promise");
|
|
9
|
+
const command_base_1 = require("../command.base");
|
|
10
|
+
class Sql extends command_base_1.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this._moduleTypes = {
|
|
14
|
+
acc: 'Accounting',
|
|
15
|
+
claims: 'Claims',
|
|
16
|
+
core: 'Core',
|
|
17
|
+
pas: 'PAS',
|
|
18
|
+
reins: 'Reinsurance',
|
|
19
|
+
shared: 'Shared'
|
|
20
|
+
};
|
|
21
|
+
this._dbmsType = ['sql', 'oradc'];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get unique scriptID by specified version
|
|
25
|
+
*/
|
|
26
|
+
async getScriptId(version) {
|
|
27
|
+
let options = {
|
|
28
|
+
uri: `https://ops.adinsure.com/api/script/next?version=${version}`,
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: 'Bearer ' + await this.security.getToken()
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return request.get(options);
|
|
34
|
+
}
|
|
35
|
+
async handleLayer(scriptDbmsFolder, scriptLayer, scriptType, dbmsFormat) {
|
|
36
|
+
let scriptFolder = path.resolve(scriptDbmsFolder, scriptLayer, scriptType);
|
|
37
|
+
let layerFolder = path.resolve(scriptDbmsFolder, scriptLayer);
|
|
38
|
+
if (!await fs.pathExists(layerFolder)) {
|
|
39
|
+
let layers = '';
|
|
40
|
+
// printout only layer folders
|
|
41
|
+
for (let layer of fs.readdirSync(scriptDbmsFolder)) {
|
|
42
|
+
if (layer.toLowerCase() !== 'schema' && layer.toLowerCase() !== 'data') {
|
|
43
|
+
layers = layers + '\n' + layer;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (layers.length > 0) {
|
|
47
|
+
this.log(`Layer ${scriptLayer} for ${dbmsFormat} does not exist, did you mean: ${layers}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.log(`Layer ${scriptLayer} for ${dbmsFormat} does not exist.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return scriptFolder;
|
|
54
|
+
}
|
|
55
|
+
async run() {
|
|
56
|
+
const { args, flags } = this.parse(Sql);
|
|
57
|
+
// Validation of input parameters
|
|
58
|
+
let scriptType = args.type;
|
|
59
|
+
if (!scriptType) {
|
|
60
|
+
let responses = await inquirer.prompt([{
|
|
61
|
+
name: 'type',
|
|
62
|
+
message: 'select a sql type',
|
|
63
|
+
type: 'list',
|
|
64
|
+
choices: [{ name: 'schema' }, { name: 'data' }, { name: 'migration' }],
|
|
65
|
+
}]);
|
|
66
|
+
scriptType = responses.type;
|
|
67
|
+
}
|
|
68
|
+
let scriptModule = args.module;
|
|
69
|
+
if (!scriptModule && scriptType === 'data') {
|
|
70
|
+
let responses = await inquirer.prompt([{
|
|
71
|
+
name: 'module',
|
|
72
|
+
message: 'select a sql module for data type',
|
|
73
|
+
type: 'list',
|
|
74
|
+
choices: [{ name: 'acc' }, { name: 'claims' }, { name: 'core' }, { name: 'pas' }, { name: 'reins' }, { name: 'shared' }],
|
|
75
|
+
}]);
|
|
76
|
+
scriptModule = responses.module;
|
|
77
|
+
}
|
|
78
|
+
let scriptLayer = flags.layer;
|
|
79
|
+
this.log(`Generating on SQL script layer:'${scriptLayer}'`);
|
|
80
|
+
const fullVersion = flags.version || await this.getVersion('PLATFORM_VERSION', 'VERSION');
|
|
81
|
+
let version = fullVersion.split('-')[0];
|
|
82
|
+
let versionRegex = /\d+\.\d+\.\d+/;
|
|
83
|
+
if (!(versionRegex.test(version))) {
|
|
84
|
+
this.error(`Version in incorrect format. Got version: '${version}'`);
|
|
85
|
+
}
|
|
86
|
+
let scriptsRootFolder = path.resolve(await this.getGitRoot(), 'database');
|
|
87
|
+
if (!await fs.pathExists(scriptsRootFolder)) {
|
|
88
|
+
this.error(`Could not resolve database scripts folder: ${scriptsRootFolder}`);
|
|
89
|
+
}
|
|
90
|
+
let scriptFolderLocations = [];
|
|
91
|
+
for (let dbmsFormat of this._dbmsType) {
|
|
92
|
+
let scriptDbmsFolder = path.resolve(scriptsRootFolder, dbmsFormat);
|
|
93
|
+
if (await fs.pathExists(scriptDbmsFolder)) {
|
|
94
|
+
let scriptFolder = path.resolve(scriptDbmsFolder, scriptType);
|
|
95
|
+
if (scriptLayer !== undefined) {
|
|
96
|
+
scriptFolder = await this.handleLayer(scriptDbmsFolder, scriptLayer, scriptType, dbmsFormat);
|
|
97
|
+
}
|
|
98
|
+
if (scriptModule !== undefined) {
|
|
99
|
+
scriptFolder = path.resolve(scriptFolder, this._moduleTypes[scriptModule]);
|
|
100
|
+
}
|
|
101
|
+
if (!await fs.pathExists(scriptFolder)) {
|
|
102
|
+
this.warn(`Could not resolve existing database scripts folder. Creating folder: ${scriptFolder}`);
|
|
103
|
+
await fs.mkdir(scriptFolder);
|
|
104
|
+
}
|
|
105
|
+
scriptFolderLocations.push(scriptFolder);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Validation of parameters succeed. Requesting new SQL script ID and creating file.
|
|
109
|
+
this.log(`Requesting new id for '${version}'`);
|
|
110
|
+
let scriptId = await this.getScriptId(version);
|
|
111
|
+
this.log(`Got: '${chalk_1.default.green(scriptId)}'`);
|
|
112
|
+
for (let scriptFolder of scriptFolderLocations) {
|
|
113
|
+
let scriptsFilePath = path.resolve(scriptFolder, `${scriptId}.sql`);
|
|
114
|
+
await fs.writeFile(scriptsFilePath, '');
|
|
115
|
+
this.log(`${chalk_1.default.yellow(scriptsFilePath)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.default = Sql;
|
|
120
|
+
Sql.description = 'creates a new database script';
|
|
121
|
+
Sql.usage = 'sql <type> <module> [flags]';
|
|
122
|
+
Sql.examples = [
|
|
123
|
+
`$ ops sql schema `,
|
|
124
|
+
`$ ops sql data shared --layer basic`
|
|
125
|
+
];
|
|
126
|
+
Sql.args = [
|
|
127
|
+
{
|
|
128
|
+
name: 'type',
|
|
129
|
+
description: 'Type of database scripts',
|
|
130
|
+
options: ['schema', 'data', 'migration']
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'module',
|
|
134
|
+
description: 'Module of data database scripts',
|
|
135
|
+
options: ['acc', 'claims', 'core', 'pas', 'reins', 'shared']
|
|
136
|
+
}
|
|
137
|
+
];
|
|
138
|
+
Sql.flags = {
|
|
139
|
+
version: command_1.flags.string({
|
|
140
|
+
char: 'v',
|
|
141
|
+
description: 'version for which you\'re generating database script'
|
|
142
|
+
}),
|
|
143
|
+
layer: command_1.flags.string({
|
|
144
|
+
char: 'l',
|
|
145
|
+
description: 'name of the configuration layer for which you are generating database script'
|
|
146
|
+
})
|
|
147
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import CommandBase from '../command.base';
|
|
3
|
+
export default class Translate extends CommandBase {
|
|
4
|
+
static description: string;
|
|
5
|
+
static usage: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static args: {
|
|
8
|
+
name: string;
|
|
9
|
+
required: boolean;
|
|
10
|
+
description: string;
|
|
11
|
+
}[];
|
|
12
|
+
static flags: {
|
|
13
|
+
format: flags.IOptionFlag<string>;
|
|
14
|
+
module: flags.IOptionFlag<string | undefined>;
|
|
15
|
+
output: flags.IOptionFlag<string>;
|
|
16
|
+
filename: flags.IOptionFlag<string | undefined>;
|
|
17
|
+
respectServerFilename: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
getFormat(format: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Gets resources, checks a response and returns a response stream.
|
|
22
|
+
* @param languages list of translations to download
|
|
23
|
+
* @param format format of translations
|
|
24
|
+
* @param modules list of modules to download
|
|
25
|
+
* @returns arhive as an byte array response stream
|
|
26
|
+
*/
|
|
27
|
+
getTranslations(languages: string, format: string, modules: string | undefined): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* Read from response stream and extract files into output directory.
|
|
30
|
+
* @param content zip file or a stream
|
|
31
|
+
* @param dest final destination to extract files
|
|
32
|
+
* @returns void
|
|
33
|
+
* @throws error message
|
|
34
|
+
*/
|
|
35
|
+
extractFiles(content: any, destinationDir: string, xmlFilename?: string): Promise<any>;
|
|
36
|
+
run(): Promise<void>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
5
|
+
const cli_ux_1 = require("cli-ux");
|
|
6
|
+
const fs = require("fs-extra");
|
|
7
|
+
const JSZip = require("jszip");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
const request = require("request-promise");
|
|
10
|
+
const command_base_1 = require("../command.base");
|
|
11
|
+
class Translate extends command_base_1.default {
|
|
12
|
+
getFormat(format) {
|
|
13
|
+
if (format === 'json') {
|
|
14
|
+
return 'text/json';
|
|
15
|
+
}
|
|
16
|
+
if (format === 'xml') {
|
|
17
|
+
return 'text/xml';
|
|
18
|
+
}
|
|
19
|
+
return this.error(`Format ${format} not supported.`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Gets resources, checks a response and returns a response stream.
|
|
23
|
+
* @param languages list of translations to download
|
|
24
|
+
* @param format format of translations
|
|
25
|
+
* @param modules list of modules to download
|
|
26
|
+
* @returns arhive as an byte array response stream
|
|
27
|
+
*/
|
|
28
|
+
async getTranslations(languages, format, modules) {
|
|
29
|
+
let requestOptions = {
|
|
30
|
+
uri: `https://dictionary.adinsure.com/api/Translations?languages=${languages}`,
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: 'Bearer ' + await this.security.getToken(),
|
|
33
|
+
'Content-Type': this.getFormat(format),
|
|
34
|
+
},
|
|
35
|
+
encoding: null
|
|
36
|
+
};
|
|
37
|
+
if (modules) {
|
|
38
|
+
requestOptions.uri += `&modules=${modules}`;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
let response = await request.get(requestOptions);
|
|
42
|
+
return response;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
const errorJson = JSON.parse(error.error);
|
|
46
|
+
const errorMessage = `An error has occurred: ${errorJson.ExceptionMessage}`;
|
|
47
|
+
this.log(chalk_1.default.red(errorMessage));
|
|
48
|
+
throw errorJson;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Read from response stream and extract files into output directory.
|
|
53
|
+
* @param content zip file or a stream
|
|
54
|
+
* @param dest final destination to extract files
|
|
55
|
+
* @returns void
|
|
56
|
+
* @throws error message
|
|
57
|
+
*/
|
|
58
|
+
async extractFiles(content, destinationDir, xmlFilename = '') {
|
|
59
|
+
const zip = await JSZip.loadAsync(content);
|
|
60
|
+
for (const fileName of Object.keys(zip.files)) {
|
|
61
|
+
const buffer = await zip.files[fileName].async('nodebuffer');
|
|
62
|
+
// Rename from translations..Xml to Translations..xml to respect naming in mono
|
|
63
|
+
if (fileName.includes('Xml')) {
|
|
64
|
+
let finalFileName = fileName;
|
|
65
|
+
if (xmlFilename !== '') {
|
|
66
|
+
finalFileName = xmlFilename;
|
|
67
|
+
}
|
|
68
|
+
const dest = destinationDir + '/' + finalFileName;
|
|
69
|
+
await fs.writeFile(dest, buffer);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const dest = destinationDir + '/' + zip.files[fileName].name;
|
|
73
|
+
await fs.writeFile(dest, buffer);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async run() {
|
|
78
|
+
const { args, flags } = this.parse(Translate);
|
|
79
|
+
let destination = flags.output;
|
|
80
|
+
if (flags.format === 'json' && flags.module === undefined) {
|
|
81
|
+
this.error('You need to specify `\'module\' when choosing client `\'json\' format.');
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
// Get translations
|
|
85
|
+
cli_ux_1.default.action.start('Fetching translations from AdDictionary', undefined, { stdout: true });
|
|
86
|
+
let response = await this.getTranslations(args.language, flags.format, flags.module);
|
|
87
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
88
|
+
if (!await fs.pathExists(destination)) {
|
|
89
|
+
await fs.mkdirp(destination);
|
|
90
|
+
}
|
|
91
|
+
// Extract files
|
|
92
|
+
cli_ux_1.default.action.start('Extracting translation zip files', undefined, { stdout: true });
|
|
93
|
+
let finalFileName = 'Translations..xml';
|
|
94
|
+
if (flags.filename) {
|
|
95
|
+
finalFileName = flags.filename;
|
|
96
|
+
}
|
|
97
|
+
// set finalFileName to empty string to indicate filename needs to be taken from server response
|
|
98
|
+
if (flags.respectServerFilename) {
|
|
99
|
+
finalFileName = '';
|
|
100
|
+
}
|
|
101
|
+
await this.extractFiles(response, destination, finalFileName);
|
|
102
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.red('error')}`);
|
|
106
|
+
this.error(error.message);
|
|
107
|
+
}
|
|
108
|
+
this.log(`Translations extracted into ${chalk_1.default.cyan(path.resolve(destination))}`);
|
|
109
|
+
this.log(`${chalk_1.default.green('Done.')}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.default = Translate;
|
|
113
|
+
Translate.description = 'downloads translate from AdDictionary service';
|
|
114
|
+
Translate.usage = 'translate <language> [flags]';
|
|
115
|
+
Translate.examples = [
|
|
116
|
+
`$ ops translate "en-US=en-US;ru-Ru=ru-RU" -f json -m "Client business accounting;Client business base;"`,
|
|
117
|
+
`$ ops translate "en-US=en-US;ru-Ru=ru-RU" -f xml -o translationDestination`
|
|
118
|
+
];
|
|
119
|
+
Translate.args = [
|
|
120
|
+
{
|
|
121
|
+
name: 'language',
|
|
122
|
+
required: true,
|
|
123
|
+
description: 'language id you want to download. Values must be semi-colon (;) separated.'
|
|
124
|
+
}
|
|
125
|
+
];
|
|
126
|
+
Translate.flags = {
|
|
127
|
+
format: command_1.flags.string({
|
|
128
|
+
char: 'f',
|
|
129
|
+
description: 'translations format [xml - server translations, json - client translations]',
|
|
130
|
+
options: ['json', 'xml'],
|
|
131
|
+
required: true
|
|
132
|
+
}),
|
|
133
|
+
module: command_1.flags.string({
|
|
134
|
+
char: 'm',
|
|
135
|
+
description: 'module name you want to download. Values must be semi-colon (;) separated.'
|
|
136
|
+
}),
|
|
137
|
+
output: command_1.flags.string({
|
|
138
|
+
char: 'o',
|
|
139
|
+
default: '.',
|
|
140
|
+
description: 'absolute or relative destination path to a folder where translations are extracted.'
|
|
141
|
+
}),
|
|
142
|
+
filename: command_1.flags.string({
|
|
143
|
+
description: 'specify filename of output (XML only).'
|
|
144
|
+
}),
|
|
145
|
+
respectServerFilename: command_1.flags.boolean({
|
|
146
|
+
default: false,
|
|
147
|
+
description: 'respect filename that is returned from AdDictionary server (XML only).'
|
|
148
|
+
})
|
|
149
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import * as semver from 'semver';
|
|
3
|
+
import CommandBase from '../command.base';
|
|
4
|
+
declare type ReleaseType = semver.ReleaseType | 'new';
|
|
5
|
+
export default class Version extends CommandBase {
|
|
6
|
+
static description: string;
|
|
7
|
+
static usage: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static args: {
|
|
10
|
+
name: string;
|
|
11
|
+
required: boolean;
|
|
12
|
+
description: string;
|
|
13
|
+
options: string[];
|
|
14
|
+
}[];
|
|
15
|
+
static flags: {
|
|
16
|
+
independent: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
17
|
+
version: flags.IOptionFlag<string | undefined>;
|
|
18
|
+
'script-prefix': flags.IOptionFlag<string>;
|
|
19
|
+
'no-deps': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
20
|
+
'no-script': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
21
|
+
'only-npm-packages': flags.IOptionFlag<string>;
|
|
22
|
+
'exclude-dir': flags.IOptionFlag<string[]>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Update NPM packages with wsrun
|
|
26
|
+
*/
|
|
27
|
+
bumpNpm(type: ReleaseType, version: string, filter: string, excludeDirs: string[]): Promise<string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Validate args and flags
|
|
30
|
+
*/
|
|
31
|
+
validateOptions(args: any, flags: any): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Update dependencies in package.json files for @adinsure packages
|
|
34
|
+
*/
|
|
35
|
+
updateDependencies(version: string, updatedPackages: Array<string>): Promise<void>;
|
|
36
|
+
insertScriptRequest(token: string, version: string, prefix: string): Promise<string>;
|
|
37
|
+
insertScript(token: string, version: string, prefix: string, skip?: boolean): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Check if version has valid prerelease as 'rc' or '201910' (year month)
|
|
40
|
+
*/
|
|
41
|
+
checkPrerelease(version: string, month: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Write new version in VERSION file
|
|
44
|
+
*/
|
|
45
|
+
setVersion(version: string): Promise<void>;
|
|
46
|
+
run(): Promise<undefined>;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
5
|
+
const cli_ux_1 = require("cli-ux");
|
|
6
|
+
const fs = require("fs-extra");
|
|
7
|
+
const globby = require("globby");
|
|
8
|
+
const moment = require("moment");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const request = require("request-promise");
|
|
11
|
+
const semver = require("semver");
|
|
12
|
+
const replaceInFile = require('replace-in-file');
|
|
13
|
+
const command_base_1 = require("../command.base");
|
|
14
|
+
class Version extends command_base_1.default {
|
|
15
|
+
/**
|
|
16
|
+
* Update NPM packages with wsrun
|
|
17
|
+
*/
|
|
18
|
+
async bumpNpm(type, version, filter, excludeDirs) {
|
|
19
|
+
const currentPrereleaseDate = moment().format('YYYYMM');
|
|
20
|
+
let bumpedPackageName = [];
|
|
21
|
+
// Find all package.json files that are not in node modules
|
|
22
|
+
let searchPattern = ['**/package.json', '!**/node_modules'];
|
|
23
|
+
if (excludeDirs) {
|
|
24
|
+
for (const exclude of excludeDirs) {
|
|
25
|
+
searchPattern.push(`!${exclude}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const paths = await globby(searchPattern);
|
|
29
|
+
for (const path of paths) {
|
|
30
|
+
try {
|
|
31
|
+
// Read the data from it
|
|
32
|
+
let data = await fs.readJSON(path);
|
|
33
|
+
// Check if version exists
|
|
34
|
+
if (!data.version || !data.name) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
let regexp = new RegExp(filter);
|
|
38
|
+
if (!regexp.test(data.name)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Increment the package version depending on the increment type
|
|
42
|
+
if (type === 'new') {
|
|
43
|
+
data.version = version;
|
|
44
|
+
}
|
|
45
|
+
else if (type === 'prerelease' && this.checkPrerelease(data.version, currentPrereleaseDate)) {
|
|
46
|
+
data.version = semver.inc(data.version, type, true);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
data.version = semver.inc(data.version, type, false, currentPrereleaseDate);
|
|
50
|
+
}
|
|
51
|
+
bumpedPackageName.push(data.name);
|
|
52
|
+
// Save file
|
|
53
|
+
await fs.writeJSON(path, data, { spaces: 4, EOL: '\r\n' });
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (err instanceof SyntaxError) {
|
|
57
|
+
this.warn(`Error reading package.json: ${chalk_1.default.yellow(err.message)}. Consider using '--exclude-dir'.`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return this.error(`Unknown error: ${chalk_1.default.red(err)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return bumpedPackageName;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate args and flags
|
|
68
|
+
*/
|
|
69
|
+
validateOptions(args, flags) {
|
|
70
|
+
if (args.type !== 'new' && flags.version) {
|
|
71
|
+
this.error(`${chalk_1.default.red('Version flag can only be used with new type')}`);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
else if (args.type === 'new' && !flags.version) {
|
|
75
|
+
this.error(`${chalk_1.default.red('Version flag is required with new type')}`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
else if (args.type === 'new' && flags.increment) {
|
|
79
|
+
this.error(`${chalk_1.default.red('Increment flag not supported with new type')}`);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Update dependencies in package.json files for @adinsure packages
|
|
86
|
+
*/
|
|
87
|
+
async updateDependencies(version, updatedPackages) {
|
|
88
|
+
// Find all package.json files that are not in node modules
|
|
89
|
+
const paths = await globby(['**/package.json', '!**/node_modules']);
|
|
90
|
+
for (const path of paths) {
|
|
91
|
+
for (const packageName of updatedPackages) {
|
|
92
|
+
let re = new RegExp('"' + packageName + '": "\\d+\\.\\d+\\..*"', 'g');
|
|
93
|
+
await replaceInFile({
|
|
94
|
+
files: path,
|
|
95
|
+
from: re,
|
|
96
|
+
to: `"${packageName}": "${version}"`
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async insertScriptRequest(token, version, prefix) {
|
|
102
|
+
let options = {
|
|
103
|
+
uri: `https://ops.adinsure.com/api/script`,
|
|
104
|
+
headers: {
|
|
105
|
+
Authorization: 'Bearer ' + token
|
|
106
|
+
},
|
|
107
|
+
body: {
|
|
108
|
+
version,
|
|
109
|
+
prefix
|
|
110
|
+
},
|
|
111
|
+
json: true
|
|
112
|
+
};
|
|
113
|
+
return request.post(options);
|
|
114
|
+
}
|
|
115
|
+
async insertScript(token, version, prefix, skip = false) {
|
|
116
|
+
cli_ux_1.default.action.start('Inserting new script version', undefined, { stdout: true });
|
|
117
|
+
if (skip) {
|
|
118
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.blue('skip')}`);
|
|
119
|
+
}
|
|
120
|
+
else if (token) {
|
|
121
|
+
try {
|
|
122
|
+
await this.insertScriptRequest(token, version, prefix);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
switch (err.statusCode) {
|
|
126
|
+
case 401: {
|
|
127
|
+
this.error(`${chalk_1.default.red('You don\'t have permissions. If this was intentional command, please contact Operations for permissions, do git reset and rerun command.')}`);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
default: {
|
|
131
|
+
this.error(`${chalk_1.default.red(err)}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.red('error')}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Check if version has valid prerelease as 'rc' or '201910' (year month)
|
|
143
|
+
*/
|
|
144
|
+
checkPrerelease(version, month) {
|
|
145
|
+
const prereleaseVersion = semver.prerelease(version, true);
|
|
146
|
+
if (!prereleaseVersion)
|
|
147
|
+
return false;
|
|
148
|
+
if (prereleaseVersion[0].toString() === month)
|
|
149
|
+
return true;
|
|
150
|
+
if (prereleaseVersion[0].toString() === 'rc')
|
|
151
|
+
return true;
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Write new version in VERSION file
|
|
156
|
+
*/
|
|
157
|
+
async setVersion(version) {
|
|
158
|
+
const versionPath = path.resolve(await this.getGitRoot(), 'VERSION');
|
|
159
|
+
if (!await fs.pathExists(versionPath)) {
|
|
160
|
+
throw new Error('VERSION file not found. File will not be updated.');
|
|
161
|
+
}
|
|
162
|
+
return fs.writeFileSync(versionPath, version, 'utf-8');
|
|
163
|
+
}
|
|
164
|
+
async run() {
|
|
165
|
+
const { args, flags } = this.parse(Version);
|
|
166
|
+
const currentPrereleaseDate = moment().format('YYYYMM');
|
|
167
|
+
// Check if token is correct and save it for later use
|
|
168
|
+
let token = '';
|
|
169
|
+
if (!flags['no-script']) {
|
|
170
|
+
token = await this.security.getToken();
|
|
171
|
+
}
|
|
172
|
+
// exit if validation fails
|
|
173
|
+
if (!this.validateOptions(args, flags)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let newVersion = null;
|
|
177
|
+
if (args.type === 'new' && flags.version) {
|
|
178
|
+
this.log(`Using 'new' command. VERSION file ignored.`);
|
|
179
|
+
newVersion = semver.valid(flags.version);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Get current version
|
|
183
|
+
const fullVersion = await this.getVersion();
|
|
184
|
+
this.log(`Current version is ${chalk_1.default.green(fullVersion)}`);
|
|
185
|
+
// Calculate new version
|
|
186
|
+
newVersion = semver.inc(fullVersion, args.type, true, currentPrereleaseDate);
|
|
187
|
+
// Force prerelease if prerelease is in same month and increment RC correctly
|
|
188
|
+
if (args.type === 'prerelease' && this.checkPrerelease(fullVersion, currentPrereleaseDate)) {
|
|
189
|
+
newVersion = semver.inc(fullVersion, args.type, true);
|
|
190
|
+
}
|
|
191
|
+
// Allow npm packages to be versioned seperately. Ultimately we want to force npm package to have same verion as VERSION file.
|
|
192
|
+
if (!flags.independent) {
|
|
193
|
+
args.type = 'new';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Stop if version invalid
|
|
197
|
+
if (!newVersion) {
|
|
198
|
+
return this.error(`${chalk_1.default.red('Version in incorrect format')}`);
|
|
199
|
+
}
|
|
200
|
+
this.log(`Setting new version to ${chalk_1.default.green(newVersion)}`);
|
|
201
|
+
try {
|
|
202
|
+
await this.setVersion(newVersion);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
this.warn(`${chalk_1.default.yellow(err.message)}`);
|
|
206
|
+
}
|
|
207
|
+
cli_ux_1.default.action.start('Bumping NPM packages', undefined, { stdout: true });
|
|
208
|
+
let packages = await this.bumpNpm(args.type, newVersion, flags['only-npm-packages'], flags['exclude-dir']);
|
|
209
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
210
|
+
cli_ux_1.default.action.start('Updating NPM dependencies in package.json files', undefined, { stdout: true });
|
|
211
|
+
if (flags['no-deps']) {
|
|
212
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.blue('skip')}`);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
await this.updateDependencies(newVersion, packages);
|
|
216
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
217
|
+
}
|
|
218
|
+
await this.insertScript(token, newVersion, flags['script-prefix'], flags['no-script']);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.default = Version;
|
|
222
|
+
Version.description = 'release new version';
|
|
223
|
+
Version.usage = 'version <type> [flags]';
|
|
224
|
+
Version.examples = [
|
|
225
|
+
`$ ops version patch`,
|
|
226
|
+
`$ ops version prerelease -i`,
|
|
227
|
+
`$ ops version new -v 3.4.3`
|
|
228
|
+
];
|
|
229
|
+
Version.args = [
|
|
230
|
+
{
|
|
231
|
+
name: 'type',
|
|
232
|
+
required: true,
|
|
233
|
+
description: 'Type of release',
|
|
234
|
+
options: ['patch', 'minor', 'major', 'prerelease', 'preminor', 'premajor', 'new']
|
|
235
|
+
},
|
|
236
|
+
];
|
|
237
|
+
Version.flags = {
|
|
238
|
+
independent: command_1.flags.boolean({
|
|
239
|
+
char: 'i',
|
|
240
|
+
description: 'increment npm packages independent of VERSION file',
|
|
241
|
+
default: false
|
|
242
|
+
}),
|
|
243
|
+
version: command_1.flags.string({
|
|
244
|
+
char: 'v',
|
|
245
|
+
description: 'force version'
|
|
246
|
+
}),
|
|
247
|
+
'script-prefix': command_1.flags.string({
|
|
248
|
+
description: 'prefix for db script version creation. (default: 7.10)',
|
|
249
|
+
default: '7.10'
|
|
250
|
+
}),
|
|
251
|
+
'no-deps': command_1.flags.boolean({
|
|
252
|
+
description: 'skip dependency update',
|
|
253
|
+
default: false
|
|
254
|
+
}),
|
|
255
|
+
'no-script': command_1.flags.boolean({
|
|
256
|
+
description: 'skip creation of script',
|
|
257
|
+
default: false
|
|
258
|
+
}),
|
|
259
|
+
'only-npm-packages': command_1.flags.string({
|
|
260
|
+
description: 'regular expression for which NPM packages to include',
|
|
261
|
+
default: '.*'
|
|
262
|
+
}),
|
|
263
|
+
'exclude-dir': command_1.flags.string({
|
|
264
|
+
description: 'exclude directories where to search for package.json',
|
|
265
|
+
multiple: true
|
|
266
|
+
})
|
|
267
|
+
};
|