@tangelo/tangelo-configuration-toolkit 1.11.2 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,7 +49,7 @@ module.exports = function deploy (argv) {
49
49
  const transfers = {
50
50
  queue: [],
51
51
  do () {
52
- this.queue = this.queue.map(p => p.replace(/fonto(.)(?:dist|dev).assets.schemas(.sx-shell-.*?).json/, 'fonto$1packages$2$1src$1assets$1schemas$2.json')) // fonto schema changes can be detected in different paths at the same time, rewrite paths to original package-path because files in build folders can be removed before transfer starts
52
+ this.queue = this.queue.map(p => p.replace(/fonto(.)(?:dist|dev).assets.schemas(.sx-shell-.*?).json/, 'fonto$1packages$2$1src$1assets$1schemas$2.json')); // fonto schema changes can be detected in different paths at the same time, rewrite paths to original package-path because files in build folders can be removed before transfer starts
53
53
  this.queue = [...new Set(this.queue)]; // remove duplicates
54
54
  this.queue.forEach(v => s.addToCache(v));
55
55
  transfer(this.queue, lrServer);
@@ -70,31 +70,31 @@ module.exports = function deploy (argv) {
70
70
  }
71
71
 
72
72
  gulp.watch(c.transferPatterns)
73
- .on('all', (event, filepath) => {
74
-
75
- if ((event=='add' || event=='change') && (
76
- // within fonto, transfer build files only, but also schema files, because
77
- // the "dist" folder isn't watched properly: it does not detect "assets" anymore after building once
78
- !/cmscustom.+fonto[\\\/]/.test(filepath) ||
79
- /fonto[\\\/]dist[\\\/]/.test(filepath) ||
80
- (/fonto[\\\/]dev[\\\/]/.test(filepath) && c.envDev) ||
81
- /fonto[\\\/]packages[\\\/]sx-shell-.*?[\\\/]assets[\\\/]schemas[\\\/]/.test(filepath)
82
- )
83
- ) {
84
- transfers.add(filepath);
85
- }
73
+ .on('all', (event, filepath) => {
74
+
75
+ if ((event=='add' || event=='change') && (
76
+ // within fonto, transfer build files only, but also schema files, because
77
+ // the "dist" folder isn't watched properly: it does not detect "assets" anymore after building once
78
+ !/cmscustom.+fonto[\\/]/.test(filepath) ||
79
+ /fonto[\\/]dist[\\/]/.test(filepath) ||
80
+ (/fonto[\\/]dev[\\/]/.test(filepath) && c.envDev) ||
81
+ /fonto[\\/]packages[\\/]sx-shell-.*?[\\/]assets[\\/]schemas[\\/]/.test(filepath)
82
+ )
83
+ ) {
84
+ transfers.add(filepath);
85
+ }
86
86
 
87
- else if (event=='unlink' && !/fonto/.test(filepath)) { // ignore fonto files
88
- s.removeFromCache(filepath);
87
+ else if (event=='unlink' && !/fonto/.test(filepath)) { // ignore fonto files
88
+ s.removeFromCache(filepath);
89
89
 
90
- if (!path.parse(filepath).base.match(/\.scss/)) {
91
- const rp = c.getRemotePath(filepath);
92
- const msg = 'Removed: ' + rp.replace(c.server.remotedir, '').white;
93
- if (c.localTransfer) del([rp], {force: true}).then(paths => _info(msg, true));
94
- else remote.add(`rm -rf "${rp}"`, msg).process();
90
+ if (!path.parse(filepath).base.match(/\.scss/)) {
91
+ const rp = c.getRemotePath(filepath);
92
+ const msg = 'Removed: ' + rp.replace(c.server.remotedir, '').white;
93
+ if (c.localTransfer) del([rp], {force: true}).then(paths => _info(msg, true));
94
+ else remote.add(`rm -rf "${rp}"`, msg).process();
95
+ }
95
96
  }
96
- }
97
- });
97
+ });
98
98
 
99
99
  }
100
100
 
@@ -3,8 +3,8 @@ const globby = require('globby');
3
3
  const path = require('path');
4
4
 
5
5
 
6
- const relPath = (d,p) => path.relative(d,p).toFws();
7
- const resolveBind = (d,p) => p.replace('#{cmscustompath}','cmscustom/').replace('{$rsrcPath}',(d.replace('stylesheets','resources')+'/'));
6
+ const relPath = (d, p) => path.relative(d, p).toFws();
7
+ const resolveBind = (d, p) => p.replace('#{cmscustompath}', 'cmscustom/').replace('{$rsrcPath}', (d.replace('stylesheets', 'resources')+'/'));
8
8
 
9
9
 
10
10
  module.exports = {
@@ -15,8 +15,8 @@ module.exports = {
15
15
  this.filesToTransfer = globby.sync(pattern, {nodir: true}); // get list of files to transfer
16
16
  this.potentialBaseFilesCache = this.potentialBaseFilesCache || globby.sync('**/*.{xml,xsd,xsl,scss}'); // get list of potential base files, if not previously done
17
17
  this.potentialBaseFiles = this.potentialBaseFilesCache
18
- .filter(p => !this.filesToTransfer.includes(p)) // subtract files to transfer from list of potential base files
19
- .map(path => [path]); // make array so file contents can be added later
18
+ .filter(p => !this.filesToTransfer.includes(p)) // subtract files to transfer from list of potential base files
19
+ .map(path => [path]); // make array so file contents can be added later
20
20
 
21
21
  if (!this.filesToTransfer[0]) _error('No files found that qualify for transfer!');
22
22
 
@@ -27,7 +27,7 @@ module.exports = {
27
27
  this.filesToTransfer.forEach(f => _write(f));
28
28
  }
29
29
 
30
- this.filesToTransfer.forEach((ftt,i,a) => {
30
+ this.filesToTransfer.forEach((ftt, i, a) => {
31
31
  a.push(...this.findBaseFiles(ftt)); // for each in list of files to transfer, find base files and add to list
32
32
  });
33
33
 
@@ -35,7 +35,7 @@ module.exports = {
35
35
  _info('\nBase files added for files above:');
36
36
  const baseFiles = this.filesToTransfer.filter(f => !filesToTransferStart.includes(f));
37
37
  baseFiles.forEach(f => _write(f));
38
- if (!baseFiles[0]) _write('None.')
38
+ if (!baseFiles[0]) _write('None.');
39
39
  _perf(startTime);
40
40
  }
41
41
 
@@ -50,19 +50,19 @@ module.exports = {
50
50
 
51
51
  if (this.potentialBaseFiles && (fttExt.xsl || fttExt.scss || fttObj.dir.includes('xopus'))) {
52
52
  const lookbehind =
53
- fttExt.xml ? 'x:import src' :
54
- fttExt.xsd ? '(xsd|schemaLocation)' :
55
- fttExt.xsl ? '(xsl|href)' :
56
- fttExt.js ? 'x:javascript src' :
57
- ''
53
+ fttExt.xml ? 'x:import src' :
54
+ fttExt.xsd ? '(xsd|schemaLocation)' :
55
+ fttExt.xsl ? '(xsl|href)' :
56
+ fttExt.js ? 'x:javascript src' :
57
+ ''
58
58
  ;
59
59
  const findIncExp = new RegExp(
60
60
  fttExt.scss ? `(?<=@import ['"])[^'"]*?${fttObj.name.replace(/^_/, '')}` // for sass include, leading _ and extension are optional
61
- : `(?<=${lookbehind}\=")[^"]*?${fttObj.base}`
62
- , 'g'
61
+ : `(?<=${lookbehind}=")[^"]*?${fttObj.base}`
62
+ , 'g'
63
63
  );
64
64
 
65
- this.potentialBaseFiles.forEach((f,i,a) => {
65
+ this.potentialBaseFiles.forEach((f) => {
66
66
  const pbfExt = {};
67
67
  pbfExt[path.extname(f[0]).substr(1)] = true;
68
68
  const canInclude = (pbfExt.xml && !fttExt.scss) || (pbfExt.xsd && fttExt.xsd) || (pbfExt.xsl && (fttExt.xsl || fttExt.js)) || (pbfExt.scss && fttExt.scss);
@@ -89,7 +89,7 @@ module.exports = {
89
89
 
90
90
  if (baseFiles) {
91
91
  this.potentialBaseFiles = this.potentialBaseFiles.filter(f => !baseFiles.includes(f[0])); // once added, do not search again
92
- baseFiles.forEach((p,i,a) => {
92
+ baseFiles.forEach((p, i, a) => {
93
93
  a.push(...this.findBaseFiles(p)); // recursively search for base files having their own base files
94
94
  });
95
95
  }
@@ -104,5 +104,5 @@ module.exports = {
104
104
  removeFromCache (filepath) {
105
105
  if (this.potentialBaseFilesCache) this.potentialBaseFilesCache = this.potentialBaseFilesCache.filter(fp => fp != filepath.toFws());
106
106
  }
107
-
107
+
108
108
  };
@@ -1,4 +1,4 @@
1
- const {exec, execSync} = require('child_process');
1
+ const {exec} = require('child_process');
2
2
  const fs = require('fs-extra');
3
3
  const gulp = require('gulp');
4
4
  const g_print = require('gulp-print');
@@ -10,34 +10,24 @@ const wws = require('../../lib/worker-with-spinner');
10
10
  g_print.setLogFunction((filepath) => _write(filepath.nostyle));
11
11
 
12
12
 
13
- const allowedFontoVersionRegex = () => {
14
- const cfvPath = path.join(_paths.repo, _paths.tdi, 'tct/fonto/compatibleVersions.json');
15
- if (fs.pathExistsSync(cfvPath)) return RegExp(fs.readJsonSync(cfvPath).regex);
16
-
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
- }
21
- };
22
-
23
13
  const compileSass = () => new Promise((resolve, reject) => {
24
14
  _info('Compile sass to css:');
25
15
  gulp.src('**/*.scss')
26
- .pipe(sass().on('error', error => reject(error)))
27
- .pipe(g_print.default())
28
- .pipe(gulp.dest('.'))
29
- .on('end', () => {
30
- resolve();
31
- _write();
32
- })
16
+ .pipe(sass().on('error', error => reject(error)))
17
+ .pipe(g_print.default())
18
+ .pipe(gulp.dest('.'))
19
+ .on('end', () => {
20
+ resolve();
21
+ _write();
22
+ })
33
23
  ;
34
24
  });
35
25
 
36
- const cmdExec = command => new Promise((resolve, reject) => {
26
+ const cmdExec = command => new Promise((resolve) => {
37
27
  _info(`Executing command (${command}):`);
38
28
  const cp = exec(command);
39
29
  const log = msg => {
40
- const line = msg.replace(/\s+$/,''); // remove excessive whitespace
30
+ const line = msg.replace(/\s+$/, ''); // remove excessive whitespace
41
31
  if (line) console.log(line);
42
32
  };
43
33
 
@@ -47,7 +37,7 @@ const cmdExec = command => new Promise((resolve, reject) => {
47
37
  else log(data);
48
38
  });
49
39
  cp.stderr.setEncoding('utf8');
50
- cp.stderr.on('data', data => log(data.replace(/Browserslist: caniuse-lite .*/s,'')));
40
+ cp.stderr.on('data', data => log(data.replace(/Browserslist: caniuse-lite .*/s, '')));
51
41
  cp.on('close', code => {
52
42
  _write();
53
43
  resolve();
@@ -57,85 +47,72 @@ const cmdExec = command => new Promise((resolve, reject) => {
57
47
 
58
48
  module.exports = {
59
49
 
60
- init (init) {
61
- let version = init;
62
-
50
+ init ([fdt, fontoVersion]) {
63
51
  return new Promise((resolve, reject) => {
64
- _info('Ensure symlink exists:');
65
- fs.symlink(path.join('../../../tdi/fonto/packages-shared'), 'packages-shared', 'dir', err => {
66
- if (err && err.code!='EEXIST') reject(err.code=='EPERM' ? 'Start your console as admin for symlink creation!' : err);
67
- else _write('Done.\n');
68
- resolve();
69
- });
70
- })
71
- .then(() => {
72
- _info('Determining Fonto version:');
73
- if (typeof init == 'boolean') { // no value passed
74
- version = fs.readJsonSync('manifest.json').sdkVersion;
75
- if (version.startsWith('Nightlies')) version = 'nightly';
76
- }
77
- else if (init == 'latest') {
78
- const data = execSync(`fdt editor versions`, {encoding: 'UTF-8'});
79
- let versionRegex = allowedFontoVersionRegex();
80
- version = data.match(/\d+\.\d+\.\d+/g).filter(v => versionRegex.test(v))[0];
81
- }
82
- _write(version+'\n');
83
- })
84
- .then(() => cmdExec(`fdt editor upgrade --version ${version} --non-interactive`))
52
+ _info('Ensure symlink exists:');
53
+ fs.symlink(path.join('../../../tdi/fonto/packages-shared'), 'packages-shared', 'dir', err => {
54
+ if (err && err.code!='EEXIST') reject(err.code=='EPERM' ? 'Start your console as admin for symlink creation!' : err);
55
+ else _write('Done.\n');
56
+ resolve();
57
+ });
58
+ })
59
+ .then(() => cmdExec(`${fdt} editor upgrade --version ${fontoVersion} --non-interactive`))
60
+ .then(() => [fdt])
85
61
  ;
86
62
  },
87
63
 
88
- schema () {
89
- return cmdExec('fdt editor schema compile ../schema --overwrite')
90
- .then(() => {
91
- _info('Updating schema configuration:');
64
+ schema ([fdt]) {
65
+ return cmdExec(`${fdt} editor schema compile ../schema --overwrite`)
66
+ .then(() => {
67
+ _info('Updating schema configuration:');
92
68
 
93
- const {rootSchemas} = fs.readJsonSync('../schema/fonto.json');
94
- const fontoManifest = fs.readJsonSync('config/fonto-manifest.json');
95
- let jsonPaths = [];
69
+ const {rootSchemas} = fs.readJsonSync('../schema/fonto.json');
70
+ const fontoManifest = fs.readJsonSync('config/fonto-manifest.json');
71
+ let jsonPaths = [];
96
72
 
97
- // remove all schema packages (sx-shell-*) from fonto-manifest.json
98
- Object.keys(fontoManifest.dependencies).filter(k => k.includes('sx-shell-')).forEach(k => {
99
- delete fontoManifest.dependencies[k];
100
- });
73
+ // remove all schema packages (sx-shell-*) from fonto-manifest.json
74
+ Object.keys(fontoManifest.dependencies).filter(k => k.includes('sx-shell-')).forEach(k => {
75
+ delete fontoManifest.dependencies[k];
76
+ });
101
77
 
102
- // add dependency for sx-module to each package fonto-manifest.json
103
- // add schema packages in fonto.json to config/fonto-manifest.json
104
- Object.entries(rootSchemas).forEach(([xsdPath, obj]) => {
105
- const pckPath = 'packages/' + obj.packageName;
106
- const pckFontoManifest = fs.readJsonSync(pckPath + '/fonto-manifest.json', {throws: false}) || {dependencies: {}};
107
- pckFontoManifest.dependencies['sx-module'] = 'packages/sx-module';
108
- fs.outputJsonSync(pckPath + '/fonto-manifest.json', pckFontoManifest, {spaces: 2});
109
- _write(`${pckPath}/fonto-manifest.json`);
110
- fontoManifest.dependencies[obj.packageName] = pckPath;
111
- jsonPaths.push(`${pckPath}/src/assets/schemas/${obj.packageName}.json`);
112
- });
78
+ // add dependency for sx-module to each package fonto-manifest.json
79
+ // add schema packages in fonto.json to config/fonto-manifest.json
80
+ Object.entries(rootSchemas).forEach(([xsdPath, obj]) => {
81
+ const pckPath = 'packages/' + obj.packageName;
82
+ const pckFontoManifest = fs.readJsonSync(pckPath + '/fonto-manifest.json', {throws: false}) || {dependencies: {}};
83
+ pckFontoManifest.dependencies['sx-module'] = 'packages/sx-module';
84
+ fs.outputJsonSync(pckPath + '/fonto-manifest.json', pckFontoManifest, {spaces: 2});
85
+ _write(`${pckPath}/fonto-manifest.json`);
86
+ fontoManifest.dependencies[obj.packageName] = pckPath;
87
+ jsonPaths.push(`${pckPath}/src/assets/schemas/${obj.packageName}.json`);
88
+ });
113
89
 
114
- fs.outputJsonSync('config/fonto-manifest.json', fontoManifest, {spaces: 2});
115
- _write('config/fonto-manifest.json');
116
- fs.outputFileSync('config/schemaExperienceResolver.js',
117
- `import tanSchemaLocationToSchemaExperienceResolver from 'tan-base/src/schemaExperienceResolver.js';`+
90
+ fs.outputJsonSync('config/fonto-manifest.json', fontoManifest, {spaces: 2});
91
+ _write('config/fonto-manifest.json');
92
+ fs.outputFileSync('config/schemaExperienceResolver.js',
93
+ `import tanSchemaLocationToSchemaExperienceResolver from 'tan-base/src/schemaExperienceResolver.js';`+
118
94
  `\n\n`+
119
95
  `tanSchemaLocationToSchemaExperienceResolver(${JSON.stringify(rootSchemas, null, 2)});`
120
- );
121
- _write('config/schemaExperienceResolver.js');
122
-
123
- _write();
124
- _info('Copying schema json files to build folders:');
125
- // deploy-watch copies schema's to server directly, so update local builds to keep integrity
126
- jsonPaths.forEach(jsonPath => {
127
- fs.copySync(jsonPath, 'dev/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
128
- fs.copySync(jsonPath, 'dist/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
96
+ );
97
+ _write('config/schemaExperienceResolver.js');
98
+
99
+ _write();
100
+ _info('Copying schema json files to build folders:');
101
+ // deploy-watch copies schema's to server directly, so update local builds to keep integrity
102
+ jsonPaths.forEach(jsonPath => {
103
+ fs.copySync(jsonPath, 'dev/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
104
+ fs.copySync(jsonPath, 'dist/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
105
+ });
106
+ _write('Done.\n');
129
107
  })
130
- _write('Done.\n');
131
- })
108
+ .then(() => [fdt])
132
109
  ;
133
110
  },
134
111
 
135
- elements () {
112
+ elements ([fdt]) {
136
113
  _info('Elements requiring custom configuration:');
137
114
 
138
- const findElements = ({rootSchemas, tdiXsdPath}) => { // cannot use variables from outside this function
115
+ const findElements = ({fdt, rootSchemas, tdiXsdPath}) => { // cannot use variables from outside this function
139
116
  const {execSync} = require('child_process'), fs = require('fs');
140
117
 
141
118
  // get all elements defined in default schema
@@ -149,8 +126,8 @@ module.exports = {
149
126
  // execute "fdt elements" for each schema package, ignore default elements, and combine results
150
127
  const schemasPerElement = {};
151
128
  Object.entries(rootSchemas).forEach(([path, obj]) => {
152
- const data = execSync(`fdt elements --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json -C name`, {encoding: 'UTF-8'});
153
- const elements = data.replace(/^.*?Name\*|Printed name\*.*$/gs, '').split(/\s+/);
129
+ const data = execSync(`${fdt} elements --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json -C name`, {encoding: 'UTF-8'});
130
+ const elements = data.replace(/(^.*?Name\*)|(Printed name\*.*$)/gs, '').split(/\s+/);
154
131
  const customElements = [...new Set(elements)].filter(e => e && !ignoreElements.includes(e));
155
132
 
156
133
  customElements.forEach(e => {
@@ -165,23 +142,26 @@ module.exports = {
165
142
  };
166
143
 
167
144
  return wws(
168
- 'searching',
169
- findElements,
170
- {
171
- rootSchemas: fs.readJsonSync('../schema/fonto.json').rootSchemas,
172
- tdiXsdPath: path.join(_paths.repo, _paths.tdi, 'src/config/cmscustom/[customer]/[project]/schema/xsd/')
173
- },
174
- result => {
175
- if (Array.isArray(result)) result.forEach(([e, s]) => _write(e, s, '\n'));
176
- else _write(result, '\n');
177
- }
178
- );
145
+ 'searching',
146
+ findElements,
147
+ {
148
+ fdt,
149
+ rootSchemas: fs.readJsonSync('../schema/fonto.json').rootSchemas,
150
+ tdiXsdPath: path.join(_paths.repo, _paths.tdi, 'src/config/cmscustom/[customer]/[project]/schema/xsd/')
151
+ },
152
+ result => {
153
+ if (Array.isArray(result)) result.forEach(([e, s]) => _write(e, s, '\n'));
154
+ else _write(result, '\n');
155
+ }
156
+ )
157
+ .then(() => [fdt])
158
+ ;
179
159
  },
180
160
 
181
- attributes () {
161
+ attributes ([fdt]) {
182
162
  _info('Attributes requiring custom configuration:');
183
163
 
184
- const findAttributes = ({rootSchemas, tdiXsdPath}) => { // cannot use variables from outside this function
164
+ const findAttributes = ({fdt, rootSchemas, tdiXsdPath}) => { // cannot use variables from outside this function
185
165
  const {execSync} = require('child_process'), fs = require('fs');
186
166
 
187
167
  // get all attributes defined in default schema
@@ -195,8 +175,8 @@ module.exports = {
195
175
  // execute "fdt attributes" for each schema package, ignore default attributes, and combine results
196
176
  const schemasPerAttribute = {};
197
177
  Object.entries(rootSchemas).forEach(([path, obj]) => {
198
- const data = execSync(`fdt attributes --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json`, {encoding: 'UTF-8'});
199
- const attributes = data.replace(/^.*?Default value\s+|\s+Printed name\*.*$/gs, '').split(/\n\s+/).map(a => a.split(/\s+/)).map(a =>
178
+ const data = execSync(`${fdt} attributes --schema packages/${obj.packageName}/src/assets/schemas/${obj.packageName}.json`, {encoding: 'UTF-8'});
179
+ const attributes = data.replace(/(^.*?Default value\s+)|(\s+Printed name\*.*$)/gs, '').split(/\n\s+/).map(a => a.split(/\s+/)).map(a =>
200
180
  a[0] + (a[2]=='required' ? ' (required)' : '') + (a[3]=='-' ? ' (no default)' : '')
201
181
  );
202
182
  const customAttributes = [...new Set(attributes)].filter(e => e && !ignoreAttributes.includes(e.replace(/ .*/, '')));
@@ -213,20 +193,23 @@ module.exports = {
213
193
  };
214
194
 
215
195
  return wws(
216
- 'searching',
217
- findAttributes,
218
- {
219
- rootSchemas: fs.readJsonSync('../schema/fonto.json').rootSchemas,
220
- tdiXsdPath: path.join(_paths.repo, _paths.tdi, 'src/config/cmscustom/[customer]/[project]/schema/xsd/')
221
- },
222
- result => {
223
- if (Array.isArray(result)) result.forEach(([e, s]) => _write(e, s, '\n'));
224
- else _write(result, '\n');
225
- }
226
- );
196
+ 'searching',
197
+ findAttributes,
198
+ {
199
+ fdt,
200
+ rootSchemas: fs.readJsonSync('../schema/fonto.json').rootSchemas,
201
+ tdiXsdPath: path.join(_paths.repo, _paths.tdi, 'src/config/cmscustom/[customer]/[project]/schema/xsd/')
202
+ },
203
+ result => {
204
+ if (Array.isArray(result)) result.forEach(([e, s]) => _write(e, s, '\n'));
205
+ else _write(result, '\n');
206
+ }
207
+ )
208
+ .then(() => [fdt])
209
+ ;
227
210
  },
228
211
 
229
- localize () {
212
+ localize ([fdt]) {
230
213
  const templateFile = 'messages-template-packages.json';
231
214
  const messagesFile = 'packages/localization/src/messages.nl.json';
232
215
  const packagesDirs = fs.readdirSync('packages')
@@ -235,55 +218,47 @@ module.exports = {
235
218
  .join(' ')
236
219
  ;
237
220
 
238
- _info(`Ensure ${messagesFile} exists:`)
221
+ _info(`Ensure ${messagesFile} exists:`);
239
222
  if (!fs.existsSync(messagesFile)) fs.outputJsonSync(messagesFile, [], {spaces: 2});
240
223
 
241
- return cmdExec(`fdt localization extract ${templateFile} --paths ` + packagesDirs)
242
- .then(() => cmdExec(`fdt localization update ${messagesFile} ${templateFile}`))
243
- .then(() => {
244
- _info('Remove template file:');
245
- fs.unlinkSync(templateFile);
246
- _write('Done.\n');
247
- })
224
+ return cmdExec(`${fdt} localization extract ${templateFile} --paths ` + packagesDirs)
225
+ .then(() => cmdExec(`${fdt} localization update ${messagesFile} ${templateFile}`))
226
+ .then(() => {
227
+ _info('Remove template file:');
228
+ fs.unlinkSync(templateFile);
229
+ _write('Done.\n');
230
+ })
231
+ .then(() => [fdt])
248
232
  ;
249
233
  },
250
234
 
251
- build () {
252
- const {sdkVersion} = fs.readJsonSync('manifest.json');
253
- if (!allowedFontoVersionRegex().test(sdkVersion)) {
254
- _error(`Fonto version ${sdkVersion} is not compatible with the current TDI submodule commit!\nExecute: tct fonto --init latest`);
255
- }
256
-
235
+ build ([fdt]) {
257
236
  return compileSass()
258
- .then(() => {
259
- _info('Delete dist/assets folder:');
260
- fs.removeSync('dist/assets');
261
- _write('Done.\n');
262
- })
263
- .then(() => cmdExec('fdt editor build'))
237
+ .then(() => {
238
+ _info('Delete dist/assets folder:');
239
+ fs.removeSync('dist/assets');
240
+ _write('Done.\n');
241
+ })
242
+ .then(() => cmdExec(`${fdt} editor build`))
243
+ .then(() => [fdt])
264
244
  ;
265
245
  },
266
246
 
267
- run () {
268
- const {sdkVersion} = fs.readJsonSync('manifest.json');
269
- if (!allowedFontoVersionRegex().test(sdkVersion)) {
270
- _error(`Fonto version ${sdkVersion} is not compatible with the current TDI submodule commit!\nExecute: tct fonto --init latest`);
271
- }
272
-
247
+ run ([fdt]) {
273
248
  return compileSass()
274
- .then(() => {
275
- _info('Starting sass watch:');
276
- gulp.watch('**/*.scss')
277
- .on('all', (event, filepath) => {
278
- _write(event + ':', filepath);
279
- gulp.src('**/*.scss')
280
- .pipe(sass().on('error', sass.logError))
281
- .pipe(gulp.dest('.'))
282
- ;
283
- });
284
- _write('Done.\n');
285
- })
286
- .then(() => cmdExec('fdt editor run --write-to-disk'))
249
+ .then(() => {
250
+ _info('Starting sass watch:');
251
+ gulp.watch('**/*.scss')
252
+ .on('all', (event, filepath) => {
253
+ _write(event + ':', filepath);
254
+ gulp.src('**/*.scss')
255
+ .pipe(sass().on('error', sass.logError))
256
+ .pipe(gulp.dest('.'))
257
+ ;
258
+ });
259
+ _write('Done.\n');
260
+ })
261
+ .then(() => cmdExec(`${fdt} editor run --write-to-disk`))
287
262
  ;
288
263
  }
289
264
 
@@ -1,47 +1,80 @@
1
- const commands = require('./commands');
2
- const fs = require('fs-extra');
3
- const globby = require('globby');
4
- const path = require('path');
1
+ const commands = require('./commands');
2
+ const {execSync} = require('child_process');
3
+ const fs = require('fs-extra');
4
+ const globby = require('globby');
5
+ const path = require('path');
5
6
 
6
7
 
8
+ const fdtCommand = (fv) => `npx -y ${_packages.FDT.name}@${fv.replace(/^(7\.|8\.[012]\.).*/, '3.12.0')}`;
9
+
7
10
  module.exports = function fonto (argv) {
8
11
 
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);
15
+
16
+ // old way: a regex for each basecommit is stored in global._git.commitTdi
17
+ for (const fv of _git.commitTdi.fontoVersions) {
18
+ if (_git.commitTdi.after(fv.commitHash)) return fv.regex;
19
+ }
20
+ })();
21
+
9
22
  if (!_tdiSubmoduleExists) _error('TDI submodule folder is missing.');
10
23
 
24
+ // check if FDT is not installed globally, because then it won't be possible to use specific versions with npx
25
+ if (fs.pathExistsSync(path.join(_appdata.npmPath, 'node_modules', _packages.FDT.name))) {
26
+ _error(`A global installation of FDT has been found! Remove it first.\nExecute: npm r -g ${_packages.FDT.name}`);
27
+ }
28
+
11
29
  process.chdir(_paths.apply || '.');
12
30
 
13
- // find fonto instances by searching for manifest.json files having a fonto property
14
- const fontoPaths = globby.sync(['**/manifest.json', `!${_paths.tdi}/**`])
15
- .filter(p => (fs.readJsonSync(p, {throws: false}) || {}).edition == 'fontoxml-platform-base')
16
- .map(p => p.replace('manifest.json', ''))
17
- ;
31
+ // find fonto instances by searching for fonto/manifest.json files
32
+ 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
+ );
18
35
 
19
36
  if (fontoPaths.length==0) _error('No Fonto instance found.');
20
37
 
21
38
  let promiseChain = Promise.resolve(); // for sequentially executing commands for each fonto instance
22
39
 
23
- fontoPaths.forEach((p, i) => {
40
+ fontoPaths.forEach(([fontoPath, fontoVersionCurrent], i) => {
41
+
24
42
  promiseChain = promiseChain
25
- .then(() => {
26
- process.chdir(path.join(_paths.repo, _paths.apply, p));
27
-
28
- if (p!='.') _info(`${i>0 ? '\n' : ''}Fonto instance #${i+1}: ${path.join(_paths.apply, p)}\n`);
29
-
30
- return Promise.resolve() // execute commands sequentially and in correct order
31
- .then(argv.init && (()=>commands.init(argv.init)))
32
- .then(argv.schema && commands.schema)
33
- .then(argv.elements && commands.elements)
34
- .then(argv.attributes && commands.attributes)
35
- .then(argv.localize && commands.localize)
36
- .then(argv.build && commands.build)
37
- .then(argv.run && commands.run)
38
- ;
39
- });
43
+ .then(() => {
44
+ process.chdir(path.join(_paths.repo, _paths.apply, fontoPath));
45
+
46
+ if (fontoPath!='.') _info(`${i>0 ? '\n' : ''}Fonto instance #${i+1}: ${path.join(_paths.apply, fontoPath)}\n`);
47
+
48
+ // execute commands sequentially and in correct order
49
+ return new Promise((resolve) => {
50
+ _info('Determining Fonto version:');
51
+ let fontoVersionNew = typeof argv.init == 'string' ? argv.init : fontoVersionCurrent;
52
+
53
+ if (fontoVersionNew == 'latest') {
54
+ const data = execSync(`${fdtCommand(fontoVersionCurrent)} editor versions`, {encoding: 'UTF-8'});
55
+ fontoVersionNew = data.match(/\d+\.\d+\.\d+/g).filter(v => allowedFontoVersionRegex.test(v))[0];
56
+ }
57
+ else if (!allowedFontoVersionRegex.test(fontoVersionNew)) {
58
+ _error(`Fonto version ${fontoVersionNew} is not compatible with the current TDI submodule commit!\nExecute: tct fonto --init latest`);
59
+ }
60
+
61
+ _write(fontoVersionNew+'\n');
62
+ return resolve([fdtCommand(fontoVersionNew), fontoVersionNew]);
63
+ })
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
+ ;
72
+ });
40
73
  });
41
74
 
42
75
  promiseChain
43
- .catch(error => {
44
- if (error) _warn(error.message || error);
45
- });
76
+ .catch(error => {
77
+ if (error) _warn(error.message || error);
78
+ });
46
79
 
47
80
  };