@tangelo/tangelo-configuration-toolkit 1.11.2 → 1.12.1
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/.eslintrc.js +46 -0
- package/.pre-commit-config.yaml +36 -0
- package/README.md +66 -66
- package/bin/index.js +2 -2
- package/index.js +26 -15
- package/package.json +1 -1
- package/src/cli.js +111 -111
- package/src/lib/exec-git-command.js +5 -5
- package/src/lib/get-repoconfig.js +23 -23
- package/src/lib/gulp-batch-replace-with-filter.js +19 -19
- package/src/lib/gulp-resolve-includes.js +14 -14
- package/src/lib/gulp-sftp.js +25 -25
- package/src/lib/gulp-simple-rename.js +11 -11
- package/src/lib/package-update-check.js +12 -12
- package/src/lib/style-string-getters.js +2 -2
- package/src/lib/worker-with-spinner.js +3 -3
- package/src/modules/build/index.js +55 -56
- package/src/modules/build/oxygen.js +167 -159
- package/src/modules/deploy/config.js +13 -13
- package/src/modules/deploy/execute.js +74 -74
- package/src/modules/deploy/index.js +23 -23
- package/src/modules/deploy/srcset.js +16 -16
- package/src/modules/fonto/commands.js +127 -152
- package/src/modules/fonto/index.js +61 -28
- package/src/modules/git/index.js +39 -37
- package/src/modules/migrate/index.js +61 -61
- package/src/modules/migrate/steps.js +11 -6
- package/src/modules/sql/index.js +39 -39
- package/src/modules/version/index.js +157 -173
- package/tct-workspace.code-workspace +0 -7
package/src/modules/git/index.js
CHANGED
|
@@ -30,16 +30,16 @@ const cmdExec = commands => new Promise(resolve => {
|
|
|
30
30
|
});
|
|
31
31
|
promise.then(()=> {
|
|
32
32
|
resolve();
|
|
33
|
-
})
|
|
33
|
+
});
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
module.exports = function git (argv) {
|
|
37
37
|
|
|
38
|
-
if (argv.
|
|
38
|
+
if (argv.init) {
|
|
39
39
|
const remoteTdiUrl = `${_paths.gitremote}/${_paths.tdi}.git`;
|
|
40
40
|
let branches;
|
|
41
41
|
|
|
42
|
-
try { branches = execSync('git ls-remote --heads ' + remoteTdiUrl, {encoding: 'UTF-8'}) }
|
|
42
|
+
try { branches = execSync('git ls-remote --heads ' + remoteTdiUrl, {encoding: 'UTF-8'}); }
|
|
43
43
|
catch (e) { _error(' '); } // execSync already prints an error to the console
|
|
44
44
|
|
|
45
45
|
branches = branches
|
|
@@ -54,28 +54,28 @@ module.exports = function git (argv) {
|
|
|
54
54
|
})
|
|
55
55
|
;
|
|
56
56
|
inquirer
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
.prompt([{
|
|
58
|
+
message: 'Choose a branch for TDI submodule: ', name: 'branch', type: 'list',
|
|
59
|
+
choices: branches, pageSize: 3, loop: false
|
|
60
|
+
}])
|
|
61
|
+
.then(a => {
|
|
62
|
+
_write();
|
|
63
|
+
cmdExec([
|
|
64
|
+
['git init', 'Initialize repo:'],
|
|
65
|
+
[`git remote add origin git@${_paths.gitremote.replace(/\//, ':')}/${path.basename(process.cwd())}.git`],
|
|
66
|
+
[`git submodule add -b ${a.branch} ${remoteTdiUrl}`, 'Add TDI submodule:'],
|
|
67
|
+
['git commit -m "added tdi submodule"', 'Commit:']
|
|
68
|
+
])
|
|
69
|
+
.then(() => {
|
|
70
|
+
_info(`Next steps:
|
|
71
71
|
1. Go to https://bitbucket.org/repo/create?workspace=tangelosoftware and create a repository named "${path.basename(process.cwd())}", with options for including README/.gitignore disabled.
|
|
72
72
|
2. Open this folder in Sourcetree (ctrl+O), and push master branch to origin.
|
|
73
73
|
`.replace(/^\s{8}/gm, ''));
|
|
74
|
+
});
|
|
74
75
|
});
|
|
75
|
-
});
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
if (argv.
|
|
78
|
+
if (argv.reset) {
|
|
79
79
|
_info('Reset and clean repo:');
|
|
80
80
|
cmdExec([
|
|
81
81
|
['git reset --hard'],
|
|
@@ -83,31 +83,33 @@ module.exports = function git (argv) {
|
|
|
83
83
|
]);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
if (argv.
|
|
86
|
+
if (argv.clone) {
|
|
87
|
+
if (argv.clone === true) _error('Pass a repository name!');
|
|
88
|
+
|
|
87
89
|
_info('Clone a client repository and do basic project initialization');
|
|
88
90
|
cmdExec([
|
|
89
91
|
// Clone repository
|
|
90
92
|
['git clone git@bitbucket.org:tangelosoftware/' + argv.clone + '.git']
|
|
91
93
|
])
|
|
92
|
-
|
|
94
|
+
.then(() => {
|
|
93
95
|
// Change directory for the next commands, it should have the same name as the clone argument from commandline at this point
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
chdir('./' + argv.clone);
|
|
97
|
+
cmdExec([
|
|
96
98
|
// Retrieve TDI submodule for this client
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
['git submodule update --init', 'Fetch submodules such as TDI'],
|
|
100
|
+
// Create symlinks for TDI
|
|
101
|
+
['tct b -s', 'Create TDI symlinks'],
|
|
102
|
+
]);
|
|
103
|
+
}).catch((e) => {
|
|
102
104
|
// Show warnings for missing, expected, system environment variables
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
if (!process.env.GIT_SSH) {
|
|
106
|
+
_warn(`System environment variable 'GIT_SSH' is missing. (link to putty plink.exe)`);
|
|
107
|
+
}
|
|
108
|
+
if (!process.env.GIT_SSH_COMMAND) {
|
|
109
|
+
_warn(`System environment variable 'GIT_SSH_COMMAND' is missing. (link to putty plink.exe)`);
|
|
110
|
+
}
|
|
111
|
+
// continue display stack trace
|
|
112
|
+
throw e;
|
|
113
|
+
});
|
|
112
114
|
}
|
|
113
115
|
};
|
|
@@ -10,78 +10,78 @@ module.exports = function migrate (argv) {
|
|
|
10
10
|
|
|
11
11
|
const scripts =
|
|
12
12
|
globby
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
13
|
+
.sync(_paths.tdi + '/tct/migrate/*.js')
|
|
14
|
+
.map(s => s.match(/([^/]+)$/)[1].replace('.js', ''))
|
|
15
|
+
.sort((a, b) => {
|
|
16
|
+
const aRelease = /^\d+-\d+/.test(a), bRelease = /^\d+-\d+/.test(b);
|
|
17
|
+
if (aRelease && bRelease) return a > b ? -1 : 1;
|
|
18
|
+
if (aRelease) return -1;
|
|
19
|
+
if (bRelease) return 1;
|
|
20
|
+
return a > b ? 1 : -1;
|
|
21
|
+
})
|
|
22
|
+
.map(s => ({
|
|
23
|
+
name: s.replace(/(\d+)-(\d+)-?(.*)/, (m, p1, p2, p3) => `${p1} -> ${p2}${p3 ? ` (${p3})` : ''}`),
|
|
24
|
+
value: s
|
|
25
|
+
}))
|
|
26
26
|
;
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
// Search scriptname set in commandline in scripts and return in cmdlScript if found
|
|
29
29
|
const cmdlScript = Object.values(scripts).filter(s => s.name === `${argv.execute}`)[0];
|
|
30
30
|
if (cmdlScript) {
|
|
31
31
|
_info(`Migration: ${cmdlScript.name}`);
|
|
32
|
-
}
|
|
33
|
-
|
|
32
|
+
}
|
|
33
|
+
|
|
34
34
|
inquirer
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
.prompt([{
|
|
36
|
+
message: 'Choose a migration: ', name: 'script', type: 'list', choices: scripts, pageSize: 5, loop: false,
|
|
37
|
+
when: !(cmdlScript) // Only show choice for migration when no script is set in commandline
|
|
38
|
+
}, {
|
|
39
|
+
message: 'Choose filter: ', name: 'filter', type: 'list', pageSize: 5, loop: false,
|
|
40
|
+
choices: [{name: `- All`, value: argv.filter}, {name: '- Choose active projects', value: 'projects'}],
|
|
41
|
+
when: argv.filter === '**' // Only show this message if no custom filter was added to the command argument -f
|
|
42
|
+
}, {
|
|
43
|
+
message: 'Choose active projects: ', name: 'projects', type: 'checkbox', validate: v => !!v[0],
|
|
44
|
+
choices: _repoconfig.map(p => ({name: `${p.customer_name} ${p.project_name}`, value: p})),
|
|
45
|
+
when: (a) => a.filter === 'projects' // Only show this message if 'Choose active projects' was chosen previously
|
|
46
|
+
}])
|
|
47
|
+
.then(a => {
|
|
48
|
+
_write();
|
|
49
|
+
_info(`Working folder set to: ${_paths.repo}`);
|
|
50
|
+
|
|
51
|
+
if (cmdlScript) {
|
|
52
52
|
// Set script to execute to script entered in commandline
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
a.script = cmdlScript.value;
|
|
54
|
+
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
if (a.filter === 'projects' && _repoconfig.length > a.projects.length) {
|
|
57
57
|
// push paths of chosen active documents to projectFolders (only if not all projects are chosen)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
_info(`Filter applied: ${filter}`);
|
|
69
|
-
_write();
|
|
70
|
-
|
|
71
|
-
inquirer
|
|
72
|
-
.prompt([{message: 'Continue?', name: 'confirm', type: 'confirm'}])
|
|
73
|
-
.then(({confirm}) => {
|
|
74
|
-
if (!confirm) return;
|
|
58
|
+
const projectFolders = [];
|
|
59
|
+
a.projects.forEach(p => {
|
|
60
|
+
projectFolders.push(p.path_dbconfig ? p.path_dbconfig.join('/') : (_repoconfig.customer.dirname+'/'+p.dirname));
|
|
61
|
+
// push cmscustom path if it differs from dbconfig path
|
|
62
|
+
if (p.path_dbconfig.join('/') != p.path_cmscustom.join('/')) projectFolders.push(p.path_cmscustom.join('/'));
|
|
63
|
+
});
|
|
64
|
+
// Set filter to chosen active documents
|
|
65
|
+
filter = projectFolders.length == 1 ? `**/${projectFolders}/**` : `**/{${projectFolders.join(',')}}/**`;
|
|
66
|
+
}
|
|
75
67
|
|
|
68
|
+
_info(`Filter applied: ${filter}`);
|
|
76
69
|
_write();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
|
|
71
|
+
inquirer
|
|
72
|
+
.prompt([{message: 'Continue?', name: 'confirm', type: 'confirm'}])
|
|
73
|
+
.then(({confirm}) => {
|
|
74
|
+
if (!confirm) return;
|
|
75
|
+
|
|
76
|
+
_write();
|
|
77
|
+
const startTime = new Date();
|
|
78
|
+
|
|
79
|
+
const scriptPath = path.join(_paths.repo, _paths.tdi, 'tct/migrate', a.script);
|
|
80
|
+
require(scriptPath).forEach(step => require('./steps')(step, argv.dry, filter));
|
|
81
|
+
|
|
82
|
+
_perf(startTime);
|
|
83
|
+
});
|
|
84
|
+
|
|
83
85
|
});
|
|
84
86
|
|
|
85
|
-
});
|
|
86
|
-
|
|
87
87
|
};
|
|
@@ -2,14 +2,14 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const globby = require('globby');
|
|
3
3
|
const minimatch = require('minimatch');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const rif
|
|
5
|
+
const rif = require('replace-in-file');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const getPaths = (search, filter) =>
|
|
9
9
|
globby
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
);
|
|
10
|
+
.sync(search, {dot: true, ignore: [_paths.tdi + '/**', '**/cmscustom/tdi/**']})
|
|
11
|
+
.filter(p => !filter || minimatch(p, filter)
|
|
12
|
+
);
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
module.exports = function steps (step, dry, filter) {
|
|
@@ -17,6 +17,10 @@ module.exports = function steps (step, dry, filter) {
|
|
|
17
17
|
const {deletePaths, renamePaths, replaceInFiles, customAction, applyFilter = true} = step;
|
|
18
18
|
const setFilter = applyFilter && filter;
|
|
19
19
|
|
|
20
|
+
if (Array.isArray(step)) {
|
|
21
|
+
step.forEach(substep => require('./steps')(substep, dry, filter));
|
|
22
|
+
}
|
|
23
|
+
|
|
20
24
|
if (deletePaths) {
|
|
21
25
|
deletePaths.forEach(curpath => {
|
|
22
26
|
_info(`Deleting paths: ${curpath}`);
|
|
@@ -48,9 +52,10 @@ module.exports = function steps (step, dry, filter) {
|
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
let filesModCount = 0;
|
|
51
|
-
for (let i=0; i<20 &&
|
|
55
|
+
for (let i=0; i<20 && r.files[0]; i++) { // execute repeatedly for modified files only (with safety limit of 20)
|
|
52
56
|
r.files = rif.sync(r).filter(f => f.hasChanged).map(f => f.file);
|
|
53
57
|
if (i==0) filesModCount = r.files.length; // save count only after first run (after this only subsets are processed)
|
|
58
|
+
if (dry) break;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
_write('Files modified:', filesModCount);
|
|
@@ -59,7 +64,7 @@ module.exports = function steps (step, dry, filter) {
|
|
|
59
64
|
|
|
60
65
|
if (!dry && customAction) {
|
|
61
66
|
customAction.forEach(([dirpath, actionFn]) => {
|
|
62
|
-
getPaths(dirpath,setFilter).forEach(p => actionFn(p));
|
|
67
|
+
getPaths(dirpath, setFilter).forEach(p => actionFn(p));
|
|
63
68
|
});
|
|
64
69
|
}
|
|
65
70
|
|
package/src/modules/sql/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const inquirer = require('inquirer');
|
|
|
6
6
|
|
|
7
7
|
const runSqlScript = (path, db, un, pw) => {
|
|
8
8
|
const connect = db ? `${un}/${pw}@${db}` : '/nolog';
|
|
9
|
-
const [dir, script] = path.split(/\/([
|
|
9
|
+
const [dir, script] = path.split(/\/([^/]+)$/);
|
|
10
10
|
_info('Running in new window:');
|
|
11
11
|
_write(path);
|
|
12
12
|
if (!fs.existsSync(path)) _error('Path does not exist!');
|
|
@@ -20,35 +20,35 @@ const checkLog = (logFilePath, remove=true) => {
|
|
|
20
20
|
// Check for ORA- error messages
|
|
21
21
|
if (logFile.match(RegExp(`ORA-`, 'gm'))) {
|
|
22
22
|
// Select each ORA- error message and up to 6 lines before (the lines before may not contain ORA- themselves)
|
|
23
|
-
const errors = logFile.match(RegExp(`((?![^\n]*ORA-)[^\n]*\n){0,6}ORA-[^\n\r]
|
|
24
|
-
_info(`${errors.length} error(s) during SQL script:\n`)
|
|
23
|
+
const errors = logFile.match(RegExp(`((?![^\n]*ORA-)[^\n]*\n){0,6}ORA-[^\n\r]*`, `gms`));
|
|
24
|
+
_info(`${errors.length} error(s) during SQL script:\n`);
|
|
25
25
|
// Print each error + lines before:
|
|
26
26
|
errors.forEach((e, i) => {
|
|
27
|
-
_info(`Tail of error ${i+1}:\n`)
|
|
27
|
+
_info(`Tail of error ${i+1}:\n`);
|
|
28
28
|
_warn(`${e.trim()}\n`);
|
|
29
|
-
})
|
|
29
|
+
});
|
|
30
30
|
}
|
|
31
31
|
if (remove) {
|
|
32
32
|
// remove log file
|
|
33
33
|
fs.removeSync(logFilePath);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
};
|
|
37
37
|
|
|
38
38
|
module.exports = function sql (argv) {
|
|
39
39
|
|
|
40
|
-
if ((argv.install || argv.configure) && _git.commitLocal.date < _git.commitRemote.date) {
|
|
41
|
-
_warn(`You're not deploying from the most recent git commit!\n`)
|
|
40
|
+
if ((argv.install || argv.configure) && _git.commitLocal().date < _git.commitRemote().date) {
|
|
41
|
+
_warn(`You're not deploying from the most recent git commit!\n`);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (argv.install) {
|
|
45
45
|
// tdi
|
|
46
46
|
const dir = `${_paths.tdi}/${_isPre51 ? 'sources' : 'src'}/database/tdi/${_isPre42 ? 'install/' : ''}`;
|
|
47
47
|
runSqlScript(dir + 'install.sql');
|
|
48
|
-
checkLog(dir + 'tdi-install.log',false);
|
|
48
|
+
checkLog(dir + 'tdi-install.log', false);
|
|
49
49
|
// custom
|
|
50
50
|
runSqlScript('database/install.sql');
|
|
51
|
-
checkLog('database/install.log',false);
|
|
51
|
+
checkLog('database/install.log', false);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
if (argv.configure) {
|
|
@@ -58,38 +58,38 @@ module.exports = function sql (argv) {
|
|
|
58
58
|
const file = cwd + 'tmp-config-loader.sql';
|
|
59
59
|
|
|
60
60
|
inquirer
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
.prompt([
|
|
62
|
+
{
|
|
63
|
+
message: 'Choose projects: ', name: 'projects', type: 'checkbox', validate: v => !!v[0],
|
|
64
|
+
choices:
|
|
65
65
|
_repoconfig.projects
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
? _repoconfig.projects.map(p => ({name: p.name, value: p})) // when using repoconfig file (old)
|
|
67
|
+
: _repoconfig.map(p => ({name: `${p.customer_name} ${p.project_name}`, value: p}))
|
|
68
|
+
},
|
|
69
|
+
{message: 'Database TNS name: ', name: 'db', default: _appconfig.defaultDatabase},
|
|
70
|
+
{message: 'TANCMS password: ', name: 'pw', default: 'tancms'}
|
|
71
|
+
])
|
|
72
|
+
.then(a => {
|
|
73
|
+
_write();
|
|
74
|
+
|
|
75
|
+
const script = [`define l_env = ${a.pw=='tancms' ? 'dev' : 'prd'}`, 'set verify off define off'];
|
|
76
|
+
|
|
77
|
+
script.push(`spool install-config.log`);
|
|
78
|
+
a.projects.forEach(p => {
|
|
79
|
+
const dir = p.path_dbconfig ? p.path_dbconfig.join('/') : (_repoconfig.customer.dirname+'/'+p.dirname);
|
|
80
|
+
script.push('prompt ', `prompt Loading configuration for: ${p.name}`);
|
|
81
|
+
script.push(...globby.sync(`${dir}/*_install.sql`, {cwd}).map(s => `@${s}`));
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
script.push(`spool off`);
|
|
85
|
+
script.push('prompt ', 'pause Press ENTER to exit', 'exit');
|
|
86
|
+
|
|
87
|
+
fs.writeFileSync(file, script.join('\n'));
|
|
88
|
+
runSqlScript(file, a.db, 'tancms', a.pw);
|
|
89
|
+
fs.removeSync(file);
|
|
90
|
+
checkLog(cwd + 'install-config.log');
|
|
82
91
|
});
|
|
83
92
|
|
|
84
|
-
script.push(`spool off`);
|
|
85
|
-
script.push('prompt ', 'pause Press ENTER to exit', 'exit');
|
|
86
|
-
|
|
87
|
-
fs.writeFileSync(file, script.join('\n'));
|
|
88
|
-
runSqlScript(file, a.db, 'tancms', a.pw);
|
|
89
|
-
fs.removeSync(file);
|
|
90
|
-
checkLog(cwd + 'install-config.log');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
93
|
}
|
|
94
94
|
else _error('No projects defined in repo config!');
|
|
95
95
|
|