@tangelo/tangelo-configuration-toolkit 1.14.2 → 1.14.4
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/.pre-commit-config.yaml +9 -10
- package/README.md +1 -1
- package/bitbucket-pipelines.yml +7 -7
- package/index.js +8 -8
- package/package.json +6 -6
- package/src/lib/get-repoconfig.js +3 -3
- package/src/lib/style-string-getters.js +2 -0
- package/src/modules/build/oxygen.js +15 -15
- package/src/modules/fonto/commands.js +4 -4
- package/src/modules/fonto/index.js +8 -8
- package/src/modules/git/index.js +1 -1
- package/src/modules/migrate/steps.js +1 -1
package/.pre-commit-config.yaml
CHANGED
|
@@ -4,33 +4,32 @@
|
|
|
4
4
|
repos:
|
|
5
5
|
|
|
6
6
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
7
|
-
rev:
|
|
7
|
+
rev: v4.4.0
|
|
8
8
|
hooks:
|
|
9
9
|
- id: trailing-whitespace
|
|
10
10
|
- id: check-json
|
|
11
|
-
- id: check-xml
|
|
12
11
|
- id: check-merge-conflict # checks for files that contain merge conflict strings
|
|
13
12
|
- id: check-added-large-files
|
|
14
13
|
args: [--maxkb=100]
|
|
15
14
|
|
|
16
15
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
|
17
|
-
rev: v1.
|
|
16
|
+
rev: v1.10.0
|
|
18
17
|
hooks:
|
|
19
18
|
- id: text-unicode-replacement-char # forbid files which have a UTF-8 Unicode replacement character
|
|
20
19
|
|
|
21
|
-
- repo: https://github.com/crate-ci/typos
|
|
22
|
-
rev: v1.12.14
|
|
23
|
-
hooks:
|
|
24
|
-
- id: typos # spell checker
|
|
25
|
-
|
|
26
20
|
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
|
27
|
-
rev: v2.
|
|
21
|
+
rev: v2.10.0
|
|
28
22
|
hooks:
|
|
29
23
|
- id: pretty-format-yaml
|
|
30
24
|
args: [--autofix, --indent, '2']
|
|
31
25
|
|
|
32
26
|
- repo: https://github.com/pre-commit/mirrors-eslint
|
|
33
|
-
rev: v8.
|
|
27
|
+
rev: v8.49.0
|
|
34
28
|
hooks:
|
|
35
29
|
- id: eslint # javascript linter and formatter
|
|
36
30
|
args: [--fix]
|
|
31
|
+
|
|
32
|
+
- repo: https://github.com/crate-ci/typos
|
|
33
|
+
rev: v1.16.11
|
|
34
|
+
hooks:
|
|
35
|
+
- id: typos # spell checker
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Tangelo Configuration Toolkit is a command-line toolkit which offers support for
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
The toolkit requires [NPM](https://www.npmjs.com/get-npm) on [Node.js®](https://nodejs.org/) (at least version
|
|
7
|
+
The toolkit requires [NPM](https://www.npmjs.com/get-npm) on [Node.js®](https://nodejs.org/) (at least version 18.x). An active or maintenance LTS release is recommended. After installing Node.js, you can install the latest version of the Tangelo Configuration Toolkit globally on your system using the following command:
|
|
8
8
|
|
|
9
9
|
npm i -g @tangelo/tangelo-configuration-toolkit
|
|
10
10
|
|
package/bitbucket-pipelines.yml
CHANGED
|
@@ -13,20 +13,20 @@ definitions:
|
|
|
13
13
|
- step: &build-test-sonarcloud
|
|
14
14
|
name: Build, test and analyze on SonarCloud
|
|
15
15
|
caches:
|
|
16
|
-
|
|
16
|
+
- sonar
|
|
17
17
|
script:
|
|
18
|
-
|
|
18
|
+
- pipe: sonarsource/sonarcloud-scan:2.0.0
|
|
19
19
|
- step: &check-quality-gate-sonarcloud
|
|
20
20
|
name: Check the Quality Gate on SonarCloud
|
|
21
21
|
script:
|
|
22
|
-
|
|
22
|
+
- pipe: sonarsource/sonarcloud-quality-gate:0.1.6
|
|
23
23
|
|
|
24
24
|
pipelines:
|
|
25
25
|
branches:
|
|
26
26
|
master:
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
- step: *build-test-sonarcloud
|
|
28
|
+
- step: *check-quality-gate-sonarcloud
|
|
29
29
|
pull-requests:
|
|
30
30
|
'**':
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
- step: *build-test-sonarcloud
|
|
32
|
+
- step: *check-quality-gate-sonarcloud
|
package/index.js
CHANGED
|
@@ -30,23 +30,23 @@ global._info = (msg, time = false) => {
|
|
|
30
30
|
console.log(msg.lgreen);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
global._warn =
|
|
33
|
+
global._warn = msg => {
|
|
34
34
|
console.log(msg.lyellow);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
global._error =
|
|
37
|
+
global._error = msg => {
|
|
38
38
|
console.log(msg.red, '\n');
|
|
39
39
|
process.exit();
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
global._perf =
|
|
42
|
+
global._perf = t1 => {
|
|
43
43
|
const t2 = new Date();
|
|
44
44
|
console.log(`\nExecution time: ${t2 - t1}ms`.blue);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
global._formatDate =
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
global._formatDate = date =>
|
|
48
|
+
date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'});
|
|
49
|
+
;
|
|
50
50
|
|
|
51
51
|
global._paths = {
|
|
52
52
|
app: __dirname,
|
|
@@ -61,7 +61,7 @@ _paths.apply = process.cwd().replace(_paths.repo, '').substr(1);
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
global._appdata = fs.readJsonSync(_paths.appdata, {throws: false}) || {};
|
|
64
|
-
_appdata._update =
|
|
64
|
+
_appdata._update = data => Object.assign(_appdata, data, {_changed: true});
|
|
65
65
|
if (!_appdata.npmPath) {
|
|
66
66
|
_appdata._update({npmPath: execSync('npm config get prefix', {encoding: 'UTF-8'}).replace(/\s$/, '')});
|
|
67
67
|
}
|
|
@@ -112,7 +112,7 @@ global._git = {
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
if (_git.commitTdi.after(_git.commitTdi.stopUsingRepoconfigFile)) {
|
|
115
|
-
global._repoconfig = require('./src/lib/get-repoconfig')();
|
|
115
|
+
global._repoconfig = require('./src/lib/get-repoconfig')(_paths.repo);
|
|
116
116
|
}
|
|
117
117
|
else {
|
|
118
118
|
try { global._repoconfig = fs.existsSync(_paths.repoconfig) && fs.readJsonSync(_paths.repoconfig) || {}; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangelo/tangelo-configuration-toolkit",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.4",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=14.0.0"
|
|
6
6
|
},
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"del": "^6.0.0",
|
|
29
29
|
"event-stream": "^4.0.1",
|
|
30
30
|
"find-up": "^5.0.0",
|
|
31
|
-
"fs-extra": "^
|
|
31
|
+
"fs-extra": "^11.1.1",
|
|
32
32
|
"globby": "^6.1.0",
|
|
33
33
|
"gulp": "^4.0.2",
|
|
34
34
|
"gulp-babel": "^8.0.0",
|
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
"gulp-sourcemaps": "^3.0.0",
|
|
41
41
|
"inquirer": "^8.2.0",
|
|
42
42
|
"istextorbinary": "^6.0.0",
|
|
43
|
-
"minimatch": "^
|
|
44
|
-
"node-ssh": "^
|
|
43
|
+
"minimatch": "^8.0.4",
|
|
44
|
+
"node-ssh": "^13.1.0",
|
|
45
45
|
"object-assign-deep": "^0.4.0",
|
|
46
46
|
"p-limit": "^3.1.0",
|
|
47
47
|
"replace-in-file": "^6.3.2",
|
|
48
48
|
"sass": "^1.43.5",
|
|
49
49
|
"saxon-js": "^2.3.0",
|
|
50
|
-
"ssh2-sftp-client": "^
|
|
50
|
+
"ssh2-sftp-client": "^9.1.0",
|
|
51
51
|
"through2": "^4.0.2",
|
|
52
52
|
"tiny-lr": "^2.0.0",
|
|
53
|
-
"yargs": "^
|
|
53
|
+
"yargs": "^17.7.2"
|
|
54
54
|
},
|
|
55
55
|
"repository": {
|
|
56
56
|
"type": "git",
|
|
@@ -2,12 +2,12 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const globby = require('globby');
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
module.exports = function getRepoconfig() {
|
|
5
|
+
module.exports = function getRepoconfig(repoPath) {
|
|
6
6
|
|
|
7
7
|
const repoconfig = [];
|
|
8
8
|
|
|
9
9
|
globby
|
|
10
|
-
.sync('database/config/**/txd_document_types.sql')
|
|
10
|
+
.sync('database/config/**/txd_document_types.sql', {cwd: repoPath, absolute: true})
|
|
11
11
|
.forEach(p => {
|
|
12
12
|
const dtSqlInsert = fs.readFileSync(p).toString().match(/select(.*?)from/s)[1];
|
|
13
13
|
const ntSqlInsert = fs.readFileSync(p.replace('txd_document_types', 'txd_node_types')).toString().match(/select(.*?)from/s)[1];
|
|
@@ -17,7 +17,7 @@ module.exports = function getRepoconfig() {
|
|
|
17
17
|
const xpiDir = ntSqlInsert.match(/'([^']+)' xsl_prep_inc/)[1];
|
|
18
18
|
|
|
19
19
|
const path_cmscustom = xpiDir.replace(/\/[^/]+$/, '').split(/\//);
|
|
20
|
-
const path_dbconfig = p.replace(
|
|
20
|
+
const path_dbconfig = p.replace(/.*\/database\/config\/(.*)\/[^/]+/, '$1').split(/[/\\]/);
|
|
21
21
|
const dnRegex = [path_cmscustom[0].replace(/[_'"]/g, '.'), path_dbconfig[0].replace(/[_'"]/g, '.')].sort((a, b) => b.length - a.length).join('|');
|
|
22
22
|
const customer_name = (dtDisplayName.match(RegExp(dnRegex, 'i')) || dtDisplayName.split(/ (.+)/))[0];
|
|
23
23
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-control-regex */
|
|
2
|
+
|
|
1
3
|
const styles = {bold: 1, underline: 4, black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, lblack: 90, lred: 91, lgreen: 92, lyellow: 93, lblue: 94, lmagenta: 95, lcyan: 96, lwhite: 97};
|
|
2
4
|
|
|
3
5
|
for (const name in styles ) {
|
|
@@ -11,14 +11,13 @@ const siteStylesheetsPath = 'config/txp/site-stylesheets/';
|
|
|
11
11
|
const masterFiles = new Set;
|
|
12
12
|
const transformationScenarios = [];
|
|
13
13
|
|
|
14
|
-
const convertToValidFilename =
|
|
14
|
+
const convertToValidFilename = string => string.replace(/[/|\\:*?"<>]/g, ' ');
|
|
15
15
|
|
|
16
|
-
const createProjectFile = (config,
|
|
16
|
+
const createProjectFile = (config, newXprFile) => {
|
|
17
17
|
_info('Initializing xpr file(s):');
|
|
18
18
|
const xprFiles = [...globby.sync(`*.xpr`)];
|
|
19
|
-
const newXprFile = (typeof filename === 'string') ? convertToValidFilename(filename) + '.xpr' : null;
|
|
20
19
|
// Add newXprFile at the start of xprFiles if it does not already exists:
|
|
21
|
-
if (xprFiles.indexOf(newXprFile)===-1) xprFiles.unshift(newXprFile);
|
|
20
|
+
if (newXprFile && xprFiles.indexOf(newXprFile)===-1) xprFiles.unshift(newXprFile);
|
|
22
21
|
|
|
23
22
|
// Copy xpr file from TDI if it does not exists yet;
|
|
24
23
|
if (xprFiles[0] && !newXprFile) _write(`Found: ${xprFiles.join(', ')}`);
|
|
@@ -49,10 +48,10 @@ const createProjectFile = (config, filename) => {
|
|
|
49
48
|
transformXprFile(xprFiles);
|
|
50
49
|
};
|
|
51
50
|
|
|
52
|
-
const getTransformations =
|
|
51
|
+
const getTransformations = config => {
|
|
53
52
|
_repoconfig.forEach(rc => {
|
|
54
53
|
// get pathname of customer/project
|
|
55
|
-
const [customerPath, projectPath] = config.location
|
|
54
|
+
const [customerPath, projectPath] = config.location === 'database' ? rc.path_dbconfig : rc.path_cmscustom;
|
|
56
55
|
|
|
57
56
|
// set pathname of customer/project in location glob-expression
|
|
58
57
|
const location = path.join(
|
|
@@ -67,7 +66,7 @@ const getTransformations = (config) => {
|
|
|
67
66
|
const fileString = fs.readFileSync(f).toString();
|
|
68
67
|
const baseStrings = fileString.match(RegExp(config.extracts.base, 'gm'));
|
|
69
68
|
|
|
70
|
-
if (fileString.replace(/\s|^prompt\s.*$/gm, '')!=='') {
|
|
69
|
+
if (fileString.replace(/\s|^prompt\s.*$/gm, '') !== '') {
|
|
71
70
|
if (baseStrings) {
|
|
72
71
|
baseStrings.forEach(s => {
|
|
73
72
|
// extract type, name, files info from baseString
|
|
@@ -79,12 +78,12 @@ const getTransformations = (config) => {
|
|
|
79
78
|
transformationScenarios.push({
|
|
80
79
|
name: `${type}: ${name} (${rc.customer_name}, ${rc.project_name})`, // note that in createProjectFile.xsl a regex is added that matches scenarios based on this name. This to preserve manually added scenarios.
|
|
81
80
|
transformationScenario: files,
|
|
82
|
-
location: config.location
|
|
81
|
+
location: config.location === 'txp' ? siteStylesheetsPath : cmscustomPath
|
|
83
82
|
});
|
|
84
83
|
|
|
85
84
|
// Add each non-tdi stylesheet in transformation scenario to the masterFiles set
|
|
86
85
|
files.split(',').forEach(f => {
|
|
87
|
-
const filePath = `${config.location
|
|
86
|
+
const filePath = `${config.location === 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
|
|
88
87
|
if (!f.startsWith('tdi')) masterFiles.add(filePath);
|
|
89
88
|
});
|
|
90
89
|
});
|
|
@@ -98,7 +97,7 @@ const getTransformations = (config) => {
|
|
|
98
97
|
};
|
|
99
98
|
|
|
100
99
|
|
|
101
|
-
const getMasterfiles =
|
|
100
|
+
const getMasterfiles = config => {
|
|
102
101
|
globby
|
|
103
102
|
.sync(`${path.join(_paths.repo, config.files)}`)
|
|
104
103
|
.forEach(cf => {
|
|
@@ -118,7 +117,7 @@ const getMasterfiles = (config) => {
|
|
|
118
117
|
// Add each non-tdi masterfile to the masterFiles set
|
|
119
118
|
filesString.split(',').forEach(f => {
|
|
120
119
|
if (!f.startsWith('tdi')){
|
|
121
|
-
const filePath = `${config.location
|
|
120
|
+
const filePath = `${config.location === 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
|
|
122
121
|
masterFiles.add(filePath);
|
|
123
122
|
}
|
|
124
123
|
});
|
|
@@ -127,7 +126,7 @@ const getMasterfiles = (config) => {
|
|
|
127
126
|
_write(`No masterfiles found in ${cf} for '${config.extracts.base}'`);
|
|
128
127
|
}
|
|
129
128
|
} else { // Add synced file to masterfiles; strip path from c:/... hence it starts with config/cmscustom or config/txp/site-stylesheets
|
|
130
|
-
const filePath = config.location
|
|
129
|
+
const filePath = config.location === 'txp' ? `${siteStylesheetsPath}${cf.split(siteStylesheetsPath)[1]}` : `${cmscustomPath}${cf.split(cmscustomPath)[1]}`;
|
|
131
130
|
masterFiles.add(filePath);
|
|
132
131
|
}
|
|
133
132
|
}
|
|
@@ -135,7 +134,7 @@ const getMasterfiles = (config) => {
|
|
|
135
134
|
|
|
136
135
|
};
|
|
137
136
|
|
|
138
|
-
const transformXprFile =
|
|
137
|
+
const transformXprFile = xprFiles => {
|
|
139
138
|
_info('\nUpdating xpr file(s):');
|
|
140
139
|
// create with: xslt3 -t -xsl:createProjectFile.xsl -export:createProjectFile.sef.json v -nogo'
|
|
141
140
|
|
|
@@ -162,7 +161,7 @@ const transformXprFile = (xprFiles) => {
|
|
|
162
161
|
};
|
|
163
162
|
|
|
164
163
|
|
|
165
|
-
module.exports = function oxygen (
|
|
164
|
+
module.exports = function oxygen (arg) {
|
|
166
165
|
// Set projects transformation scenarios and masterfiles in oXygen project file
|
|
167
166
|
// - Will try to preserve manually added entries in the transformation scenarios and masterfiles
|
|
168
167
|
// - Will remove non existing masterfiles or masterfiles that start with a '_'
|
|
@@ -171,5 +170,6 @@ module.exports = function oxygen (filename) {
|
|
|
171
170
|
_error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`);
|
|
172
171
|
}
|
|
173
172
|
|
|
174
|
-
|
|
173
|
+
const newXprFile = (typeof arg === 'string') ? convertToValidFilename(arg) + '.xpr' : null;
|
|
174
|
+
createProjectFile(require(spConfigPath), newXprFile);
|
|
175
175
|
};
|
|
@@ -56,8 +56,8 @@ module.exports = {
|
|
|
56
56
|
resolve();
|
|
57
57
|
});
|
|
58
58
|
})
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
.then(() => cmdExec(`${fdt} editor upgrade --version ${fontoVersion} --non-interactive`))
|
|
60
|
+
.then(() => [fdt])
|
|
61
61
|
;
|
|
62
62
|
},
|
|
63
63
|
|
|
@@ -154,7 +154,7 @@ module.exports = {
|
|
|
154
154
|
else _write(result, '\n');
|
|
155
155
|
}
|
|
156
156
|
)
|
|
157
|
-
|
|
157
|
+
.then(() => [fdt])
|
|
158
158
|
;
|
|
159
159
|
},
|
|
160
160
|
|
|
@@ -205,7 +205,7 @@ module.exports = {
|
|
|
205
205
|
else _write(result, '\n');
|
|
206
206
|
}
|
|
207
207
|
)
|
|
208
|
-
|
|
208
|
+
.then(() => [fdt])
|
|
209
209
|
;
|
|
210
210
|
},
|
|
211
211
|
|
|
@@ -31,7 +31,7 @@ module.exports = function fonto (argv) {
|
|
|
31
31
|
// find fonto instances by searching for fonto/manifest.json files
|
|
32
32
|
const fontoPaths = globby.sync(['**/fonto/manifest.json', 'manifest.json', `!${_paths.tdi}/**`])
|
|
33
33
|
.map(p => ([p.replace('manifest.json', ''), fs.readJsonSync(p).sdkVersion.replace(/Nightlies.*/, 'nightly')])
|
|
34
|
-
|
|
34
|
+
);
|
|
35
35
|
|
|
36
36
|
if (fontoPaths.length===0) _error('No Fonto instance found.');
|
|
37
37
|
|
|
@@ -61,13 +61,13 @@ module.exports = function fonto (argv) {
|
|
|
61
61
|
_write(fontoVersionNew+'\n');
|
|
62
62
|
return resolve([fdtCommand(fontoVersionNew), fontoVersionNew]);
|
|
63
63
|
})
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
.then(argv.init && commands.init)
|
|
65
|
+
.then(argv.schema && commands.schema)
|
|
66
|
+
.then(argv.elements && commands.elements)
|
|
67
|
+
.then(argv.attributes && commands.attributes)
|
|
68
|
+
.then(argv.localize && commands.localize)
|
|
69
|
+
.then(argv.build && commands.build)
|
|
70
|
+
.then(argv.run && commands.run)
|
|
71
71
|
;
|
|
72
72
|
});
|
|
73
73
|
});
|
package/src/modules/git/index.js
CHANGED
|
@@ -146,7 +146,7 @@ module.exports = function git (argv) {
|
|
|
146
146
|
if (fs.existsSync(tdiMigrationFilePath)) {
|
|
147
147
|
const migrations = require(tdiMigrationFilePath);
|
|
148
148
|
const fromTdiDate = tdiFromDateCustom ? new Date(tdiFromDateCustom) : (tdiBranch.commonAncestor) ? tdiBranch.commonAncestor.date: _git.commitTdi.local().date;
|
|
149
|
-
const toTdiDate = tdiToDateCustom ? new Date(tdiToDateCustom) : new Date(
|
|
149
|
+
const toTdiDate = tdiToDateCustom ? new Date(tdiToDateCustom) : new Date();
|
|
150
150
|
|
|
151
151
|
_info(`TDI commits requiring migration between ${_formatDate(fromTdiDate)} and ${_formatDate(toTdiDate)}`);
|
|
152
152
|
// Filter the migrations that should be applied/considered; Also display older releases migrations
|
|
@@ -52,7 +52,7 @@ module.exports = function steps (step, dry, filter) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
let filesModCount = 0;
|
|
55
|
-
let maxRepeat =
|
|
55
|
+
let maxRepeat = 15;
|
|
56
56
|
for (let i=0; i<maxRepeat && r.files[0]; i++) { // execute repeatedly for modified files only (with safety limit of 20)
|
|
57
57
|
r.files = rif.sync(r).filter(f => f.hasChanged).map(f => f.file);
|
|
58
58
|
if (i===0) filesModCount = r.files.length; // save count only after first run (after this only subsets are processed)
|