@tangelo/tangelo-configuration-toolkit 1.14.4 → 1.16.0
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/README.md +2 -7
- package/index.js +72 -14
- package/package.json +1 -1
- package/src/cli.js +17 -19
- package/src/modules/build/index.js +10 -14
- package/src/modules/build/oxygen.js +10 -7
- package/src/modules/fonto/index.js +8 -10
- package/src/modules/git/index.js +18 -24
- package/src/modules/info/index.js +3 -4
- package/src/modules/migrate/index.js +3 -3
- package/src/modules/sql/index.js +3 -3
- package/.eslintrc.js +0 -47
- package/.pre-commit-config.yaml +0 -35
- package/.vscode/settings.json +0 -6
- package/bitbucket-pipelines.yml +0 -32
package/README.md
CHANGED
|
@@ -26,7 +26,8 @@ Use the `tct` shorthand instead of `tangelo-configuration-toolkit`:
|
|
|
26
26
|
|
|
27
27
|
### Global
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
TCT requires a config file to work: `${userhome}/.tct/appconfig.json`\
|
|
30
|
+
Several commands, like the `deploy` command, require server connection information, which can be stored in here.
|
|
30
31
|
|
|
31
32
|
The contents looks like this (all properties are optional):
|
|
32
33
|
|
|
@@ -53,12 +54,6 @@ The contents looks like this (all properties are optional):
|
|
|
53
54
|
|
|
54
55
|
When passing a server name, `tct` will look for a full match with a name or a partial match (the start) with a domain.
|
|
55
56
|
|
|
56
|
-
### Repo
|
|
57
|
-
|
|
58
|
-
The `build` and `sql` commands make use of a configuration file in the repository named `tangelo-configuration-toolkit-repoconfig.json`. This contains information about the customer projects.
|
|
59
|
-
|
|
60
|
-
For a new repository, using `tct build --init` also creates the repoconfig-file. For existing projects not having the repoconfig-file, you can use `tct build --config` to generate it.
|
|
61
|
-
|
|
62
57
|
### oXygen
|
|
63
58
|
|
|
64
59
|
The `build -x` commands set projects transformation scenarios and masterfiles in the oXygen project file with the following functionality:
|
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@ String.prototype.toFws = function(){
|
|
|
8
8
|
const {execSync} = require('child_process');
|
|
9
9
|
const findUp = require('find-up');
|
|
10
10
|
const fs = require('fs-extra');
|
|
11
|
+
const homedir = require('os').homedir();
|
|
11
12
|
const path = require('path');
|
|
12
13
|
|
|
13
14
|
const execGitCommand = require('./src/lib/exec-git-command');
|
|
@@ -45,17 +46,25 @@ global._perf = t1 => {
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
global._formatDate = date =>
|
|
48
|
-
date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'})
|
|
49
|
+
date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'})
|
|
49
50
|
;
|
|
50
51
|
|
|
52
|
+
|
|
53
|
+
global._packages = {
|
|
54
|
+
TCT: {name: '@tangelo/tangelo-configuration-toolkit', version: require('./package.json')?.version},
|
|
55
|
+
FDT: {name: '@fontoxml/fontoxml-development-tools'}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
51
59
|
global._paths = {
|
|
52
60
|
app: __dirname,
|
|
53
|
-
|
|
54
|
-
appconfig: findUp.sync(appname+'-appconfig.json'),
|
|
61
|
+
apphome: path.join(homedir, '.tct'),
|
|
55
62
|
repo: findUp.sync(dir => fs.existsSync(path.join(dir, '.git')) && dir, {type: 'directory'}) || '',
|
|
56
63
|
tdi: 'tangelo-default-implementation',
|
|
57
64
|
gitremote: 'git@bitbucket.org:tangelosoftware'
|
|
58
65
|
};
|
|
66
|
+
_paths.appdata = path.join(_paths.apphome, 'appdata.json');
|
|
67
|
+
_paths.appconfig = path.join(_paths.apphome, 'appconfig.json');
|
|
59
68
|
_paths.repoconfig = path.join(_paths.repo, appname+'-repoconfig.json');
|
|
60
69
|
_paths.apply = process.cwd().replace(_paths.repo, '').substr(1);
|
|
61
70
|
|
|
@@ -66,15 +75,37 @@ if (!_appdata.npmPath) {
|
|
|
66
75
|
_appdata._update({npmPath: execSync('npm config get prefix', {encoding: 'UTF-8'}).replace(/\s$/, '')});
|
|
67
76
|
}
|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
|
|
79
|
+
if (!fs.existsSync(_paths.appconfig)) { // try to find old appconfig (TCT-162 => remove code block in next version)
|
|
80
|
+
fs.ensureDirSync(_paths.apphome);
|
|
81
|
+
const oldPathAppconfig = findUp.sync(appname+'-appconfig.json');
|
|
82
|
+
if (oldPathAppconfig) {
|
|
83
|
+
fs.renameSync(oldPathAppconfig, _paths.appconfig);
|
|
84
|
+
_info(`${appname}-appconfig.json moved to ${_paths.apphome}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
global._appconfig = { // default appconfig if file not found
|
|
89
|
+
'sharedConfigPath': path.join(homedir, 'Dropbox (Tangelo Software)/Product Distribution/tooling'),
|
|
90
|
+
'servers': [],
|
|
91
|
+
'defaultServer': 'tdpXX',
|
|
92
|
+
'defaultDatabase': 'tdpXX'
|
|
72
93
|
};
|
|
73
94
|
|
|
74
|
-
try {
|
|
75
|
-
|
|
95
|
+
try {
|
|
96
|
+
global._appconfig = fs.readJsonSync(_paths.appconfig);
|
|
97
|
+
}
|
|
98
|
+
catch({code, message}) {
|
|
99
|
+
if (code === 'ENOENT') { // create appconfig json if not exists
|
|
100
|
+
fs.ensureDirSync(_paths.apphome);
|
|
101
|
+
fs.writeJsonSync(_paths.appconfig, global._appconfig, {spaces: 2});
|
|
102
|
+
_info(`${_paths.appconfig} was created`);
|
|
103
|
+
}
|
|
104
|
+
else _error('Could not load app-config: '+message);
|
|
105
|
+
}
|
|
106
|
+
|
|
76
107
|
|
|
77
|
-
_appconfig.sharedConfigPath = path.resolve(_paths.appconfig
|
|
108
|
+
_appconfig.sharedConfigPath = path.resolve(_paths.appconfig, '..', _appconfig.sharedConfigPath || '', appname+'-appconfig.json');
|
|
78
109
|
_appconfig.shared = fs.readJsonSync(_appconfig.sharedConfigPath, {throws: false}) || {};
|
|
79
110
|
|
|
80
111
|
|
|
@@ -83,7 +114,8 @@ global._git = {
|
|
|
83
114
|
if (!_appdata.gitUser) _appdata._update({gitUser: execGitCommand(`config --get user.email`, _paths.repo)});
|
|
84
115
|
return _appdata.gitUser;
|
|
85
116
|
},
|
|
86
|
-
commitLocal () {
|
|
117
|
+
commitLocal (clearcache) {
|
|
118
|
+
if (clearcache) delete this.cache;
|
|
87
119
|
this.cache ??= execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, _paths.repo, ['branch', 'hash', 'date']);
|
|
88
120
|
return this.cache;
|
|
89
121
|
},
|
|
@@ -92,7 +124,8 @@ global._git = {
|
|
|
92
124
|
return this.cache;
|
|
93
125
|
},
|
|
94
126
|
commitTdi: {
|
|
95
|
-
local () {
|
|
127
|
+
local (clearcache) {
|
|
128
|
+
if (clearcache) delete this.cache;
|
|
96
129
|
this.cache ??= execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, path.join(_paths.repo, _paths.tdi), ['tags', 'hash', 'date']);
|
|
97
130
|
return this.cache;
|
|
98
131
|
},
|
|
@@ -124,9 +157,34 @@ else {
|
|
|
124
157
|
}
|
|
125
158
|
|
|
126
159
|
|
|
127
|
-
global._tdiSubmoduleExists = fs.existsSync(path.join(_paths.repo, _paths.tdi));
|
|
128
|
-
global._isPre42 = fs.existsSync(path.join(_paths.repo, _paths.tdi, 'create_new_project')); // folder changed in 4.2
|
|
129
|
-
global._isPre51 = !fs.existsSync(path.join(_paths.repo, _paths.tdi, 'src')); // folder changed in 5.1 (check new folder because old one could still exist after branch switch)
|
|
160
|
+
global._tdiSubmoduleExists = () => fs.existsSync(path.join(_paths.repo, _paths.tdi));
|
|
161
|
+
global._isPre42 = () => fs.existsSync(path.join(_paths.repo, _paths.tdi, 'create_new_project')); // folder changed in 4.2
|
|
162
|
+
global._isPre51 = () => !fs.existsSync(path.join(_paths.repo, _paths.tdi, 'src')); // folder changed in 5.1 (check new folder because old one could still exist after branch switch)
|
|
163
|
+
|
|
164
|
+
global._modulesTdi = {
|
|
165
|
+
absolutePathTdi: path.join(_paths.repo, _paths.tdi),
|
|
166
|
+
ensureDepsUpToDate() {
|
|
167
|
+
if (this.depsUpToDate) return;
|
|
168
|
+
try {
|
|
169
|
+
_info('Checking installed dependencies in submodule');
|
|
170
|
+
execSync('npm list', {cwd: this.absolutePathTdi, stdio: 'ignore'});
|
|
171
|
+
} catch (e) {
|
|
172
|
+
_info('Updating dependencies in submodule');
|
|
173
|
+
execSync('npm update', {cwd: this.absolutePathTdi, stdio: 'ignore'});
|
|
174
|
+
}
|
|
175
|
+
this.depsUpToDate = true;
|
|
176
|
+
},
|
|
177
|
+
require(module) {
|
|
178
|
+
this.ensureDepsUpToDate();
|
|
179
|
+
_info(`Loading ${path.join(_paths.tdi, 'tct', module)}\n`);
|
|
180
|
+
try {
|
|
181
|
+
return require(path.join(this.absolutePathTdi, 'tct', module));
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
_error('Module could not be loaded');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
130
188
|
|
|
131
189
|
|
|
132
190
|
process.on('beforeExit', () => {
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -8,13 +8,22 @@ module.exports = function cli () {
|
|
|
8
8
|
const txtTitle = 'Tangelo Configuration Toolkit'.bold.underline.cyan;
|
|
9
9
|
const txtVersion = `v${_packages.TCT.version}`.lblack;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
yargs
|
|
12
12
|
.scriptName('tct')
|
|
13
13
|
.usage(`${txtTitle} ${txtVersion}\n\nUsage: $0 <command> [options]`)
|
|
14
14
|
.middleware(argv => { // executes before command handlers
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const command = argv._[0];
|
|
16
|
+
const optionsPassed = Object.keys(argv).length > 2;
|
|
17
|
+
const gitInitOrClone = (command === 'git' || command === 'g') && (argv.init || argv.clone);
|
|
18
|
+
|
|
19
|
+
if (!command && argv.config) {
|
|
20
|
+
_info(`Loaded appconfig:`);
|
|
21
|
+
_write(_paths.appconfig);
|
|
22
|
+
_write(_appconfig);
|
|
23
|
+
}
|
|
24
|
+
else if (optionsPassed && !gitInitOrClone) {
|
|
25
|
+
if (_tdiSubmoduleExists()) process.chdir(_paths.repo); // set cwd to repo root before executing an option
|
|
26
|
+
else _error('This option can only be used inside a git repo having the TDI submodule!');
|
|
18
27
|
}
|
|
19
28
|
})
|
|
20
29
|
.command({
|
|
@@ -119,24 +128,13 @@ module.exports = function cli () {
|
|
|
119
128
|
['$0 git --update tdi --branch 5.4', 'Update TDI submodule to latest in specified branch']
|
|
120
129
|
])
|
|
121
130
|
.check((argv, options) => {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return true;
|
|
131
|
+
const nonDefaultOptions = Object.keys(options.key).filter(o => !Object.keys(options.default).includes(o));
|
|
132
|
+
if (nonDefaultOptions.some(o => argv[o])) return true;
|
|
133
|
+
else throw new Error('Pass a non-default option');
|
|
126
134
|
})
|
|
127
135
|
.strict()
|
|
128
136
|
.wrap(100)
|
|
137
|
+
.parse()
|
|
129
138
|
;
|
|
130
139
|
|
|
131
|
-
|
|
132
|
-
if (!argv._[0]) { // no command chosen
|
|
133
|
-
|
|
134
|
-
if (argv.config) {
|
|
135
|
-
if (!_paths.appconfig) _error('No config loaded: tangelo-configuration-toolkit-appconfig.json not found');
|
|
136
|
-
_info(`Loaded appconfig (using ${_paths.appconfig}):`);
|
|
137
|
-
_write(_appconfig);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
140
|
};
|
|
@@ -17,7 +17,7 @@ const createSymlink = (t, p) => {
|
|
|
17
17
|
|
|
18
18
|
const createSymlinks = () => {
|
|
19
19
|
_info('Creating symlinks:');
|
|
20
|
-
const src = _isPre51 ? 'sources' : 'src';
|
|
20
|
+
const src = _isPre51() ? 'sources' : 'src';
|
|
21
21
|
createSymlink(src + '/config/cmscustom/tdi', 'config/cmscustom/tdi');
|
|
22
22
|
globby
|
|
23
23
|
.sync('config/cmscustom/!(tdi)/**/fonto')
|
|
@@ -29,17 +29,16 @@ const createSymlinks = () => {
|
|
|
29
29
|
|
|
30
30
|
module.exports = function build (argv) {
|
|
31
31
|
|
|
32
|
-
if (argv.init)
|
|
33
|
-
if (_isPre51) _error('This option only works when using branch release/5.1 and up.');
|
|
32
|
+
if ((argv.init || argv.project) && _isPre51()) _error('This option only works when using branch release/5.1 and up.');
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (argv.project) {
|
|
39
|
-
if (_isPre51) _error('This option only works when using branch release/5.1 and up.');
|
|
34
|
+
const predefinedAnswers = (argv.init === 'file' || argv.project === 'file') ? _appconfig.build : undefined;
|
|
35
|
+
// if not chosen to use predefined values by passing "file", erase the "build" property for old TDI commits
|
|
36
|
+
_appconfig.build = predefinedAnswers;
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
if (argv.init) _modulesTdi.require('build/init')(createSymlinks, predefinedAnswers);
|
|
42
39
|
|
|
40
|
+
if (argv.project === 'file') _modulesTdi.require('build/project').projectNew(createSymlinks, _repoconfig[0], predefinedAnswers);
|
|
41
|
+
else if (argv.project) {
|
|
43
42
|
inquirer
|
|
44
43
|
.prompt([{
|
|
45
44
|
message: 'Create project: ', name: 'project', type: 'list',
|
|
@@ -53,10 +52,8 @@ module.exports = function build (argv) {
|
|
|
53
52
|
]
|
|
54
53
|
}])
|
|
55
54
|
.then(a => {
|
|
56
|
-
if (a.project
|
|
57
|
-
else
|
|
58
|
-
projectCopy(createSymlinks, a.project);
|
|
59
|
-
}
|
|
55
|
+
if (a.project === 'TDI') _modulesTdi.require('build/project').projectNew(createSymlinks, _repoconfig[0]);
|
|
56
|
+
else _modulesTdi.require('build/project').projectCopy(createSymlinks, a.project);
|
|
60
57
|
});
|
|
61
58
|
}
|
|
62
59
|
|
|
@@ -76,7 +73,6 @@ module.exports = function build (argv) {
|
|
|
76
73
|
if (argv.config) {
|
|
77
74
|
if (_git.commitTdi.after(_git.commitTdi.stopUsingRepoconfigFile)) _error('This option only works for older repo\'s using a repoconfig file.');
|
|
78
75
|
|
|
79
|
-
|
|
80
76
|
inquirer
|
|
81
77
|
.prompt([{message: 'Be sure paths for projects are [customer]/[project]. Continue?', name: 'confirm', type: 'confirm'}])
|
|
82
78
|
.then(({confirm}) => {
|
|
@@ -3,14 +3,16 @@ const globby = require('globby');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const SaxonJS = require('saxon-js');
|
|
5
5
|
|
|
6
|
-
const spConfigPath =
|
|
7
|
-
const sefFilePath =
|
|
6
|
+
const spConfigPath = 'build/oxygen/stylesheetPaths.json';
|
|
7
|
+
const sefFilePath = 'build/oxygen/createProjectFile.sef.json';
|
|
8
8
|
const cmscustomPath = 'config/cmscustom/';
|
|
9
9
|
const siteStylesheetsPath = 'config/txp/site-stylesheets/';
|
|
10
10
|
|
|
11
11
|
const masterFiles = new Set;
|
|
12
12
|
const transformationScenarios = [];
|
|
13
13
|
|
|
14
|
+
let spConfig, sefFile;
|
|
15
|
+
|
|
14
16
|
const convertToValidFilename = string => string.replace(/[/|\\:*?"<>]/g, ' ');
|
|
15
17
|
|
|
16
18
|
const createProjectFile = (config, newXprFile) => {
|
|
@@ -143,7 +145,7 @@ const transformXprFile = xprFiles => {
|
|
|
143
145
|
// Transform xpr; add masterfiles and transformationScenarios as parameters of the stylesheet
|
|
144
146
|
_write(`${xprFile}\n`);
|
|
145
147
|
SaxonJS.transform({
|
|
146
|
-
stylesheetText:
|
|
148
|
+
stylesheetText: JSON.stringify(sefFile),
|
|
147
149
|
stylesheetBaseURI: 'createProjectFile.sef.json',
|
|
148
150
|
sourceFileName: path.join(_paths.repo, xprFile),
|
|
149
151
|
destination: 'serialized',
|
|
@@ -166,10 +168,11 @@ module.exports = function oxygen (arg) {
|
|
|
166
168
|
// - Will try to preserve manually added entries in the transformation scenarios and masterfiles
|
|
167
169
|
// - Will remove non existing masterfiles or masterfiles that start with a '_'
|
|
168
170
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
spConfig = _modulesTdi.require(spConfigPath);
|
|
172
|
+
sefFile = _modulesTdi.require(sefFilePath);
|
|
173
|
+
|
|
174
|
+
if (!spConfig || !sefFile) _error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`);
|
|
172
175
|
|
|
173
176
|
const newXprFile = (typeof arg === 'string') ? convertToValidFilename(arg) + '.xpr' : null;
|
|
174
|
-
createProjectFile(
|
|
177
|
+
createProjectFile(spConfig, newXprFile);
|
|
175
178
|
};
|
|
@@ -5,13 +5,13 @@ const globby = require('globby');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
const fdtCommand =
|
|
8
|
+
const fdtCommand = fv => `npx -y ${_packages.FDT.name}@${fv.replace(/^(7\.|8\.[012]\.).*/, '3.12.0')}`;
|
|
9
9
|
|
|
10
10
|
module.exports = function fonto (argv) {
|
|
11
11
|
|
|
12
12
|
const allowedFontoVersionRegex = (() => {
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
13
|
+
const cvRegex = _modulesTdi.require('fonto/compatibleVersions.json')?.regex;
|
|
14
|
+
if (cvRegex) return RegExp(cvRegex);
|
|
15
15
|
|
|
16
16
|
// old way: a regex for each basecommit is stored in global._git.commitTdi
|
|
17
17
|
for (const fv of _git.commitTdi.fontoVersions) {
|
|
@@ -19,8 +19,6 @@ module.exports = function fonto (argv) {
|
|
|
19
19
|
}
|
|
20
20
|
})();
|
|
21
21
|
|
|
22
|
-
if (!_tdiSubmoduleExists) _error('TDI submodule folder is missing.');
|
|
23
|
-
|
|
24
22
|
// check if FDT is not installed globally, because then it won't be possible to use specific versions with npx
|
|
25
23
|
if (fs.pathExistsSync(path.join(_appdata.npmPath, 'node_modules', _packages.FDT.name))) {
|
|
26
24
|
_error(`A global installation of FDT has been found! Remove it first.\nExecute: npm r -g ${_packages.FDT.name}`);
|
|
@@ -30,8 +28,8 @@ module.exports = function fonto (argv) {
|
|
|
30
28
|
|
|
31
29
|
// find fonto instances by searching for fonto/manifest.json files
|
|
32
30
|
const fontoPaths = globby.sync(['**/fonto/manifest.json', 'manifest.json', `!${_paths.tdi}/**`])
|
|
33
|
-
.map(p => ([p.replace('manifest.json', ''), fs.readJsonSync(p).sdkVersion.replace(/Nightlies.*/, 'nightly')])
|
|
34
|
-
|
|
31
|
+
.map(p => ([p.replace('manifest.json', ''), fs.readJsonSync(p).sdkVersion.replace(/Nightlies.*/, 'nightly')]))
|
|
32
|
+
;
|
|
35
33
|
|
|
36
34
|
if (fontoPaths.length===0) _error('No Fonto instance found.');
|
|
37
35
|
|
|
@@ -43,14 +41,14 @@ module.exports = function fonto (argv) {
|
|
|
43
41
|
.then(() => {
|
|
44
42
|
process.chdir(path.join(_paths.repo, _paths.apply, fontoPath));
|
|
45
43
|
|
|
46
|
-
if (fontoPath
|
|
44
|
+
if (fontoPath !== '.') _info(`${i>0 ? '\n' : ''}Fonto instance #${i+1}: ${path.join(_paths.apply, fontoPath)}\n`);
|
|
47
45
|
|
|
48
46
|
// execute commands sequentially and in correct order
|
|
49
|
-
return new Promise(
|
|
47
|
+
return new Promise(resolve => {
|
|
50
48
|
_info('Determining Fonto version:');
|
|
51
49
|
let fontoVersionNew = typeof argv.init == 'string' ? argv.init : fontoVersionCurrent;
|
|
52
50
|
|
|
53
|
-
if (fontoVersionNew
|
|
51
|
+
if (fontoVersionNew === 'latest') {
|
|
54
52
|
const data = execSync(`${fdtCommand(fontoVersionCurrent)} editor versions`, {encoding: 'UTF-8'});
|
|
55
53
|
fontoVersionNew = data.match(/\d+\.\d+\.\d+/g).filter(v => allowedFontoVersionRegex.test(v))[0];
|
|
56
54
|
}
|
package/src/modules/git/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const {execSync, spawn} = require('child_process');
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const fs = require('fs-extra');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const path = require('path');
|
|
6
4
|
|
|
7
5
|
const execGitCommand = require('../../lib/exec-git-command');
|
|
8
6
|
const getTdiBranch = require('../../lib/get-tdi-branch');
|
|
@@ -15,7 +13,8 @@ const cmdExec = commands => new Promise(resolve => {
|
|
|
15
13
|
|
|
16
14
|
const log = msg => {
|
|
17
15
|
const line = msg.replace(/\s+$/, ''); // remove excessive whitespace
|
|
18
|
-
if (line)
|
|
16
|
+
if (line?.startsWith('fatal:')) _error(line);
|
|
17
|
+
else if (line) _write(line);
|
|
19
18
|
};
|
|
20
19
|
|
|
21
20
|
const cmdArr = command.split(/ (.+)/);
|
|
@@ -36,7 +35,6 @@ const cmdExec = commands => new Promise(resolve => {
|
|
|
36
35
|
});
|
|
37
36
|
});
|
|
38
37
|
|
|
39
|
-
const tdiMigrationFilePath = path.join(_paths.repo, _paths.tdi, 'tct/git/tdiCommitsRequiringMigration.js');
|
|
40
38
|
|
|
41
39
|
module.exports = function git (argv) {
|
|
42
40
|
|
|
@@ -89,7 +87,7 @@ module.exports = function git (argv) {
|
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
if (argv.clone) {
|
|
92
|
-
if (argv.clone
|
|
90
|
+
if (typeof argv.clone !== 'string') _error('Pass a repository name!');
|
|
93
91
|
|
|
94
92
|
_info('Clone a client repository and do basic project initialization');
|
|
95
93
|
cmdExec([
|
|
@@ -97,8 +95,8 @@ module.exports = function git (argv) {
|
|
|
97
95
|
['git clone git@bitbucket.org:tangelosoftware/' + argv.clone + '.git']
|
|
98
96
|
])
|
|
99
97
|
.then(() => {
|
|
100
|
-
|
|
101
|
-
chdir('./' + argv.clone);
|
|
98
|
+
// Change directory for the next commands, it should have the same name as the clone argument from commandline at this point
|
|
99
|
+
process.chdir('./' + argv.clone);
|
|
102
100
|
cmdExec([
|
|
103
101
|
// Retrieve TDI submodule for this client
|
|
104
102
|
['git submodule update --init', 'Fetch submodules such as TDI'],
|
|
@@ -107,17 +105,9 @@ module.exports = function git (argv) {
|
|
|
107
105
|
// Create Oxygen project file and set name equal to repo name
|
|
108
106
|
[`tct b -x ${argv.clone}`, 'Create Oxygen project file'],
|
|
109
107
|
]);
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
_warn(`System environment variable 'GIT_SSH' is missing. (link to putty plink.exe)`);
|
|
114
|
-
}
|
|
115
|
-
if (!process.env.GIT_SSH_COMMAND) {
|
|
116
|
-
_warn(`System environment variable 'GIT_SSH_COMMAND' is missing. (link to putty plink.exe)`);
|
|
117
|
-
}
|
|
118
|
-
// continue display stack trace
|
|
119
|
-
throw e;
|
|
120
|
-
});
|
|
108
|
+
})
|
|
109
|
+
.catch(e => {throw e;})
|
|
110
|
+
;
|
|
121
111
|
}
|
|
122
112
|
|
|
123
113
|
if (argv.update) {
|
|
@@ -140,11 +130,14 @@ module.exports = function git (argv) {
|
|
|
140
130
|
const updateSubmoduleMsg = execGitCommand(`submodule update --remote`, _paths.repo);
|
|
141
131
|
if (updateSubmoduleMsg.error && !tdiFromDateCustom) _error(`Update submodule failed\n${updateSubmoduleMsg.error}`);
|
|
142
132
|
|
|
133
|
+
// update local TDI commit data
|
|
134
|
+
_git.commitTdi.local(true);
|
|
135
|
+
|
|
143
136
|
if (!tdiFromDateCustom) _info(`TDI submodule updated:\n${updateSubmoduleMsg}`);
|
|
144
137
|
|
|
145
138
|
// tdiMigrationFilePath should exist in latest commits of releases 5.3+; As we updated to the latest version this should work
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
const migrations = _modulesTdi.require('git/tdiCommitsRequiringMigration.js');
|
|
140
|
+
if (migrations) {
|
|
148
141
|
const fromTdiDate = tdiFromDateCustom ? new Date(tdiFromDateCustom) : (tdiBranch.commonAncestor) ? tdiBranch.commonAncestor.date: _git.commitTdi.local().date;
|
|
149
142
|
const toTdiDate = tdiToDateCustom ? new Date(tdiToDateCustom) : new Date();
|
|
150
143
|
|
|
@@ -163,6 +156,7 @@ module.exports = function git (argv) {
|
|
|
163
156
|
let relevantMigrationCount = 0;
|
|
164
157
|
// Apply callback for migrations
|
|
165
158
|
migrationsFiltered
|
|
159
|
+
.sort((a, b) => Date(a.releases[0].date)>Date(b.releases[0].date)?1:-1)
|
|
166
160
|
.forEach((m) => {
|
|
167
161
|
const date = _formatDate(new Date(m.releases.filter((r) => tdiBranch.name >= `release/${r.release}`)[0].date));
|
|
168
162
|
relevantMigrationCount += (m.callback(date, relevantMigrationCount+1)) === 1 ? 1 : 0;
|
|
@@ -196,13 +190,13 @@ module.exports = function git (argv) {
|
|
|
196
190
|
if (cmdPull.error) _warn(`Pull failed\n${cmdPull.error}`);
|
|
197
191
|
|
|
198
192
|
_info(`Checked out at commit:`);
|
|
199
|
-
const repoLog =
|
|
193
|
+
const repoLog = _git.commitLocal(true);
|
|
200
194
|
_write(`${_formatDate(repoLog.date)} - ${repoLog.tags} - ${repoLog.hash}`);
|
|
201
195
|
|
|
202
196
|
_info(`Retrieve submodules that belong to this repo-commit`); // update submodule recursively (set to version that belongs to repo)
|
|
203
197
|
_write(execGitCommand(`submodule update --recursive`, path.join(_paths.repo)));
|
|
204
198
|
_info(`Submodule checked out at commit:`);
|
|
205
|
-
const tdiLog =
|
|
199
|
+
const tdiLog = _git.commitTdi.local(true);
|
|
206
200
|
_write(`${_formatDate(tdiLog.date)} - ${tdiLog.tags} - ${tdiLog.hash}`);
|
|
207
201
|
const tdiBranch = getTdiBranch();
|
|
208
202
|
|
|
@@ -57,7 +57,6 @@ const getFileExtractInfo = (sorting) => {
|
|
|
57
57
|
// version info miscellaneous
|
|
58
58
|
const projects = new Set;
|
|
59
59
|
const types = new Set;
|
|
60
|
-
const versionInfoConfigPath = path.join(_paths.repo, _paths.tdi, 'tct/version/versionInfo.js');
|
|
61
60
|
const versionInfo = new Table({
|
|
62
61
|
columns: [
|
|
63
62
|
{name: 'path', alignment: 'left'},
|
|
@@ -69,10 +68,10 @@ const getFileExtractInfo = (sorting) => {
|
|
|
69
68
|
sort: (a, b) => a.sort.toLowerCase() > b.sort.toLowerCase() ? 1 : -1
|
|
70
69
|
});
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const versionInfoConfig = _modulesTdi.require('version/versionInfo.js');
|
|
72
|
+
if (versionInfoConfig) {
|
|
74
73
|
|
|
75
|
-
|
|
74
|
+
versionInfoConfig.forEach(v => {
|
|
76
75
|
const location = path.join(_paths.repo, v.glob);
|
|
77
76
|
|
|
78
77
|
globby
|
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
module.exports = function migrate (argv) {
|
|
7
|
-
if (_isPre51) _error('This command only works when using branch release/5.1 and up.');
|
|
7
|
+
if (_isPre51()) _error('This command only works when using branch release/5.1 and up.');
|
|
8
8
|
|
|
9
9
|
let filter = path.join(_paths.apply, argv.filter).toFws(); // Default set filter with filter added to the command argument -f
|
|
10
10
|
|
|
@@ -76,8 +76,8 @@ module.exports = function migrate (argv) {
|
|
|
76
76
|
_write();
|
|
77
77
|
const startTime = new Date();
|
|
78
78
|
|
|
79
|
-
const scriptPath = path.join(
|
|
80
|
-
require(scriptPath).forEach(step => require('./steps')(step, argv.dry, filter));
|
|
79
|
+
const scriptPath = path.join('migrate', a.script);
|
|
80
|
+
_modulesTdi.require(scriptPath).forEach(step => require('./steps')(step, argv.dry, filter));
|
|
81
81
|
|
|
82
82
|
_perf(startTime);
|
|
83
83
|
});
|
package/src/modules/sql/index.js
CHANGED
|
@@ -43,7 +43,7 @@ module.exports = function sql (argv) {
|
|
|
43
43
|
|
|
44
44
|
if (argv.install) {
|
|
45
45
|
// tdi
|
|
46
|
-
const dir = `${_paths.tdi}/${_isPre51 ? 'sources' : 'src'}/database/tdi/${_isPre42 ? 'install/' : ''}`;
|
|
46
|
+
const dir = `${_paths.tdi}/${_isPre51() ? 'sources' : 'src'}/database/tdi/${_isPre42() ? 'install/' : ''}`;
|
|
47
47
|
runSqlScript(dir + 'install.sql');
|
|
48
48
|
checkLog(dir + 'tdi-install.log', false);
|
|
49
49
|
// custom
|
|
@@ -96,7 +96,7 @@ module.exports = function sql (argv) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
if (argv.generate) {
|
|
99
|
-
const dir = _paths.tdi + (_isPre51 ? '/util/db-config-generator/' : '/tct/sql/generate/');
|
|
99
|
+
const dir = _paths.tdi + (_isPre51() ? '/util/db-config-generator/' : '/tct/sql/generate/');
|
|
100
100
|
fs.ensureSymlinkSync(_paths.apply, dir + 'dist', 'junction');
|
|
101
101
|
runSqlScript(dir + 'start.sql');
|
|
102
102
|
fs.removeSync(dir + 'dist');
|
|
@@ -104,7 +104,7 @@ module.exports = function sql (argv) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
if (argv.remove) {
|
|
107
|
-
const dir = _paths.tdi + (_isPre51 ? '/util/db-config-remover/' : '/tct/sql/remove/');
|
|
107
|
+
const dir = _paths.tdi + (_isPre51() ? '/util/db-config-remover/' : '/tct/sql/remove/');
|
|
108
108
|
runSqlScript(dir + 'start.sql');
|
|
109
109
|
checkLog(dir + 'remove-config.log');
|
|
110
110
|
}
|
package/.eslintrc.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
'env': {
|
|
3
|
-
'browser': true,
|
|
4
|
-
'commonjs': true,
|
|
5
|
-
'es2021': true
|
|
6
|
-
},
|
|
7
|
-
'extends': 'eslint:recommended',
|
|
8
|
-
'overrides': [],
|
|
9
|
-
'parserOptions': {'ecmaVersion': 'latest'},
|
|
10
|
-
'globals': {
|
|
11
|
-
'process': 'readonly',
|
|
12
|
-
'Buffer': 'readonly',
|
|
13
|
-
'__dirname': 'readonly',
|
|
14
|
-
'_write': 'writable',
|
|
15
|
-
'_info': 'writable',
|
|
16
|
-
'_warn': 'writable',
|
|
17
|
-
'_formatDate': 'writable',
|
|
18
|
-
'_error': 'writable',
|
|
19
|
-
'_perf': 'writable',
|
|
20
|
-
'_paths': 'writable',
|
|
21
|
-
'_appdata': 'writable',
|
|
22
|
-
'_packages': 'writable',
|
|
23
|
-
'_appconfig': 'writable',
|
|
24
|
-
'_git': 'writable',
|
|
25
|
-
'_repoconfig': 'writable',
|
|
26
|
-
'_tdiSubmoduleExists': 'writable',
|
|
27
|
-
'_isPre42': 'writable',
|
|
28
|
-
'_isPre51': 'writable'
|
|
29
|
-
},
|
|
30
|
-
'rules': {
|
|
31
|
-
'no-var': ['error'],
|
|
32
|
-
'indent': ['error', 2],
|
|
33
|
-
'quotes': [
|
|
34
|
-
'error',
|
|
35
|
-
'single',
|
|
36
|
-
{'avoidEscape': true, 'allowTemplateLiterals': true}
|
|
37
|
-
],
|
|
38
|
-
'semi': ['error', 'always'],
|
|
39
|
-
'comma-style': ['error', 'last'],
|
|
40
|
-
'array-bracket-spacing': ['error', 'never'],
|
|
41
|
-
'object-curly-spacing': ['error', 'never'],
|
|
42
|
-
'key-spacing': ['error'],
|
|
43
|
-
'comma-spacing': ['error'],
|
|
44
|
-
'rest-spread-spacing': ['error', 'never'],
|
|
45
|
-
'spaced-comment': ['error', 'always'],
|
|
46
|
-
}
|
|
47
|
-
};
|
package/.pre-commit-config.yaml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# See https://pre-commit.com for more information
|
|
2
|
-
# See https://pre-commit.com/hooks.html for more hooks
|
|
3
|
-
|
|
4
|
-
repos:
|
|
5
|
-
|
|
6
|
-
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
7
|
-
rev: v4.4.0
|
|
8
|
-
hooks:
|
|
9
|
-
- id: trailing-whitespace
|
|
10
|
-
- id: check-json
|
|
11
|
-
- id: check-merge-conflict # checks for files that contain merge conflict strings
|
|
12
|
-
- id: check-added-large-files
|
|
13
|
-
args: [--maxkb=100]
|
|
14
|
-
|
|
15
|
-
- repo: https://github.com/pre-commit/pygrep-hooks
|
|
16
|
-
rev: v1.10.0
|
|
17
|
-
hooks:
|
|
18
|
-
- id: text-unicode-replacement-char # forbid files which have a UTF-8 Unicode replacement character
|
|
19
|
-
|
|
20
|
-
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
|
21
|
-
rev: v2.10.0
|
|
22
|
-
hooks:
|
|
23
|
-
- id: pretty-format-yaml
|
|
24
|
-
args: [--autofix, --indent, '2']
|
|
25
|
-
|
|
26
|
-
- repo: https://github.com/pre-commit/mirrors-eslint
|
|
27
|
-
rev: v8.49.0
|
|
28
|
-
hooks:
|
|
29
|
-
- id: eslint # javascript linter and formatter
|
|
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/.vscode/settings.json
DELETED
package/bitbucket-pipelines.yml
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
image: atlassian/default-image:4
|
|
2
|
-
|
|
3
|
-
clone:
|
|
4
|
-
depth: full # SonarCloud scanner needs the full history to assign issues properly
|
|
5
|
-
|
|
6
|
-
definitions:
|
|
7
|
-
caches:
|
|
8
|
-
sonar: ~/.sonar/cache # Caching SonarCloud artifacts will speed up your build
|
|
9
|
-
services:
|
|
10
|
-
docker:
|
|
11
|
-
memory: 2048 # For large file line code
|
|
12
|
-
steps:
|
|
13
|
-
- step: &build-test-sonarcloud
|
|
14
|
-
name: Build, test and analyze on SonarCloud
|
|
15
|
-
caches:
|
|
16
|
-
- sonar
|
|
17
|
-
script:
|
|
18
|
-
- pipe: sonarsource/sonarcloud-scan:2.0.0
|
|
19
|
-
- step: &check-quality-gate-sonarcloud
|
|
20
|
-
name: Check the Quality Gate on SonarCloud
|
|
21
|
-
script:
|
|
22
|
-
- pipe: sonarsource/sonarcloud-quality-gate:0.1.6
|
|
23
|
-
|
|
24
|
-
pipelines:
|
|
25
|
-
branches:
|
|
26
|
-
master:
|
|
27
|
-
- step: *build-test-sonarcloud
|
|
28
|
-
- step: *check-quality-gate-sonarcloud
|
|
29
|
-
pull-requests:
|
|
30
|
-
'**':
|
|
31
|
-
- step: *build-test-sonarcloud
|
|
32
|
-
- step: *check-quality-gate-sonarcloud
|