@sap/cds-dk 4.6.0 → 4.7.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/bin/add.js +2 -1
  3. package/bin/bind.js +121 -48
  4. package/bin/cds.js +8 -0
  5. package/bin/compile/index.js +2 -1
  6. package/bin/env.js +0 -2
  7. package/bin/repl.js +11 -4
  8. package/bin/watch.js +25 -13
  9. package/lib/bind/bindingResolver.js +26 -14
  10. package/lib/bind/bindingUtil.js +144 -0
  11. package/lib/bind/cfKeyProvider.js +2 -80
  12. package/lib/bind/kubernetesCredentialsProvider.js +157 -0
  13. package/lib/bind/userCdsrcJsonStorageProvider.js +7 -7
  14. package/lib/client/activate.js +9 -17
  15. package/lib/client/auth_manager.js +1 -1
  16. package/lib/client/extend.js +4 -9
  17. package/lib/client/settings_manager.js +5 -4
  18. package/lib/import/index.js +3 -2
  19. package/lib/import/internalDoc/edm2cdsTypeMapping.md +38 -0
  20. package/lib/import/utils/MultiMap.js +1 -0
  21. package/lib/import/v2parser.js +102 -37
  22. package/lib/import/v4parser.js +59 -20
  23. package/lib/index.js +6 -5
  24. package/lib/init/constants.js +2 -2
  25. package/lib/init/index.js +1 -0
  26. package/lib/init/template/data/index.js +29 -7
  27. package/lib/init/template/hana/files/common/undeploy.json +5 -0
  28. package/lib/init/template/hana/files/java/package.json +3 -0
  29. package/lib/init/template/hana/index.js +19 -23
  30. package/lib/init/template/lint/index.js +28 -18
  31. package/lib/init/template/mta/files/mta.yaml.hbs +12 -5
  32. package/lib/init/template/mta/projectReader.js +1 -3
  33. package/lib/init/template/nodejs/files/.gitignore.hbs +0 -2
  34. package/lib/init/template/samples/index.js +1 -1
  35. package/lib/init/template/templateBase.js +10 -41
  36. package/lib/init/util/fsUtil.js +1 -1
  37. package/lib/lint/Linter.js +13 -33
  38. package/lib/lint/checks.js +1 -5
  39. package/lib/lint/generators.js +5 -4
  40. package/lib/lint/io.js +23 -31
  41. package/lib/watch/node-watch.js +46 -20
  42. package/npm-shrinkwrap.json +11524 -5622
  43. package/package.json +3 -3
