@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 CHANGED
@@ -26,7 +26,8 @@ Use the `tct` shorthand instead of `tangelo-configuration-toolkit`:
26
26
 
27
27
  ### Global
28
28
 
29
- The `deploy` command requires server connection information. So you'll have to create a configuration file named `tangelo-configuration-toolkit-appconfig.json` in which such information can be stored. This file will be searched for in an ancestor directory of the current working directory.
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
- appdata: path.resolve(__dirname, '..', appname+'-appdata.json'),
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
- global._packages = {
70
- TCT: {name: '@tangelo/tangelo-configuration-toolkit', version: require('./package.json')?.version},
71
- FDT: {name: '@fontoxml/fontoxml-development-tools'}
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 { global._appconfig = _paths.appconfig && fs.readJsonSync(_paths.appconfig) || {}; }
75
- catch({message}) { _error('Error in '+message); }
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 || '', '..', _appconfig.sharedConfigPath || '', appname+'-appconfig.json');
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangelo/tangelo-configuration-toolkit",
3
- "version": "1.14.4",
3
+ "version": "1.16.0",
4
4
  "engines": {
5
5
  "node": ">=14.0.0"
6
6
  },
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
- const {argv} = yargs
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
- if (!(['git', 'g'].includes(argv._[0]) && (argv.init || argv.clone))) {
16
- if (!_paths.repo) _error('This command can only be used inside a customer git repo!');
17
- process.chdir(_paths.repo);
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 passedOpts = Object.keys(argv).filter(k => !['_', '$0', 'server', 's', 'filter', 'f', 'branch', 'b'].includes(k)); // also filter options with defaults
123
- const hasOpts = Object.keys(options)[0];
124
- if (hasOpts && !passedOpts[0]) yargs.showHelp();
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
- require(path.join(_paths.repo, _paths.tdi, 'tct/build/init'))(createSymlinks);
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
- const {projectNew, projectCopy} = require(path.join(_paths.repo, _paths.tdi, 'tct/build/project'));
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=='TDI') projectNew(createSymlinks);
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 = path.join(_paths.repo, _paths.tdi, 'tct/build/oxygen/stylesheetPaths.json');
7
- const sefFilePath = path.join(_paths.repo, _paths.tdi, 'tct/build/oxygen/createProjectFile.sef.json');
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: fs.readFileSync(sefFilePath),
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
- if (!fs.existsSync(spConfigPath) || !fs.existsSync(sefFilePath)) {
170
- _error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`);
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(require(spConfigPath), newXprFile);
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 = (fv) => `npx -y ${_packages.FDT.name}@${fv.replace(/^(7\.|8\.[012]\.).*/, '3.12.0')}`;
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 cfvPath = path.join(_paths.repo, _paths.tdi, 'tct/fonto/compatibleVersions.json');
14
- if (fs.pathExistsSync(cfvPath)) return RegExp(fs.readJsonSync(cfvPath).regex);
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!='.') _info(`${i>0 ? '\n' : ''}Fonto instance #${i+1}: ${path.join(_paths.apply, fontoPath)}\n`);
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((resolve) => {
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 == 'latest') {
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
  }
@@ -1,8 +1,6 @@
1
1
  const {execSync, spawn} = require('child_process');
2
- const {chdir} = require('process');
3
- const inquirer = require('inquirer');
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) _write(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 === true) _error('Pass a repository name!');
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
- // Change directory for the next commands, it should have the same name as the clone argument from commandline at this point
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
- }).catch((e) => {
111
- // Show warnings for missing, expected, system environment variables
112
- if (!process.env.GIT_SSH) {
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
- if (fs.existsSync(tdiMigrationFilePath)) {
147
- const migrations = require(tdiMigrationFilePath);
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 = execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, _paths.repo, ['tags', 'hash', 'date']);
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 = execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, path.join(_paths.repo, _paths.tdi), ['tags', 'hash', 'date']);
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
- if (fs.existsSync(versionInfoConfigPath)) {
73
- const config = require(versionInfoConfigPath);
71
+ const versionInfoConfig = _modulesTdi.require('version/versionInfo.js');
72
+ if (versionInfoConfig) {
74
73
 
75
- config.forEach(v => {
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(_paths.repo, _paths.tdi, 'tct/migrate', a.script);
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
  });
@@ -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
- };
@@ -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
@@ -1,6 +0,0 @@
1
- {
2
- "sonarlint.connectedMode.project": {
3
- "connectionId": "tangelosoftware",
4
- "projectKey": "tangelosoftware_tangelo-configuration-toolkit"
5
- }
6
- }
@@ -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