cc-vscode-shebang-markdown 0.1.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/CHANGELOG.md +28 -0
- package/CONTRIBUTING.md +27 -0
- package/LICENSE +20 -0
- package/README.md +337 -0
- package/README_IT.md +96 -0
- package/SECURITY.md +20 -0
- package/extension.js +221 -0
- package/package.json +149 -0
- package/scripts/cc-install-local.sh +19 -0
- package/scripts/cc-npm-bump.sh +81 -0
- package/scripts/cc-npm-publish.sh +134 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
Initial public release.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Custom shebang detection on the first line.
|
|
10
|
+
- Automatic language mode switch to Markdown.
|
|
11
|
+
- Configurable detection pattern.
|
|
12
|
+
- Configurable target language id.
|
|
13
|
+
- Local VSIX packaging scripts.
|
|
14
|
+
- npm package metadata and documentation.
|
|
15
|
+
|
|
16
|
+
## 0.1.1
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- POSIX shell shebang fallback for `bash`, `zsh` and `sh`.
|
|
21
|
+
- Support for `/bin/*`, `/usr/bin/*`, `/usr/local/bin/*` and `/usr/bin/env` shebang variants.
|
|
22
|
+
- Support for `/usr/bin/env -S bash ...` style shebangs.
|
|
23
|
+
- Fallback detection for `nginx.conf` and `conf.d/*.conf`.
|
|
24
|
+
- Content-based nginx fallback for common nginx blocks.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Removed `.vscodeignore` because VSCE does not support using `.vscodeignore` together with the `files` property in `package.json`.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions are welcome.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run pack:vsix
|
|
10
|
+
npm run reinstall
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Before opening a pull request
|
|
14
|
+
|
|
15
|
+
Please check:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run pack:npm
|
|
19
|
+
npm run pack:vsix
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Guidelines
|
|
23
|
+
|
|
24
|
+
- Keep the extension small.
|
|
25
|
+
- Avoid project-specific hardcoding.
|
|
26
|
+
- Preserve the configurable shebang pattern.
|
|
27
|
+
- Document behavior changes in `CHANGELOG.md`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CodeCorn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files, to deal in the Software
|
|
7
|
+
without restriction, including without limitation the rights to use, copy,
|
|
8
|
+
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
9
|
+
Software, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# CodeCorn Shebang Markdown
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/cc-vscode-shebang-markdown)
|
|
4
|
+
[](https://www.npmjs.com/package/cc-vscode-shebang-markdown)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://code.visualstudio.com/)
|
|
7
|
+
|
|
8
|
+
**CodeCorn Shebang Markdown** is a tiny Visual Studio Code extension that detects a custom shebang on the first line of a file and switches the editor language mode to Markdown.
|
|
9
|
+
|
|
10
|
+
It is designed for workflows where Markdown-like operational files, scripts, notes or generated artifacts do not use the `.md` extension, but still need to be handled as Markdown by VS Code, markdownlint, formatters and language-aware tooling.
|
|
11
|
+
|
|
12
|
+
Italian documentation: [README_IT.md](README_IT.md)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Why
|
|
17
|
+
|
|
18
|
+
VS Code file associations are path/name based. They are great when a file extension or filename is predictable, but they do not inspect the first line of a document.
|
|
19
|
+
|
|
20
|
+
This extension fills that gap with a small content-based rule:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
first line contains a CodeCorn Markdown shebang
|
|
24
|
+
→ switch document language mode to markdown
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
#!/usr/bin/env cc-md
|
|
31
|
+
|
|
32
|
+
# Deployment checklist
|
|
33
|
+
|
|
34
|
+
- backup database
|
|
35
|
+
- dump environment
|
|
36
|
+
- apply patch
|
|
37
|
+
- verify logs
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Even if the file has no `.md` extension, VS Code will treat it as Markdown.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- Detects custom Markdown shebangs on the first line.
|
|
47
|
+
- Forces VS Code language mode to `markdown`.
|
|
48
|
+
- Works with untitled files, extensionless files and script-like notes.
|
|
49
|
+
- Configurable regex pattern.
|
|
50
|
+
- Configurable target VS Code language id.
|
|
51
|
+
- Useful with `markdownlint`, Markdown formatters and editor tooling.
|
|
52
|
+
- No runtime dependencies.
|
|
53
|
+
- Minimal extension footprint.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Default shebangs
|
|
58
|
+
|
|
59
|
+
The default pattern is:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
^#!.*\bcc-(md|markdown)\b
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Supported examples:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
#!/usr/bin/env cc-md
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
#!cc-md
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
#!/usr/bin/env cc-markdown
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
#!cc-markdown
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Installation
|
|
86
|
+
|
|
87
|
+
### Local VSIX install
|
|
88
|
+
|
|
89
|
+
This package is primarily a VS Code extension. For local development or internal usage:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm install
|
|
93
|
+
npm run reinstall
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This builds the `.vsix` package and installs it in VS Code.
|
|
97
|
+
|
|
98
|
+
### npm package
|
|
99
|
+
|
|
100
|
+
The package is also published on npm for traceability, reuse and source distribution:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm install cc-vscode-shebang-markdown
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Installing from npm does not automatically install the extension into VS Code. For actual editor installation, use a generated `.vsix` file or publish the extension to the Visual Studio Code Marketplace.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Usage
|
|
111
|
+
|
|
112
|
+
Create or open any file whose first line matches the configured shebang pattern:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
#!/usr/bin/env cc-md
|
|
116
|
+
|
|
117
|
+
# Server audit
|
|
118
|
+
|
|
119
|
+
## Build log
|
|
120
|
+
|
|
121
|
+
- collect build output
|
|
122
|
+
- inspect warnings
|
|
123
|
+
- normalize report
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
When the document opens, the extension switches its language mode to:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
markdown
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
You can verify this in the bottom-right language selector in VS Code.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Configuration
|
|
137
|
+
|
|
138
|
+
### `ccShebangMarkdown.pattern`
|
|
139
|
+
|
|
140
|
+
Regex applied to the first line of the document.
|
|
141
|
+
|
|
142
|
+
Default:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"ccShebangMarkdown.pattern": "^#!.*\\bcc-(md|markdown)\\b"
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `ccShebangMarkdown.targetLanguage`
|
|
151
|
+
|
|
152
|
+
VS Code language id to apply when the pattern matches.
|
|
153
|
+
|
|
154
|
+
Default:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"ccShebangMarkdown.targetLanguage": "markdown"
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Advanced example:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"ccShebangMarkdown.pattern": "^#!.*\\bcompany-doc\\b",
|
|
167
|
+
"ccShebangMarkdown.targetLanguage": "markdown"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## markdownlint note
|
|
174
|
+
|
|
175
|
+
Some lint configurations require the first line of a Markdown document to be a heading. A shebang intentionally violates that rule.
|
|
176
|
+
|
|
177
|
+
For shebang-based Markdown files, you may want to disable `MD041`:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"markdownlint.config": {
|
|
182
|
+
"MD041": false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
Clone the repository and install dependencies:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm install
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Package the VS Code extension:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npm run pack:vsix
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Install it locally:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm run reinstall
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Check npm package contents before publishing:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm run pack:npm
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Release flow
|
|
218
|
+
|
|
219
|
+
Bump the version in `package.json`, then run:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm install
|
|
223
|
+
npm run pack:vsix
|
|
224
|
+
npm run pack:npm
|
|
225
|
+
npm publish
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
For scoped npm packages, npm requires public scoped packages to be published with `npm publish --access public`. This package is intentionally unscoped, so plain `npm publish` is enough.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Design principles
|
|
233
|
+
|
|
234
|
+
- Do one thing.
|
|
235
|
+
- Avoid filename conventions when the contract belongs in the file content.
|
|
236
|
+
- Keep the rule explicit and visible.
|
|
237
|
+
- Do not hijack unrelated files.
|
|
238
|
+
- Prefer configurable detection over hardcoded project paths.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Security
|
|
243
|
+
|
|
244
|
+
This extension only reads the first line of open text documents and changes VS Code language mode through the VS Code API.
|
|
245
|
+
|
|
246
|
+
It does not:
|
|
247
|
+
|
|
248
|
+
- execute file contents;
|
|
249
|
+
- send telemetry;
|
|
250
|
+
- perform network requests;
|
|
251
|
+
- read secrets;
|
|
252
|
+
- modify files on disk.
|
|
253
|
+
|
|
254
|
+
Please report security issues privately when possible. See [SECURITY.md](SECURITY.md).
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Contributing
|
|
259
|
+
|
|
260
|
+
Issues and pull requests are welcome.
|
|
261
|
+
|
|
262
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT. See [LICENSE](LICENSE).
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Maintainer
|
|
273
|
+
|
|
274
|
+
Built and maintained by **Federico Girolami** / **CodeCorn Technology**.
|
|
275
|
+
|
|
276
|
+
CodeCorn™ — We build software that Corn.
|
|
277
|
+
|
|
278
|
+
## Language fallback rules
|
|
279
|
+
|
|
280
|
+
Besides CodeCorn Markdown shebangs, the extension also ships with defensive fallback rules for common script/config files.
|
|
281
|
+
|
|
282
|
+
### Shell scripts
|
|
283
|
+
|
|
284
|
+
The extension reinforces VS Code detection for:
|
|
285
|
+
|
|
286
|
+
```text
|
|
287
|
+
#!/bin/bash
|
|
288
|
+
#!/bin/zsh
|
|
289
|
+
#!/bin/sh
|
|
290
|
+
#!/usr/bin/bash
|
|
291
|
+
#!/usr/bin/zsh
|
|
292
|
+
#!/usr/bin/sh
|
|
293
|
+
#!/usr/local/bin/bash
|
|
294
|
+
#!/usr/bin/env bash
|
|
295
|
+
#!/usr/bin/env zsh
|
|
296
|
+
#!/usr/bin/env sh
|
|
297
|
+
#!/usr/bin/env -S bash -euo pipefail
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Matching files are switched to:
|
|
301
|
+
|
|
302
|
+
```text
|
|
303
|
+
shellscript
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### nginx
|
|
307
|
+
|
|
308
|
+
The extension includes a defensive fallback for:
|
|
309
|
+
|
|
310
|
+
```text
|
|
311
|
+
nginx.conf
|
|
312
|
+
conf.d/*.conf
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
and for files containing common nginx blocks near the top:
|
|
316
|
+
|
|
317
|
+
```nginx
|
|
318
|
+
events {
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
http {
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
server {
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
upstream backend {
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Matching files are switched to:
|
|
332
|
+
|
|
333
|
+
```text
|
|
334
|
+
nginx
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
If the `nginx` language id is not available in the current VS Code installation, the rule falls back to `plaintext` instead of throwing.
|
package/README_IT.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# CodeCorn Shebang Markdown
|
|
2
|
+
|
|
3
|
+
**CodeCorn Shebang Markdown** è una piccola estensione per Visual Studio Code che legge la prima riga di un file e, se trova uno shebang configurato, forza il language mode a Markdown.
|
|
4
|
+
|
|
5
|
+
Serve quando hai file senza estensione `.md`, oppure file operativi/script-like, che devono comunque essere trattati come Markdown da VS Code, markdownlint e formatter.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Esempio
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
#!/usr/bin/env cc-md
|
|
13
|
+
|
|
14
|
+
# Checklist deploy
|
|
15
|
+
|
|
16
|
+
- backup database
|
|
17
|
+
- dump env
|
|
18
|
+
- patch
|
|
19
|
+
- verifica log
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Anche senza estensione `.md`, VS Code imposta il file come `markdown`.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Shebang supportati
|
|
27
|
+
|
|
28
|
+
Pattern default:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
^#!.*\bcc-(md|markdown)\b
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Esempi:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
#!/usr/bin/env cc-md
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
#!cc-md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
#!/usr/bin/env cc-markdown
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Configurazione
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"ccShebangMarkdown.pattern": "^#!.*\\bcc-(md|markdown)\\b",
|
|
55
|
+
"ccShebangMarkdown.targetLanguage": "markdown"
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Nota markdownlint
|
|
62
|
+
|
|
63
|
+
Se `markdownlint` segnala che la prima riga non è un heading, puoi disattivare `MD041` per questo workflow:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"markdownlint.config": {
|
|
68
|
+
"MD041": false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Installazione locale
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install
|
|
79
|
+
npm run reinstall
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Questo genera il `.vsix` e lo installa in VS Code.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Licenza
|
|
87
|
+
|
|
88
|
+
MIT.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Maintainer
|
|
93
|
+
|
|
94
|
+
Federico Girolami / CodeCorn Technology.
|
|
95
|
+
|
|
96
|
+
CodeCorn™ — We build software that Corn.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes are provided for the latest published version.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Please report security issues privately when possible.
|
|
10
|
+
|
|
11
|
+
Contact:
|
|
12
|
+
|
|
13
|
+
- Federico Girolami
|
|
14
|
+
- f.girolami@codecorn.it
|
|
15
|
+
|
|
16
|
+
## Security model
|
|
17
|
+
|
|
18
|
+
This extension only reads the first line of open text documents and changes the VS Code language mode when the configured pattern matches.
|
|
19
|
+
|
|
20
|
+
It does not execute file contents, send telemetry, perform network requests or modify files on disk.
|
package/extension.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
const vscode = require('vscode');
|
|
2
|
+
|
|
3
|
+
const applying = new WeakSet();
|
|
4
|
+
|
|
5
|
+
const DEFAULT_RULES = [
|
|
6
|
+
{
|
|
7
|
+
name: 'CodeCorn Markdown shebang',
|
|
8
|
+
when: 'firstLine',
|
|
9
|
+
pattern: '^#!.*\\bcc-(md|markdown)\\b',
|
|
10
|
+
language: 'markdown'
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'POSIX shell shebang',
|
|
14
|
+
when: 'firstLine',
|
|
15
|
+
pattern: '^#!\\s*(?:/(?:usr/)?(?:local/)?bin/(?:bash|zsh|sh)\\b|/usr/bin/env\\s+(?:-[^\\s]+\\s+)*(?:bash|zsh|sh)\\b|/bin/env\\s+(?:-[^\\s]+\\s+)*(?:bash|zsh|sh)\\b)',
|
|
16
|
+
language: 'shellscript'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'nginx.conf path',
|
|
20
|
+
when: 'path',
|
|
21
|
+
pattern: '(?:^|[/\\\\])nginx\\.conf$|(?:^|[/\\\\])conf\\.d[/\\\\].*\\.conf$',
|
|
22
|
+
language: 'nginx',
|
|
23
|
+
fallbackLanguage: 'plaintext'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'nginx content fallback',
|
|
27
|
+
when: 'content',
|
|
28
|
+
pattern: '(?m)^\\s*(events|http|server|upstream)\\s*\\{|^\\s*location\\s+[^\\n]+\\{',
|
|
29
|
+
language: 'nginx',
|
|
30
|
+
fallbackLanguage: 'plaintext'
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
function compileRule(rule) {
|
|
35
|
+
if (!rule || typeof rule !== 'object') return null;
|
|
36
|
+
if (!rule.pattern || !rule.language) return null;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
return {
|
|
40
|
+
name: String(rule.name || rule.language),
|
|
41
|
+
when: String(rule.when || 'firstLine'),
|
|
42
|
+
pattern: new RegExp(String(rule.pattern)),
|
|
43
|
+
language: String(rule.language),
|
|
44
|
+
fallbackLanguage: rule.fallbackLanguage ? String(rule.fallbackLanguage) : ''
|
|
45
|
+
};
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.warn('[cc-shebang-markdown] Invalid rule regex:', rule, err);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readRules() {
|
|
53
|
+
const cfg = vscode.workspace.getConfiguration();
|
|
54
|
+
|
|
55
|
+
const legacyPattern = cfg.get(
|
|
56
|
+
'ccShebangMarkdown.pattern',
|
|
57
|
+
'^#!.*\\bcc-(md|markdown)\\b'
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const legacyTargetLanguage = cfg.get(
|
|
61
|
+
'ccShebangMarkdown.targetLanguage',
|
|
62
|
+
'markdown'
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const configuredRules = cfg.get('ccShebangMarkdown.rules', DEFAULT_RULES);
|
|
66
|
+
|
|
67
|
+
const rules = Array.isArray(configuredRules) && configuredRules.length > 0
|
|
68
|
+
? configuredRules
|
|
69
|
+
: DEFAULT_RULES;
|
|
70
|
+
|
|
71
|
+
const compiled = rules
|
|
72
|
+
.map(compileRule)
|
|
73
|
+
.filter(Boolean);
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
* Backward compatibility:
|
|
77
|
+
* old config keys still work and remain first priority.
|
|
78
|
+
*/
|
|
79
|
+
const legacyRule = compileRule({
|
|
80
|
+
name: 'legacy ccShebangMarkdown.pattern',
|
|
81
|
+
when: 'firstLine',
|
|
82
|
+
pattern: legacyPattern,
|
|
83
|
+
language: legacyTargetLanguage
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return [
|
|
87
|
+
legacyRule,
|
|
88
|
+
...compiled
|
|
89
|
+
].filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getProbeText(document) {
|
|
93
|
+
if (!document || document.lineCount < 1) return '';
|
|
94
|
+
|
|
95
|
+
const endLine = Math.min(document.lineCount, 80);
|
|
96
|
+
const endCharacter = endLine > 0 ? document.lineAt(endLine - 1).text.length : 0;
|
|
97
|
+
|
|
98
|
+
return document.getText(
|
|
99
|
+
new vscode.Range(0, 0, Math.max(0, endLine - 1), endCharacter)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function matchesRule(document, rule) {
|
|
104
|
+
if (!document || !rule) return false;
|
|
105
|
+
|
|
106
|
+
if (rule.when === 'path') {
|
|
107
|
+
const path = document.uri && document.uri.fsPath
|
|
108
|
+
? document.uri.fsPath
|
|
109
|
+
: document.fileName || '';
|
|
110
|
+
|
|
111
|
+
return rule.pattern.test(path);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (rule.when === 'content') {
|
|
115
|
+
return rule.pattern.test(getProbeText(document));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const firstLine = document.lineCount > 0
|
|
119
|
+
? document.lineAt(0).text
|
|
120
|
+
: '';
|
|
121
|
+
|
|
122
|
+
return rule.pattern.test(firstLine);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function resolveLanguage(rule) {
|
|
126
|
+
const available = await vscode.languages.getLanguages();
|
|
127
|
+
|
|
128
|
+
if (available.includes(rule.language)) {
|
|
129
|
+
return rule.language;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (rule.fallbackLanguage && available.includes(rule.fallbackLanguage)) {
|
|
133
|
+
console.warn(
|
|
134
|
+
`[cc-shebang-markdown] Language "${rule.language}" unavailable, using fallback "${rule.fallbackLanguage}" for rule "${rule.name}".`
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return rule.fallbackLanguage;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.warn(
|
|
141
|
+
`[cc-shebang-markdown] Language "${rule.language}" unavailable for rule "${rule.name}".`
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return '';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function maybeForceLanguage(document) {
|
|
148
|
+
if (!document || document.isClosed) return;
|
|
149
|
+
if (document.lineCount < 1) return;
|
|
150
|
+
if (applying.has(document)) return;
|
|
151
|
+
|
|
152
|
+
const rules = readRules();
|
|
153
|
+
const matchedRule = rules.find((rule) => matchesRule(document, rule));
|
|
154
|
+
|
|
155
|
+
if (!matchedRule) return;
|
|
156
|
+
|
|
157
|
+
const targetLanguage = await resolveLanguage(matchedRule);
|
|
158
|
+
|
|
159
|
+
if (!targetLanguage) return;
|
|
160
|
+
if (document.languageId === targetLanguage) return;
|
|
161
|
+
|
|
162
|
+
applying.add(document);
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
await vscode.languages.setTextDocumentLanguage(document, targetLanguage);
|
|
166
|
+
console.info(
|
|
167
|
+
`[cc-shebang-markdown] Applied "${targetLanguage}" via rule "${matchedRule.name}".`
|
|
168
|
+
);
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.warn(
|
|
171
|
+
'[cc-shebang-markdown] Could not change language mode:',
|
|
172
|
+
err
|
|
173
|
+
);
|
|
174
|
+
} finally {
|
|
175
|
+
applying.delete(document);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function activate(context) {
|
|
180
|
+
for (const document of vscode.workspace.textDocuments) {
|
|
181
|
+
maybeForceLanguage(document);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
context.subscriptions.push(
|
|
185
|
+
vscode.workspace.onDidOpenTextDocument((document) => {
|
|
186
|
+
maybeForceLanguage(document);
|
|
187
|
+
}),
|
|
188
|
+
|
|
189
|
+
vscode.workspace.onDidChangeTextDocument((event) => {
|
|
190
|
+
const touchesFirstLine = event.contentChanges.some((change) => {
|
|
191
|
+
return change.range.start.line === 0 || change.range.end.line === 0;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* For content-based fallbacks, also retry on early document edits.
|
|
196
|
+
*/
|
|
197
|
+
const touchesProbeArea = event.contentChanges.some((change) => {
|
|
198
|
+
return change.range.start.line < 80 || change.range.end.line < 80;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (touchesFirstLine || touchesProbeArea) {
|
|
202
|
+
maybeForceLanguage(event.document);
|
|
203
|
+
}
|
|
204
|
+
}),
|
|
205
|
+
|
|
206
|
+
vscode.workspace.onDidChangeConfiguration((event) => {
|
|
207
|
+
if (!event.affectsConfiguration('ccShebangMarkdown')) return;
|
|
208
|
+
|
|
209
|
+
for (const document of vscode.workspace.textDocuments) {
|
|
210
|
+
maybeForceLanguage(document);
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function deactivate() {}
|
|
217
|
+
|
|
218
|
+
module.exports = {
|
|
219
|
+
activate,
|
|
220
|
+
deactivate
|
|
221
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-vscode-shebang-markdown",
|
|
3
|
+
"displayName": "CodeCorn Shebang Markdown",
|
|
4
|
+
"description": "VS Code extension that detects custom shebangs and file fallbacks to switch language mode for linters.",
|
|
5
|
+
"version": "0.1.1",
|
|
6
|
+
"publisher": "codecorn",
|
|
7
|
+
"engines": {
|
|
8
|
+
"vscode": "^1.80.0"
|
|
9
|
+
},
|
|
10
|
+
"categories": [
|
|
11
|
+
"Linters",
|
|
12
|
+
"Other"
|
|
13
|
+
],
|
|
14
|
+
"activationEvents": [
|
|
15
|
+
"onStartupFinished",
|
|
16
|
+
"onLanguage:plaintext",
|
|
17
|
+
"onLanguage:shellscript"
|
|
18
|
+
],
|
|
19
|
+
"main": "./extension.js",
|
|
20
|
+
"contributes": {
|
|
21
|
+
"configuration": {
|
|
22
|
+
"title": "CodeCorn Shebang Markdown",
|
|
23
|
+
"properties": {
|
|
24
|
+
"ccShebangMarkdown.pattern": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"default": "^#!.*\\\\bcc-(md|markdown)\\\\b",
|
|
27
|
+
"description": "Legacy regex applicata alla prima riga. Se matcha, viene applicato ccShebangMarkdown.targetLanguage."
|
|
28
|
+
},
|
|
29
|
+
"ccShebangMarkdown.targetLanguage": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"default": "markdown",
|
|
32
|
+
"description": "Legacy VS Code language id da applicare quando ccShebangMarkdown.pattern matcha."
|
|
33
|
+
},
|
|
34
|
+
"ccShebangMarkdown.rules": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"description": "Regole ordinate per forzare il language mode in base a firstLine, path o content.",
|
|
37
|
+
"default": [
|
|
38
|
+
{
|
|
39
|
+
"name": "CodeCorn Markdown shebang",
|
|
40
|
+
"when": "firstLine",
|
|
41
|
+
"pattern": "^#!.*\\\\bcc-(md|markdown)\\\\b",
|
|
42
|
+
"language": "markdown"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "POSIX shell shebang",
|
|
46
|
+
"when": "firstLine",
|
|
47
|
+
"pattern": "^#!\\\\s*(?:/(?:usr/)?(?:local/)?bin/(?:bash|zsh|sh)\\\\b|/usr/bin/env\\\\s+(?:-[^\\\\s]+\\\\s+)*(?:bash|zsh|sh)\\\\b|/bin/env\\\\s+(?:-[^\\\\s]+\\\\s+)*(?:bash|zsh|sh)\\\\b)",
|
|
48
|
+
"language": "shellscript"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "nginx.conf path",
|
|
52
|
+
"when": "path",
|
|
53
|
+
"pattern": "(?:^|[/\\\\\\\\])nginx\\\\.conf$|(?:^|[/\\\\\\\\])conf\\\\.d[/\\\\\\\\].*\\\\.conf$",
|
|
54
|
+
"language": "nginx",
|
|
55
|
+
"fallbackLanguage": "plaintext"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "nginx content fallback",
|
|
59
|
+
"when": "content",
|
|
60
|
+
"pattern": "(?m)^\\\\s*(events|http|server|upstream)\\\\s*\\\\{|^\\\\s*location\\\\s+[^\\\\n]+\\\\{",
|
|
61
|
+
"language": "nginx",
|
|
62
|
+
"fallbackLanguage": "plaintext"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"required": [
|
|
68
|
+
"pattern",
|
|
69
|
+
"language"
|
|
70
|
+
],
|
|
71
|
+
"properties": {
|
|
72
|
+
"name": {
|
|
73
|
+
"type": "string"
|
|
74
|
+
},
|
|
75
|
+
"when": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"enum": [
|
|
78
|
+
"firstLine",
|
|
79
|
+
"path",
|
|
80
|
+
"content"
|
|
81
|
+
],
|
|
82
|
+
"default": "firstLine"
|
|
83
|
+
},
|
|
84
|
+
"pattern": {
|
|
85
|
+
"type": "string"
|
|
86
|
+
},
|
|
87
|
+
"language": {
|
|
88
|
+
"type": "string"
|
|
89
|
+
},
|
|
90
|
+
"fallbackLanguage": {
|
|
91
|
+
"type": "string"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"scripts": {
|
|
100
|
+
"build": "npm run pack:vsix",
|
|
101
|
+
"package": "vsce package",
|
|
102
|
+
"pack:npm": "npm pack --dry-run",
|
|
103
|
+
"pack:vsix": "vsce package",
|
|
104
|
+
"install:local": "bash scripts/cc-install-local.sh",
|
|
105
|
+
"reinstall": "npm run pack:vsix && npm run install:local",
|
|
106
|
+
"bump": "bash scripts/cc-npm-bump.sh",
|
|
107
|
+
"publish": "bash scripts/cc-npm-publish.sh",
|
|
108
|
+
"prepublishOnly": "npm run pack:npm"
|
|
109
|
+
},
|
|
110
|
+
"repository": {
|
|
111
|
+
"type": "git",
|
|
112
|
+
"url": "git+https://github.com/fgirolami/cc-vscode-shebang-markdown.git"
|
|
113
|
+
},
|
|
114
|
+
"keywords": [
|
|
115
|
+
"vscode",
|
|
116
|
+
"vscode-extension",
|
|
117
|
+
"markdown",
|
|
118
|
+
"shebang",
|
|
119
|
+
"markdownlint",
|
|
120
|
+
"linter",
|
|
121
|
+
"language-detection",
|
|
122
|
+
"language-mode",
|
|
123
|
+
"developer-tools",
|
|
124
|
+
"codecorn"
|
|
125
|
+
],
|
|
126
|
+
"author": {
|
|
127
|
+
"name": "Federico Girolami",
|
|
128
|
+
"email": "f.girolami@codecorn.it",
|
|
129
|
+
"url": "https://codecorn.it"
|
|
130
|
+
},
|
|
131
|
+
"license": "MIT",
|
|
132
|
+
"devDependencies": {
|
|
133
|
+
"@vscode/vsce": "^3.9.2"
|
|
134
|
+
},
|
|
135
|
+
"files": [
|
|
136
|
+
"extension.js",
|
|
137
|
+
"README.md",
|
|
138
|
+
"README_IT.md",
|
|
139
|
+
"CHANGELOG.md",
|
|
140
|
+
"SECURITY.md",
|
|
141
|
+
"CONTRIBUTING.md",
|
|
142
|
+
"LICENSE",
|
|
143
|
+
"package.json",
|
|
144
|
+
"scripts/cc-install-local.sh",
|
|
145
|
+
"scripts/cc-npm-bump.sh",
|
|
146
|
+
"scripts/cc-npm-publish.sh"
|
|
147
|
+
],
|
|
148
|
+
"sideEffects": false
|
|
149
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PKG_NAME="$(node -p "require('./package.json').name")"
|
|
5
|
+
VERSION="$(node -p "require('./package.json').version")"
|
|
6
|
+
VSIX="${PKG_NAME}-${VERSION}.vsix"
|
|
7
|
+
|
|
8
|
+
echo "===== CC LOCAL VSIX INSTALL ====="
|
|
9
|
+
echo "PKG_NAME: $PKG_NAME"
|
|
10
|
+
echo "VERSION: $VERSION"
|
|
11
|
+
echo "VSIX: $VSIX"
|
|
12
|
+
echo
|
|
13
|
+
|
|
14
|
+
if [ ! -f "$VSIX" ]; then
|
|
15
|
+
echo "VSIX non trovato, genero package..."
|
|
16
|
+
npm run pack:vsix
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
code --install-extension "$VSIX" --force
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
BUMP="${1:-patch}"
|
|
5
|
+
NO_COMMIT="${NO_COMMIT:-0}"
|
|
6
|
+
|
|
7
|
+
if [ ! -f package.json ]; then
|
|
8
|
+
echo "ERRORE: package.json non trovato."
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
CURRENT_VERSION="$(node -p "require('./package.json').version")"
|
|
13
|
+
PKG_NAME="$(node -p "require('./package.json').name")"
|
|
14
|
+
|
|
15
|
+
echo "===== CC NPM BUMP ====="
|
|
16
|
+
echo "PKG_NAME: $PKG_NAME"
|
|
17
|
+
echo "CURRENT_VERSION: $CURRENT_VERSION"
|
|
18
|
+
echo "BUMP: $BUMP"
|
|
19
|
+
echo
|
|
20
|
+
|
|
21
|
+
BACKUP_DIR=".cc-backups/npm-bump-$(date +%Y%m%d-%H%M%S)"
|
|
22
|
+
mkdir -p "$BACKUP_DIR"
|
|
23
|
+
cp -p package.json "$BACKUP_DIR/package.json"
|
|
24
|
+
[ -f package-lock.json ] && cp -p package-lock.json "$BACKUP_DIR/package-lock.json"
|
|
25
|
+
|
|
26
|
+
echo "Backup: $BACKUP_DIR"
|
|
27
|
+
echo
|
|
28
|
+
|
|
29
|
+
echo "===== VERSION UPDATE ====="
|
|
30
|
+
npm version "$BUMP" --no-git-tag-version
|
|
31
|
+
|
|
32
|
+
NEW_VERSION="$(node -p "require('./package.json').version")"
|
|
33
|
+
|
|
34
|
+
echo
|
|
35
|
+
echo "===== LOCK REFRESH ====="
|
|
36
|
+
npm install --package-lock-only
|
|
37
|
+
|
|
38
|
+
echo
|
|
39
|
+
echo "===== INSTALL SCRIPT VERSION CHECK ====="
|
|
40
|
+
node <<'NODE'
|
|
41
|
+
const fs = require('fs');
|
|
42
|
+
|
|
43
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
44
|
+
const version = pkg.version;
|
|
45
|
+
const name = pkg.name;
|
|
46
|
+
|
|
47
|
+
if (!pkg.scripts) pkg.scripts = {};
|
|
48
|
+
|
|
49
|
+
pkg.scripts['install:local'] = 'bash scripts/cc-install-local.sh';
|
|
50
|
+
pkg.scripts['reinstall'] = 'npm run pack:vsix && npm run install:local';
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
53
|
+
|
|
54
|
+
console.log(`${name}@${version}`);
|
|
55
|
+
NODE
|
|
56
|
+
|
|
57
|
+
echo
|
|
58
|
+
echo "===== GIT DIFF ====="
|
|
59
|
+
git diff -- package.json package-lock.json || true
|
|
60
|
+
|
|
61
|
+
if [ "$NO_COMMIT" = "1" ]; then
|
|
62
|
+
echo
|
|
63
|
+
echo "NO_COMMIT=1: commit saltato."
|
|
64
|
+
else
|
|
65
|
+
echo
|
|
66
|
+
echo "===== GIT COMMIT ====="
|
|
67
|
+
git add package.json package-lock.json
|
|
68
|
+
|
|
69
|
+
if ! git diff --cached --quiet; then
|
|
70
|
+
git commit -m "chore: bump version to ${NEW_VERSION}"
|
|
71
|
+
else
|
|
72
|
+
echo "Nothing to commit."
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo
|
|
77
|
+
echo "===== DONE ====="
|
|
78
|
+
echo "${PKG_NAME}: ${CURRENT_VERSION} -> ${NEW_VERSION}"
|
|
79
|
+
echo
|
|
80
|
+
echo "Next:"
|
|
81
|
+
echo "npm run publish"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PKG_NAME="${PKG_NAME:-$(node -p "require('./package.json').name")}"
|
|
5
|
+
VERSION="${VERSION:-$(node -p "require('./package.json').version")}"
|
|
6
|
+
REMOTE_NAME="${REMOTE_NAME:-origin}"
|
|
7
|
+
|
|
8
|
+
PUBLISH_NEEDED=1
|
|
9
|
+
PUBLISH_OK=0
|
|
10
|
+
NPM_AUTH_OK=0
|
|
11
|
+
NPM_USER=""
|
|
12
|
+
|
|
13
|
+
echo "===== PACKAGE META ====="
|
|
14
|
+
echo "PKG_NAME: $PKG_NAME"
|
|
15
|
+
echo "VERSION: $VERSION"
|
|
16
|
+
echo
|
|
17
|
+
|
|
18
|
+
echo "===== NPM AUTH CHECK ====="
|
|
19
|
+
if NPM_USER="$(npm whoami 2>/dev/null)"; then
|
|
20
|
+
NPM_AUTH_OK=1
|
|
21
|
+
echo "NPM_USER: $NPM_USER"
|
|
22
|
+
else
|
|
23
|
+
NPM_AUTH_OK=0
|
|
24
|
+
echo "WARN: npm non è loggato oppure la sessione è scaduta."
|
|
25
|
+
echo " Esegui: npm login"
|
|
26
|
+
echo " Publish e tag verranno saltati, ma build/commit continuano."
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo
|
|
30
|
+
echo "===== INSTALL / LOCK REFRESH ====="
|
|
31
|
+
npm install
|
|
32
|
+
|
|
33
|
+
echo
|
|
34
|
+
echo "===== VSIX BUILD ====="
|
|
35
|
+
npm run pack:vsix
|
|
36
|
+
|
|
37
|
+
echo
|
|
38
|
+
echo "===== NPM PACK DRY RUN ====="
|
|
39
|
+
npm run pack:npm
|
|
40
|
+
|
|
41
|
+
echo
|
|
42
|
+
echo "===== NPM VERSION CHECK ====="
|
|
43
|
+
EXISTING_LATEST="$(npm view "$PKG_NAME" version 2>/dev/null || true)"
|
|
44
|
+
EXISTING_THIS_VERSION="$(npm view "${PKG_NAME}@${VERSION}" version 2>/dev/null || true)"
|
|
45
|
+
|
|
46
|
+
if [ -n "$EXISTING_LATEST" ]; then
|
|
47
|
+
echo "Package npm già esistente: $PKG_NAME"
|
|
48
|
+
echo "Latest npm version: $EXISTING_LATEST"
|
|
49
|
+
else
|
|
50
|
+
echo "Package npm non ancora esistente: $PKG_NAME"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [ -n "$EXISTING_THIS_VERSION" ]; then
|
|
54
|
+
echo "Versione già pubblicata su npm: ${PKG_NAME}@${VERSION}"
|
|
55
|
+
echo "Publish non necessario."
|
|
56
|
+
PUBLISH_NEEDED=0
|
|
57
|
+
else
|
|
58
|
+
echo "Versione pubblicabile: ${PKG_NAME}@${VERSION}"
|
|
59
|
+
PUBLISH_NEEDED=1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
echo
|
|
63
|
+
echo "===== GIT COMMIT ====="
|
|
64
|
+
git add package.json package-lock.json README.md README_IT.md CHANGELOG.md SECURITY.md CONTRIBUTING.md .npmignore .vscodeignore extension.js LICENSE scripts/cc-npm-publish.sh scripts/cc-npm-bump.sh scripts/cc-install-local.sh 2>/dev/null || true
|
|
65
|
+
|
|
66
|
+
if ! git diff --cached --quiet; then
|
|
67
|
+
git commit -m "chore: prepare npm package ${VERSION}"
|
|
68
|
+
else
|
|
69
|
+
echo "Nothing to commit."
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
echo
|
|
73
|
+
echo "===== GIT PUSH MAIN ====="
|
|
74
|
+
if git remote get-url "$REMOTE_NAME" >/dev/null 2>&1; then
|
|
75
|
+
git push "$REMOTE_NAME" main
|
|
76
|
+
else
|
|
77
|
+
echo "WARN: remote '$REMOTE_NAME' non configurato. Push main saltato."
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
echo
|
|
81
|
+
echo "===== NPM PUBLISH ====="
|
|
82
|
+
if [ "$PUBLISH_NEEDED" = "0" ]; then
|
|
83
|
+
echo "SKIP: ${PKG_NAME}@${VERSION} è già pubblicato."
|
|
84
|
+
PUBLISH_OK=1
|
|
85
|
+
elif [ "$NPM_AUTH_OK" != "1" ]; then
|
|
86
|
+
echo "SKIP: npm auth non disponibile."
|
|
87
|
+
echo
|
|
88
|
+
echo "Dopo login puoi rilanciare:"
|
|
89
|
+
echo "npm run publish"
|
|
90
|
+
PUBLISH_OK=0
|
|
91
|
+
else
|
|
92
|
+
if npm publish; then
|
|
93
|
+
PUBLISH_OK=1
|
|
94
|
+
echo "OK: pubblicato ${PKG_NAME}@${VERSION}"
|
|
95
|
+
else
|
|
96
|
+
PUBLISH_OK=0
|
|
97
|
+
echo "WARN: npm publish fallito."
|
|
98
|
+
echo " Possibili cause: sessione scaduta, 2FA/OTP, permessi package, nome già riservato."
|
|
99
|
+
echo " Nessun tag git verrà creato."
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
echo
|
|
104
|
+
echo "===== GIT TAG ====="
|
|
105
|
+
if [ "$PUBLISH_OK" = "1" ]; then
|
|
106
|
+
TAG="v${VERSION}"
|
|
107
|
+
|
|
108
|
+
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
|
109
|
+
echo "Tag già esistente localmente: $TAG"
|
|
110
|
+
else
|
|
111
|
+
git tag "$TAG"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
if git remote get-url "$REMOTE_NAME" >/dev/null 2>&1; then
|
|
115
|
+
git push "$REMOTE_NAME" "$TAG"
|
|
116
|
+
else
|
|
117
|
+
echo "WARN: remote '$REMOTE_NAME' non configurato. Push tag saltato."
|
|
118
|
+
fi
|
|
119
|
+
else
|
|
120
|
+
echo "SKIP: tag saltato perché npm publish non è andato a buon fine."
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
echo
|
|
124
|
+
echo "===== DONE ====="
|
|
125
|
+
echo "Package: ${PKG_NAME}@${VERSION}"
|
|
126
|
+
|
|
127
|
+
if npm view "$PKG_NAME" version >/dev/null 2>&1; then
|
|
128
|
+
echo "NPM VERSION:"
|
|
129
|
+
npm view "$PKG_NAME" version
|
|
130
|
+
echo "NPM HOMEPAGE:"
|
|
131
|
+
npm view "$PKG_NAME" homepage 2>/dev/null || true
|
|
132
|
+
else
|
|
133
|
+
echo "Npm package non ancora visibile/pubblicato."
|
|
134
|
+
fi
|