nanos-lint 3.0.1 → 3.2.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/README.md CHANGED
@@ -104,18 +104,22 @@ jobs:
104
104
 
105
105
  ### Action Inputs
106
106
 
107
- | Input | Description | Default |
108
- | :-------------- | :---------------------------------------------------------------------------------- | :-------- |
109
- | `path` | Path to workspace directory or Lua file to check | `.` |
110
- | `checklevel` | Minimum severity to report (`Error`, `Warning`, `Information`, `Hint`) | `Warning` |
111
- | `config` | Path to a custom `.luarc.json` configuration file | `""` |
112
- | `annotations` | Path to a custom `annotations.lua` file | `""` |
113
- | `ignore` | Files or directories to ignore (supports glob patterns, newline or comma separated) | `""` |
114
- | `luals-version` | Version of `lua-language-server` to use | `latest` |
115
- | `fail-on-error` | Fail the workflow step if diagnostics are found | `true` |
116
- | `log-level` | Logging level (`error`, `warn`, `info`, `debug`, `silent`) | `warn` |
117
- | `realm` | Execution realm to check (`all`, `client`, `server`, `shared`) | `all` |
118
- | `cache` | Whether to cache the LuaLS binary and annotations across workflow runs | `true` |
107
+ | Input | Description | Default |
108
+ | :-------------- | :------------------------------------------------------------------------------------ | :-------- |
109
+ | `path` | Path to workspace directory or Lua file to check | `.` |
110
+ | `paths` | One or more workspace target paths or Lua files to check (newline or comma-separated) | `""` |
111
+ | `dep` | External package dependency paths or definition files (newline or comma-separated) | `""` |
112
+ | `checklevel` | Minimum severity to report (`Error`, `Warning`, `Information`, `Hint`) | `Warning` |
113
+ | `config` | Path to a custom `.luarc.json` configuration file | `""` |
114
+ | `annotations` | Path to a custom `annotations.lua` file | `""` |
115
+ | `ignore` | Files or directories to ignore (supports glob patterns, newline or comma separated) | `""` |
116
+ | `luals-version` | Version of `lua-language-server` to use | `latest` |
117
+ | `fail-on-error` | Fail the workflow step if diagnostics are found | `true` |
118
+ | `log-level` | Logging level (`error`, `warn`, `info`, `debug`, `silent`) | `warn` |
119
+ | `realm` | Execution realm to check (`all`, `client`, `server`, `shared`) | `all` |
120
+ | `cache` | Whether to cache the LuaLS binary and annotations across workflow runs | `true` |
121
+
122
+ `paths` takes precedence over `path` when both are set; `path` is kept for backwards compatibility with the single-target form.
119
123
 
120
124
  When caching is enabled, the cache key rolls over each ISO week, so a freshly downloaded LuaLS binary is actually persisted under the new week's key; in the meantime the previous week's entry is restored from the cache.
121
125
 
@@ -126,10 +130,10 @@ When running inside GitHub Actions, `nanos-lint` automatically outputs **workflo
126
130
  ## CLI Reference
127
131
 
