@tangelo/tangelo-configuration-toolkit 1.18.0 → 1.20.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/index.js +15 -54
- package/package.json +8 -3
- package/src/cli.js +2 -2
- package/src/lib/gulp-sftp.js +2 -2
- package/src/lib/gulp-tcl-config.js +40 -0
- package/src/lib/package-update-check.js +7 -5
- package/src/lib/set-global-functions.js +24 -0
- package/src/lib/{style-string-getters.js → set-string-getters.js} +6 -0
- package/src/lib/tcl-config.js +101 -0
- package/src/modules/deploy/config.js +2 -2
- package/src/modules/deploy/execute.js +4 -1
- package/src/modules/deploy/index.js +1 -1
- package/src/modules/deploy/srcset.js +3 -3
- package/src/modules/fonto/commands.js +34 -15
- package/src/modules/fonto/index.js +7 -5
- package/src/modules/git/index.js +22 -8
- package/src/modules/migrate/index.js +1 -1
- package/src/modules/sql/index.js +1 -4
package/index.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
global._appStartTime = new Date();
|
|
2
2
|
|
|
3
|
-
require('./src/lib/
|
|
4
|
-
|
|
5
|
-
String.prototype.toFws = function(){
|
|
6
|
-
return this.replace(/\\/g, '/');
|
|
7
|
-
};
|
|
3
|
+
require('./src/lib/set-string-getters.js');
|
|
4
|
+
require('./src/lib/set-global-functions.js');
|
|
8
5
|
|
|
9
6
|
|
|
10
7
|
const {execSync} = require('child_process');
|
|
@@ -17,51 +14,12 @@ const execGitCommand = require('./src/lib/exec-git-command');
|
|
|
17
14
|
const memoize = require('./src/lib/memoize');
|
|
18
15
|
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
global._write = (...msg) => {
|
|
24
|
-
msg = msg.map(m => typeof m == 'object' ? JSON.stringify(m, null, 2).cyan : m);
|
|
25
|
-
console.log(msg.join(' ').replace(/^/gm, ' ')); // indent each line
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
global._info = (msg, time = false) => {
|
|
29
|
-
if (time) {
|
|
30
|
-
const tzDiff = new Date().getTimezoneOffset() * 60000;
|
|
31
|
-
const time = new Date(Date.now() - tzDiff).toISOString().match(/\d\d:\d\d:\d\d/)[0];
|
|
32
|
-
msg = `[${time}] ${msg}`;
|
|
33
|
-
}
|
|
34
|
-
console.log(msg.lgreen);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
global._warn = msg => {
|
|
38
|
-
console.log(msg.lyellow);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
global._error = msg => {
|
|
42
|
-
console.log(msg.red, '\n');
|
|
43
|
-
process.exit();
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
global._perf = t1 => {
|
|
47
|
-
const t2 = new Date();
|
|
48
|
-
console.log(`\nExecution time: ${t2 - t1}ms`.blue);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
global._formatDate = date =>
|
|
52
|
-
date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'})
|
|
53
|
-
;
|
|
17
|
+
global._package = require('./package.json');
|
|
54
18
|
|
|
55
19
|
|
|
56
20
|
global._devmode = !__dirname.includes('node_modules');
|
|
57
21
|
|
|
58
22
|
|
|
59
|
-
global._packages = {
|
|
60
|
-
TCT: {name: '@tangelo/tangelo-configuration-toolkit', version: require('./package.json')?.version},
|
|
61
|
-
FDT: {name: '@fontoxml/fontoxml-development-tools'}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
|
|
65
23
|
global._paths = {
|
|
66
24
|
app: __dirname,
|
|
67
25
|
apphome: path.join(homedir, '.tct'),
|
|
@@ -71,8 +29,7 @@ global._paths = {
|
|
|
71
29
|
};
|
|
72
30
|
_paths.appdata = path.join(_paths.apphome, 'appdata.json');
|
|
73
31
|
_paths.appconfig = path.join(_paths.apphome, 'appconfig.json');
|
|
74
|
-
_paths.
|
|
75
|
-
_paths.apply = process.cwd().replace(_paths.repo, '').substr(1);
|
|
32
|
+
_paths.apply = process.cwd().replace(_paths.repo, '').slice(1);
|
|
76
33
|
|
|
77
34
|
|
|
78
35
|
global._appdata = fs.readJsonSync(_paths.appdata, {throws: false}) || {};
|
|
@@ -105,7 +62,8 @@ catch({code, message}) {
|
|
|
105
62
|
global._repoconfig = require('./src/lib/get-repoconfig')(_paths.repo);
|
|
106
63
|
|
|
107
64
|
|
|
108
|
-
|
|
65
|
+
const filenameSC = _package.name.split('/').pop() + '-appconfig.json';
|
|
66
|
+
_appconfig.sharedConfigPath = path.resolve(_paths.appconfig, '..', _appconfig.sharedConfigPath || '', filenameSC);
|
|
109
67
|
_appconfig.shared = fs.readJsonSync(_appconfig.sharedConfigPath, {throws: false}) || {};
|
|
110
68
|
|
|
111
69
|
|
|
@@ -134,29 +92,32 @@ global._isPre51 = () => !fs.existsSync(path.join(_paths.repo, _paths.tdi, 'src')
|
|
|
134
92
|
|
|
135
93
|
global._modulesTdi = {
|
|
136
94
|
absolutePathTdi: path.join(_paths.repo, _paths.tdi),
|
|
137
|
-
ensureDepsUpToDate() {
|
|
95
|
+
ensureDepsUpToDate(message) {
|
|
138
96
|
if (this.depsUpToDate) return;
|
|
139
97
|
try {
|
|
140
|
-
_info('Checking installed dependencies in submodule');
|
|
98
|
+
if (message) _info('Checking installed dependencies in submodule');
|
|
141
99
|
execSync('npm list', {cwd: this.absolutePathTdi, stdio: 'ignore'});
|
|
142
100
|
} catch (e) {
|
|
143
|
-
_info('Updating dependencies in submodule');
|
|
101
|
+
if (message) _info('Updating dependencies in submodule');
|
|
144
102
|
execSync('npm update', {cwd: this.absolutePathTdi, stdio: 'ignore'});
|
|
145
103
|
}
|
|
146
104
|
this.depsUpToDate = true;
|
|
147
105
|
},
|
|
148
|
-
require(module) {
|
|
106
|
+
require(module, {throws = true, message = true} = {}) {
|
|
149
107
|
if (path.extname(module) !== '.json') this.ensureDepsUpToDate();
|
|
150
|
-
_info(`Loading ${path.join(_paths.tdi, 'tct', module)}\n`);
|
|
108
|
+
if (message) _info(`Loading ${path.join(_paths.tdi, 'tct', module)}\n`);
|
|
151
109
|
try {
|
|
152
110
|
return require(path.join(this.absolutePathTdi, 'tct', module));
|
|
153
111
|
}
|
|
154
112
|
catch (e) {
|
|
155
|
-
_error('Module could not be loaded');
|
|
113
|
+
if (throws) _error('Module could not be loaded: ' + module);
|
|
114
|
+
else return undefined;
|
|
156
115
|
}
|
|
157
116
|
}
|
|
158
117
|
};
|
|
159
118
|
|
|
119
|
+
global._settingsTdi = memoize(() => Object.assign(_package.settingsTdiDefault, _modulesTdi.require('settings.json', {throws: false, message: false}) ?? {}));
|
|
120
|
+
|
|
160
121
|
|
|
161
122
|
process.on('beforeExit', () => {
|
|
162
123
|
_write(); // print empty line before and after update check
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangelo/tangelo-configuration-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=14.0.0"
|
|
6
6
|
},
|
|
@@ -46,15 +46,20 @@
|
|
|
46
46
|
"p-limit": "^3.1.0",
|
|
47
47
|
"replace-in-file": "^6.3.2",
|
|
48
48
|
"sass": "^1.43.5",
|
|
49
|
-
"saxon-js": "^2.
|
|
49
|
+
"saxon-js": "^2.5.0",
|
|
50
50
|
"ssh2-sftp-client": "^9.1.0",
|
|
51
51
|
"through2": "^4.0.2",
|
|
52
52
|
"tiny-lr": "^2.0.0",
|
|
53
|
+
"xml2js": "^0.6.2",
|
|
53
54
|
"yargs": "^17.7.2"
|
|
54
55
|
},
|
|
55
56
|
"repository": {
|
|
56
57
|
"type": "git",
|
|
57
58
|
"url": "git+ssh://git@bitbucket.org/tangelosoftware/tangelo-configuration-toolkit.git"
|
|
58
59
|
},
|
|
59
|
-
"homepage": "https://bitbucket.org/tangelosoftware/tangelo-configuration-toolkit#readme"
|
|
60
|
+
"homepage": "https://bitbucket.org/tangelosoftware/tangelo-configuration-toolkit#readme",
|
|
61
|
+
"settingsTdiDefault": {
|
|
62
|
+
"#": "Defaults for tangelo-default-implementation/tct/settings.json",
|
|
63
|
+
"transpileToES5": true
|
|
64
|
+
}
|
|
60
65
|
}
|
package/src/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = function cli () {
|
|
|
6
6
|
_write();
|
|
7
7
|
|
|
8
8
|
const txtTitle = 'Tangelo Configuration Toolkit'.bold.underline.cyan;
|
|
9
|
-
const txtVersion = `v${
|
|
9
|
+
const txtVersion = `v${_package.version}`.lblack;
|
|
10
10
|
|
|
11
11
|
yargs
|
|
12
12
|
.scriptName('tct')
|
|
@@ -77,7 +77,7 @@ module.exports = function cli () {
|
|
|
77
77
|
clone: {alias: 'c', desc: 'Clone a client repository and do basic setup', conflicts: ['i', 'r', 'u']},
|
|
78
78
|
'update-repo': {alias: 'ur', desc: 'Update repository', conflicts: ['i', 'r', 'c']},
|
|
79
79
|
'update-submodule': {alias: 'us', desc: 'Update TDI submodule, optionally pass release branch (without "release/")', conflicts: ['i', 'r', 'c']},
|
|
80
|
-
dates: {alias: 'd', desc: '[hidden] Use i.c.w. update-submodule, pass 2 dates in format
|
|
80
|
+
dates: {alias: 'd', desc: '[hidden] Use i.c.w. update-submodule, pass 2 dates in format yyyy-mm-dd', conflicts: ['i', 'r', 'c'], implies: 'update-submodule', requiresArg: true, array: true, hidden: !_devmode}
|
|
81
81
|
},
|
|
82
82
|
handler: require('./modules/git')
|
|
83
83
|
})
|
package/src/lib/gulp-sftp.js
CHANGED
|
@@ -14,9 +14,9 @@ module.exports = function(ftpConfig, remotedir) {
|
|
|
14
14
|
|
|
15
15
|
function transform (file, _, cb) {
|
|
16
16
|
if (file.isStream()) return cb(new Error('Streaming not supported.'));
|
|
17
|
-
if (file.stat
|
|
17
|
+
if (file.stat?.isDirectory()) return cb();
|
|
18
18
|
|
|
19
|
-
file.destination = path.join(remotedir, file.relative).toFws
|
|
19
|
+
file.destination = path.join(remotedir, file.relative).toFws;
|
|
20
20
|
files.push(file); // collect all files in array
|
|
21
21
|
return cb();
|
|
22
22
|
},
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const TclConfig = require('./tcl-config');
|
|
4
|
+
const through2 = require('through2');
|
|
5
|
+
const Vinyl = require('vinyl');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
function createAddToStreamFn(stream) {
|
|
9
|
+
return (path, content) => stream.push(new Vinyl({
|
|
10
|
+
path: path,
|
|
11
|
+
contents: Buffer.from(content)
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = function() {
|
|
16
|
+
const tclFileDirs = [];
|
|
17
|
+
|
|
18
|
+
return through2.obj(
|
|
19
|
+
|
|
20
|
+
function transform (file, _, cb) {
|
|
21
|
+
if (file.isStream()) return cb(new Error('Streaming not supported.'));
|
|
22
|
+
|
|
23
|
+
if (file.extname == '.tcl') tclFileDirs.push(path.dirname(file.relative));
|
|
24
|
+
return cb(null, file);
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
function flush(cb) {
|
|
28
|
+
for (const tclFileDir of tclFileDirs) {
|
|
29
|
+
const tclConfig = new TclConfig(tclFileDir, createAddToStreamFn(this));
|
|
30
|
+
tclConfig.outputJson(path.resolve(tclFileDir, 'fonto/assets'));
|
|
31
|
+
tclConfig.outputCss(path.resolve(tclFileDir, 'fonto'));
|
|
32
|
+
const esefCssDir = path.resolve(tclFileDir, 'export/esef/esef_out/css');
|
|
33
|
+
if (fs.existsSync(esefCssDir)) tclConfig.outputCss(esefCssDir);
|
|
34
|
+
}
|
|
35
|
+
cb();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
)
|
|
39
|
+
.resume(); // required for triggering 'end' event
|
|
40
|
+
};
|
|
@@ -2,12 +2,14 @@ const {compare} = require('compare-versions');
|
|
|
2
2
|
const exec = require('util').promisify(require('child_process').exec);
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
const packages = {TCT: _package};
|
|
6
|
+
|
|
5
7
|
const doUpdateCheck = (pkg) => (
|
|
6
|
-
exec(`npm view -g ${
|
|
8
|
+
exec(`npm view -g ${packages[pkg].name} version`)
|
|
7
9
|
.then(r => {
|
|
8
10
|
const versionAvailable = r.stdout.match(/([\d/.]+)/)[1];
|
|
9
|
-
if (!
|
|
10
|
-
else if (compare(
|
|
11
|
+
if (!packages[pkg].version) _warn(`${pkg} is not installed! Run ` + `npm i -g ${packages[pkg].name}`.white);
|
|
12
|
+
else if (compare(packages[pkg].version, versionAvailable, '<')) {
|
|
11
13
|
_appdata._update({[`updateCheck${pkg}`]: {executed: new Date(), versionAvailable}});
|
|
12
14
|
return versionAvailable;
|
|
13
15
|
}
|
|
@@ -25,14 +27,14 @@ module.exports = function packageUpdateCheck () {
|
|
|
25
27
|
checkUpdatesDone = true;
|
|
26
28
|
|
|
27
29
|
['TCT'].forEach(pkg => {
|
|
28
|
-
const updateMsg = (va) => `| Update ${pkg} to ${va} | ` + `npm i -g ${
|
|
30
|
+
const updateMsg = (va) => `| Update ${pkg} to ${va} | ` + `npm i -g ${packages[pkg].name}`.white;
|
|
29
31
|
const {versionAvailable} = _appdata[`updateCheck${pkg}`] || {};
|
|
30
32
|
|
|
31
33
|
if (new Date() - new Date(_appdata[`updateCheck${pkg}`]?.executed || 0) > 1000*3600*24*1) { // check every day
|
|
32
34
|
doUpdateCheck(pkg).then(r => r && _warn(updateMsg(r)));
|
|
33
35
|
}
|
|
34
36
|
else if (versionAvailable) {
|
|
35
|
-
if (compare(
|
|
37
|
+
if (compare(packages[pkg].version, versionAvailable, '<')) _warn(updateMsg(versionAvailable));
|
|
36
38
|
else _appdata._update({[`updateCheck${pkg}`]: {executed: new Date()}});
|
|
37
39
|
}
|
|
38
40
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
global._write = (...msg) => {
|
|
2
|
+
msg = msg.map(m => typeof m == 'object' ? JSON.stringify(m, null, 2).cyan : m);
|
|
3
|
+
console.log(msg.join(' ').replace(/^/gm, ' ')); // indent each line
|
|
4
|
+
};
|
|
5
|
+
global._info = (msg, time = false) => {
|
|
6
|
+
if (time) {
|
|
7
|
+
const tzDiff = new Date().getTimezoneOffset() * 60000;
|
|
8
|
+
const time = new Date(Date.now() - tzDiff).toISOString().match(/\d\d:\d\d:\d\d/)[0];
|
|
9
|
+
msg = `[${time}] ${msg}`;
|
|
10
|
+
}
|
|
11
|
+
console.log(msg.lgreen);
|
|
12
|
+
};
|
|
13
|
+
global._warn = msg => {
|
|
14
|
+
console.log(msg.lyellow);
|
|
15
|
+
};
|
|
16
|
+
global._error = msg => {
|
|
17
|
+
console.log(msg.red, '\n');
|
|
18
|
+
process.exit();
|
|
19
|
+
};
|
|
20
|
+
global._perf = t1 => {
|
|
21
|
+
const t2 = new Date();
|
|
22
|
+
console.log(`\nExecution time: ${t2 - t1}ms`.blue);
|
|
23
|
+
};
|
|
24
|
+
global._formatDate = date => date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'});
|
|
@@ -15,4 +15,10 @@ Object.defineProperty(String.prototype, 'nostyle', {
|
|
|
15
15
|
get () {
|
|
16
16
|
return this.replace(/[\u001b\u009b][[()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
|
|
17
17
|
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Object.defineProperty(String.prototype, 'toFws', {
|
|
21
|
+
get () {
|
|
22
|
+
return this.replace(/\\/g, '/');
|
|
23
|
+
}
|
|
18
24
|
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const sass = require('sass');
|
|
4
|
+
const SaxonJS = require('saxon-js');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module.exports = class TclConfig {
|
|
8
|
+
|
|
9
|
+
static #SEF_FILE_PATH = 'tcl/configToJson.sef.json';
|
|
10
|
+
static #JSON_TO_SCSS_FILE_PATH = 'tcl/configJsonToScss';
|
|
11
|
+
static #TCL_FILE_NAME = 'project.tcl';
|
|
12
|
+
static #TCL_JSON_FILE_NAME = 'tcl-config.json';
|
|
13
|
+
static #TCL_CSS_FILE_NAME = 'tcl-styles.css';
|
|
14
|
+
static #FONTO_HTML_FILE_NAME = 'index.html';
|
|
15
|
+
|
|
16
|
+
static #sefFile;
|
|
17
|
+
static #jsonToScssFile;
|
|
18
|
+
|
|
19
|
+
static #transformTclConfigToJson(tclFilePathRel) {
|
|
20
|
+
this.#sefFile ??= _modulesTdi.require(this.#SEF_FILE_PATH, {message: false});
|
|
21
|
+
|
|
22
|
+
const messages = [` Warnings from transformation of ${tclFilePathRel}`];
|
|
23
|
+
const transformation = SaxonJS.transform({
|
|
24
|
+
stylesheetText: JSON.stringify(this.#sefFile),
|
|
25
|
+
sourceFileName: tclFilePathRel,
|
|
26
|
+
destination: 'raw',
|
|
27
|
+
deliverMessage(messageNode) {
|
|
28
|
+
messages.push(messageNode.textContent);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (messages[1]) _warn(messages.join('\n '));
|
|
33
|
+
return transformation.principalResult ?? _error(`No result from transformation of ${tclFilePathRel}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static #transformJsonToCss(tclFilePathRel, json, moduleName) {
|
|
37
|
+
this.#jsonToScssFile ??= _modulesTdi.require(this.#JSON_TO_SCSS_FILE_PATH, {message: false});
|
|
38
|
+
const scss = this.#jsonToScssFile(json.project, moduleName);
|
|
39
|
+
const url = new URL(path.join('file://', path.resolve(tclFilePathRel)));
|
|
40
|
+
return sass.compileString(scss, {url, style: 'compressed'}).css;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static #addCssImportToHtml(dir) {
|
|
44
|
+
const filepath = path.join(dir, this.#FONTO_HTML_FILE_NAME);
|
|
45
|
+
|
|
46
|
+
if (fs.existsSync(filepath)) {
|
|
47
|
+
const html = fs.readFileSync(filepath).toString();
|
|
48
|
+
|
|
49
|
+
if (!RegExp(`<link[^>]*${this.#TCL_CSS_FILE_NAME}[^>]*>`).test(html)) {
|
|
50
|
+
const newHtml = html.replace(/((\s+<link.*")[^"]+\.css(.*))/, `$1$2${this.#TCL_CSS_FILE_NAME}$3`);
|
|
51
|
+
fs.outputFileSync(filepath, newHtml);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#outputFn;
|
|
57
|
+
#doModifyFontoHtml;
|
|
58
|
+
#tclFilePathRel;
|
|
59
|
+
#tclFileExists;
|
|
60
|
+
#resultJson;
|
|
61
|
+
#resultCss = {};
|
|
62
|
+
|
|
63
|
+
constructor(tclFileRelDir, addToStreamFn) {
|
|
64
|
+
this.#tclFilePathRel = path.join(tclFileRelDir, TclConfig.#TCL_FILE_NAME);
|
|
65
|
+
this.#tclFileExists = fs.existsSync(this.#tclFilePathRel);
|
|
66
|
+
this.#outputFn = addToStreamFn ?? fs.outputFileSync;
|
|
67
|
+
this.#doModifyFontoHtml = !addToStreamFn;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#getJson() {
|
|
71
|
+
return this.#resultJson ??= TclConfig.#transformTclConfigToJson(this.#tclFilePathRel);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#getCss(moduleName) {
|
|
75
|
+
return this.#resultCss[moduleName] ??= TclConfig.#transformJsonToCss(this.#tclFilePathRel, this.#getJson(), moduleName);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
outputJson(dir) {
|
|
79
|
+
if (this.#tclFileExists) {
|
|
80
|
+
const filepath = path.join(dir, TclConfig.#TCL_JSON_FILE_NAME);
|
|
81
|
+
this.#outputFn(filepath, JSON.stringify(this.#getJson()));
|
|
82
|
+
}
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
outputCss(dir) {
|
|
87
|
+
if (this.#tclFileExists) {
|
|
88
|
+
const filepath = path.join(dir, TclConfig.#TCL_CSS_FILE_NAME);
|
|
89
|
+
const moduleName = dir.includes('esef') ? 'ESEF' : 'FONTO';
|
|
90
|
+
this.#outputFn(filepath, this.#getCss(moduleName));
|
|
91
|
+
this.modifyFontoHtml(dir);
|
|
92
|
+
}
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
modifyFontoHtml(dir) {
|
|
97
|
+
if (this.#tclFileExists && this.#doModifyFontoHtml) TclConfig.#addCssImportToHtml(dir);
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
};
|
|
@@ -5,7 +5,7 @@ const path = require('path');
|
|
|
5
5
|
|
|
6
6
|
function getRemotePath (...arr) {
|
|
7
7
|
const fp = path.join(this.server.remotedir, ...arr);
|
|
8
|
-
return this.server.remotedir.includes(':') ? fp : fp.toFws
|
|
8
|
+
return this.server.remotedir.includes(':') ? fp : fp.toFws;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
|
|
@@ -82,7 +82,7 @@ function prepareForCopy (filter) {
|
|
|
82
82
|
.map(p => '!' + (p.match(/^config/) ? p : '**/' + p.split('**/').pop()) + (p.match(/\/$/) ? '**' : '')) // negate expressions, remove base dir, suffix folders with **
|
|
83
83
|
;
|
|
84
84
|
|
|
85
|
-
let transferPattern = path.join(_paths.apply, filter).toFws
|
|
85
|
+
let transferPattern = path.join(_paths.apply, filter).toFws;
|
|
86
86
|
|
|
87
87
|
// test if 'cmscustom/tdi' would be included, then add specifically, because following symlinks doesnt work with glob stars
|
|
88
88
|
const tdiIncRegex = /^(config\/)?((\{\w*,?)?cmscustom(,?\w*\})?\/|\*\/)?\*\*/;
|
|
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
|
|
|
4
4
|
const globby = require('globby');
|
|
5
5
|
const gulp = require('gulp');
|
|
6
6
|
const {NodeSSH} = require('node-ssh');
|
|
7
|
+
const g_tcl = require('../../lib/gulp-tcl-config');
|
|
7
8
|
const through2 = require('through2');
|
|
8
9
|
const {spawnSync} = require('child_process');
|
|
9
10
|
|
|
@@ -120,9 +121,10 @@ const createDeliveryPack = () => { // create install scripts if necessary, zip o
|
|
|
120
121
|
|
|
121
122
|
|
|
122
123
|
const transfer = (paths, lrServer) => {
|
|
124
|
+
const jsFGlob = _settingsTdi().transpileToES5 ? ['**/*.js', '!**/hce/**/template_*', '!**/fonto/**', '!**/vendor/**', '!**/*.min.js'] : [];
|
|
125
|
+
const jsF = g_filter(jsFGlob, {restore: true});
|
|
123
126
|
const xpsF = g_filter(['**/xopus/**/*.x*'], {restore: true});
|
|
124
127
|
const sassF = g_filter(['**/*.scss'], {restore: true});
|
|
125
|
-
const jsF = g_filter(['**/*.js', '!**/hce/**/template_*', '!**/fonto/**', '!**/vendor/**', '!**/*.min.js'], {restore: true});
|
|
126
128
|
const shF = g_filter(['**/*.sh'], {restore: true});
|
|
127
129
|
const srcset = s.create(paths);
|
|
128
130
|
const files = [];
|
|
@@ -159,6 +161,7 @@ const transfer = (paths, lrServer) => {
|
|
|
159
161
|
.pipe(xpsF)
|
|
160
162
|
.pipe(g_resolveIncl())
|
|
161
163
|
.pipe(xpsF.restore)
|
|
164
|
+
.pipe(g_tcl())
|
|
162
165
|
.pipe(jsF)
|
|
163
166
|
.pipe(g_sourcemaps.init())
|
|
164
167
|
.pipe(g_babel({presets: [[babel_pe, {modules: false}]], comments: false, minified: true})) // function must be executed here, otherwise second execution during watch fails
|
|
@@ -77,7 +77,7 @@ module.exports = function deploy (argv) {
|
|
|
77
77
|
// the "dist" folder isn't watched properly: it does not detect "assets" anymore after building once
|
|
78
78
|
!/cmscustom.+fonto[\\/]/.test(filepath) ||
|
|
79
79
|
/fonto[\\/]dist[\\/]/.test(filepath) ||
|
|
80
|
-
(/fonto[\\/]dev[\\/]/.test(filepath)) ||
|
|
80
|
+
(/fonto[\\/]dev[\\/]/.test(filepath) && c.envDev) ||
|
|
81
81
|
/fonto[\\/]packages[\\/]sx-shell-.*?[\\/]assets[\\/]schemas[\\/]/.test(filepath)
|
|
82
82
|
)
|
|
83
83
|
) {
|
|
@@ -3,7 +3,7 @@ const globby = require('globby');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
const relPath = (d, p) => path.relative(d, p).toFws
|
|
6
|
+
const relPath = (d, p) => path.relative(d, p).toFws;
|
|
7
7
|
const resolveBind = (d, p) => p.replace('#{cmscustompath}', 'cmscustom/').replace('{$rsrcPath}', (d.replace('stylesheets', 'resources')+'/'));
|
|
8
8
|
|
|
9
9
|
|
|
@@ -98,11 +98,11 @@ module.exports = {
|
|
|
98
98
|
},
|
|
99
99
|
|
|
100
100
|
addToCache (filepath) {
|
|
101
|
-
if (this.potentialBaseFilesCache) this.potentialBaseFilesCache.push(filepath.toFws
|
|
101
|
+
if (this.potentialBaseFilesCache) this.potentialBaseFilesCache.push(filepath.toFws);
|
|
102
102
|
},
|
|
103
103
|
|
|
104
104
|
removeFromCache (filepath) {
|
|
105
|
-
if (this.potentialBaseFilesCache) this.potentialBaseFilesCache = this.potentialBaseFilesCache.filter(fp => fp != filepath.toFws
|
|
105
|
+
if (this.potentialBaseFilesCache) this.potentialBaseFilesCache = this.potentialBaseFilesCache.filter(fp => fp != filepath.toFws);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
const del
|
|
2
|
-
const {exec}
|
|
3
|
-
const fs
|
|
4
|
-
const globby
|
|
5
|
-
const gulp
|
|
6
|
-
const g_print
|
|
7
|
-
const path
|
|
8
|
-
const sass
|
|
9
|
-
const
|
|
1
|
+
const del = require('del');
|
|
2
|
+
const {exec} = require('child_process');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const globby = require('globby');
|
|
5
|
+
const gulp = require('gulp');
|
|
6
|
+
const g_print = require('gulp-print');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const sass = require('gulp-sass')(require('sass'));
|
|
9
|
+
const TclConfig = require('../../lib/tcl-config');
|
|
10
|
+
const wws = require('../../lib/worker-with-spinner');
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
g_print.setLogFunction((filepath) => _write(filepath.nostyle));
|
|
@@ -261,6 +262,11 @@ module.exports = {
|
|
|
261
262
|
_write('Done.\n');
|
|
262
263
|
})
|
|
263
264
|
.then(() => cmdExec(`${fdt} editor build`))
|
|
265
|
+
.then(() => {
|
|
266
|
+
_info('Read project configuration and create json and css for Fonto:');
|
|
267
|
+
new TclConfig('..').outputJson('dist/assets').outputCss('dist');
|
|
268
|
+
_write('Done.\n');
|
|
269
|
+
})
|
|
264
270
|
.then(() => [fdt])
|
|
265
271
|
;
|
|
266
272
|
},
|
|
@@ -268,14 +274,27 @@ module.exports = {
|
|
|
268
274
|
run ([fdt]) {
|
|
269
275
|
return compileSass()
|
|
270
276
|
.then(() => {
|
|
271
|
-
_info('
|
|
272
|
-
|
|
277
|
+
_info('Read project configuration and create json and css for Fonto:');
|
|
278
|
+
new TclConfig('..').outputJson('dev/assets').outputCss('dev');
|
|
279
|
+
_write('Done.\n');
|
|
280
|
+
})
|
|
281
|
+
.then(() => {
|
|
282
|
+
_info('Starting watch for tcl and sass files:');
|
|
283
|
+
gulp.watch(['**/*.scss', '../*.tcl', 'dev/index.html'])
|
|
273
284
|
.on('all', (event, filepath) => {
|
|
274
285
|
_write(event + ':', filepath);
|
|
275
|
-
|
|
276
|
-
.
|
|
277
|
-
|
|
278
|
-
|
|
286
|
+
if (filepath.endsWith('.scss')) {
|
|
287
|
+
gulp.src('**/*.scss')
|
|
288
|
+
.pipe(sass().on('error', sass.logError))
|
|
289
|
+
.pipe(gulp.dest('.'))
|
|
290
|
+
;
|
|
291
|
+
}
|
|
292
|
+
else if (filepath.endsWith('.html')) {
|
|
293
|
+
new TclConfig('..').modifyFontoHtml('dev');
|
|
294
|
+
}
|
|
295
|
+
else if (filepath.endsWith('.tcl')) {
|
|
296
|
+
new TclConfig('..').outputJson('dev/assets').outputCss('dev');
|
|
297
|
+
}
|
|
279
298
|
});
|
|
280
299
|
_write('Done.\n');
|
|
281
300
|
})
|
|
@@ -5,23 +5,25 @@ const globby = require('globby');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const fdtPackage = '@fontoxml/fontoxml-development-tools';
|
|
9
|
+
const fdtCommand = fv => `npx -y ${fdtPackage}@${fv.replace(/^(7\.|8\.[012]\.).*/, '3.12.0')}`;
|
|
9
10
|
|
|
10
11
|
module.exports = function fonto (argv) {
|
|
11
12
|
|
|
12
13
|
const allowedFontoVersionRegex = (() => {
|
|
13
|
-
const cvRegex = _modulesTdi.require('fonto/compatibleVersions.json')?.regex;
|
|
14
|
+
const cvRegex = _settingsTdi().compatibleFontoVersions ?? _modulesTdi.require('fonto/compatibleVersions.json', {throws: false})?.regex;
|
|
14
15
|
if (cvRegex) return RegExp(cvRegex);
|
|
15
16
|
|
|
16
17
|
// old way: a regex for each basecommit is stored in global._git.commitTdi
|
|
18
|
+
_info('Fallback to list of commits for determining compatible Fonto versions\n');
|
|
17
19
|
for (const fv of _git.commitTdi.fontoVersions) {
|
|
18
20
|
if (_git.commitTdi.after(fv.commitHash)) return fv.regex;
|
|
19
21
|
}
|
|
20
22
|
})();
|
|
21
23
|
|
|
22
24
|
// check if FDT is not installed globally, because then it won't be possible to use specific versions with npx
|
|
23
|
-
if (fs.pathExistsSync(path.join(_appdata.npmPath, 'node_modules',
|
|
24
|
-
_error(`A global installation of FDT has been found! Remove it first.\nExecute: npm r -g ${
|
|
25
|
+
if (fs.pathExistsSync(path.join(_appdata.npmPath, 'node_modules', fdtPackage))) {
|
|
26
|
+
_error(`A global installation of FDT has been found! Remove it first.\nExecute: npm r -g ${fdtPackage}`);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
process.chdir(_paths.apply || '.');
|
|
@@ -50,7 +52,7 @@ module.exports = function fonto (argv) {
|
|
|
50
52
|
|
|
51
53
|
if (fontoVersionNew === 'latest') {
|
|
52
54
|
const data = execSync(`${fdtCommand(fontoVersionCurrent)} editor versions`, {encoding: 'UTF-8'});
|
|
53
|
-
fontoVersionNew = data.match(/\d+\.\d+\.\d+/g).
|
|
55
|
+
fontoVersionNew = data.match(/\d+\.\d+\.\d+/g).find(v => allowedFontoVersionRegex.test(v));
|
|
54
56
|
}
|
|
55
57
|
else if (!allowedFontoVersionRegex.test(fontoVersionNew)) {
|
|
56
58
|
_error(`Fonto version ${fontoVersionNew} is not compatible with the current TDI submodule commit!\nExecute: ${'tct fonto --init latest'.cyan}`);
|
package/src/modules/git/index.js
CHANGED
|
@@ -71,9 +71,9 @@ function init () {
|
|
|
71
71
|
])
|
|
72
72
|
.then(() => {
|
|
73
73
|
_info(`Next steps:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
1. Go to https://bitbucket.org/repo/create?workspace=tangelosoftware and create a repository named "${path.basename(process.cwd()).replace(/\W/, '-')}", with options for including README/.gitignore disabled.
|
|
75
|
+
2. Open this folder in Sourcetree (ctrl+O), and push master branch to origin.
|
|
76
|
+
`.replace(/^\s{8}/gm, ''));
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
}
|
|
@@ -101,7 +101,7 @@ function clone ({clone: repoName}) {
|
|
|
101
101
|
// Change directory for the next commands, it should have the same name as the clone argument from commandline at this point
|
|
102
102
|
process.chdir('./' + repoName);
|
|
103
103
|
cmdExec([
|
|
104
|
-
|
|
104
|
+
// Retrieve TDI submodule for this client
|
|
105
105
|
['git submodule update --init', 'Fetch submodules such as TDI'],
|
|
106
106
|
// Create symlinks for TDI
|
|
107
107
|
['tct b -s', 'Create TDI symlinks'],
|
|
@@ -123,6 +123,7 @@ function updateRepo () {
|
|
|
123
123
|
const fontoLocations = globby.sync('*/*/fonto/manifest.json', {cwd: path.join(_paths.repo, 'config/cmscustom')});
|
|
124
124
|
const fontoVersions = {};
|
|
125
125
|
fontoLocations.forEach(p => {fontoVersions[p] = readFontoVersionFromFile(p);});
|
|
126
|
+
const tdiLogBeforeUpdate = _git.commitTdi.local();
|
|
126
127
|
|
|
127
128
|
_info(`Fetch all`);
|
|
128
129
|
const cmdFetch = execGitCommand('fetch -pf --all', _paths.repo);
|
|
@@ -138,11 +139,24 @@ function updateRepo () {
|
|
|
138
139
|
|
|
139
140
|
if (fontoLocations.find(p => fontoVersions[p] !== readFontoVersionFromFile(p))) _warn(`\nChanges in Fonto instance versions have been pulled. Therefore you must execute ${'tct fonto --init'.cyan} before building and deploying Fonto.`);
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
// update submodule recursively (set to version that belongs to repo)
|
|
143
|
+
execGitCommand(`submodule update --recursive`, _paths.repo);
|
|
144
|
+
|
|
145
|
+
// clear memoize cache; which is filled with the old TDI data due to tdiLogBeforeUpdate
|
|
146
|
+
_git.commitTdi.local.clear();
|
|
144
147
|
const tdiLog = _git.commitTdi.local();
|
|
145
|
-
|
|
148
|
+
|
|
149
|
+
_info(`\nTDI submodule:`);
|
|
150
|
+
_write(`Submodule in repo-commit: ${[_formatDate(tdiLog.date), tdiLog.tags, tdiLog.hash].filter(v=>v).join(' - ')}`);
|
|
151
|
+
|
|
152
|
+
if (tdiLog.date < tdiLogBeforeUpdate.date) {
|
|
153
|
+
_write(`Restore TDI submodule because it was newer before the repository update:`);
|
|
154
|
+
execGitCommand(`checkout ${tdiLogBeforeUpdate.hash}`, path.join(_paths.repo, _paths.tdi));
|
|
155
|
+
_write(`Submodule checked out: ${[_formatDate(tdiLogBeforeUpdate.date), tdiLogBeforeUpdate.tags, tdiLogBeforeUpdate.hash].filter(v=>v).join(' - ')}\n`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
_write(`Submodule in repo-commit is checked out\n`);
|
|
159
|
+
}
|
|
146
160
|
|
|
147
161
|
const tdiBranch = getTdiBranch();
|
|
148
162
|
_info(`\nTDI branch ${tdiBranch.name} is ${tdiBranch.commitsBehind} commits behind.\nUpdate TDI submodule to latest version with ${'tct git --update-submodule'.cyan}`);
|
|
@@ -51,7 +51,7 @@ module.exports = function migrate (argv) {
|
|
|
51
51
|
a.script = cmdlScript.value;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
let filter = path.join(_paths.apply, argv.filter??'**').toFws
|
|
54
|
+
let filter = path.join(_paths.apply, argv.filter??'**').toFws; // Default set filter with filter added to the command argument -f
|
|
55
55
|
|
|
56
56
|
if (a.filter === 'projects' && _repoconfig.length > a.projects.length) {
|
|
57
57
|
// push paths of chosen active documents to projectFolders (only if not all projects are chosen)
|
package/src/modules/sql/index.js
CHANGED
|
@@ -61,10 +61,7 @@ module.exports = function sql (argv) {
|
|
|
61
61
|
.prompt([
|
|
62
62
|
{
|
|
63
63
|
message: 'Choose projects: ', name: 'projects', type: 'checkbox', validate: v => !!v[0],
|
|
64
|
-
choices:
|
|
65
|
-
_repoconfig.projects
|
|
66
|
-
? _repoconfig.projects.map(p => ({name: p.name, value: p})) // when using repoconfig file (old)
|
|
67
|
-
: _repoconfig.map(p => ({name: `${p.customer_name} ${p.project_name}`, value: p}))
|
|
64
|
+
choices: _repoconfig.map(p => ({name: `${p.customer_name} ${p.project_name}`, value: p}))
|
|
68
65
|
},
|
|
69
66
|
{message: 'Database TNS name: ', name: 'db', default: _appconfig.defaultDatabase},
|
|
70
67
|
{message: 'TANCMS password: ', name: 'pw', default: 'tancms'}
|