@tangelo/tangelo-configuration-toolkit 1.11.0 → 1.11.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.
package/README.md CHANGED
@@ -1,67 +1,67 @@
1
- # tangelo-configuration-toolkit
2
-
3
- Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.
4
-
5
- ## Installation
6
-
7
- The toolkit requires [NPM](https://www.npmjs.com/get-npm) on [Node.js®](https://nodejs.org/) (at least version 14.x). An active or maintenance LTS release is recommended. After installing Node.js, you can install the latest version of the Tangelo Configuration Toolkit globally on your system using the following command:
8
-
9
- npm i -g @tangelo/tangelo-configuration-toolkit
10
-
11
- ## Usage
12
-
13
- Get help for the available commands and see version:
14
-
15
- tangelo-configuration-toolkit
16
-
17
- Get help for a specific command, detailing all its arguments:
18
-
19
- tangelo-configuration-toolkit <command>
20
-
21
- Use the `tct` shorthand instead of `tangelo-configuration-toolkit`:
22
-
23
- tct <command>
24
-
25
- ## Config
26
-
27
- ### Global
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.
30
-
31
- The contents looks like this (all properties are optional):
32
-
33
- {
34
- "sharedConfigPath": "absolute/or/relative/path/to/folder/containing/shared/config",
35
- "servers": [{
36
- "config": {
37
- "port": 22,
38
- "parallel": 4,
39
- "username": "username",
40
- "remotedir": "/absolute/path/to/tangelo/config/folder/on/server"
41
- },
42
- "domains": ["domain.name.com"],
43
- "name": "name-for-local-deploy"
44
- }],
45
- "serverDefaults": {
46
- "config": {
47
- ...
48
- }
49
- }
50
- "defaultServer": "can be set to the name of e.g. your favorite dev server",
51
- "defaultDatabase": "can be set to the tnsname of e.g. your favorite dev server"
52
- }
53
-
54
- 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
- ### 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
- ### oXygen
63
-
64
- The `build -x` commands set projects transformation scenarios and masterfiles in the oXygen project file with the following functionality:
65
- - Will try to preserve manually added entries in the transformation scenarios and masterfiles
66
- - Will remove non existing masterfiles or masterfiles that start with a '_'
1
+ # tangelo-configuration-toolkit
2
+
3
+ Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.
4
+
5
+ ## Installation
6
+
7
+ The toolkit requires [NPM](https://www.npmjs.com/get-npm) on [Node.js®](https://nodejs.org/) (at least version 14.x). An active or maintenance LTS release is recommended. After installing Node.js, you can install the latest version of the Tangelo Configuration Toolkit globally on your system using the following command:
8
+
9
+ npm i -g @tangelo/tangelo-configuration-toolkit
10
+
11
+ ## Usage
12
+
13
+ Get help for the available commands and see version:
14
+
15
+ tangelo-configuration-toolkit
16
+
17
+ Get help for a specific command, detailing all its arguments:
18
+
19
+ tangelo-configuration-toolkit <command>
20
+
21
+ Use the `tct` shorthand instead of `tangelo-configuration-toolkit`:
22
+
23
+ tct <command>
24
+
25
+ ## Config
26
+
27
+ ### Global
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.
30
+
31
+ The contents looks like this (all properties are optional):
32
+
33
+ {
34
+ "sharedConfigPath": "absolute/or/relative/path/to/folder/containing/shared/config",
35
+ "servers": [{
36
+ "config": {
37
+ "port": 22,
38
+ "parallel": 4,
39
+ "username": "username",
40
+ "remotedir": "/absolute/path/to/tangelo/config/folder/on/server"
41
+ },
42
+ "domains": ["domain.name.com"],
43
+ "name": "name-for-local-deploy"
44
+ }],
45
+ "serverDefaults": {
46
+ "config": {
47
+ ...
48
+ }
49
+ }
50
+ "defaultServer": "can be set to the name of e.g. your favorite dev server",
51
+ "defaultDatabase": "can be set to the tnsname of e.g. your favorite dev server"
52
+ }
53
+
54
+ 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
+ ### 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
+ ### oXygen
63
+
64
+ The `build -x` commands set projects transformation scenarios and masterfiles in the oXygen project file with the following functionality:
65
+ - Will try to preserve manually added entries in the transformation scenarios and masterfiles
66
+ - Will remove non existing masterfiles or masterfiles that start with a '_'
67
67
  - No masterfiles / scenarios will be added if their path match with oXygens hidden directory patterns
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangelo/tangelo-configuration-toolkit",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
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",
@@ -1,19 +1,19 @@
1
- // based on gulp-batch-replace
2
-
3
- const es = require('event-stream'), minimatch = require("minimatch"), istextorbinary = require('istextorbinary');
4
-
5
- const execReplace = (c, s, r) => Buffer.from(s instanceof RegExp ? String(c).replace(s,r) : String(c).split(s).join(r));
6
-
7
- module.exports = (arr) => {
8
- return es.map((file, callback) => {
9
- if(file.contents instanceof Buffer) {
10
- arr.forEach(e => {
11
- // exec if no glob is passed or if glob matches, and it's a text file
12
- if ((!e[2] || minimatch(file.path,e[2])) && istextorbinary.isText(file.path,file)) {
13
- file.contents = execReplace(file.contents, e[0], e[1]);
14
- }
15
- });
16
- }
17
- callback(null,file);
18
- });
19
- };
1
+ // based on gulp-batch-replace
2
+
3
+ const es = require('event-stream'), minimatch = require("minimatch"), istextorbinary = require('istextorbinary');
4
+
5
+ const execReplace = (c, s, r) => Buffer.from(s instanceof RegExp ? String(c).replace(s,r) : String(c).split(s).join(r));
6
+
7
+ module.exports = (arr) => {
8
+ return es.map((file, callback) => {
9
+ if(file.contents instanceof Buffer) {
10
+ arr.forEach(e => {
11
+ // exec if no glob is passed or if glob matches, and it's a text file
12
+ if ((!e[2] || minimatch(file.path,e[2])) && istextorbinary.isText(file.path,file)) {
13
+ file.contents = execReplace(file.contents, e[0], e[1]);
14
+ }
15
+ });
16
+ }
17
+ callback(null,file);
18
+ });
19
+ };
@@ -1,11 +1,11 @@
1
- // replacement for the official (but deprecated) gulp-simple-rename
2
- // kept same name because of usage in tdi
3
-
4
- const through2 = require('through2');
5
-
6
- module.exports = (fn) => {
7
- return through2.obj((file, enc, cb) => {
8
- file.path = fn(file.path);
9
- cb(null, file);
10
- });
11
- };
1
+ // replacement for the official (but deprecated) gulp-simple-rename
2
+ // kept same name because of usage in tdi
3
+
4
+ const through2 = require('through2');
5
+
6
+ module.exports = (fn) => {
7
+ return through2.obj((file, enc, cb) => {
8
+ file.path = fn(file.path);
9
+ cb(null, file);
10
+ });
11
+ };
@@ -1,160 +1,160 @@
1
- const fs = require('fs-extra');
2
- const globby = require('globby');
3
- const path = require('path');
4
- const SaxonJS = require('saxon-js');
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');
8
- const cmscustomPath = 'config/cmscustom/';
9
- const siteStylesheetsPath = 'config/txp/site-stylesheets/';
10
-
11
- const masterFiles = new Set;
12
- const transformationScenarios = [];
13
-
14
- const createProjectFile = (config) => {
15
- _info('Initializing xpr file(s):');
16
- const xprFiles = globby.sync(`*.xpr`);
17
-
18
- // Copy xpr file from TDI if it does not exists yet;
19
- if (xprFiles[0]) _write(`Found: ${xprFiles.join(', ')}`);
20
- else {
21
- const customers = new Set;
22
- _repoconfig.forEach(p => customers.add(p.customer_name));
23
- xprFiles.push([...customers].join(' - ') + '.xpr');
24
- fs.copySync(path.join(_paths.repo,'tangelo-default-implementation/src/[customer].xpr'), path.join(_paths.repo, xprFiles[0]));
25
- _write(`Created: '${xprFiles[0]}'`);
26
- }
27
-
28
- // Search for transformationScenarios/masterfiles based on TDI submodule oxygenProjectFile config
29
- _info('\nSearching for transformationScenarios/masterfiles');
30
- config.oxygenProjectFile.forEach(
31
- pf => {
32
- // Collect transformation scenarios and add them to the transformationScenarios array; add individual stylesheets to the masterFiles set.
33
- if (pf.transformation) getTransformations(pf.transformation);
34
- // Add files to the masterfiles set.
35
- else if (pf.masterfile) getMasterfiles(pf.masterfile);
36
- }
37
- );
38
-
39
- // update all .xpr files with collected transformation scenarios and masterfiles.
40
- transformXprFile(xprFiles);
41
- };
42
-
43
- const getTransformations = (config) => {
44
- _repoconfig.forEach(rc => {
45
- // get pathname of customer/project
46
- const [customerPath, projectPath] = config.location == 'database' ? rc.path_dbconfig : rc.path_cmscustom;
47
-
48
- // set pathname of customer/project in location glob-expression
49
- const location = path.join(
50
- _paths.repo,
51
- config.files.replace(/\[customer\]/, customerPath).replace(/\[project\]/, projectPath)
52
- );
53
-
54
- globby
55
- .sync(`${location}`)
56
- .forEach(f => {
57
- // extract baseStrings from file
58
- const baseStrings = fs.readFileSync(f).toString().match(RegExp(config.extracts.base, 'gm'));
59
-
60
- if (baseStrings) {
61
- baseStrings.forEach(s => {
62
- // extract type, name, files info from baseString
63
- const type = config.extracts.type ? s.match(RegExp(config.extracts.type))[1] : config.values.type;
64
- const name = config.extracts.name ? s.match(RegExp(config.extracts.name))[1] : config.values.name;
65
- const files = s.match(RegExp(config.extracts.files))[1];
66
-
67
- // Add transformation scenario to the transformationScenario array
68
- transformationScenarios.push({
69
- name: `${type}: ${name} (${rc.customer_name}, ${rc.project_name})`, // note that in createProjectFile.xsl a regex is added that matches scenarios based on this name. This to preserve manually added scenarios.
70
- transformationScenario: files,
71
- location: config.location == 'txp' ? siteStylesheetsPath : cmscustomPath
72
- });
73
-
74
- // Add each non-tdi stylesheet in transformation scenario to the masterFiles set
75
- files.split(',').forEach(f => {
76
- const filePath = `${config.location == 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
77
- if (!f.startsWith('tdi')) masterFiles.add(filePath);
78
- });
79
- });
80
- } else {
81
- _write(`No transformation scenarios found in ${f} for '${config.extracts.base}'`);
82
- }
83
- });
84
- });
85
-
86
- };
87
-
88
-
89
- const getMasterfiles = (config) => {
90
- globby
91
- .sync(`${path.join(_paths.repo, config.files)}`)
92
- .forEach(cf => {
93
- // Check if masterfile should be extracted from file
94
- if (config.extracts) {
95
- // extract baseStrings from file
96
- const baseStrings = fs.readFileSync(cf).toString().match(RegExp(config.extracts.base,'gm'));
97
-
98
- if (baseStrings) {
99
- baseStrings.forEach(s => {
100
- // extract (comma-separated) list of masterfiles
101
- const filesString = s.match(RegExp(config.extracts.files))[1];
102
- if (!filesString) _error(`No masterfiles found in '${baseString}' for '${config.extracts.files}'`);
103
-
104
- // Add each non-tdi masterfile to the masterFiles set
105
- filesString.split(',').forEach(f => {
106
- if (!f.startsWith('tdi')){
107
- const filePath = `${config.location == 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
108
- masterFiles.add(filePath);
109
- }
110
- });
111
- });
112
- } else {
113
- _write(`No masterfiles found in ${cf} for '${config.extracts.base}'`);
114
- };
115
- } else { // Add synced file to masterfiles; strip path from c:/... hence it starts with config/cmscustom or config/txp/site-stylesheets
116
- const filePath = config.location == 'txp' ? `${siteStylesheetsPath}${cf.split(siteStylesheetsPath)[1]}` : `${cmscustomPath}${cf.split(cmscustomPath)[1]}`;
117
- masterFiles.add(filePath);
118
- }
119
- });
120
-
121
- };
122
-
123
- const transformXprFile = (xprFiles) => {
124
- _info('\nUpdating xpr file(s):');
125
- // create with: xslt3 -t -xsl:createProjectFile.xsl -export:createProjectFile.sef.json v -nogo'
126
-
127
- xprFiles
128
- .forEach(xprFile => {
129
- // Transform xpr; add masterfiles and transformationScenarios as parameters of the stylesheet
130
- _write(`${xprFile}\n`);
131
- SaxonJS.transform({
132
- stylesheetText: fs.readFileSync(sefFilePath),
133
- stylesheetBaseURI: "createProjectFile.sef.json",
134
- sourceFileName: path.join(_paths.repo, xprFile),
135
- destination: "serialized",
136
- stylesheetParams: {
137
- "masterfiles": [...masterFiles],
138
- "Q{}transformationScenarios": transformationScenarios
139
- }
140
- }, "async")
141
- .then(output => {
142
- // Write result of transformation to xpr file
143
- fs.writeFileSync(path.join(_paths.repo, xprFile), output.principalResult);
144
- })
145
- .catch(e => _warn(`Failed to update: ${xprFile}\n ${e}`));
146
- });
147
- };
148
-
149
-
150
- module.exports = function oxygen () {
151
- // _info(`Set projects transformation scenarios and masterfiles in oXygen project file...`);
152
- // _info(`- Will try to preserve manually added entries in the transformation scenarios and masterfiles`);
153
- // _info(`- Will remove non existing masterfiles or masterfiles that start with a '_'\n`);
154
-
155
- if (!fs.existsSync(spConfigPath) || !fs.existsSync(sefFilePath)) {
156
- _error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`);
157
- }
158
-
159
- createProjectFile(require(spConfigPath));
1
+ const fs = require('fs-extra');
2
+ const globby = require('globby');
3
+ const path = require('path');
4
+ const SaxonJS = require('saxon-js');
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');
8
+ const cmscustomPath = 'config/cmscustom/';
9
+ const siteStylesheetsPath = 'config/txp/site-stylesheets/';
10
+
11
+ const masterFiles = new Set;
12
+ const transformationScenarios = [];
13
+
14
+ const createProjectFile = (config) => {
15
+ _info('Initializing xpr file(s):');
16
+ const xprFiles = globby.sync(`*.xpr`);
17
+
18
+ // Copy xpr file from TDI if it does not exists yet;
19
+ if (xprFiles[0]) _write(`Found: ${xprFiles.join(', ')}`);
20
+ else {
21
+ const customers = new Set;
22
+ _repoconfig.forEach(p => customers.add(p.customer_name));
23
+ xprFiles.push([...customers].join(' - ') + '.xpr');
24
+ fs.copySync(path.join(_paths.repo,'tangelo-default-implementation/src/[customer].xpr'), path.join(_paths.repo, xprFiles[0]));
25
+ _write(`Created: '${xprFiles[0]}'`);
26
+ }
27
+
28
+ // Search for transformationScenarios/masterfiles based on TDI submodule oxygenProjectFile config
29
+ _info('\nSearching for transformationScenarios/masterfiles');
30
+ config.oxygenProjectFile.forEach(
31
+ pf => {
32
+ // Collect transformation scenarios and add them to the transformationScenarios array; add individual stylesheets to the masterFiles set.
33
+ if (pf.transformation) getTransformations(pf.transformation);
34
+ // Add files to the masterfiles set.
35
+ else if (pf.masterfile) getMasterfiles(pf.masterfile);
36
+ }
37
+ );
38
+
39
+ // update all .xpr files with collected transformation scenarios and masterfiles.
40
+ transformXprFile(xprFiles);
41
+ };
42
+
43
+ const getTransformations = (config) => {
44
+ _repoconfig.forEach(rc => {
45
+ // get pathname of customer/project
46
+ const [customerPath, projectPath] = config.location == 'database' ? rc.path_dbconfig : rc.path_cmscustom;
47
+
48
+ // set pathname of customer/project in location glob-expression
49
+ const location = path.join(
50
+ _paths.repo,
51
+ config.files.replace(/\[customer\]/, customerPath).replace(/\[project\]/, projectPath)
52
+ );
53
+
54
+ globby
55
+ .sync(`${location}`)
56
+ .forEach(f => {
57
+ // extract baseStrings from file
58
+ const baseStrings = fs.readFileSync(f).toString().match(RegExp(config.extracts.base, 'gm'));
59
+
60
+ if (baseStrings) {
61
+ baseStrings.forEach(s => {
62
+ // extract type, name, files info from baseString
63
+ const type = config.extracts.type ? s.match(RegExp(config.extracts.type))[1] : config.values.type;
64
+ const name = config.extracts.name ? s.match(RegExp(config.extracts.name))[1] : config.values.name;
65
+ const files = s.match(RegExp(config.extracts.files))[1];
66
+
67
+ // Add transformation scenario to the transformationScenario array
68
+ transformationScenarios.push({
69
+ name: `${type}: ${name} (${rc.customer_name}, ${rc.project_name})`, // note that in createProjectFile.xsl a regex is added that matches scenarios based on this name. This to preserve manually added scenarios.
70
+ transformationScenario: files,
71
+ location: config.location == 'txp' ? siteStylesheetsPath : cmscustomPath
72
+ });
73
+
74
+ // Add each non-tdi stylesheet in transformation scenario to the masterFiles set
75
+ files.split(',').forEach(f => {
76
+ const filePath = `${config.location == 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
77
+ if (!f.startsWith('tdi')) masterFiles.add(filePath);
78
+ });
79
+ });
80
+ } else {
81
+ _write(`No transformation scenarios found in ${f} for '${config.extracts.base}'`);
82
+ }
83
+ });
84
+ });
85
+
86
+ };
87
+
88
+
89
+ const getMasterfiles = (config) => {
90
+ globby
91
+ .sync(`${path.join(_paths.repo, config.files)}`)
92
+ .forEach(cf => {
93
+ // Check if masterfile should be extracted from file
94
+ if (config.extracts) {
95
+ // extract baseStrings from file
96
+ const baseStrings = fs.readFileSync(cf).toString().match(RegExp(config.extracts.base,'gm'));
97
+
98
+ if (baseStrings) {
99
+ baseStrings.forEach(s => {
100
+ // extract (comma-separated) list of masterfiles
101
+ const filesString = s.match(RegExp(config.extracts.files))[1];
102
+ if (!filesString) _error(`No masterfiles found in '${baseString}' for '${config.extracts.files}'`);
103
+
104
+ // Add each non-tdi masterfile to the masterFiles set
105
+ filesString.split(',').forEach(f => {
106
+ if (!f.startsWith('tdi')){
107
+ const filePath = `${config.location == 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`;
108
+ masterFiles.add(filePath);
109
+ }
110
+ });
111
+ });
112
+ } else {
113
+ _write(`No masterfiles found in ${cf} for '${config.extracts.base}'`);
114
+ };
115
+ } else { // Add synced file to masterfiles; strip path from c:/... hence it starts with config/cmscustom or config/txp/site-stylesheets
116
+ const filePath = config.location == 'txp' ? `${siteStylesheetsPath}${cf.split(siteStylesheetsPath)[1]}` : `${cmscustomPath}${cf.split(cmscustomPath)[1]}`;
117
+ masterFiles.add(filePath);
118
+ }
119
+ });
120
+
121
+ };
122
+
123
+ const transformXprFile = (xprFiles) => {
124
+ _info('\nUpdating xpr file(s):');
125
+ // create with: xslt3 -t -xsl:createProjectFile.xsl -export:createProjectFile.sef.json v -nogo'
126
+
127
+ xprFiles
128
+ .forEach(xprFile => {
129
+ // Transform xpr; add masterfiles and transformationScenarios as parameters of the stylesheet
130
+ _write(`${xprFile}\n`);
131
+ SaxonJS.transform({
132
+ stylesheetText: fs.readFileSync(sefFilePath),
133
+ stylesheetBaseURI: "createProjectFile.sef.json",
134
+ sourceFileName: path.join(_paths.repo, xprFile),
135
+ destination: "serialized",
136
+ stylesheetParams: {
137
+ "masterfiles": [...masterFiles],
138
+ "Q{}transformationScenarios": transformationScenarios
139
+ }
140
+ }, "async")
141
+ .then(output => {
142
+ // Write result of transformation to xpr file
143
+ fs.writeFileSync(path.join(_paths.repo, xprFile), output.principalResult);
144
+ })
145
+ .catch(e => _warn(`Failed to update: ${xprFile}\n ${e}`));
146
+ });
147
+ };
148
+
149
+
150
+ module.exports = function oxygen () {
151
+ // _info(`Set projects transformation scenarios and masterfiles in oXygen project file...`);
152
+ // _info(`- Will try to preserve manually added entries in the transformation scenarios and masterfiles`);
153
+ // _info(`- Will remove non existing masterfiles or masterfiles that start with a '_'\n`);
154
+
155
+ if (!fs.existsSync(spConfigPath) || !fs.existsSync(sefFilePath)) {
156
+ _error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`);
157
+ }
158
+
159
+ createProjectFile(require(spConfigPath));
160
160
  };
@@ -1,174 +1,174 @@
1
- const {execSync} = require('child_process');
2
- const fs = require('fs-extra');
3
- const globby = require('globby');
4
- const path = require('path');
5
- const {Table} = require('console-table-printer');
6
- const execGitCommand = require('../../lib/exec-git-command');
7
- const c = require('../deploy/config');
8
- const {remote} = require('../deploy/execute');
9
-
10
- const getGitInfo = (argv) => {
11
- // Version info TDI submodule
12
-
13
- const branchInfo = [];
14
- const gitSubmoduleInfo = new Table({
15
- columns: [
16
- { name: 'property', title: 'TDI - submodule', alignment: 'left'},
17
- { name: 'value', alignment: 'left'}
18
- ],
19
- });
20
-
21
- // Fetch all
22
- execGitCommand(`fetch -pf --all`, path.join(_paths.repo, _paths.tdi));
23
-
24
- // Get branches containing TDI HEAD commit
25
- const releaseBranches = execGitCommand(`branch --contains ${_git.commitLocalTdi.hash}`, path.join(_paths.repo, _paths.tdi)).match(/release\/[^\s]+/gsm);
26
- if (releaseBranches) {
27
- releaseBranches.forEach(b => {
28
- // Get number of commits behind
29
- const count = execGitCommand(`rev-list HEAD...origin/${b} --count`, path.join(_paths.repo, _paths.tdi));
30
- // _info(`debug: [${b}]:${count}`);
31
- // Push number of commits behind to branchInfo
32
- branchInfo.push({name:b,commitsBehind:count});
33
- });
34
- }
35
-
36
- // Get the first possible branch; prefer release/5.1 over release/5.2:
37
- const firstBranch = branchInfo.sort((a, b) => a.name > b.name ? 1 : -1)[0];
38
-
39
- // Create table rows for TDI submodule info
40
- gitSubmoduleInfo.addRow({
41
- property: `Commit date (DD-MM-YYYY)`,
42
- value: `${_git.commitLocalTdi.date.toLocaleDateString('nl-nl')}`
43
- });
44
- if (firstBranch) {
45
- gitSubmoduleInfo.addRow({
46
- property: `Branch`,
47
- value: `${firstBranch.name}`
48
- });
49
- gitSubmoduleInfo.addRow({
50
- property: `Commits behind`,
51
- value: `${firstBranch.commitsBehind}`
52
- });
53
- } else {
54
- gitSubmoduleInfo.addRow({
55
- property: `Branch could not be determined`,
56
- value: ``
57
- });
58
- }
59
-
60
- // Print TDI submodule info
61
- gitSubmoduleInfo.printTable();
62
- }
63
-
64
- const getFileExtractInfo = (argv) => {
65
- // version info miscellaneous
66
- const sorting = `${argv.info}`.includes(`sort-type`) ? `type` : `project`;
67
- const projects = new Set;
68
- const types = new Set;
69
- const versionInfoConfigPath = path.join(_paths.repo, _paths.tdi, 'tct/version/versionInfo.js');
70
- const versionInfo = new Table({
71
- columns: [
72
- { name: 'path', alignment: 'left'},
73
- { name: 'type', alignment: 'left'},
74
- { name: 'version', alignment: 'left'},
75
- { name: 'sort'}
76
- ],
77
- disabledColumns: ['sort'],
78
- sort: (a, b) => a.sort.toLowerCase() > b.sort.toLowerCase() ? 1 : -1
79
- });
80
-
81
- if (fs.existsSync(versionInfoConfigPath)) {
82
- const config = require(`${versionInfoConfigPath}`);
83
-
84
- config.forEach(v => {
85
- const location = path.join(_paths.repo,v.glob);
86
-
87
- globby
88
- .sync(`${location}`)
89
- .forEach(f => {
90
- const filePathExtract = f.match(/.*(?<path>(cmscustom|site-stylesheets)\/(?<customer>[^\/]*)\/(?<project>[^\/]*)\/.*)/);
91
- const path = filePathExtract.groups.path ? filePathExtract.groups.path : '';
92
- const customer = filePathExtract.groups.customer ? filePathExtract.groups.customer : '';
93
- const project = filePathExtract.groups.project ? filePathExtract.groups.project : '';
94
-
95
- const fileContent = fs.readFileSync(f).toString();
96
- v.extracts.forEach(e => {
97
- const extract = fileContent.match(e.regex);
98
- if (extract) {
99
- projects.add(project); // Store the projects where versioninfo is found
100
- types.add(e.type); // Store the types for which versioninfo is found
101
- versionInfo.addRow( // Create row with version information to output
102
- { path: `${path}`
103
- , sort: `${sorting==`project` ? project : e.type}_2${sorting==`project` ? e.type : extract.groups.version}` // Output is sorted on project or type: '_2' ensures it is rendered after the empty row and the row with the project name
104
- , type: `${e.type}`
105
- , version: `${extract.groups.version}`
106
- }
107
- );
108
- }
109
- });
110
- })
111
- });
112
-
113
- if (sorting==`project`) {
114
- /* For projects containing version information */
115
- projects.forEach(p => {
116
- /* Add empty row after project */
117
- versionInfo.addRow(
118
- { path: ``
119
- , sort: `${p}_3`
120
- , type: ``
121
- , version: ``
122
- }
123
- )
124
- /* Add row with project name */
125
- versionInfo.addRow(
126
- { path: `-- ${p}:`
127
- , sort: `${p}_1`
128
- , type: ``
129
- , version: ``
130
- },
131
- { color: 'yellow' }
132
- )
133
- });
134
- } else
135
- if (sorting==`type`) {
136
- types.forEach(t => {
137
- /* Add empty row after type */
138
- versionInfo.addRow(
139
- { path: ``
140
- , sort: `${t}_3`
141
- , type: ``
142
- , version: ``
143
- }
144
- )
145
- });
146
- }
147
- versionInfo.printTable();
148
- } else {
149
- _warn(`Version info of miscellaneous items cannot be extracted:\nCannot find required files in TDI submodule. Try updating TDI submodule.`);
150
- }
151
- }
152
-
153
- const getServerInfo = (argv) => {
154
- // Remote server info
155
- // common setup
156
- _write();
157
- c.setServer(argv.server);
158
-
159
- if (!c.envDev) {
160
- _info(`Remote version info for '${c.server.ftpConfig.host}':\n`)
161
- remote.add('sudo ~root/scripts/version.sh', '').process();
162
- } else {
163
- _info(`For development environments no server version information is available. Check rancher / database for this information.\nAdd the --server option with a non-dev environment to see version information for that server.`);
164
- }
165
- }
166
-
167
- module.exports = function version (argv) {
168
- _info(`Version information of this git repository\n`)
169
-
170
- getGitInfo(argv);
171
- getFileExtractInfo(argv);
172
- getServerInfo(argv);
173
-
1
+ const {execSync} = require('child_process');
2
+ const fs = require('fs-extra');
3
+ const globby = require('globby');
4
+ const path = require('path');
5
+ const {Table} = require('console-table-printer');
6
+ const execGitCommand = require('../../lib/exec-git-command');
7
+ const c = require('../deploy/config');
8
+ const {remote} = require('../deploy/execute');
9
+
10
+ const getGitInfo = (argv) => {
11
+ // Version info TDI submodule
12
+
13
+ const branchInfo = [];
14
+ const gitSubmoduleInfo = new Table({
15
+ columns: [
16
+ { name: 'property', title: 'TDI - submodule', alignment: 'left'},
17
+ { name: 'value', alignment: 'left'}
18
+ ],
19
+ });
20
+
21
+ // Fetch all
22
+ execGitCommand(`fetch -pf --all`, path.join(_paths.repo, _paths.tdi));
23
+
24
+ // Get branches containing TDI HEAD commit
25
+ const releaseBranches = execGitCommand(`branch --contains ${_git.commitLocalTdi.hash}`, path.join(_paths.repo, _paths.tdi)).match(/release\/[^\s]+/gsm);
26
+ if (releaseBranches) {
27
+ releaseBranches.forEach(b => {
28
+ // Get number of commits behind
29
+ const count = execGitCommand(`rev-list HEAD...origin/${b} --count`, path.join(_paths.repo, _paths.tdi));
30
+ // _info(`debug: [${b}]:${count}`);
31
+ // Push number of commits behind to branchInfo
32
+ branchInfo.push({name:b,commitsBehind:count});
33
+ });
34
+ }
35
+
36
+ // Get the first possible branch; prefer release/5.1 over release/5.2:
37
+ const firstBranch = branchInfo.sort((a, b) => a.name > b.name ? 1 : -1)[0];
38
+
39
+ // Create table rows for TDI submodule info
40
+ gitSubmoduleInfo.addRow({
41
+ property: `Commit date (DD-MM-YYYY)`,
42
+ value: `${_git.commitLocalTdi.date.toLocaleDateString('nl-nl')}`
43
+ });
44
+ if (firstBranch) {
45
+ gitSubmoduleInfo.addRow({
46
+ property: `Branch`,
47
+ value: `${firstBranch.name}`
48
+ });
49
+ gitSubmoduleInfo.addRow({
50
+ property: `Commits behind`,
51
+ value: `${firstBranch.commitsBehind}`
52
+ });
53
+ } else {
54
+ gitSubmoduleInfo.addRow({
55
+ property: `Branch could not be determined`,
56
+ value: ``
57
+ });
58
+ }
59
+
60
+ // Print TDI submodule info
61
+ gitSubmoduleInfo.printTable();
62
+ }
63
+
64
+ const getFileExtractInfo = (argv) => {
65
+ // version info miscellaneous
66
+ const sorting = `${argv.find}`.includes(`sort-type`) ? `type` : `project`;
67
+ const projects = new Set;
68
+ const types = new Set;
69
+ const versionInfoConfigPath = path.join(_paths.repo, _paths.tdi, 'tct/version/versionInfo.js');
70
+ const versionInfo = new Table({
71
+ columns: [
72
+ { name: 'path', alignment: 'left'},
73
+ { name: 'type', alignment: 'left'},
74
+ { name: 'version', alignment: 'left'},
75
+ { name: 'sort'}
76
+ ],
77
+ disabledColumns: ['sort'],
78
+ sort: (a, b) => a.sort.toLowerCase() > b.sort.toLowerCase() ? 1 : -1
79
+ });
80
+
81
+ if (fs.existsSync(versionInfoConfigPath)) {
82
+ const config = require(`${versionInfoConfigPath}`);
83
+
84
+ config.forEach(v => {
85
+ const location = path.join(_paths.repo,v.glob);
86
+
87
+ globby
88
+ .sync(`${location}`)
89
+ .forEach(f => {
90
+ const filePathExtract = f.match(/.*(?<path>(cmscustom|site-stylesheets)\/(?<customer>[^\/]*)\/(?<project>[^\/]*)\/.*)/);
91
+ const path = filePathExtract.groups.path ? filePathExtract.groups.path : '';
92
+ const customer = filePathExtract.groups.customer ? filePathExtract.groups.customer : '';
93
+ const project = filePathExtract.groups.project ? filePathExtract.groups.project : '';
94
+
95
+ const fileContent = fs.readFileSync(f).toString();
96
+ v.extracts.forEach(e => {
97
+ const extract = fileContent.match(e.regex);
98
+ if (extract) {
99
+ projects.add(project); // Store the projects where versioninfo is found
100
+ types.add(e.type); // Store the types for which versioninfo is found
101
+ versionInfo.addRow( // Create row with version information to output
102
+ { path: `${path}`
103
+ , sort: `${sorting==`project` ? project : e.type}_2${sorting==`project` ? e.type : extract.groups.version}` // Output is sorted on project or type: '_2' ensures it is rendered after the empty row and the row with the project name
104
+ , type: `${e.type}`
105
+ , version: `${extract.groups.version}`
106
+ }
107
+ );
108
+ }
109
+ });
110
+ })
111
+ });
112
+
113
+ if (sorting==`project`) {
114
+ /* For projects containing version information */
115
+ projects.forEach(p => {
116
+ /* Add empty row after project */
117
+ versionInfo.addRow(
118
+ { path: ``
119
+ , sort: `${p}_3`
120
+ , type: ``
121
+ , version: ``
122
+ }
123
+ )
124
+ /* Add row with project name */
125
+ versionInfo.addRow(
126
+ { path: `-- ${p}:`
127
+ , sort: `${p}_1`
128
+ , type: ``
129
+ , version: ``
130
+ },
131
+ { color: 'yellow' }
132
+ )
133
+ });
134
+ } else
135
+ if (sorting==`type`) {
136
+ types.forEach(t => {
137
+ /* Add empty row after type */
138
+ versionInfo.addRow(
139
+ { path: ``
140
+ , sort: `${t}_3`
141
+ , type: ``
142
+ , version: ``
143
+ }
144
+ )
145
+ });
146
+ }
147
+ versionInfo.printTable();
148
+ } else {
149
+ _warn(`Version info of miscellaneous items cannot be extracted:\nCannot find required files in TDI submodule. Try updating TDI submodule.`);
150
+ }
151
+ }
152
+
153
+ const getServerInfo = (argv) => {
154
+ // Remote server info
155
+ // common setup
156
+ _write();
157
+ c.setServer(argv.server);
158
+
159
+ if (!c.envDev) {
160
+ _info(`Remote version info for '${c.server.ftpConfig.host}':\n`)
161
+ remote.add('sudo ~root/scripts/version.sh', '').process();
162
+ } else {
163
+ _info(`For development environments no server version information is available. Check rancher / database for this information.\nAdd the --server option with a non-dev environment to see version information for that server.`);
164
+ }
165
+ }
166
+
167
+ module.exports = function version (argv) {
168
+ _info(`Version information of this git repository\n`)
169
+
170
+ getGitInfo(argv);
171
+ getFileExtractInfo(argv);
172
+ getServerInfo(argv);
173
+
174
174
  };
@@ -0,0 +1,7 @@
1
+ {
2
+ "folders": [
3
+ {
4
+ "path": "."
5
+ }
6
+ ]
7
+ }