@@ -11,16 +11,12 @@ module.exports = class DataTemplate extends TemplateBase {
11
11
  async run() {
12
12
  const env = await this.getEnv();
13
13
 
14
- const prefix = (typeof this.options.for === 'string') // --for <prefix>
15
- ? this.options.for
16
- : '';
17
- const prefixedWith = (definition) => definition.name === prefix || definition.name.startsWith(prefix);
18
-
19
14
  let dest = (typeof this.options.out === 'string') // target folder
20
15
  ? this.options.out
21
16
  : getDefaultTargetFolder(env, this.projectPath);
22
17
  dest = resolve(this.projectPath, dest);
23
18
 
19
+ const nameFilter = asRegex(this.options.for)
24
20
  const force = this.options.force;
25
21
  const logger = this.logger;
26
22
 
@@ -29,18 +25,44 @@ module.exports = class DataTemplate extends TemplateBase {
29
25
 
30
26
  // Also include 'external' entities w/ cds.persistence.skip (similar to 'mocked' option of serve).
31
27
  // Could be too much sometimes, but don't want to bother users w/ a separate option for this.
32
- cds.deploy.include_external_entities_in(csn)
28
+ includeExternalEntities(csn, logger)
33
29
 
34
30
  csn = cds.compile.for.sql(csn, { names:env.sql.names, messages:[] }) // CSN w/ persistence information
35
31
  csn = cds.reflect(csn); // reflected model (adds additional helper functions)
36
32
 
37
33
  csn.all('entity')
38
- .filter(prefixedWith)
34
+ .filter (e => e.name.match(nameFilter)) // --for prefix|regex
39
35
  .filter (e => !e.query) // exclude entities with queries (projection on, select from ...)
40
36
  .filter (e => e.name !== 'DRAFT.DraftAdministrativeData' && !e.name.endsWith('.drafts')) // exclude draft stuff
41
37
  .forEach(e => processEntity(e, dest, this.projectPath, csn, force, logger));
42
38
  }
39
+ }
40
+
41
+ function includeExternalEntities(model, logger) {
42
+ for (let each in model.definitions) {
43
+ const def = model.definitions[each]
44
+ if (def['@cds.persistence.skip'] === true) {
45
+ logger.debug ('Including skipped entity '+each)
46
+ delete def['@cds.persistence.skip']
47
+ }
48
+ }
49
+ return model
50
+ }
43
51
 
52
+ function asRegex(spec) {
53
+ if (typeof spec === 'string') {
54
+ try {
55
+ if (spec.match(/[\^$|*]/))
56
+ return new RegExp(spec)
57
+ else { // no meta chars -> prefix semantics
58
+ spec = spec.replace(/\./g, '\\.') // escape dot
59
+ return new RegExp('^'+spec+'.*')
60
+ }
61
+ } catch (err) {
62
+ throw new Error (err.message) // user error, so cut off stack trace
63
+ }
64
+ }
65
+ return /.*/
44
66
  }
45
67
 
46
68
  function processEntity (entity, dest, projectPath, csn, force, logger) {
@@ -0,0 +1,5 @@
1
+ [
2
+ "src/gen/**/*.hdbview",
3
+ "src/gen/**/*.hdbindex",
4
+ "src/gen/**/*.hdbconstraint"
5
+ ]
@@ -3,6 +3,9 @@
3
3
  "dependencies": {
4
4
  "@sap/hdi-deploy": "^4"
5
5
  },
6
+ "engines": {
7
+ "node": "^16"
8
+ },
6
9
  "scripts": {
7
10
  "start": "node node_modules/@sap/hdi-deploy/deploy.js"
8
11
  }
@@ -13,8 +13,6 @@ const { nullLogger } = require('../../util/logger');
13
13
  module.exports = class HanaTemplate extends TemplateBase {
14
14
  constructor(projectPath, generator) {
15
15
  super(projectPath, generator, __dirname);
16
-
17
- this.env = null;
18
16
  }
19
17
 
20
18
  async checkEnabled() {
@@ -22,34 +20,32 @@ module.exports = class HanaTemplate extends TemplateBase {
22
20
  return true;
23
21
  }
24
22
 
25
- this.env = await this.getEnv(true);
23
+ const env = await this.getEnv();
26
24
 
27
- const hdiConfigPath = path.join(this.projectPath, this.env.folders.db, 'src/.hdiconfig');
28
- if (await this.fsUtil.pathExists(hdiConfigPath)) {
29
- const configFilePath = path.join(this.env.folders.db, 'src/.hdiconfig');
30
- throw new Error(`Database config file ${configFilePath} already exists. Use --force to overwrite.`);
31
- }
25
+ await Promise.all(['src/.hdiconfig', 'undeploy.json'].map(async(filePath) => {
26
+ if (await this.fsUtil.pathExists(path.join(this.projectPath, env.folders.db, filePath))) {
27
+ throw new Error(`File ${path.join(env.folders.db, filePath)} already exists. Use --force to overwrite.`);
28
+ }
29
+ }))
32
30
 
33
31
  return true;
34
32
  }
35
33
 
36
34
  // read env from project
37
- async getEnv(force) {
35
+ async getEnv() {
38
36
  const cdsEnvVar = process.env.CDS_ENV;
39
37
  process.env.CDS_ENV = 'production'
40
- let env
41
38
  try {
42
- env = await super.getEnv(force);
39
+ return await super.getEnv();
43
40
  } finally {
44
41
  cdsEnvVar ? process.env.CDS_ENV = cdsEnvVar : delete process.env.CDS_ENV
45
42
  }
46
- return env
47
43
  }
48
44
 
49
45
  async run() {
50
- this.env = await this.getEnv(true);
46
+ const env = await this.getEnv();
51
47
 
52
- await this.templateUtil.copyFiles('common', path.join(this.projectPath, this.env.folders.db), {
48
+ await this.templateUtil.copyFiles('common', path.join(this.projectPath, env.folders.db), {
53
49
  projectName: this.projectName
54
50
  }, this.options.force);
55
51
 
@@ -57,13 +53,13 @@ module.exports = class HanaTemplate extends TemplateBase {
57
53
  const projectType = await this.getProjectType();
58
54
  switch (projectType) {
59
55
  case PROJECT_TYPE.java:
60
- await this.templateUtil.copyFiles('java', path.join(this.projectPath, this.env.folders.db), {}, this.options.force);
56
+ await this.templateUtil.copyFiles('java', path.join(this.projectPath, env.folders.db), {}, this.options.force);
61
57
  await this._updatePomXml();
62
- await this._updateCdsrcJson(cdsrcJsonPath, this.env.folders.db);
58
+ await this._updateCdsrcJson(cdsrcJsonPath, env.folders.db, env);
63
59
  break;
64
60
 
65
61
  case PROJECT_TYPE.nodejs:
66
- await this._updatePackageJson(path.join(this.projectPath, 'package.json'), this.env.folders.db);
62
+ await this._updatePackageJson(path.join(this.projectPath, 'package.json'), env.folders.db, env);
67
63
  break;
68
64
 
69
65
  default: break;
@@ -87,7 +83,7 @@ module.exports = class HanaTemplate extends TemplateBase {
87
83
  }
88
84
  }
89
85
 
90
- async _updatePackageJson(packageJsonPath, modelName) { //NOSONAR
86
+ async _updatePackageJson(packageJsonPath, modelName, env) { //NOSONAR
91
87
  modelName = path.basename(modelName);
92
88
 
93
89
  if (!await this.fsUtil.pathExists(packageJsonPath)) {
@@ -109,7 +105,7 @@ module.exports = class HanaTemplate extends TemplateBase {
109
105
  changed = true
110
106
  }
111
107
 
112
- if (!this._isUsingHana(modelName)) {
108
+ if (!this._isUsingHana(modelName, env)) {
113
109
  packageJson.cds = packageJson.cds || {};
114
110
  packageJson.cds.requires = packageJson.cds.requires || {};
115
111
  packageJson.cds.requires[modelName] = packageJson.cds.requires[modelName] || {};
@@ -130,7 +126,7 @@ module.exports = class HanaTemplate extends TemplateBase {
130
126
  }
131
127
  }
132
128
 
133
- async _updateCdsrcJson(cdsrcJsonPath, modelName) {
129
+ async _updateCdsrcJson(cdsrcJsonPath, modelName, env) {
134
130
  modelName = path.basename(modelName);
135
131
 
136
132
  let changed;
@@ -143,7 +139,7 @@ module.exports = class HanaTemplate extends TemplateBase {
143
139
 
144
140
  this.logger.isDebug && this.logger.debug(`_updateCdsrcJson before: ${JSON.stringify(cdsrcJson, null, 2)}`);
145
141
 
146
- if (!this._isUsingHana(modelName)) {
142
+ if (!this._isUsingHana(modelName, env)) {
147
143
  cdsrcJson.requires = cdsrcJson.requires || {};
148
144
  cdsrcJson.requires[modelName] = cdsrcJson.requires[modelName] || {};
149
145
  cdsrcJson.requires[modelName].kind = KIND_SQL;
@@ -161,7 +157,7 @@ module.exports = class HanaTemplate extends TemplateBase {
161
157
  }
162
158
  }
163
159
 
164
- _isUsingHana(db) {
165
- return this.env.get(`requires.${db}.kind`) === KIND_HANA || this.env.get(`requires.${db}.dialect`) === KIND_HANA || this.env.get(`requires.${db}.use`) === KIND_HANA;
160
+ _isUsingHana(db, env) {
161
+ return env.get(`requires.${db}.kind`) === KIND_HANA || env.get(`requires.${db}.dialect`) === KIND_HANA || env.get(`requires.${db}.use`) === KIND_HANA;
166
162
  }
167
163
  }
@@ -9,10 +9,15 @@ const readline = require("readline");
9
9
 
10
10
  const { OPTION_LINT_DEV, OPTION_LINT_GLOBAL } = require("../../constants");
11
11
  const { mkdirp, fs } = require("@sap/cds/lib/utils");
12
- const { getConfigPath } = require("@sap/eslint-plugin-cds/lib/api");
12
+ const { getConfigPath, getFileExtensions } = require("@sap/eslint-plugin-cds/lib/api");
13
13
  const generators = require("../../../lint/generators");
14
14
 
15
15
  const IS_WIN = os.platform() === "win32";
16
+ const ALLOWED_FILE_EXTENSIONS = getFileExtensions();
17
+ const VSCODE_FILE_ASSOCIATIONS = {
18
+ "csv": [ "csv", "csv (semicolon)", "tsv", "tab" ]
19
+ }
20
+
16
21
  module.exports = class LintTemplate extends TemplateBase {
17
22
  constructor(projectPath, generator) {
18
23
  super(projectPath, generator, __dirname);
@@ -42,12 +47,9 @@ module.exports = class LintTemplate extends TemplateBase {
42
47
  }
43
48
 
44
49
  async run() {
45
- const cdsdkPath = path.join(__dirname, "../../../..");
46
- const globalPath = path.join(cdsdkPath, "../..");
47
-
48
50
  // Require ESLint v>=7.0.0
49
51
  if (!this.isTest) {
50
- this._checkEslint(globalPath);
52
+ this._checkEslint();
51
53
  }
52
54
 
53
55
  // To enable custom lint rules ('lint' or 'lint:dev')
@@ -69,15 +71,27 @@ module.exports = class LintTemplate extends TemplateBase {
69
71
  // Generate custom lint rules docs
70
72
  await generators.genDocs(this.projectPath);
71
73
  }
74
+
75
+ // Generate VS Code extension settings
76
+ const extensions = ALLOWED_FILE_EXTENSIONS.map((ext) => {
77
+ return path.extname(ext).replace('.', '');
78
+ })
79
+ extensions.forEach((ext) => {
80
+ if (ext in VSCODE_FILE_ASSOCIATIONS) {
81
+ VSCODE_FILE_ASSOCIATIONS[ext].forEach((assoc) => {
82
+ extensions.push(assoc)
83
+ })
84
+ }
85
+ });
86
+ await io.sanitizeVscodeSettings(
87
+ this.projectPath,
88
+ path.join(this.projectPath, ".vscode/settings.json"),
89
+ this.lintType,
90
+ extensions,
91
+ this.customRuleExample
92
+ );
72
93
  }
73
94
 
74
- // Generate VS Code extension settings
75
- await io.sanitizeVscodeSettings(
76
- this.projectPath,
77
- path.join(this.projectPath, ".vscode/settings.json"),
78
- this.lintType,
79
- this.customRuleExample
80
- );
81
95
  }
82
96
 
83
97
  async finalize() {
@@ -111,12 +125,8 @@ module.exports = class LintTemplate extends TemplateBase {
111
125
 
112
126
  }
113
127
 
114
- _checkEslint(globalPath) {
115
- const eslintInfo = checks.resolveEslint(this.projectPath, globalPath);
116
- let eslintCmd;
117
- if (eslintInfo) {
118
- eslintCmd = eslintInfo.cmd;
119
- }
128
+ _checkEslint() {
129
+ const eslintCmd = checks.resolveEslint(this.projectPath, '');
120
130
  if (!eslintCmd) {
121
131
  this.missingNpmDependencies["names"].push("eslint");
122
132
  this.missingNpmDependencies["msgs"].push("ESLint v>=7.0.0");
@@ -13,7 +13,12 @@ build-parameters:
13
13
  before-all:
14
14
  - builder: custom
15
15
  commands:
16
+ {{#cap.isNodejs}}
17
+ - npm ci
18
+ {{/cap.isNodejs}}
19
+ {{#cap.isJava}}
16
20
  - npm install --production
21
+ {{/cap.isJava}}
17
22
  - npx -p @sap/cds-dk cds build --production
18
23
 
19
24
  {{! This template creates one or two deployable modules:
@@ -30,6 +35,8 @@ modules:
30
35
  {{#cap.isNodejs}}
31
36
  parameters:
32
37
  buildpack: nodejs_buildpack
38
+ build-parameters:
39
+ builder: npm-ci
33
40
  {{/cap.isNodejs}}
34
41
  {{#cap.isJava}}
35
42
  parameters:
@@ -207,11 +214,11 @@ resources:
207
214
  type: org.cloudfoundry.managed-service
208
215
  requires:
209
216
  - name: {{cap.appName}}-uaa-mt
210
- - name: mtx-api
211
- properties:
212
- prop: ~{mtx-url}
213
- parameters:
214
- param: ~{mtx-url}
217
+ - name: mtx-api
218
+ properties:
219
+ prop: ~{mtx-url}
220
+ parameters:
221
+ param: ~{mtx-url}
215
222
  parameters:
216
223
  service: saas-registry
217
224
  service-plan: application
@@ -22,13 +22,11 @@ module.exports = class ProjectReader {
22
22
  async getEnv(profile = 'production') {
23
23
  const cdsEnvVar = process.env.CDS_ENV
24
24
  process.env.CDS_ENV = profile
25
- let env
26
25
  try {
27
- env = await this.template.getEnv(true);
26
+ return await this.template.getEnv();
28
27
  } finally {
29
28
  cdsEnvVar ? process.env.CDS_ENV = cdsEnvVar : delete process.env.CDS_ENV
30
29
  }
31
- return env
32
30
  }
33
31
 
34
32
  get fsUtil() {
@@ -28,5 +28,3 @@ mta_archives/
28
28
  # IDEs
29
29
  # .vscode
30
30
  # .idea
31
-
32
- .cdsrc-private.json
@@ -58,7 +58,7 @@ module.exports = class SamplesTemplate extends TemplateBase {
58
58
  }
59
59
 
60
60
  async _addNodejsSamples() {
61
- const folders = (await this.getEnv(true)).folders;
61
+ const folders = (await this.getEnv()).folders;
62
62
  const dbFolder = path.join(this.projectPath, folders.db);
63
63
  await this.templateUtil.copyFiles('nodejs/db', dbFolder, {}, this.options.force);
64
64
 
@@ -1,11 +1,9 @@
1
1
  const path = require('path');
2
- const cds = require('@sap/cds/lib');
2
+ const Config = require('@sap/cds/lib/env');
3
3
 
4
4
  const TemplateUtil = require('../util/templateUtil');
5
- const commandUtil = require('../util/commandUtil');
6
- const { nullLogger } = require('../util/logger');
7
5
 
8
- const { IS_WIN, PROJECT_TYPE } = require('../constants');
6
+ const { PROJECT_TYPE } = require('../constants');
9
7
 
10
8
 
11
9
  module.exports = class TemplateBase {
@@ -43,49 +41,20 @@ module.exports = class TemplateBase {
43
41
  return true;
44
42
  }
45
43
 
46
- getCdsModulePath() {
47
- return path.join(__dirname, '../../../bin/cds.js');
48
- }
49
-
50
44
  /**
51
45
  * calls cds env and caches result
52
46
  * @param {boolean} force, ignore cached value
53
47
  * @returns {object} the current cds env
54
48
  */
55
- async getEnv(force = false) {
56
- if (!this.env || force) {
57
- let projectPath;
58
- if (await this.fsUtil.pathExists(this.projectPath)) {
59
- projectPath = this.projectPath;
60
- } else {
61
- projectPath = this.cwd;
62
- }
63
-
64
- const logger = (this.logger.isDebug ? this.logger : nullLogger);
65
-
66
- let modPath = this.getCdsModulePath();
67
- if (IS_WIN) {
68
- modPath = `"${modPath}"`;
69
- }
70
-
71
- let envJsonOutput = await commandUtil.spawnCommand('node', [modPath, 'env', 'json'], {
72
- cwd: projectPath,
73
- env: process.env
74
- }, logger, true);
75
-
76
- if (envJsonOutput) {
77
- // cheap check to see if json is valid
78
- if (envJsonOutput.indexOf('":') < 0) {
79
- // eslint-disable-next-line no-control-regex
80
- envJsonOutput = envJsonOutput.replace(/'/g, '"').replace(/\s(\w+):\s/g, ' "$1": ').replace(/\x1b\[\w+m/g, '');
81
- }
82
-
83
- this.env = JSON.parse(envJsonOutput);
84
- // env has additional getters and setters
85
- Object.setPrototypeOf(this.env, cds.env.__proto__);
86
- }
49
+ async getEnv() {
50
+ let projectPath;
51
+ if (await this.fsUtil.pathExists(this.projectPath)) {
52
+ projectPath = this.projectPath;
53
+ } else {
54
+ projectPath = this.cwd;
87
55
  }
88
- return this.env;
56
+
57
+ return Config.for('cds', projectPath);
89
58
  }
90
59
 
91
60
  /**
@@ -18,7 +18,7 @@ module.exports = class FsUtil {
18
18
  await fse.outputFile(filepath, content, UTF_8);
19
19
  }
20
20
 
21
- async writeJSON(filepath, object, options = { spaces: 4 }, skipFileLog = false) {
21
+ async writeJSON(filepath, object, options = { spaces: 2 }, skipFileLog = false) {
22
22
  if (!skipFileLog) {
23
23
  this._addTouchedFile(filepath);
24
24
  }
@@ -14,6 +14,8 @@ const {
14
14
  } = require("@sap/eslint-plugin-cds/lib/api");
15
15
 
16
16
  const IS_WIN = os.platform() === "win32";
17
+ const ALLOWED_FILE_EXTENSIONS = getFileExtensions();
18
+
17
19
  class Linter {
18
20
  constructor() {
19
21
  this.eslintCmd = "";
@@ -45,11 +47,7 @@ class Linter {
45
47
  * @returns object continaing help, options, flags and shortcuts
46
48
  */
47
49
  init(help = "", options = [], flags = [], shortcuts = []) {
48
- const eslintInfo = checks.resolveEslint(this.cdsdkPath, this.globalPath);
49
- if (eslintInfo) {
50
- this.eslintCmd = eslintInfo.cmd;
51
- }
52
- this.addFormatter = eslintInfo.addFormatter;
50
+ this.eslintCmd = checks.resolveEslint(this.cdsdkPath, this.globalPath);
53
51
  if (this.eslintCmd) {
54
52
  help = generators.genEslintHelp(this.eslintCmd);
55
53
  flags = generators.genEslintFlags(help);
@@ -98,7 +96,7 @@ class Linter {
98
96
  }
99
97
 
100
98
  // Limit to CDS file extensions
101
- this._addExtensions(this.addFormatter);
99
+ this._addExtensions();
102
100
  // Run ESLint with collected options
103
101
  try {
104
102
  await this._runEslint();
@@ -141,29 +139,16 @@ class Linter {
141
139
  return;
142
140
  }
143
141
 
144
- _addExtensions(addFormatter) {
142
+ _addExtensions() {
145
143
  // Add CDS file extensions to lint
144
+ const extensions = ALLOWED_FILE_EXTENSIONS.map((ext) => path.extname(ext));
146
145
  this.eslintCmdOpts = io.mergeWithUserOpts(
147
146
  this.eslintCmdOpts,
148
147
  "ext",
149
- ".cds,.csn"
148
+ extensions.join(',')
150
149
  );
151
- // Add custom CDS formatter (for ESLint v<8)
152
- if (addFormatter) {
153
- const formatterPath = this.pluginPath.replace(
154
- "index.js",
155
- "../api/formatter.js"
156
- );
157
- this.eslintCmdOpts = io.mergeWithUserOpts(
158
- this.eslintCmdOpts,
159
- "format",
160
- path.relative(".", formatterPath)
161
- );
162
- }
163
150
  // Enable colored output
164
- if (process.stdout.isTTY) {
165
- this.eslintCmdOpts = io.mergeWithUserOpts(this.eslintCmdOpts, "color");
166
- }
151
+ this.eslintCmdOpts = io.mergeWithUserOpts(this.eslintCmdOpts, "color");
167
152
  return;
168
153
  }
169
154
 
@@ -193,7 +178,6 @@ class Linter {
193
178
  }
194
179
  }
195
180
  // Only lint file extensions prescribed by plugin
196
- const fileExtensions = getFileExtensions();
197
181
  eslintCmdOpts.push("--ignore-pattern");
198
182
  let ignorePattern = "*.*";
199
183
  if (IS_WIN) {
@@ -202,7 +186,7 @@ class Linter {
202
186
  ignorePattern = `'${ignorePattern}'`;
203
187
  }
204
188
  eslintCmdOpts.push(ignorePattern);
205
- fileExtensions.forEach((ext) => {
189
+ ALLOWED_FILE_EXTENSIONS.forEach((ext) => {
206
190
  eslintCmdOpts.push("--ignore-pattern");
207
191
  ignorePattern = `!${ext}`;
208
192
  if (IS_WIN) {
@@ -219,22 +203,18 @@ class Linter {
219
203
  } else {
220
204
  input = `'${this.eslintCmdFileExpr.join("' '")}'`;
221
205
  }
222
- const eslintCmdSplit = this.eslintCmd.split(" ");
223
- this.eslintCmd = eslintCmdSplit[0];
224
- eslintCmdOpts.unshift(eslintCmdSplit[1]);
225
- eslintCmdOpts.push(input);
226
206
  // Run ESLint with given cmd line options
227
- // - Show 'eslint' instead of 'node ...eslint.js' cmd
228
- // - Remove debug flag for printed cmd
207
+ // - Show 'eslint' instead of actual eslint cmd ('node .../.eslint.js')
208
+ // - Remove debug flag for printed cmd line
229
209
  if (this.eslintCmdOpts.debug) {
230
210
  eslintCmdOpts.splice(eslintCmdOpts.indexOf('--debug'), 1);
231
211
  console.log(
232
- `Linting:\n ${term.info(`eslint ${eslintCmdOpts.slice(1).join(' ')}`)}\n`
212
+ `Linting:\n ${term.info(`eslint ${eslintCmdOpts.concat(input).join(' ')}`)}\n`
233
213
  );
234
214
  eslintCmdOpts.push('--debug');
235
215
  }
236
216
  if (!dryRun) {
237
- return commandUtil.spawnCommand(this.eslintCmd, eslintCmdOpts, {
217
+ return commandUtil.spawnCommand(this.eslintCmd, eslintCmdOpts.concat(input), {
238
218
  cwd: process.cwd(),
239
219
  shell: true,
240
220
  stdio: process.env.NODE_ENV === 'test' ? 'pipe' : 'inherit',
@@ -21,7 +21,6 @@ module.exports = {
21
21
  let cmd;
22
22
  let version;
23
23
  let errMessage;
24
- let addFormatter = false;
25
24
  try {
26
25
  const eslintPath = require.resolve("eslint/package.json", {
27
26
  paths: [inputPath, globalPath],
@@ -29,9 +28,6 @@ module.exports = {
29
28
  const packageJson = require(eslintPath);
30
29
  if (packageJson.version > "7") {
31
30
  version = packageJson.version;
32
- if (version < "8") {
33
- addFormatter = true;
34
- }
35
31
  } else {
36
32
  errMessage =
37
33
  `ESLint v>=6.0.0 required!\n\n` +
@@ -55,7 +51,7 @@ module.exports = {
55
51
  )}\n`;
56
52
  }
57
53
  if (cmd && version) {
58
- return { cmd, addFormatter };
54
+ return cmd;
59
55
  }
60
56
  if (logger) {
61
57
  logger.error(errMessage);
@@ -3,6 +3,7 @@ const os = require("os");
3
3
  const cp = require("child_process");
4
4
  const path = require("path");
5
5
  const { mkdirp } = require("@sap/cds/lib/utils");
6
+ const term = require("../util/term");
6
7
 
7
8
  const IS_WIN = os.platform() === "win32";
8
9
 
@@ -35,12 +36,12 @@ module.exports = {
35
36
  let cdslintCmd = eslintOpts[0].replace("eslint", "*cds lint*");
36
37
  eslintOpts[0] = `
37
38
  # SYNOPSIS
38
-
39
+
39
40
  ${cdslintCmd} [beta]
40
-
41
+
41
42
  Runs environment checks and/or checks the specified models
42
43
  based on the ESLint framework
43
-
44
+
44
45
  # OPTIONS`;
45
46
  return `${eslintOpts.join("\n ")}\n`;
46
47
  },
@@ -97,7 +98,7 @@ module.exports = {
97
98
  },
98
99
 
99
100
  /**
100
- * Generates custom rules documentation for user
101
+ * Generates custom rules documentation for user
101
102
  * according to contents of rules files
102
103
  * @param {*} projectPath
103
104
  */