@jrc03c/gtlint 0.12.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/LICENSE +21 -0
- package/README.md +235 -0
- package/bin/gtlint.js +4 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +248 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +112 -0
- package/dist/config.js.map +1 -0
- package/dist/formatter/formatter.d.ts +22 -0
- package/dist/formatter/formatter.d.ts.map +1 -0
- package/dist/formatter/formatter.js +376 -0
- package/dist/formatter/formatter.js.map +1 -0
- package/dist/formatter/index.d.ts +2 -0
- package/dist/formatter/index.d.ts.map +1 -0
- package/dist/formatter/index.js +2 -0
- package/dist/formatter/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/language/index.d.ts +8 -0
- package/dist/language/index.d.ts.map +1 -0
- package/dist/language/index.js +8 -0
- package/dist/language/index.js.map +1 -0
- package/dist/language/keyword-spec.d.ts +87 -0
- package/dist/language/keyword-spec.d.ts.map +1 -0
- package/dist/language/keyword-spec.js +772 -0
- package/dist/language/keyword-spec.js.map +1 -0
- package/dist/lexer/index.d.ts +3 -0
- package/dist/lexer/index.d.ts.map +1 -0
- package/dist/lexer/index.js +3 -0
- package/dist/lexer/index.js.map +1 -0
- package/dist/lexer/lexer.d.ts +36 -0
- package/dist/lexer/lexer.d.ts.map +1 -0
- package/dist/lexer/lexer.js +709 -0
- package/dist/lexer/lexer.js.map +1 -0
- package/dist/lexer/tokens.d.ts +45 -0
- package/dist/lexer/tokens.d.ts.map +1 -0
- package/dist/lexer/tokens.js +170 -0
- package/dist/lexer/tokens.js.map +1 -0
- package/dist/linter/directives.d.ts +71 -0
- package/dist/linter/directives.d.ts.map +1 -0
- package/dist/linter/directives.js +329 -0
- package/dist/linter/directives.js.map +1 -0
- package/dist/linter/index.d.ts +6 -0
- package/dist/linter/index.d.ts.map +1 -0
- package/dist/linter/index.js +4 -0
- package/dist/linter/index.js.map +1 -0
- package/dist/linter/linter.d.ts +39 -0
- package/dist/linter/linter.d.ts.map +1 -0
- package/dist/linter/linter.js +292 -0
- package/dist/linter/linter.js.map +1 -0
- package/dist/linter/rules/correct-indentation.d.ts +22 -0
- package/dist/linter/rules/correct-indentation.d.ts.map +1 -0
- package/dist/linter/rules/correct-indentation.js +111 -0
- package/dist/linter/rules/correct-indentation.js.map +1 -0
- package/dist/linter/rules/goto-needs-reset-in-events.d.ts +28 -0
- package/dist/linter/rules/goto-needs-reset-in-events.d.ts.map +1 -0
- package/dist/linter/rules/goto-needs-reset-in-events.js +88 -0
- package/dist/linter/rules/goto-needs-reset-in-events.js.map +1 -0
- package/dist/linter/rules/indent-style.d.ts +3 -0
- package/dist/linter/rules/indent-style.d.ts.map +1 -0
- package/dist/linter/rules/indent-style.js +41 -0
- package/dist/linter/rules/indent-style.js.map +1 -0
- package/dist/linter/rules/index.d.ts +5 -0
- package/dist/linter/rules/index.d.ts.map +1 -0
- package/dist/linter/rules/index.js +47 -0
- package/dist/linter/rules/index.js.map +1 -0
- package/dist/linter/rules/no-duplicate-labels.d.ts +3 -0
- package/dist/linter/rules/no-duplicate-labels.d.ts.map +1 -0
- package/dist/linter/rules/no-duplicate-labels.js +75 -0
- package/dist/linter/rules/no-duplicate-labels.js.map +1 -0
- package/dist/linter/rules/no-empty-blocks.d.ts +15 -0
- package/dist/linter/rules/no-empty-blocks.d.ts.map +1 -0
- package/dist/linter/rules/no-empty-blocks.js +45 -0
- package/dist/linter/rules/no-empty-blocks.js.map +1 -0
- package/dist/linter/rules/no-inline-argument.d.ts +14 -0
- package/dist/linter/rules/no-inline-argument.d.ts.map +1 -0
- package/dist/linter/rules/no-inline-argument.js +56 -0
- package/dist/linter/rules/no-inline-argument.js.map +1 -0
- package/dist/linter/rules/no-invalid-goto.d.ts +3 -0
- package/dist/linter/rules/no-invalid-goto.d.ts.map +1 -0
- package/dist/linter/rules/no-invalid-goto.js +92 -0
- package/dist/linter/rules/no-invalid-goto.js.map +1 -0
- package/dist/linter/rules/no-single-quotes.d.ts +3 -0
- package/dist/linter/rules/no-single-quotes.d.ts.map +1 -0
- package/dist/linter/rules/no-single-quotes.js +73 -0
- package/dist/linter/rules/no-single-quotes.js.map +1 -0
- package/dist/linter/rules/no-unclosed-bracket.d.ts +3 -0
- package/dist/linter/rules/no-unclosed-bracket.d.ts.map +1 -0
- package/dist/linter/rules/no-unclosed-bracket.js +108 -0
- package/dist/linter/rules/no-unclosed-bracket.js.map +1 -0
- package/dist/linter/rules/no-unclosed-string.d.ts +3 -0
- package/dist/linter/rules/no-unclosed-string.d.ts.map +1 -0
- package/dist/linter/rules/no-unclosed-string.js +48 -0
- package/dist/linter/rules/no-unclosed-string.js.map +1 -0
- package/dist/linter/rules/no-undefined-vars.d.ts +3 -0
- package/dist/linter/rules/no-undefined-vars.d.ts.map +1 -0
- package/dist/linter/rules/no-undefined-vars.js +257 -0
- package/dist/linter/rules/no-undefined-vars.js.map +1 -0
- package/dist/linter/rules/no-unreachable-code.d.ts +3 -0
- package/dist/linter/rules/no-unreachable-code.d.ts.map +1 -0
- package/dist/linter/rules/no-unreachable-code.js +215 -0
- package/dist/linter/rules/no-unreachable-code.js.map +1 -0
- package/dist/linter/rules/no-unused-labels.d.ts +3 -0
- package/dist/linter/rules/no-unused-labels.d.ts.map +1 -0
- package/dist/linter/rules/no-unused-labels.js +77 -0
- package/dist/linter/rules/no-unused-labels.js.map +1 -0
- package/dist/linter/rules/no-unused-vars.d.ts +3 -0
- package/dist/linter/rules/no-unused-vars.d.ts.map +1 -0
- package/dist/linter/rules/no-unused-vars.js +288 -0
- package/dist/linter/rules/no-unused-vars.js.map +1 -0
- package/dist/linter/rules/purchase-subkeyword-constraints.d.ts +15 -0
- package/dist/linter/rules/purchase-subkeyword-constraints.d.ts.map +1 -0
- package/dist/linter/rules/purchase-subkeyword-constraints.js +88 -0
- package/dist/linter/rules/purchase-subkeyword-constraints.js.map +1 -0
- package/dist/linter/rules/required-subkeywords.d.ts +14 -0
- package/dist/linter/rules/required-subkeywords.d.ts.map +1 -0
- package/dist/linter/rules/required-subkeywords.js +64 -0
- package/dist/linter/rules/required-subkeywords.js.map +1 -0
- package/dist/linter/rules/valid-keyword.d.ts +3 -0
- package/dist/linter/rules/valid-keyword.d.ts.map +1 -0
- package/dist/linter/rules/valid-keyword.js +41 -0
- package/dist/linter/rules/valid-keyword.js.map +1 -0
- package/dist/linter/rules/valid-sub-keyword.d.ts +3 -0
- package/dist/linter/rules/valid-sub-keyword.d.ts.map +1 -0
- package/dist/linter/rules/valid-sub-keyword.js +89 -0
- package/dist/linter/rules/valid-sub-keyword.js.map +1 -0
- package/dist/linter/rules/valid-subkeyword-value.d.ts +16 -0
- package/dist/linter/rules/valid-subkeyword-value.d.ts.map +1 -0
- package/dist/linter/rules/valid-subkeyword-value.js +100 -0
- package/dist/linter/rules/valid-subkeyword-value.js.map +1 -0
- package/dist/parser/ast.d.ts +119 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/ast.js +58 -0
- package/dist/parser/ast.js.map +1 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parser.d.ts +55 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +608 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +36 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Spark Wave
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# GTLint ✨
|
|
2
|
+
|
|
3
|
+
**GTLint** is a linter, formatter, and syntax highlighter for the [GuidedTrack](https://guidedtrack.com) language, inspired by ESLint and Prettier. It can be used at the command line or installed as a VSCode extension.
|
|
4
|
+
|
|
5
|
+
- [Disclaimer](#disclaimer)
|
|
6
|
+
- [VSCode extension](#vscode-extension)
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Command Line](#command-line)
|
|
10
|
+
- [Installation](#installation-1)
|
|
11
|
+
- [Usage](#usage-1)
|
|
12
|
+
- [Configuration](#configuration) (i.e., project-wide settings)
|
|
13
|
+
- [Directives](#directives) (i.e., inline settings)
|
|
14
|
+
- [Tests](#tests)
|
|
15
|
+
- [License](#license)
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
# Disclaimer
|
|
22
|
+
|
|
23
|
+
This tool was written almost exclusively by [Claude Code](https://claude.com/product/claude-code). [Josh Castle](https://github.com/jrc03c) directed Claude Code and made a few small changes to `CLAUDE.md`, `README.md`, and the GuidedTrack files in the `samples` directory; but virtually everything else was written by Claude Code.
|
|
24
|
+
|
|
25
|
+
# VSCode extension
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
(1) Download the `.vsix` file from here:
|
|
30
|
+
|
|
31
|
+
[https://github.com/jrc03c/gtlint/releases/latest/download/gtlint.vsix](https://github.com/jrc03c/gtlint/releases/latest/download/gtlint.vsix)
|
|
32
|
+
|
|
33
|
+
(2) In VSCode, open the command palette and search for "vsix":
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
Select "Extensions: Install from VSIX...".
|
|
38
|
+
|
|
39
|
+
(3) Select the `gtlint.vsix` file that you downloaded in the first step.
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
The linter works while you write code in `.gt` files and will show errors as soon as it detects them. The formatter will format code in `.gt` files on save.
|
|
44
|
+
|
|
45
|
+
See the [Configuration](#configuration) section below for more info about how to control the extension's behavior.
|
|
46
|
+
|
|
47
|
+
# Command Line
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
> **NOTE:** Requires [Node](https://nodejs.org/en).
|
|
52
|
+
|
|
53
|
+
In a specific project:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install --save-dev @jrc03c/gtlint
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or globally:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install -g @jrc03c/gtlint
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
> **NOTE:** When installed in a specific project, GTLint must be invoked with `npx gtlint`. When installed globally, it can be invoked with just `gtlint`. The examples below assume that it has been installed in a specific project.
|
|
68
|
+
|
|
69
|
+
**Syntax:**
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
# lint:
|
|
73
|
+
npx gtlint lint [options] [files]
|
|
74
|
+
|
|
75
|
+
# format:
|
|
76
|
+
npx gtlint format [options] [files]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Show help:**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx gtlint
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Lint:**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# show errors and warnings in a particular file
|
|
89
|
+
npx gtlint lint path/to/some-file.gt
|
|
90
|
+
|
|
91
|
+
# show all errors and warnings in all *.gt files in a directory (recursive)
|
|
92
|
+
npx gtlint lint path/to/some-dir
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Format:**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# format a specific file
|
|
99
|
+
npx gtlint format path/to/some-file.gt
|
|
100
|
+
|
|
101
|
+
# format all *.gt files in a directory (recursive)
|
|
102
|
+
npx gtlint format path/to/some-dir
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
See the [Configuration](#configuration) section below for more info about how to control the command line tool's behavior.
|
|
106
|
+
|
|
107
|
+
# Configuration
|
|
108
|
+
|
|
109
|
+
The linter's and formatter's default behaviors can be controlled by settings in a `gtlint.config.js` file at the root of a repository. Here's a sample configuration file containing all of the default values:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
export default {
|
|
113
|
+
// formatter settings
|
|
114
|
+
format: {
|
|
115
|
+
insertFinalNewline: true,
|
|
116
|
+
spaceAfterComma: true,
|
|
117
|
+
spaceAroundArrow: true,
|
|
118
|
+
spaceAroundOperators: true,
|
|
119
|
+
trimTrailingWhitespace: true,
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
// linter settings
|
|
123
|
+
rules: {
|
|
124
|
+
correctIndentation: "error",
|
|
125
|
+
indentStyle: "error",
|
|
126
|
+
noDuplicateLabels: "error",
|
|
127
|
+
noInvalidGoto: "error",
|
|
128
|
+
noSingleQuotes: "warn",
|
|
129
|
+
noUnclosedBracket: "error",
|
|
130
|
+
noUnclosedString: "error",
|
|
131
|
+
noUndefinedVars: "error",
|
|
132
|
+
noUnusedVars: "warn",
|
|
133
|
+
validKeyword: "error",
|
|
134
|
+
validSubKeyword: "error",
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Linter rules can have these values:
|
|
140
|
+
|
|
141
|
+
- `"off"` or `0` - Disable the rule
|
|
142
|
+
- `"warn"` or `1` - Show as warning (doesn't fail linting)
|
|
143
|
+
- `"error"` or `2` - Show as error (fails linting)
|
|
144
|
+
|
|
145
|
+
# Directives
|
|
146
|
+
|
|
147
|
+
The linter's and formatter's behaviors can also be overridden by inline _directives_ written directly into `.gt` files. Directives are always commented out. For example:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
-- @to-child: email_address
|
|
151
|
+
>> email_address = "someone@example.com"
|
|
152
|
+
*program: Add to Mailing List
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Here are the available directives and what they do:
|
|
156
|
+
|
|
157
|
+
**Combined (lint + format):**
|
|
158
|
+
|
|
159
|
+
- **`@gt-disable`**<br>
|
|
160
|
+
Disable lint + format until `@gt-enable` or EOF
|
|
161
|
+
|
|
162
|
+
- **`@gt-enable`**<br>
|
|
163
|
+
Re-enable lint + format
|
|
164
|
+
|
|
165
|
+
- **`@gt-disable-next-line`**<br>
|
|
166
|
+
Disable lint + format for next line only
|
|
167
|
+
|
|
168
|
+
- **`@gt-disable-next-line rule1, rule2`**<br>
|
|
169
|
+
Disable specific lint rules + format for next line
|
|
170
|
+
|
|
171
|
+
**Lint-only:**
|
|
172
|
+
|
|
173
|
+
- **`@gtlint-disable`**<br>
|
|
174
|
+
Disable all lint rules until `@gtlint-enable` or EOF
|
|
175
|
+
|
|
176
|
+
- **`@gtlint-disable rule1, rule2`**<br>
|
|
177
|
+
Disable specific lint rules
|
|
178
|
+
|
|
179
|
+
- **`@gtlint-enable`**<br>
|
|
180
|
+
Re-enable all lint rules
|
|
181
|
+
|
|
182
|
+
- **`@gtlint-enable rule1`**<br>
|
|
183
|
+
Re-enable specific lint rule
|
|
184
|
+
|
|
185
|
+
- **`@gtlint-disable-next-line`**<br>
|
|
186
|
+
Disable all lint rules for next line
|
|
187
|
+
|
|
188
|
+
- **`@gtlint-disable-next-line rule1, rule2`**<br>
|
|
189
|
+
Disable specific rules for next line
|
|
190
|
+
|
|
191
|
+
- **`@from-child: var1, var2, ...`**<br>
|
|
192
|
+
Do not mark listed variables as undefined (because they are defined in a child program); warns if a listed variable is never used
|
|
193
|
+
|
|
194
|
+
- **`@from-parent: var1, var2, ...`**<br>
|
|
195
|
+
Do not mark listed variables as undefined (because they are defined in a parent program); warns if a listed variable is never used or if its value is overwritten before being read
|
|
196
|
+
|
|
197
|
+
- **`@from-url: var1, var2, ...`**<br>
|
|
198
|
+
Do not mark listed variables as undefined (because they are defined in URL query string parameters); warns if a listed variable is never used or if its value is overwritten before being read
|
|
199
|
+
|
|
200
|
+
- **`@to-child: var1, var2, ...`**<br>
|
|
201
|
+
Do not mark listed variables as unused (because they will be used in a child program)
|
|
202
|
+
|
|
203
|
+
- **`@to-parent: var1, var2, ...`**<br>
|
|
204
|
+
Do not mark listed variables as unused (because they will be used in a parent program)
|
|
205
|
+
|
|
206
|
+
- **`@to-csv: var1, var2, ...`**<br>
|
|
207
|
+
Do not mark listed variables as unused (because they will be saved in the root program's CSV)
|
|
208
|
+
|
|
209
|
+
> **NOTE:** Inline directive rule names always use kebab-case (e.g., `no-unused-vars`), even though config files use camelCase.
|
|
210
|
+
|
|
211
|
+
**Format-only:**
|
|
212
|
+
|
|
213
|
+
- **`@gtformat-disable`**<br>
|
|
214
|
+
Disable formatting until `@gtformat-enable` or EOF
|
|
215
|
+
|
|
216
|
+
- **`@gtformat-enable`**<br>
|
|
217
|
+
Re-enable formatting
|
|
218
|
+
|
|
219
|
+
> **NOTE:** `@gtformat-*` directives don't support rule lists since formatting isn't rule-based.
|
|
220
|
+
|
|
221
|
+
# Tests
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
pnpm test
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The test suite includes integration tests that exercise real GuidedTrack programs from a git submodule (`submodules/gt-lib`). This submodule points to a private repository and is optional. If it's not initialized, those tests are skipped automatically. All other tests will run normally.
|
|
228
|
+
|
|
229
|
+
# Feedback
|
|
230
|
+
|
|
231
|
+
If you run into bugs or have feature requests, please [open an issue](https://github.com/jrc03c/gtlint/issues).
|
|
232
|
+
|
|
233
|
+
# License
|
|
234
|
+
|
|
235
|
+
MIT
|
package/bin/gtlint.js
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAgQA,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChF"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, statSync } from 'fs';
|
|
3
|
+
import { resolve, relative, extname, dirname, join } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { globSync } from 'glob';
|
|
6
|
+
import { Linter } from './linter/index.js';
|
|
7
|
+
import { Formatter } from './formatter/index.js';
|
|
8
|
+
import { loadConfig } from './config.js';
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const { version } = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
11
|
+
function printHelp() {
|
|
12
|
+
console.log(`
|
|
13
|
+
gtlint - A linter and formatter for GuidedTrack
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
gtlint lint [options] [files...] Lint GuidedTrack files
|
|
17
|
+
gtlint format [options] [files...] Format GuidedTrack files
|
|
18
|
+
|
|
19
|
+
Lint Options:
|
|
20
|
+
--quiet Only report errors, not warnings
|
|
21
|
+
--format <type> Output format: stylish (default), json, compact
|
|
22
|
+
|
|
23
|
+
Format Options:
|
|
24
|
+
--write Format and write back to files
|
|
25
|
+
|
|
26
|
+
Common Options:
|
|
27
|
+
--config <path> Path to config file
|
|
28
|
+
--help, -h Show this help message
|
|
29
|
+
--version, -v Show version number
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
gtlint lint . Lint all .gt files in current directory
|
|
33
|
+
gtlint lint src/ Lint all .gt files in src directory
|
|
34
|
+
gtlint lint program.gt Lint a specific file
|
|
35
|
+
gtlint format . Print formatted output to stdout
|
|
36
|
+
gtlint format --write . Format all files in place
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
function printVersion() {
|
|
40
|
+
console.log(`gtlint v${version}`);
|
|
41
|
+
}
|
|
42
|
+
function parseArgs(args) {
|
|
43
|
+
const options = {};
|
|
44
|
+
const files = [];
|
|
45
|
+
let command = '';
|
|
46
|
+
let i = 0;
|
|
47
|
+
while (i < args.length) {
|
|
48
|
+
const arg = args[i];
|
|
49
|
+
if (arg === 'lint' || arg === 'format') {
|
|
50
|
+
command = arg;
|
|
51
|
+
}
|
|
52
|
+
else if (arg === '--config' && args[i + 1]) {
|
|
53
|
+
options.config = args[++i];
|
|
54
|
+
}
|
|
55
|
+
else if (arg === '--write') {
|
|
56
|
+
options.write = true;
|
|
57
|
+
}
|
|
58
|
+
else if (arg === '--quiet') {
|
|
59
|
+
options.quiet = true;
|
|
60
|
+
}
|
|
61
|
+
else if (arg === '--format' && args[i + 1]) {
|
|
62
|
+
options.format = args[++i];
|
|
63
|
+
}
|
|
64
|
+
else if (arg === '--help' || arg === '-h') {
|
|
65
|
+
options.help = true;
|
|
66
|
+
}
|
|
67
|
+
else if (arg === '--version' || arg === '-v') {
|
|
68
|
+
options.version = true;
|
|
69
|
+
}
|
|
70
|
+
else if (!arg.startsWith('-')) {
|
|
71
|
+
files.push(arg);
|
|
72
|
+
}
|
|
73
|
+
i++;
|
|
74
|
+
}
|
|
75
|
+
return { command, files, options };
|
|
76
|
+
}
|
|
77
|
+
function findFiles(patterns, ignore) {
|
|
78
|
+
const files = [];
|
|
79
|
+
for (const pattern of patterns) {
|
|
80
|
+
const resolved = resolve(pattern);
|
|
81
|
+
if (existsSync(resolved) && statSync(resolved).isFile()) {
|
|
82
|
+
if (extname(resolved) === '.gt') {
|
|
83
|
+
files.push(resolved);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (existsSync(resolved) && statSync(resolved).isDirectory()) {
|
|
87
|
+
// Find all .gt files in directory
|
|
88
|
+
const globPattern = `${resolved}/**/*.gt`;
|
|
89
|
+
const found = globSync(globPattern, { ignore });
|
|
90
|
+
files.push(...found);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Treat as glob pattern
|
|
94
|
+
const found = globSync(pattern, { ignore });
|
|
95
|
+
files.push(...found.filter(f => extname(f) === '.gt'));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return [...new Set(files)]; // Remove duplicates
|
|
99
|
+
}
|
|
100
|
+
function formatStylish(results) {
|
|
101
|
+
const lines = [];
|
|
102
|
+
let totalErrors = 0;
|
|
103
|
+
let totalWarnings = 0;
|
|
104
|
+
for (const result of results) {
|
|
105
|
+
if (result.messages.length === 0)
|
|
106
|
+
continue;
|
|
107
|
+
lines.push('');
|
|
108
|
+
lines.push(result.filePath);
|
|
109
|
+
for (const msg of result.messages) {
|
|
110
|
+
const severity = msg.severity === 'error' ? '\x1b[31merror\x1b[0m' : '\x1b[33mwarning\x1b[0m';
|
|
111
|
+
const location = `${msg.line}:${msg.column}`;
|
|
112
|
+
lines.push(` ${location.padEnd(8)} ${severity.padEnd(17)} ${msg.message} \x1b[90m${msg.ruleId}\x1b[0m`);
|
|
113
|
+
}
|
|
114
|
+
totalErrors += result.errorCount;
|
|
115
|
+
totalWarnings += result.warningCount;
|
|
116
|
+
}
|
|
117
|
+
if (totalErrors > 0 || totalWarnings > 0) {
|
|
118
|
+
lines.push('');
|
|
119
|
+
const summary = [];
|
|
120
|
+
if (totalErrors > 0)
|
|
121
|
+
summary.push(`${totalErrors} error${totalErrors === 1 ? '' : 's'}`);
|
|
122
|
+
if (totalWarnings > 0)
|
|
123
|
+
summary.push(`${totalWarnings} warning${totalWarnings === 1 ? '' : 's'}`);
|
|
124
|
+
lines.push(`\x1b[1m${summary.join(', ')}\x1b[0m`);
|
|
125
|
+
}
|
|
126
|
+
return lines.join('\n');
|
|
127
|
+
}
|
|
128
|
+
function formatCompact(results) {
|
|
129
|
+
const lines = [];
|
|
130
|
+
for (const result of results) {
|
|
131
|
+
for (const msg of result.messages) {
|
|
132
|
+
lines.push(`${result.filePath}:${msg.line}:${msg.column}: ${msg.severity}: ${msg.message} [${msg.ruleId}]`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return lines.join('\n');
|
|
136
|
+
}
|
|
137
|
+
function formatJson(results) {
|
|
138
|
+
const sanitized = results.map(({ source, output, ...rest }) => rest);
|
|
139
|
+
return JSON.stringify(sanitized, null, 2);
|
|
140
|
+
}
|
|
141
|
+
async function runLint(files, options) {
|
|
142
|
+
const cwd = process.cwd();
|
|
143
|
+
const configPath = options.config || cwd;
|
|
144
|
+
const { linter: linterConfig, ignore } = await loadConfig(configPath);
|
|
145
|
+
const targetFiles = files.length > 0 ? files : ['.'];
|
|
146
|
+
const filePaths = findFiles(targetFiles, ignore);
|
|
147
|
+
if (filePaths.length === 0) {
|
|
148
|
+
console.log('No .gt files found');
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
const linter = new Linter(linterConfig);
|
|
152
|
+
const results = [];
|
|
153
|
+
for (const filePath of filePaths) {
|
|
154
|
+
const source = readFileSync(filePath, 'utf-8');
|
|
155
|
+
const relativePath = relative(cwd, filePath);
|
|
156
|
+
const result = linter.lint(source, relativePath);
|
|
157
|
+
results.push(result);
|
|
158
|
+
}
|
|
159
|
+
// Filter warnings if quiet mode
|
|
160
|
+
if (options.quiet) {
|
|
161
|
+
for (const result of results) {
|
|
162
|
+
result.messages = result.messages.filter(m => m.severity === 'error');
|
|
163
|
+
result.warningCount = 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Format output
|
|
167
|
+
let output;
|
|
168
|
+
switch (options.format) {
|
|
169
|
+
case 'json':
|
|
170
|
+
output = formatJson(results);
|
|
171
|
+
break;
|
|
172
|
+
case 'compact':
|
|
173
|
+
output = formatCompact(results);
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
output = formatStylish(results);
|
|
177
|
+
}
|
|
178
|
+
if (output.trim()) {
|
|
179
|
+
console.log(output);
|
|
180
|
+
}
|
|
181
|
+
// Return exit code
|
|
182
|
+
const hasErrors = results.some(r => r.errorCount > 0);
|
|
183
|
+
return hasErrors ? 1 : 0;
|
|
184
|
+
}
|
|
185
|
+
async function runFormat(files, options) {
|
|
186
|
+
const cwd = process.cwd();
|
|
187
|
+
const configPath = options.config || cwd;
|
|
188
|
+
const { formatter: formatterConfig, ignore } = await loadConfig(configPath);
|
|
189
|
+
const targetFiles = files.length > 0 ? files : ['.'];
|
|
190
|
+
const filePaths = findFiles(targetFiles, ignore);
|
|
191
|
+
if (filePaths.length === 0) {
|
|
192
|
+
console.log('No .gt files found');
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
const formatter = new Formatter(formatterConfig);
|
|
196
|
+
let changedCount = 0;
|
|
197
|
+
for (const filePath of filePaths) {
|
|
198
|
+
const source = readFileSync(filePath, 'utf-8');
|
|
199
|
+
const formatted = formatter.format(source);
|
|
200
|
+
const relativePath = relative(cwd, filePath);
|
|
201
|
+
if (options.write) {
|
|
202
|
+
if (source !== formatted) {
|
|
203
|
+
writeFileSync(filePath, formatted, 'utf-8');
|
|
204
|
+
changedCount++;
|
|
205
|
+
console.log(`Formatted: ${relativePath}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
process.stdout.write(formatted);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (options.write && changedCount === 0) {
|
|
213
|
+
console.log('All files are already properly formatted');
|
|
214
|
+
}
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
export async function main(args = process.argv.slice(2)) {
|
|
218
|
+
const { command, files, options } = parseArgs(args);
|
|
219
|
+
if (options.help || (!command && !options.version)) {
|
|
220
|
+
printHelp();
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
if (options.version) {
|
|
224
|
+
printVersion();
|
|
225
|
+
process.exit(0);
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
let exitCode = 0;
|
|
229
|
+
switch (command) {
|
|
230
|
+
case 'lint':
|
|
231
|
+
exitCode = await runLint(files, options);
|
|
232
|
+
break;
|
|
233
|
+
case 'format':
|
|
234
|
+
exitCode = await runFormat(files, options);
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
console.error(`Unknown command: ${command}`);
|
|
238
|
+
printHelp();
|
|
239
|
+
exitCode = 1;
|
|
240
|
+
}
|
|
241
|
+
process.exit(exitCode);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { LinterConfig, FormatterConfig } from './types.js';
|
|
2
|
+
export interface GTLintConfig {
|
|
3
|
+
rules?: LinterConfig['rules'];
|
|
4
|
+
format?: Partial<FormatterConfig>;
|
|
5
|
+
ignore?: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Find a config file by searching up the directory tree
|
|
9
|
+
*/
|
|
10
|
+
export declare function findConfigFile(startDir: string): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Load a config file
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfigFile(configPath: string): Promise<GTLintConfig>;
|
|
15
|
+
/**
|
|
16
|
+
* Merge user config with defaults
|
|
17
|
+
*/
|
|
18
|
+
export declare function mergeConfig(userConfig: GTLintConfig): {
|
|
19
|
+
linter: LinterConfig;
|
|
20
|
+
formatter: FormatterConfig;
|
|
21
|
+
ignore: string[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Load config from a directory or specific file path
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadConfig(pathOrDir: string): Promise<{
|
|
27
|
+
linter: LinterConfig;
|
|
28
|
+
formatter: FormatterConfig;
|
|
29
|
+
ignore: string[];
|
|
30
|
+
configPath: string | null;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA4BhE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAOD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyB9D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAQ9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,YAAY,GAAG;IACrD,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAqBA;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3D,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAyBD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { resolve, dirname } from 'path';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
4
|
+
import { DEFAULT_LINTER_CONFIG, DEFAULT_FORMATTER_CONFIG } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Convert camelCase to kebab-case (e.g., noUnusedVars → no-unused-vars).
|
|
7
|
+
* Strings that are already kebab-case pass through unchanged.
|
|
8
|
+
*/
|
|
9
|
+
function camelToKebab(str) {
|
|
10
|
+
return str.replace(/[A-Z]/g, m => '-' + m.toLowerCase());
|
|
11
|
+
}
|
|
12
|
+
function normalizeRuleKeys(rules) {
|
|
13
|
+
const normalized = {};
|
|
14
|
+
for (const [key, value] of Object.entries(rules)) {
|
|
15
|
+
normalized[camelToKebab(key)] = value;
|
|
16
|
+
}
|
|
17
|
+
return normalized;
|
|
18
|
+
}
|
|
19
|
+
const CONFIG_FILENAMES = [
|
|
20
|
+
'gtlint.config.js',
|
|
21
|
+
'gtlint.config.mjs',
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Find a config file by searching up the directory tree
|
|
25
|
+
*/
|
|
26
|
+
export function findConfigFile(startDir) {
|
|
27
|
+
let currentDir = resolve(startDir);
|
|
28
|
+
const root = dirname(currentDir);
|
|
29
|
+
while (currentDir !== root) {
|
|
30
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
31
|
+
const configPath = resolve(currentDir, filename);
|
|
32
|
+
if (existsSync(configPath)) {
|
|
33
|
+
return configPath;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const parentDir = dirname(currentDir);
|
|
37
|
+
if (parentDir === currentDir)
|
|
38
|
+
break;
|
|
39
|
+
currentDir = parentDir;
|
|
40
|
+
}
|
|
41
|
+
// Check root directory
|
|
42
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
43
|
+
const configPath = resolve(currentDir, filename);
|
|
44
|
+
if (existsSync(configPath)) {
|
|
45
|
+
return configPath;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load a config file
|
|
52
|
+
*/
|
|
53
|
+
export async function loadConfigFile(configPath) {
|
|
54
|
+
try {
|
|
55
|
+
const fileUrl = pathToFileURL(resolve(configPath)).href;
|
|
56
|
+
const module = await import(fileUrl);
|
|
57
|
+
return module.default || module;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`Failed to load config file: ${configPath}\n${error}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Merge user config with defaults
|
|
65
|
+
*/
|
|
66
|
+
export function mergeConfig(userConfig) {
|
|
67
|
+
const linterConfig = {
|
|
68
|
+
...DEFAULT_LINTER_CONFIG,
|
|
69
|
+
rules: {
|
|
70
|
+
...DEFAULT_LINTER_CONFIG.rules,
|
|
71
|
+
...(userConfig.rules ? normalizeRuleKeys(userConfig.rules) : {}),
|
|
72
|
+
},
|
|
73
|
+
format: {
|
|
74
|
+
...DEFAULT_LINTER_CONFIG.format,
|
|
75
|
+
...userConfig.format,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
const formatterConfig = {
|
|
79
|
+
...DEFAULT_FORMATTER_CONFIG,
|
|
80
|
+
...userConfig.format,
|
|
81
|
+
};
|
|
82
|
+
const ignore = userConfig.ignore || ['**/node_modules/**', '**/dist/**'];
|
|
83
|
+
return { linter: linterConfig, formatter: formatterConfig, ignore };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Load config from a directory or specific file path
|
|
87
|
+
*/
|
|
88
|
+
export async function loadConfig(pathOrDir) {
|
|
89
|
+
let configPath = null;
|
|
90
|
+
// If path points to a config file, use it directly
|
|
91
|
+
if (pathOrDir.endsWith('.js') || pathOrDir.endsWith('.mjs')) {
|
|
92
|
+
if (existsSync(pathOrDir)) {
|
|
93
|
+
configPath = pathOrDir;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Search for config file
|
|
98
|
+
configPath = findConfigFile(pathOrDir);
|
|
99
|
+
}
|
|
100
|
+
if (configPath) {
|
|
101
|
+
const userConfig = await loadConfigFile(configPath);
|
|
102
|
+
return { ...mergeConfig(userConfig), configPath };
|
|
103
|
+
}
|
|
104
|
+
// No config file found, use defaults
|
|
105
|
+
return {
|
|
106
|
+
linter: DEFAULT_LINTER_CONFIG,
|
|
107
|
+
formatter: DEFAULT_FORMATTER_CONFIG,
|
|
108
|
+
ignore: ['**/node_modules/**', '**/dist/**'],
|
|
109
|
+
configPath: null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=config.js.map
|