128
132
  ```
129
- nanos-lint [command] [options] [path]
133
+ nanos-lint [command] [options] [paths...]
130
134
 
131
135
  COMMANDS:
132
- check [path] Check a workspace or Lua file (default)
136
+ check [paths...] Check workspace files or directories (default)
133
137
  init [path] Scaffold a .luarc.json configuration in the workspace (copies definitions to .nanos-lint/; supports --annotations <path>)
134
138
  warmup, download Pre-fetch and cache both LuaLS binary and annotations for offline execution
135
139
  cache status, cache info Show cache status, installed versions, and disk usage (supports --json)
@@ -142,9 +146,10 @@ COMMANDS:
142
146
 
143
147
  OPTIONS:
144
148
  -i, --ignore <pattern> Files or directories to ignore (supports globs, repeatable, comma/newline-separated)
149
+ -d, --dep <path> Path to package dependency directory or Lua definition file (repeatable; resolves relative to cwd)
145
150
  -l, --log-level <level> Logging level: error, warn, info, debug, silent (default: warn)
146
- silent suppresses all output, including the final report (only the exit code remains)
147
- error and warn (the default) suppress progress messages but still print the report
151
+ silent suppresses all output, including the final report and the progress display (only the exit code remains)
152
+ error and warn (the default) hide the info-level log lines and the non-interactive progress milestones but still print the report and the interactive progress bar
148
153
  debug adds diagnostic tracing
149
154
  --checklevel=<level> Minimum diagnostic level: Error, Warning, Information, Hint (default: Warning)
150
155
  --config=<path> Path to custom .luarc.json configuration file
@@ -154,9 +159,38 @@ OPTIONS:
154
159
  --luals-version=<ver> Version of LuaLS to use (default: latest, falling back to 3.19.1 when offline)
155
160
  --no-fail Do not exit with code 1 if diagnostics are found
156
161
  --realm <realm> Execution realm to check: all, client, server, shared (default: all)
162
+ --no-progress Disable the interactive download, extraction and realm derivation progress display
157
163
  -f, --force (init command only) Overwrite existing .luarc.json
158
164
  ```
159
165
 
166
+ ### Progress Display
167
+
168
+ Downloads and extractions (`LuaLS` archive, `annotations.lua`, realm derivation) report their
169
+ progress on **stderr**, so `stdout` keeps carrying only the diagnostic report:
170
+
171
+ ```
172
+ [luals] Downloading lua-language-server-3.19.1-linux-x64.tar.gz [=====> ] 37% (1.31 MB / 3.51 MB, 8.2 MB/s, ETA 0.3s)
173
+ [luals] Extracting lua-language-server-3.19.1-linux-x64.tar.gz ⠹ (2.4s)
174
+ ```
175
+
176
+ A live, in-place redraw is used only when stderr is an interactive terminal. Everywhere else
177
+ (CI runners, pipes, redirected output, `TERM=dumb`) the same information is emitted as discrete
178
+ single-line milestones, so logs stay free of carriage returns:
179
+
180
+ ```
181
+ [luals] Downloading lua-language-server-3.19.1-linux-x64.tar.gz: 25% (901 KB / 3.51 MB)
182
+ [luals] Downloaded lua-language-server-3.19.1-linux-x64.tar.gz (3.51 MB in 0.1s (37.3 MB/s))
183
+ ```
184
+
185
+ Dynamic redrawing is also disabled by `--no-progress`, `NANOS_NO_PROGRESS`, `--format json`,
186
+ `-l silent`, `CI`, `NO_COLOR` and `TERM=dumb`. When a transfer declares a compressed
187
+ `content-length` (GitHub serves `annotations.lua` gzip-encoded), the percentage is dropped in
188
+ favour of transferred bytes and speed instead of reporting a misleading total.
189
+
190
+ Machine-readable output owns `stdout`: with `--format json` (and `cache status --json`) the
191
+ milestones, completions and every other `info`/`debug` diagnostic move to `stderr` as well, so
192
+ `nanos-lint check . --format json -l info | jq .` works at any log level.
193
+
160
194
  ### Environment Variables
161
195
 
162
196
  | Variable | Description |
@@ -165,7 +199,8 @@ OPTIONS:
165
199
  | `NANOS_ANNOTATIONS_PATH`, `NANOS_ANNOTATIONS` | Explicit path to a custom `annotations.lua` file |
166
200
  | `NANOS_LOG_LEVEL` | Default logging level: `error`, `warn`, `info`, `debug`, `silent` (default: `warn`) |
167
201
  | `GITHUB_TOKEN` | GitHub personal access token used for authenticated GitHub API requests (avoids unauthenticated rate limits) |
168
- | `NO_COLOR` | Disables ANSI color output when set to any non-empty value |
202
+ | `NANOS_NO_PROGRESS` | Disables the interactive download/extraction progress display when set to any non-empty value other than `0`, `false`, `no` or `off` |
203
+ | `NO_COLOR` | Disables ANSI color output when set to any non-empty value; dynamic progress redrawing stops for any non-empty value other than `0`, `false`, `no` or `off` |
169
204
  | `FORCE_COLOR` | Forces ANSI color output even in non-TTY environments |
