@sasjs/cli 3.24.1 → 3.25.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.
@@ -57,8 +57,8 @@ var processLint_1 = require("./processLint");
57
57
  var command_1 = require("../../types/command");
58
58
  var types_1 = require("../../types");
59
59
  var utils_1 = require("../../utils");
60
- var syntax = 'lint [subCommand]';
61
- var usage = 'sasjs lint [ fix | lint ]';
60
+ var syntax = 'lint <subCommand> [filterStrings..]';
61
+ var usage = 'sasjs lint [ find | fix | init ]';
62
62
  var description = "Provides the capability to identify, for SAS file, whether there are any ERRORs or WARNINGs present and if so, which line number they are on.";
63
63
  var examples = [
64
64
  {
@@ -66,11 +66,41 @@ var examples = [
66
66
  description: 'Lints all .sas files in the current project.\n' +
67
67
  'All the exceptions (along with line / column numbers) will be shown in the console.'
68
68
  },
69
+ {
70
+ command: 'sasjs lint find mf_a mf_b',
71
+ description: 'Lints all .sas files starting from mf_a or mf_b in the current project.\n' +
72
+ 'All the exceptions (along with line / column numbers) will be shown in the console.'
73
+ },
74
+ {
75
+ command: 'sasjs lint find /home/user/project/sasjs/services/appinit.sas',
76
+ description: 'Lints only appinit.sas file present in services folder.\n' +
77
+ 'All the exceptions (along with line / column numbers) will be shown in the console.'
78
+ },
79
+ {
80
+ command: 'sasjs lint find sasjs/macros',
81
+ description: 'Lints all .sas files present in sasjs/macros folder.\n' +
82
+ 'All the exceptions (along with line / column numbers) will be shown in the console.'
83
+ },
69
84
  {
70
85
  command: 'sasjs lint fix',
71
86
  description: 'Fixes lint violations in all .sas files in the current project.\n' +
72
87
  'All the exceptions (along with line / column numbers) will be fixed.'
73
88
  },
89
+ {
90
+ command: 'sasjs lint fix mf_a mf_b',
91
+ description: 'Fixes lint violations in all .sas files starting from mf_a or mf_b in the current project.\n' +
92
+ 'All the exceptions (along with line / column numbers) will be fixed.'
93
+ },
94
+ {
95
+ command: 'sasjs lint fix /home/user/project/sasjs/services/appinit.sas',
96
+ description: 'Fixes lint violations in only appinit.sas in services folder.\n' +
97
+ 'All the exceptions (along with line / column numbers) will be fixed.'
98
+ },
99
+ {
100
+ command: 'sasjs lint fix sasjs/macros/',
101
+ description: 'Fixes lint violations in all .sas files in the macros folder.\n' +
102
+ 'All the exceptions (along with line / column numbers) will be fixed.'
103
+ },
74
104
  {
75
105
  command: 'sasjs lint init',
76
106
  description: "Creates a SASjs Lint configuration file. Its name will be of the form '.sasjslint'"
@@ -79,20 +109,25 @@ var examples = [
79
109
  var LintCommand = /** @class */ (function (_super) {
80
110
  __extends(LintCommand, _super);
81
111
  function LintCommand(args) {
82
- return _super.call(this, args, {
112
+ var _this = this;
113
+ if (args.length < 4) {
114
+ args.splice(3, 0, 'find');
115
+ }
116
+ _this = _super.call(this, args, {
83
117
  syntax: syntax,
84
118
  usage: usage,
85
119
  description: description,
86
120
  examples: examples
87
121
  }) || this;
122
+ return _this;
88
123
  }
89
124
  LintCommand.prototype.execute = function () {
90
125
  return __awaiter(this, void 0, void 0, function () {
91
- var subCommand;
92
- return __generator(this, function (_a) {
93
- switch (_a.label) {
126
+ var _a, subCommand, filterStrings;
127
+ return __generator(this, function (_b) {
128
+ switch (_b.label) {
94
129
  case 0:
95
- subCommand = this.parsed.subCommand;
130
+ _a = this.parsed, subCommand = _a.subCommand, filterStrings = _a.filterStrings;
96
131
  if (!(subCommand === 'init')) return [3 /*break*/, 2];
97
132
  return [4 /*yield*/, (0, initLint_1.initLint)()
98
133
  .then(function (res) {
@@ -106,17 +141,17 @@ var LintCommand = /** @class */ (function (_super) {
106
141
  (0, utils_1.displayError)(err, 'An error has occurred whilst initialising SASjs Lint.');
107
142
  return command_1.ReturnCode.InternalError;
108
143
  })];
109
- case 1: return [2 /*return*/, _a.sent()];
144
+ case 1: return [2 /*return*/, _b.sent()];
110
145
  case 2:
111
146
  if (!(subCommand === 'fix')) return [3 /*break*/, 4];
112
- return [4 /*yield*/, (0, processLint_1.lintFix)()
147
+ return [4 /*yield*/, (0, processLint_1.lintFix)(filterStrings)
113
148
  .then(function () { return command_1.ReturnCode.Success; })
114
149
  .catch(function (err) {
115
150
  (0, utils_1.displayError)(err, 'An error has occurred while running SASjs Lint Fix.');
116
151
  return command_1.ReturnCode.LintError;
117
152
  })];
118
- case 3: return [2 /*return*/, _a.sent()];
119
- case 4: return [4 /*yield*/, (0, processLint_1.processLint)()
153
+ case 3: return [2 /*return*/, _b.sent()];
154
+ case 4: return [4 /*yield*/, (0, processLint_1.processLint)(filterStrings)
120
155
  .then(function (result) {
121
156
  if (result.errors) {
122
157
  (0, utils_1.displayError)('Please fix the identified lint errors.');
@@ -133,7 +168,7 @@ var LintCommand = /** @class */ (function (_super) {
133
168
  (0, utils_1.displayError)(err, 'An error has occurred when processing lint operation.');
134
169
  return command_1.ReturnCode.InternalError;
135
170
  })];
136
- case 5: return [2 /*return*/, _a.sent()];
171
+ case 5: return [2 /*return*/, _b.sent()];
137
172
  }
138
173
  });
139
174
  });
@@ -3,13 +3,15 @@ interface LintResult {
3
3
  errors: boolean;
4
4
  }
5
5
  /**
6
- * Fixes lint violations in all .sas files in the current project
6
+ * Fixes lint violations in all .sas files in the current project if no filterArray is provided
7
+ * Otherwise fixes lint violations of only those .sas files which matches filter array
7
8
  * @returns {Promise<void>} resolves successfully when formatting has completed
8
9
  */
9
- export declare function lintFix(): Promise<void>;
10
+ export declare function lintFix(filterArray?: string[]): Promise<void>;
10
11
  /**
11
- * Lints all .sas files in the current project
12
+ * Lints all .sas files in the current project if no filterArray is provided
13
+ * Otherwise lints .sas files which matches filter array
12
14
  * @returns an object containing booleans `warnings` and `errors`
13
15
  */
14
- export declare function processLint(): Promise<LintResult>;
16
+ export declare function processLint(filterArray?: string[]): Promise<LintResult>;
15
17
  export {};
@@ -35,36 +35,146 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
36
  }
37
37
  };
38
+ var __read = (this && this.__read) || function (o, n) {
39
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
40
+ if (!m) return o;
41
+ var i = m.call(o), r, ar = [], e;
42
+ try {
43
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
44
+ }
45
+ catch (error) { e = { error: error }; }
46
+ finally {
47
+ try {
48
+ if (r && !r.done && (m = i["return"])) m.call(i);
49
+ }
50
+ finally { if (e) throw e.error; }
51
+ }
52
+ return ar;
53
+ };
54
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
55
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56
+ if (ar || !(i in from)) {
57
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
58
+ ar[i] = from[i];
59
+ }
60
+ }
61
+ return to.concat(ar || Array.prototype.slice.call(from));
62
+ };
38
63
  var __importDefault = (this && this.__importDefault) || function (mod) {
39
64
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
65
  };
41
66
  Object.defineProperty(exports, "__esModule", { value: true });
42
67
  exports.processLint = exports.lintFix = void 0;
68
+ var path_1 = __importDefault(require("path"));
43
69
  var chalk_1 = __importDefault(require("chalk"));
44
70
  var lint_1 = require("@sasjs/lint");
71
+ var utils_1 = require("@sasjs/utils");
45
72
  /**
46
- * Fixes lint violations in all .sas files in the current project
73
+ * Fixes lint violations in all .sas files in the current project if no filterArray is provided
74
+ * Otherwise fixes lint violations of only those .sas files which matches filter array
47
75
  * @returns {Promise<void>} resolves successfully when formatting has completed
48
76
  */
49
- function lintFix() {
77
+ function lintFix(filterArray) {
78
+ var _a, _b, _c;
79
+ if (filterArray === void 0) { filterArray = []; }
50
80
  return __awaiter(this, void 0, void 0, function () {
51
- return __generator(this, function (_a) {
52
- switch (_a.label) {
53
- case 0: return [4 /*yield*/, (0, lint_1.formatProject)().then(function (result) {
54
- var _a, _b, _c;
55
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("Resolved ".concat(result.fixedDiagnosticsCount, " violations."));
81
+ var results, result, absoluteFilePaths, nonAbsoluteFilePathPatterns, regexPattern, regex_1, sasFiles, filesToLint, unfixedDiagnostics;
82
+ var _this = this;
83
+ return __generator(this, function (_d) {
84
+ switch (_d.label) {
85
+ case 0:
86
+ results = [];
87
+ result = {
88
+ updatedFilePaths: [],
89
+ fixedDiagnosticsCount: 0,
90
+ unfixedDiagnostics: new Map()
91
+ };
92
+ if (!filterArray.length) return [3 /*break*/, 5];
93
+ absoluteFilePaths = filterArray.filter(function (pattern) {
94
+ return path_1.default.isAbsolute(pattern);
95
+ });
96
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(absoluteFilePaths, function (filePath) { return __awaiter(_this, void 0, void 0, function () {
97
+ var formatResult, unfixedDiagnostics;
98
+ var _a;
99
+ return __generator(this, function (_b) {
100
+ switch (_b.label) {
101
+ case 0: return [4 /*yield*/, (0, lint_1.formatFile)(filePath)];
102
+ case 1:
103
+ formatResult = _b.sent();
104
+ (_a = result.updatedFilePaths).push.apply(_a, __spreadArray([], __read(formatResult.updatedFilePaths), false));
105
+ result.fixedDiagnosticsCount += formatResult.fixedDiagnosticsCount;
106
+ unfixedDiagnostics = formatResult.unfixedDiagnostics;
107
+ if (unfixedDiagnostics.length) {
108
+ ;
109
+ result.unfixedDiagnostics.set(filePath, unfixedDiagnostics);
110
+ }
111
+ return [2 /*return*/];
112
+ }
113
+ });
114
+ }); })
115
+ // Remove absolute file path patterns.
116
+ // No need to include these patterns in regex,
117
+ // Because we have already formatted on these patterns
118
+ ];
119
+ case 1:
120
+ _d.sent();
121
+ nonAbsoluteFilePathPatterns = filterArray.filter(function (pattern) { return !path_1.default.isAbsolute(pattern); });
122
+ if (!nonAbsoluteFilePathPatterns.length) return [3 /*break*/, 4];
123
+ regexPattern = nonAbsoluteFilePathPatterns
124
+ .map(function (pattern) { return "(".concat(pattern, ")"); })
125
+ .join('|');
126
+ regex_1 = new RegExp(regexPattern);
127
+ return [4 /*yield*/, (0, utils_1.listSasFilesInFolder)(process.projectDir, true, [
128
+ 'node_modules'
129
+ ])];
130
+ case 2:
131
+ sasFiles = _d.sent();
132
+ filesToLint = sasFiles.filter(function (file) { return regex_1.test(file); });
133
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(filesToLint, function (file) { return __awaiter(_this, void 0, void 0, function () {
134
+ var formatResult, unfixedDiagnostics;
135
+ var _a;
136
+ return __generator(this, function (_b) {
137
+ switch (_b.label) {
138
+ case 0: return [4 /*yield*/, (0, lint_1.formatFile)(file)];
139
+ case 1:
140
+ formatResult = _b.sent();
141
+ (_a = result.updatedFilePaths).push.apply(_a, __spreadArray([], __read(formatResult.updatedFilePaths), false));
142
+ result.fixedDiagnosticsCount += formatResult.fixedDiagnosticsCount;
143
+ unfixedDiagnostics = formatResult.unfixedDiagnostics;
144
+ if (unfixedDiagnostics.length) {
145
+ ;
146
+ result.unfixedDiagnostics.set(file, unfixedDiagnostics);
147
+ }
148
+ return [2 /*return*/];
149
+ }
150
+ });
151
+ }); })];
152
+ case 3:
153
+ _d.sent();
154
+ _d.label = 4;
155
+ case 4: return [3 /*break*/, 7];
156
+ case 5: return [4 /*yield*/, (0, lint_1.formatProject)()];
157
+ case 6:
158
+ result = _d.sent();
159
+ _d.label = 7;
160
+ case 7:
161
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("Resolved ".concat(result.fixedDiagnosticsCount, " violations."));
162
+ if (result.updatedFilePaths.length) {
56
163
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info('Updated files:');
57
164
  result.updatedFilePaths.forEach(function (filePath) {
58
165
  var _a;
59
166
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info(filePath);
60
167
  });
168
+ }
169
+ unfixedDiagnostics = (result.unfixedDiagnostics);
170
+ if (unfixedDiagnostics.size) {
61
171
  (_c = process.logger) === null || _c === void 0 ? void 0 : _c.warn('Unresolved violations: ');
62
172
  result.unfixedDiagnostics.forEach(function (diagnostics, filePath) {
63
- displayDiagnostics(filePath, diagnostics);
173
+ if (diagnostics.length) {
174
+ displayDiagnostics(filePath, diagnostics);
175
+ }
64
176
  });
65
- })];
66
- case 1:
67
- _a.sent();
177
+ }
68
178
  return [2 /*return*/];
69
179
  }
70
180
  });
@@ -72,19 +182,81 @@ function lintFix() {
72
182
  }
73
183
  exports.lintFix = lintFix;
74
184
  /**
75
- * Lints all .sas files in the current project
185
+ * Lints all .sas files in the current project if no filterArray is provided
186
+ * Otherwise lints .sas files which matches filter array
76
187
  * @returns an object containing booleans `warnings` and `errors`
77
188
  */
78
- function processLint() {
189
+ function processLint(filterArray) {
190
+ if (filterArray === void 0) { filterArray = []; }
79
191
  return __awaiter(this, void 0, void 0, function () {
80
- var found, sasjsDiagnosticsMap;
192
+ var found, sasjsDiagnosticsMap, absoluteFilePaths, nonAbsoluteFilePathPatterns, regexPattern, regex_2, sasFiles, filesToLint;
193
+ var _this = this;
81
194
  return __generator(this, function (_a) {
82
195
  switch (_a.label) {
83
196
  case 0:
84
197
  found = { warnings: false, errors: false };
85
- return [4 /*yield*/, (0, lint_1.lintProject)()];
198
+ sasjsDiagnosticsMap = new Map();
199
+ if (!filterArray.length) return [3 /*break*/, 5];
200
+ absoluteFilePaths = filterArray.filter(function (pattern) {
201
+ return path_1.default.isAbsolute(pattern);
202
+ });
203
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(absoluteFilePaths, function (filePath) { return __awaiter(_this, void 0, void 0, function () {
204
+ var _a, _b, _c;
205
+ return __generator(this, function (_d) {
206
+ switch (_d.label) {
207
+ case 0:
208
+ _b = (_a = sasjsDiagnosticsMap).set;
209
+ _c = [filePath];
210
+ return [4 /*yield*/, (0, lint_1.lintFile)(filePath)];
211
+ case 1:
212
+ _b.apply(_a, _c.concat([_d.sent()]));
213
+ return [2 /*return*/];
214
+ }
215
+ });
216
+ }); })
217
+ // Remove absolute file path patterns.
218
+ // No need to include these patterns in regex,
219
+ // Because we have already run lint on these patterns
220
+ ];
86
221
  case 1:
222
+ _a.sent();
223
+ nonAbsoluteFilePathPatterns = filterArray.filter(function (pattern) { return !path_1.default.isAbsolute(pattern); });
224
+ if (!nonAbsoluteFilePathPatterns.length) return [3 /*break*/, 4];
225
+ regexPattern = nonAbsoluteFilePathPatterns
226
+ .map(function (pattern) { return "(".concat(pattern, ")"); })
227
+ .join('|');
228
+ regex_2 = new RegExp(regexPattern);
229
+ return [4 /*yield*/, (0, utils_1.listSasFilesInFolder)(process.projectDir, true, [
230
+ 'node_modules'
231
+ ])];
232
+ case 2:
233
+ sasFiles = _a.sent();
234
+ filesToLint = sasFiles.filter(function (file) { return regex_2.test(file); });
235
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(filesToLint, function (file) { return __awaiter(_this, void 0, void 0, function () {
236
+ var filePath, _a, _b, _c;
237
+ return __generator(this, function (_d) {
238
+ switch (_d.label) {
239
+ case 0:
240
+ filePath = path_1.default.join(process.projectDir, file);
241
+ _b = (_a = sasjsDiagnosticsMap).set;
242
+ _c = [filePath];
243
+ return [4 /*yield*/, (0, lint_1.lintFile)(filePath)];
244
+ case 1:
245
+ _b.apply(_a, _c.concat([_d.sent()]));
246
+ return [2 /*return*/];
247
+ }
248
+ });
249
+ }); })];
250
+ case 3:
251
+ _a.sent();
252
+ _a.label = 4;
253
+ case 4: return [3 /*break*/, 7];
254
+ case 5: return [4 /*yield*/, (0, lint_1.lintProject)()];
255
+ case 6:
256
+ // if filterArray is empty, lint whole project
87
257
  sasjsDiagnosticsMap = _a.sent();
258
+ _a.label = 7;
259
+ case 7:
88
260
  sasjsDiagnosticsMap.forEach(function (sasjsDiagnostics, filePath) {
89
261
  found.warnings =
90
262
  found.warnings ||
@@ -94,7 +94,13 @@ describe('LintCommand', function () {
94
94
  var args = __spreadArray(__spreadArray([], __read(defaultArgs), false), ['lint'], false);
95
95
  var command = new lintCommand_1.LintCommand(args);
96
96
  expect(command.name).toEqual('lint');
97
- expect(command.subCommand).toEqual('');
97
+ expect(command.subCommand).toEqual('find');
98
+ });
99
+ it('should parse a sasjs lint command with filter strings', function () {
100
+ var args = __spreadArray(__spreadArray([], __read(defaultArgs), false), ['lint', 'find', 'pattern1', 'pattern2'], false);
101
+ var command = new lintCommand_1.LintCommand(args);
102
+ expect(command.name).toEqual('lint');
103
+ expect(command.subCommand).toEqual('find');
98
104
  });
99
105
  it('should log success and return the success code when execution is successful', function () { return __awaiter(void 0, void 0, void 0, function () {
100
106
  var args, command, returnCode;
@@ -184,6 +190,12 @@ describe('LintCommand - fix', function () {
184
190
  expect(command.name).toEqual('lint');
185
191
  expect(command.subCommand).toEqual('fix');
186
192
  });
193
+ it('should parse sasjs lint command', function () {
194
+ var args = __spreadArray(__spreadArray([], __read(defaultArgs), false), ['lint', 'fix', 'pattern1', 'pattern2'], false);
195
+ var command = new lintCommand_1.LintCommand(args);
196
+ expect(command.name).toEqual('lint');
197
+ expect(command.subCommand).toEqual('fix');
198
+ });
187
199
  it('should log success and return the success code when execution is successful', function () { return __awaiter(void 0, void 0, void 0, function () {
188
200
  var args, command, returnCode;
189
201
  return __generator(this, function (_a) {
@@ -85,7 +85,7 @@ var subCommandMap = new Map([
85
85
  ['doc', ['init', 'lineage']],
86
86
  ['servicepack', ['deploy']],
87
87
  ['add', ['cred']],
88
- ['lint', ['init', 'fix']],
88
+ ['lint', ['init', 'fix', 'find']],
89
89
  ['flow', ['execute']]
90
90
  ]);
91
91
  exports.defaultCommandOptions = {
package/package.json CHANGED
@@ -52,8 +52,8 @@
52
52
  "dependencies": {
53
53
  "@sasjs/adapter": "4.1.0",
54
54
  "@sasjs/core": "4.45.4",
55
- "@sasjs/lint": "2.1.2",
56
- "@sasjs/utils": "2.51.5",
55
+ "@sasjs/lint": "2.1.3",
56
+ "@sasjs/utils": "2.52.0",
57
57
  "adm-zip": "0.5.9",
58
58
  "chalk": "4.1.2",
59
59
  "csv-stringify": "5.6.5",
@@ -101,5 +101,5 @@
101
101
  "typescript": "4.5.4",
102
102
  "util": "0.12.4"
103
103
  },
104
- "version": "3.24.1"
104
+ "version": "3.25.0"
105
105
  }