@tangelo/tangelo-configuration-toolkit 1.10.1 → 1.10.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/index.js CHANGED
@@ -5,10 +5,10 @@ String.prototype.toFws = function(){
5
5
  };
6
6
 
7
7
 
8
- const findUp = require('find-up');
9
- const fs = require('fs-extra');
10
- const {getPath} = require('global-modules-path');
11
- const path = require('path');
8
+ const {execSync} = require('child_process');
9
+ const findUp = require('find-up');
10
+ const fs = require('fs-extra');
11
+ const path = require('path');
12
12
 
13
13
  const execGitCommand = require('./src/lib/exec-git-command');
14
14
 
@@ -57,12 +57,17 @@ _paths.repoconfig = path.join(_paths.repo, appname+'-repoconfig.json');
57
57
  _paths.apply = process.cwd().replace(_paths.repo, '').substr(1);
58
58
 
59
59
 
60
- global._appdata = fs.readJsonSync(_paths.appdata, {throws: false}) || {};
60
+ global._appdata = fs.readJsonSync(_paths.appdata, {throws: false}) || {};
61
+ _appdata._update = (data) => Object.assign(_appdata, data, {_changed: true});
62
+ if (!_appdata.npmPath) {
63
+ _appdata._update({npmPath: execSync('npm config get prefix', {encoding: 'UTF-8'}).replace(/\s$/, '')});
64
+ }
65
+
61
66
  global._packages = {
62
67
  TCT: {name: '@tangelo/tangelo-configuration-toolkit', version: require('./package.json')?.version},
63
68
  FDT: {name: '@fontoxml/fontoxml-development-tools'}
64
69
  }
65
- _packages.FDT.version = fs.readJsonSync(`${getPath(_packages.FDT.name)}/package.json`, {throws: false})?.version;
70
+ _packages.FDT.version = fs.readJsonSync(path.join(_appdata.npmPath, 'node_modules', _packages.FDT.name, 'package.json'), {throws: false})?.version;
66
71
 
67
72
  try { global._appconfig = _paths.appconfig && fs.readJsonSync(_paths.appconfig) || {}; }
68
73
  catch({message}) { _error('Error in '+message); }
