@sasjs/lint 5.0.0 → 5.0.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,6 +1,6 @@
1
1
  # SAS Code linting and formatting
2
2
 
3
- ![GitHub top language](https://img.shields.io/github/languages/top/sasjs/lint) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sasjs/lint)](https://github.com/sasjs/lint/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues-raw/sasjs/lint)](https://github.com/sasjs/lint/issues) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sasjs/lint/badge)](https://scorecard.dev/viewer/?uri=github.com/sasjs/lint) ![total lines](https://tokei.rs/b1/github/sasjs/lint) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/sasjs/lint)
3
+ ![GitHub top language](https://img.shields.io/github/languages/top/sasjs/lint) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sasjs/lint)](https://github.com/sasjs/lint/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues-raw/sasjs/lint)](https://github.com/sasjs/lint/issues) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sasjs/lint/badge)](https://scorecard.dev/viewer/?uri=github.com/sasjs/lint)
4
4
 
5
5
  Our goal is to help SAS developers everywhere spend less time on code reviews, bug fixing and arguing about standards - and more time delivering extraordinary business value.
6
6
 
@@ -487,6 +487,8 @@ This will highlight lines with trailing spaces. Trailing spaces serve no useful
487
487
 
488
488
  SASjs programs declare the macros they use in the `<h4> SAS Macros </h4>` section of the header, so that the compiler can assemble the job before it runs. This rule reports a warning for each macro that a file invokes without declaring it - either by defining it in the file, or by listing it in the `<h4> SAS Macros </h4>` section. That is the only header list `sasjs compile` reads, so it is the only one that makes a macro available to the job; entries anywhere else in the header do not count.
489
489
 
490
+ The rule only looks at a file that has a header. A file with no header has no `<h4> SAS Macros </h4>` section to declare a macro in, and the formatter cannot create one, so its calls are not reported - `hasDoxygenHeader` reports the missing header, and that is the change the file needs first. A file whose header is a single-asterisk `/* ... */` block does count as having one: `hasDoxygenHeader` asks for the Doxygen form, its fix widens the block, and the declarations are added in the same `sasjs lint fix` pass.
491
+
490
492
  The macros that ship with SAS (`%scan`, `%index`, `%sysfunc` and the other macro functions, along with the macro language keywords such as `%if`, `%then` and `%do`) are always considered declared, so they are never reported. That list is generated from the `macroStatements` and `macroFunctions` groups of `@sasjs/sas-language` (`npm run generate:macros`), so it tracks the SAS language data rather than being maintained here. Macros made available through the `SASAUTOS` system option are not visible to the linter and will be reported - list them in [`ignoredMacros`](#ignoredmacros), which carries `webout` by default.
491
493
 
492
494
  An invocation written inside the argument of `%str` / `%nrstr` is not reported. A file masks a trigger to print it as often as to defer it, and nothing runs at that point, so a warning there would land on text that may never be code. [`noUnusedMacros`](#nounusedmacros) counts such a name as a use, so the deferred form - `%mp_abort(iftrue=%str(%mf_existds(work.x)=1))` - satisfies the declaration it depends on without demanding one.
package/package.json CHANGED
@@ -93,7 +93,7 @@
93
93
  "glob": "^14.0.2",
94
94
  "minimatch": "^11.0.1"
95
95
  },
96
- "version": "5.0.0",
96
+ "version": "5.0.1",
97
97
  "devEngines": {
98
98
  "runtime": {
99
99
  "name": "node",
@@ -4,6 +4,7 @@ exports.noUndeclaredMacros = void 0;
4
4
  const types_1 = require("../../types");
5
5
  const LintRuleType_1 = require("../../types/LintRuleType");
6
6
  const Severity_1 = require("../../types/Severity");
7
+ const getHeaderLinesCount_1 = require("../../utils/getHeaderLinesCount");
7
8
  const headerMacros_1 = require("../../utils/headerMacros");
8
9
  const parseMacroCalls_1 = require("../../utils/parseMacroCalls");
9
10
  const parseMacros_1 = require("../../utils/parseMacros");
@@ -20,6 +21,9 @@ const message = `Macro '{macro}' is not declared - add it to the <h4> SAS Macros
20
21
  * names the configuration lists in `ignoredMacros` - a macro such as `%webout`
21
22
  * has no file to point at.
22
23
  *
24
+ * A file with no header is not scanned at all: the declaration the rule asks
25
+ * for goes in the header, so a file without one has no place to put it.
26
+ *
23
27
  * The scan leaves out the argument of `%str` / `%nrstr`: a file that masks a
24
28
  * trigger usually does so to print it, and reporting it would be a new warning
25
29
  * on text that never runs at that point. `noUnusedMacros` counts those names,
@@ -29,6 +33,13 @@ const message = `Macro '{macro}' is not declared - add it to the <h4> SAS Macros
29
33
  const getUndeclaredCalls = (value, config) => {
30
34
  if (!value)
31
35
  return [];
36
+ // A file with no header has no `<h4> SAS Macros </h4>` section to declare a
37
+ // macro in, and `addMacrosToHeader` cannot write into one - so a report here
38
+ // would be a warning no pass could resolve. It is also the only reading that
39
+ // lets `test` and `fix` agree on such a file. `hasDoxygenHeader` reports the
40
+ // missing header itself, which is the change the file needs.
41
+ if (!(0, getHeaderLinesCount_1.getHeaderLinesCount)(value, config))
42
+ return [];
32
43
  const declared = new Set();
33
44
  (0, parseMacros_1.parseMacros)(value, config).forEach((macro) => {
34
45
  if (macro.name)
@@ -1 +1 @@
1
- {"version":3,"file":"noUndeclaredMacros.js","sourceRoot":"","sources":["../../../src/rules/file/noUndeclaredMacros.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"noUndeclaredMacros.js","sourceRoot":"","sources":["../../../src/rules/file/noUndeclaredMacros.ts"],"names":[],"mappings":"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"}
@@ -274,7 +274,7 @@
274
274
  "$id": "#/properties/noUndeclaredMacros",
275
275
  "type": "boolean",
276
276
  "title": "noUndeclaredMacros",
277
- "description": "Reports a warning for each macro a file invokes without declaring it in the `<h4> SAS Macros </h4>` section of the header - the only header list `sasjs compile` reads. Macros that ship with SAS are always considered declared, and so are the macros listed in `ignoredMacros` (`webout` by default). The formatter resolves the warning by adding the macro names to the header, sorted alphabetically.",
277
+ "description": "Reports a warning for each macro a file invokes without declaring it in the `<h4> SAS Macros </h4>` section of the header - the only header list `sasjs compile` reads. Macros that ship with SAS are always considered declared, and so are the macros listed in `ignoredMacros` (`webout` by default). The formatter resolves the warning by adding the macro names to the header, sorted alphabetically. A file with no header is not reported: it has no `<h4> SAS Macros </h4>` section, and the fix cannot write into one, so `hasDoxygenHeader` reports the missing header instead.",
278
278
  "default": true,
279
279
  "examples": [true, false]
280
280
  },