170
205
 
171
206
  Only `NANOS_LOG_LEVEL` controls the logging level; a generic `LOG_LEVEL` environment variable is intentionally not read, because CI images commonly set it.
@@ -225,6 +260,23 @@ nanos world runs two isolated Lua VMs: the server executes `Server/**` + `Shared
225
260
 
226
261
  The `nanos` key is nanos-lint specific and ignored by LuaLS, so the same `.luarc.json` keeps working in the editor.
227
262
 
263
+ ### Package Dependencies (`nanos.deps`)
264
+
265
+ When packages depend on other packages (e.g. located in `Server/Packages/` or external integration folders), you can declare them in `.luarc.json` under `nanos.deps` or via the `-d, --dep` CLI option:
266
+
267
+ ```json
268
+ {
269
+ "nanos": {
270
+ "deps": ["../base_package", "../integration_package", "../definitions/common.lua"]
271
+ }
272
+ }
273
+ ```
274
+
275
+ - **Path Resolution**: Paths defined in `nanos.deps` resolve relative to the package directory containing the `.luarc.json`. In contrast, paths passed via the `-d, --dep <path>` CLI option resolve relative to the current working directory (`process.cwd()`).
276
+ - **Transitive Dependencies & Cycle Detection**: Dependencies are traversed recursively. If a dependency defines its own `nanos.deps` in `.luarc.json`, those dependencies are loaded automatically. Circular dependencies are detected and visited only once.
277
+ - **Realm Partitioning**: Dependency directories are inspected for realm conventions (`Server/`, `Client/`, `Shared/`). Server passes only include `Server/` and `Shared/` folders of dependencies; client passes only include `Client/` and `Shared/` folders. Single definition `.lua` files and non-partitioned dependency directories are included in all passes.
278
+ - **Resilience**: If a declared dependency path does not exist, `nanos-lint` emits a warning and continues without failing the lint pass.
279
+
228
280
  ### File Counting and Glob Semantics
229
281
 
230
282
  The `N files checked` figure is produced by matching `workspace.ignoreDir` and `files.exclude` with the bundled `glob` engine. The v3.0.0 contract is:
@@ -266,6 +318,22 @@ Deliberate limits:
266
318
  - **`Package.Require` keeps resolving across realms**, because `runtime.path` keeps `?.lua`, `Shared/?.lua`, `Client/?.lua` and `Server/?.lua` in every pass. A shared file may require a realm-specific module behind a guard.
267
319
  - **Realm checking only activates when a configured pattern matches at least one checked Lua file**, so non-package repositories keep running a single standard pass. `"nanos": { "realms": {} }` disables it explicitly.
268
320
 
321
+ ### Variadic Target Paths & Scoped Context
322
+
323
+ `nanos-lint` accepts multiple files or directories on the command line:
324
+
325
+ ```bash
326
+ # Lint both Shared and Server folders in one pass
327
+ npx nanos-lint check Shared/ Server/ --realm server
328
+
329
+ # Lint multiple specific files
330
+ npx nanos-lint check Shared/utility.lua Server/main.lua
331
+ ```
332
+
333
+ - **Project Root Discovery**: When checking subpaths or individual files (e.g. `Server/main.lua`), `nanos-lint` searches upward to locate the enclosing project root containing `.luarc.json` so custom realm mappings and dependencies are properly loaded.
334
+ - **Unrequested Sibling Exclusion**: To prevent unrelated files under the common ancestor directory from defining globals that mask `undefined-global` diagnostics in requested files, `nanos-lint` automatically excludes unrequested siblings during the check.
335
+ - **Root Filesystem Protection**: Target paths must share a common project directory. Passing disjoint paths spanning the filesystem root (or different drive letters on Windows) is rejected with an error.
336
+
269
337
  ---
270
338
 
271
339
  ## Pre-packaged Release Distributions (Offline / CD)
package/action.yml CHANGED
@@ -10,6 +10,14 @@ inputs:
10
10
  description: "Path to workspace directory or Lua file to check"
11
11
  required: false
12
12
  default: "."
13
+ paths:
14
+ description: "One or more workspace target paths or Lua files to check (supports newline or comma-separated entries)"
15
+ required: false
16
+ default: ""
17
+ dep:
18
+ description: "External package dependency paths or definition files (supports newline or comma-separated entries)"
19
+ required: false
20
+ default: ""
13
21
  checklevel:
14
22
  description: "Minimum diagnostic severity level to report (Error, Warning, Information, Hint)"
15
23
  required: false
@@ -79,6 +87,8 @@ runs:
79
87
  shell: bash
80
88
  env:
81
89
  INPUT_PATH: ${{ inputs.path }}
90
+ INPUT_PATHS: ${{ inputs.paths }}
91
+ INPUT_DEP: ${{ inputs.dep }}
82
92
  INPUT_CHECKLEVEL: ${{ inputs.checklevel }}
83
93
  INPUT_CONFIG: ${{ inputs.config }}
84
94
  INPUT_ANNOTATIONS: ${{ inputs.annotations }}
@@ -89,7 +99,27 @@ runs:
89
99
  INPUT_IGNORE: ${{ inputs.ignore }}
90
100
  ACTION_PATH: ${{ github.action_path }}
91
101
  run: |
92
- ARGS=("check" "$INPUT_PATH" "--checklevel=$INPUT_CHECKLEVEL" "--luals-version=$INPUT_LUALS_VERSION" "--format=github")
102
+ TARGET_PATHS=()
103
+ if [ -n "$INPUT_PATHS" ]; then
104
+ while IFS= read -r line || [ -n "$line" ]; do
105
+ trimmed=$(echo "$line" | xargs)
106
+ if [ -n "$trimmed" ]; then
107
+ IFS=',' read -ra ADDR <<< "$trimmed"
108
+ for i in "${ADDR[@]}"; do
109
+ sub_trimmed=$(echo "$i" | xargs)
110
+ if [ -n "$sub_trimmed" ]; then
111
+ TARGET_PATHS+=("$sub_trimmed")
112
+ fi
113
+ done
114
+ fi
115
+ done <<< "$INPUT_PATHS"
116
+ elif [ -n "$INPUT_PATH" ]; then
117
+ TARGET_PATHS+=("$INPUT_PATH")
118
+ else
119
+ TARGET_PATHS+=(".")
120
+ fi
121
+
122
+ ARGS=("check" "${TARGET_PATHS[@]}" "--checklevel=$INPUT_CHECKLEVEL" "--luals-version=$INPUT_LUALS_VERSION" "--format=github")
93
123
 
94
124
  if [ -n "$INPUT_CONFIG" ]; then
95
125
  ARGS+=("--config=$INPUT_CONFIG")
@@ -99,6 +129,21 @@ runs:
99
129
  ARGS+=("--annotations=$INPUT_ANNOTATIONS")
100
130
  fi
101
131
 
132
+ if [ -n "$INPUT_DEP" ]; then
133
+ while IFS= read -r line || [ -n "$line" ]; do
134
+ trimmed=$(echo "$line" | xargs)
135
+ if [ -n "$trimmed" ]; then
136
+ IFS=',' read -ra ADDR <<< "$trimmed"
137
+ for i in "${ADDR[@]}"; do
138
+ sub_trimmed=$(echo "$i" | xargs)
139
+ if [ -n "$sub_trimmed" ]; then
140
+ ARGS+=("--dep=$sub_trimmed")
141
+ fi
142
+ done
143
+ fi
144
+ done <<< "$INPUT_DEP"
145
+ fi
146
+
102
147
  if [ -n "$INPUT_IGNORE" ]; then
103
148
  while IFS= read -r line || [ -n "$line" ]; do
104
149
  trimmed=$(echo "$line" | xargs)
@@ -127,5 +172,5 @@ runs:
127
172
  else
128
173
  # Exact version: a range could run a different release than the pinned
129
174
  # tag. Bump together with "version" in package.json.
130
- npx --yes nanos-lint@3.0.1 "${ARGS[@]}"
175
+ npx --yes nanos-lint@3.2.0 "${ARGS[@]}"
131
176
  fi