@@ -71,29 +76,27 @@ _appconfig.sharedConfigPath = path.resolve(_paths.appconfig || '', '..', _appcon
71
76
  _appconfig.shared = fs.readJsonSync(_appconfig.sharedConfigPath, {throws: false}) || {};
72
77
 
73
78
 
74
- global._commit = {
75
- branch: execGitCommand('rev-parse --abbrev-ref HEAD', _paths.repo),
76
- hash: execGitCommand('rev-parse HEAD', _paths.repo),
77
- date: execGitCommand('log -1 --format=%cd --date=iso-strict', _paths.repo)
78
- };
79
- _commit.lastDateRemote = execGitCommand('log -1 --format=%cd --date=iso-strict origin/'+_commit.branch,_paths.repo);
80
-
81
- global._tdiCommit = {
82
- hash: execGitCommand('rev-parse HEAD', path.join(_paths.repo, _paths.tdi)),
83
- after (commitHash) {
84
- return execGitCommand(`merge-base --is-ancestor ${commitHash} ${this.hash}`, path.join(_paths.repo, _paths.tdi), 0);
85
- },
86
- fontoVersions: [ // latest commits first
87
- {commitHash: 'e599766', regex: /^7\.1[45]\./},
88
- {commitHash: '77b8ea9', regex: /^7\.14\./}, // 7.14.x
89
- {commitHash: '8066c44', regex: /^7\.13\./}, // 7.13.x
90
- {commitHash: 'a2b2d4e', regex: /^7\.12\./} // 7.12.x
91
- ],
92
- stopUsingRepoconfigFile: '1f12bff' // release/5.1 10-05-2021
79
+ global._git = {
80
+ user: execGitCommand(`config --get user.email`, _paths.repo),
81
+ commitLocal: execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, _paths.repo, ['branch', 'hash', 'date']),
82
+ commitLocalTdi: {
83
+ hash: execGitCommand('rev-parse HEAD', path.join(_paths.repo, _paths.tdi)),
84
+ after (commitHash) {
85
+ return execGitCommand(`merge-base --is-ancestor ${commitHash} ${this.hash}`, path.join(_paths.repo, _paths.tdi), null, 0);
86
+ },
87
+ fontoVersions: [ // latest commits first
88
+ {commitHash: 'e599766', regex: /^7\.1[45]\./},
89
+ {commitHash: '77b8ea9', regex: /^7\.14\./}, // 7.14.x
90
+ {commitHash: '8066c44', regex: /^7\.13\./}, // 7.13.x
91
+ {commitHash: 'a2b2d4e', regex: /^7\.12\./} // 7.12.x
92
+ ],
93
+ stopUsingRepoconfigFile: '1f12bff' // release/5.1 10-05-2021
94
+ }
93
95
  };
96
+ _git.commitRemote = execGitCommand('log -1 --format=%cd --date=iso-strict origin/'+_git.commitLocal.branch, _paths.repo, ['date']);
94
97
 
95
98
 
96
- if (_tdiCommit.after(_tdiCommit.stopUsingRepoconfigFile)) {
99
+ if (_git.commitLocalTdi.after(_git.commitLocalTdi.stopUsingRepoconfigFile)) {
97
100
  global._repoconfig = require('./src/lib/get-repoconfig')();
98
101
  }
99
102
  else {
@@ -111,4 +114,19 @@ global._isPre42 = fs.existsSync(path.join(_paths.repo, _paths.tdi, 'create_new_p
111
114
  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)
112
115
 
113
116
 
117
+
118
+ process.on('beforeExit', () => {
119
+ _write(); // print empty line before and after update check
120
+
121
+ require('./src/lib/package-update-check')();
122
+
123
+ if (_appdata._changed) {
124
+ delete _appdata._update;
125
+ delete _appdata._changed;
126
+ fs.writeJsonSync(_paths.appdata, _appdata, {spaces: 2});
127
+ }
128
+
129
+ });
130
+
131
+
114
132
  require('./src/cli.js')();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangelo/tangelo-configuration-toolkit",
3
- "version": "1.10.1",
3
+ "version": "1.10.4",
4
4
  "description": "Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.",
5
5
  "bin": {
6
6
  "tct": "bin/index.js",
@@ -25,7 +25,6 @@
25
25
  "event-stream": "^4.0.1",
26
26
  "find-up": "^5.0.0",
27
27
  "fs-extra": "^10.0.0",
28
- "global-modules-path": "^2.3.1",
29
28
  "globby": "^6.1.0",
30
29
  "gulp": "^4.0.2",
31
30
  "gulp-babel": "^8.0.0",
package/src/cli.js CHANGED
@@ -1,26 +1,6 @@
1
- const {compare} = require('compare-versions');
2
- const exec = require('util').promisify(require('child_process').exec);
3
- const fs = require('fs-extra');
4
1
  const yargs = require('yargs');
5
2
 
6
3
 
7
- const updateAppdata = (data) => Object.assign(_appdata, data, {_changed: true});
8
-
9
- const checkForPackageUpdate = (package) => (
10
- exec(`npm view -g ${_packages[package].name} version`)
11
- .then(r => {
12
- const versionAvailable = r.stdout.match(/([\d/.]+)/)[1];
13
- if (!_packages[package].version) _warn(`${package} is not installed! Run ` + `npm i -g ${_packages[package].name}`.white);
14
- else if (compare(_packages[package].version, versionAvailable, '<')) {
15
- updateAppdata({[`updateCheck${package}`]: {executed: new Date(), versionAvailable}});
16
- return versionAvailable;
17
- }
18
- else updateAppdata({[`updateCheck${package}`]: {executed: new Date()}});
19
- })
20
- .catch(e => _warn(`Failed checking latest version of ${package}.`))
21
- );
22
-
23
-
24
4
  module.exports = function cli () {
25
5
 
26
6
  _write();
@@ -45,7 +25,7 @@ module.exports = function cli () {
45
25
  init: {alias: 'i', desc: 'Create repository content structure', conflicts: ['p', 's', 'c']},
46
26
  project: {alias: 'p', desc: 'Create project configuration', conflicts: ['i', 's', 'c']},
47
27
  symlinks: {alias: 's', desc: 'Recreate symlinks to TDI', conflicts: ['p', 'i', 'c']},
48
- config: {alias: 'c', desc: 'Create repo-config file', conflicts: ['p', 'i', 's'], hidden: _tdiCommit.after(_tdiCommit.stopUsingRepoconfigFile)},
28
+ config: {alias: 'c', desc: 'Create repo-config file', conflicts: ['p', 'i', 's'], hidden: _git.commitLocalTdi.after(_git.commitLocalTdi.stopUsingRepoconfigFile)},
49
29
  oxygen: {alias: 'x', desc: 'Create or update oXygen project file (.xpr)', conflicts: ['p', 'i', 'c']}
50
30
  },
51
31
  handler: require('./modules/build')
@@ -143,34 +123,4 @@ module.exports = function cli () {
143
123
 
144
124
  }
145
125
 
146
-
147
- let checkUpdatesDone = false;
148
-
149
- process.on('beforeExit', () => {
150
- _write(); // print empty line before and after update check
151
-
152
- if (!checkUpdatesDone) { // check if updatecheck has ran before because async calls below trigger beforeExit again
153
- checkUpdatesDone = true;
154
-
155
- ['TCT', 'FDT'].forEach(p => {
156
- const updateMsg = (va) => `| Update ${p} to ${va} | ` + `npm i -g ${_packages[p].name}`.white;
157
- const {versionAvailable} = _appdata[`updateCheck${p}`] || {};
158
-
159
- if (new Date() - new Date(_appdata[`updateCheck${p}`]?.executed || 0) > 1000*3600*24*7) { // check every week
160
- checkForPackageUpdate(p).then(r => r && _warn(updateMsg(r)));
161
- }
162
- else if (versionAvailable) {
163
- if (compare(_packages[p].version, versionAvailable, '<')) _warn(updateMsg(versionAvailable));
164
- else updateAppdata({[`updateCheck${p}`]: {executed: new Date()}});
165
- }
166
- });
167
- }
168
-
169
- if (_appdata._changed) {
170
- delete _appdata._changed;
171
- fs.writeJsonSync(_paths.appdata, _appdata, {spaces: 2});
172
- }
173
-
174
- });
175
-
176
126
  }
@@ -1,10 +1,26 @@
1
1
  const {spawnSync} = require('child_process');
2
2
 
3
3
 
4
- module.exports = function execGitCommand(args, path, status) {
4
+ module.exports = function execGitCommand(args, path, returnProperties = [], expectedStatus) {
5
5
 
6
6
  const cmd = spawnSync('git', [args], {cwd: path, shell: true});
7
- const res = status!=undefined ? cmd.status == status : (cmd.stdout||'').toString().trim();
8
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(res) ? new Date(res) : res;
7
+
8
+ if (expectedStatus!=undefined) return cmd.status == expectedStatus;
9
+
10
+ let retObj = (cmd.stdout||'').toString().trim().split(';');
11
+ if (returnProperties[0]) {
12
+ retObj = (
13
+ o = {},
14
+ retObj.forEach((v,i) => {
15
+ o[returnProperties[i]] =
16
+ returnProperties[i] == 'date' ? new Date(v) :
17
+ returnProperties[i] == 'branch' ? v.replace(/HEAD -> ([^,]+).*/, '$1') :
18
+ v
19
+ ;
20
+ }),
21
+ o
22
+ )
23
+ }
24
+ return retObj.length==1 ? retObj[0] : retObj;
9
25
 
10
26
  };
@@ -2,7 +2,7 @@ const fs = require('fs-extra');
2
2
  const globby = require('globby');
3
3
 
4
4
 
5
- module.exports = function getRepoconfig(repoconfigPath) {
5
+ module.exports = function getRepoconfig() {
6
6
 
7
7
  const repoconfig = [];
8
8
 
@@ -0,0 +1,39 @@
1
+ const {compare} = require('compare-versions');
2
+ const exec = require('util').promisify(require('child_process').exec);
3
+
4
+
5
+ const doUpdateCheck = (package) => (
6
+ exec(`npm view -g ${_packages[package].name} version`)
7
+ .then(r => {
8
+ const versionAvailable = r.stdout.match(/([\d/.]+)/)[1];
9
+ if (!_packages[package].version) _warn(`${package} is not installed! Run ` + `npm i -g ${_packages[package].name}`.white);
10
+ else if (compare(_packages[package].version, versionAvailable, '<')) {
11
+ _appdata._update({[`updateCheck${package}`]: {executed: new Date(), versionAvailable}});
12
+ return versionAvailable;
13
+ }
14
+ else _appdata._update({[`updateCheck${package}`]: {executed: new Date()}});
15
+ })
16
+ .catch(e => _warn(`Failed checking latest version of ${package}.`))
17
+ );
18
+
19
+ let checkUpdatesDone = false;
20
+
21
+
22
+ module.exports = function packageUpdateCheck () {
23
+ if (!checkUpdatesDone) { // check if updatecheck has ran before because async calls below trigger beforeExit again
24
+ checkUpdatesDone = true;
25
+
26
+ ['TCT', 'FDT'].forEach(p => {
27
+ const updateMsg = (va) => `| Update ${p} to ${va} | ` + `npm i -g ${_packages[p].name}`.white;
28
+ const {versionAvailable} = _appdata[`updateCheck${p}`] || {};
29
+
30
+ if (new Date() - new Date(_appdata[`updateCheck${p}`]?.executed || 0) > 1000*3600*24*7) { // check every week
31
+ doUpdateCheck(p).then(r => r && _warn(updateMsg(r)));
32
+ }
33
+ else if (versionAvailable) {
34
+ if (compare(_packages[p].version, versionAvailable, '<')) _warn(updateMsg(versionAvailable));
35
+ else _appdata._update({[`updateCheck${p}`]: {executed: new Date()}});
36
+ }
37
+ });
38
+ }
39
+ }
@@ -20,6 +20,7 @@ module.exports = function workerWithSpinner (spinnerTxt, workerFn, postMsg, onMe
20
20
  onMessageFn(msg);
21
21
  resolve();
22
22
  });
23
+ worker.on('error', err => _error('\n' + err.stdout));
23
24
  worker.postMessage(postMsg);
24
25
  });
25
26
 
@@ -74,7 +74,7 @@ module.exports = function build (argv) {
74
74
  }
75
75
 
76
76
  if (argv.config) {
77
- if (_tdiCommit.after(_tdiCommit.stopUsingRepoconfigFile)) _error('This option only works for older repo\'s using a repoconfig file.');
77
+ if (_git.commitLocalTdi.after(_git.commitLocalTdi.stopUsingRepoconfigFile)) _error('This option only works for older repo\'s using a repoconfig file.');
78
78
 
79
79
 
80
80
  inquirer
@@ -55,7 +55,7 @@ module.exports = {
55
55
  username: serverConfig.config.username,
56
56
  agent: process.platform=='win32' ? 'pageant' : process.env.SSH_AUTH_SOCK,
57
57
  agentForward: process.platform!='win32',
58
- readyTimeout: 10000,
58
+ readyTimeout: 15000,
59
59
  retries: 1
60
60
  }
61
61
  };
@@ -91,7 +91,7 @@ module.exports = {
91
91
  let transferPattern = path.join(_paths.apply, filter).toFws();
92
92
 
93
93
  // test if 'cmscustom/tdi' would be included, then add specifically, because following symlinks doesnt work with glob stars
94
- const tdiIncRegex = /^(({\w*,?)?cmscustom(,?\w*})?\/|\*\/)?\*\*/;
94
+ const tdiIncRegex = /^(config\/)?(({\w*,?)?cmscustom(,?\w*})?\/|\*\/)?\*\*/;
95
95
  const tdiPattern = tdiIncRegex.test(transferPattern) ? transferPattern.replace(tdiIncRegex, `${this.deliveryPack ? 'config/' : ''}cmscustom/tdi/**`) : 'nomatch';
96
96
 
97
97
  if (!transferPattern)
@@ -129,13 +129,13 @@ module.exports = {
129
129
  }
130
130
  else this.replaceStrings.push(['debugMode>true', 'debugMode>false', '**/xopus/xml/*']);
131
131
 
132
- _info(`Branch: ${_commit.branch}`);
132
+ _info(`Branch: ${_git.commitLocal.branch}`);
133
133
  _info(`Source: ${path.join(process.cwd(), transferPattern)}`);
134
134
  _info(`Server: ${ftpConfig.host ? `${ftpConfig.host}:${ftpConfig.port}` : 'local'}`);
135
135
  _info(`Target: ${this.getRemotePath(transferPattern)}`);
136
136
  _write();
137
137
 
138
- if (_commit.date < _commit.lastDateRemote) {
138
+ if (_git.commitLocal.date < _git.commitRemote.date) {
139
139
  _warn(`You're not deploying from the most recent git commit!\n`)
140
140
  }
141
141
  }
@@ -126,15 +126,19 @@ const transfer = (paths, lrServer) => {
126
126
  const srcset = s.create(paths);
127
127
  const files = [];
128
128
 
129
+ // local git repo must be on latest commit containing fonto changes, and fonto build files must be newer than that commit, unless that commit belongs to the current user
129
130
  const fontoPaths = {outdated: [], uptodate: []};
130
- const removeOutdatedFontoBuild = g_filter(file => { // fonto build files must be newer than the last commit date containing fonto changes
131
+ const removeOutdatedFontoBuild = g_filter(file => {
131
132
  const prPath = 'config\\'+file.relative.replace(/fonto.+$/, '');
132
133
  if (fontoPaths.outdated.includes(prPath)) return false;
133
134
  if (fontoPaths.uptodate.includes(prPath)) return true;
134
135
  if (file.relative.match(/fonto[\\\/]dist/)) {
135
136
  const paths = `${prPath}\\fonto ${prPath}\\schema ${_paths.tdi}`; // only check paths containing fonto sources
136
- const lastFontoCommitDate = execGitCommand(`log -1 --format=%cd --date=iso-strict origin/${_commit.branch} ${paths}`, _paths.repo);
137
- if (fs.statSync(file.relative).mtime < lastFontoCommitDate) {
137
+ const lastFontoCommit = execGitCommand(`log -1 --format=%ae;%cd --date=iso-strict origin/${_git.commitLocal.branch} ${paths}`, _paths.repo, ['author', 'date']);
138
+ if (
139
+ lastFontoCommit.author != _git.user &&
140
+ (lastFontoCommit.date > _git.commitLocal.date || lastFontoCommit.date > fs.statSync(file.relative).mtime)
141
+ ) {
138
142
  fontoPaths.outdated.push(prPath);
139
143
  return false;
140
144
  }
@@ -75,9 +75,9 @@ module.exports = function deploy (argv) {
75
75
  if ((event=='add' || event=='change') && (
76
76
  // within fonto, transfer build files only, but also schema files, because
77
77
  // the "dist" folder isn't watched properly: it does not detect "assets" anymore after building once
78
- !/fonto[\\\/]/.test(filepath) ||
79
- /fonto[\\\/]dist/.test(filepath) ||
80
- (/fonto[\\\/]dev/.test(filepath) && c.envDev) ||
78
+ !/cmscustom.+fonto[\\\/]/.test(filepath) ||
79
+ /fonto[\\\/]dist[\\\/]/.test(filepath) ||
80
+ (/fonto[\\\/]dev[\\\/]/.test(filepath) && c.envDev) ||
81
81
  /fonto[\\\/]packages[\\\/]sx-shell-.*?[\\\/]assets[\\\/]schemas[\\\/]/.test(filepath)
82
82
  )
83
83
  ) {
@@ -14,9 +14,9 @@ const allowedFontoVersionRegex = () => {
14
14
  const cfvPath = path.join(_paths.repo, _paths.tdi, 'tct/fonto/compatibleVersions.json');
15
15
  if (fs.pathExistsSync(cfvPath)) return RegExp(fs.readJsonSync(cfvPath).regex);
16
16
 
17
- // old way: a regex for each basecommit is stored in global._tdiCommit
18
- for (const fv of _tdiCommit.fontoVersions) {
19
- if (_tdiCommit.after(fv.commitHash)) return fv.regex;
17
+ // old way: a regex for each basecommit is stored in global._git.commitLocalTdi
18
+ for (const fv of _git.commitLocalTdi.fontoVersions) {
19
+ if (_git.commitLocalTdi.after(fv.commitHash)) return fv.regex;
20
20
  }
21
21
  };
22
22
 
@@ -149,7 +149,7 @@ module.exports = {
149
149
  // execute "fdt elements" for each schema package, ignore default elements, and combine results
150
150
  const schemasPerElement = {};
151
151
  Object.entries(rootSchemas).forEach(([path, obj]) => {
152
- const data = execSync(`fdt elements --schema ${obj.packageName} -C name`, {encoding: 'UTF-8'});
152
+ const data = execSync(`fdt elements --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json -C name`, {encoding: 'UTF-8'});
153
153
  const elements = data.replace(/^.*?Name\*|Printed name\*.*$/gs, '').split(/\s+/);
154
154
  const customElements = [...new Set(elements)].filter(e => e && !ignoreElements.includes(e));
155
155
 
@@ -195,7 +195,7 @@ module.exports = {
195
195
  // execute "fdt attributes" for each schema package, ignore default attributes, and combine results
196
196
  const schemasPerAttribute = {};
197
197
  Object.entries(rootSchemas).forEach(([path, obj]) => {
198
- const data = execSync(`fdt attributes --schema ${obj.packageName}`, {encoding: 'UTF-8'});
198
+ const data = execSync(`fdt attributes --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json`, {encoding: 'UTF-8'});
199
199
  const attributes = data.replace(/^.*?Default value\s+|\s+Printed name\*.*$/gs, '').split(/\n\s+/).map(a => a.split(/\s+/)).map(a =>
200
200
  a[0] + (a[2]=='required' ? ' (required)' : '') + (a[3]=='-' ? ' (no default)' : '')
201
201
  );
@@ -37,7 +37,7 @@ const checkLog = (logFilePath, remove=true) => {
37
37
 
38
38
  module.exports = function sql (argv) {
39
39
 
40
- if ((argv.install || argv.configure) && _commit.date < _commit.lastDateRemote) {
40
+ if ((argv.install || argv.configure) && _git.commitLocal.date < _git.commitRemote.date) {
41
41
  _warn(`You're not deploying from the most recent git commit!\n`)
42
42
  }
43
43