Skip to content

Commit ff886b9

Browse files
camchenrycamc314
andcommitted
refactor: update headless payload to be config-based instead of file-based
Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
1 parent b59efbc commit ff886b9

File tree

2 files changed

+69
-41
lines changed

2 files changed

+69
-41
lines changed

cmd/tsgolint/headless.go

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ import (
2525
"github.com/typescript-eslint/tsgolint/internal/utils"
2626
)
2727

28-
type headlessConfigForFile struct {
29-
FilePath string `json:"file_path"`
30-
Rules []string `json:"rules"`
28+
type headlessPayload struct {
29+
Version string `json:"version,omitempty"`
30+
Configs []headlessConfig `json:"configs"`
3131
}
32+
3233
type headlessConfig struct {
33-
Files []headlessConfigForFile `json:"files"`
34+
FilePaths []string `json:"file_paths"`
35+
Rules []headlessRule `json:"rules"`
36+
}
37+
38+
type headlessRule struct {
39+
Name string `json:"name"`
3440
}
3541

3642
type headlessRange struct {
@@ -154,51 +160,60 @@ func runHeadless(args []string) int {
154160
return 1
155161
}
156162

157-
var config headlessConfig
163+
var payload headlessPayload
158164

159-
if err := json.Unmarshal(configRaw, &config); err != nil {
160-
writeErrorMessage(fmt.Sprintf("error parsing config: %v", err))
165+
if err := json.Unmarshal(configRaw, &payload); err != nil {
166+
writeErrorMessage(fmt.Sprintf("error parsing payload: %v", err))
161167
return 1
162168
}
163-
if len(config.Files) == 0 {
164-
writeErrorMessage("no files specified in config")
169+
if len(payload.Configs) == 0 {
170+
writeErrorMessage("invalid payload format: 'configs' field is required and must not be empty")
165171
return 1
166172
}
167173

168-
fileConfigs := make(map[string]headlessConfigForFile, len(config.Files))
169174
workload := linter.Workload{
170175
Programs: make(map[string][]string),
171176
UnmatchedFiles: []string{},
172177
}
173178

179+
totalFileCount := 0
180+
for _, config := range payload.Configs {
181+
totalFileCount += len(config.FilePaths)
182+
}
174183
if logLevel == utils.LogLevelDebug {
175-
log.Printf("Starting to assign files to programs. Total files: %d", len(config.Files))
184+
log.Printf("Starting to assign files to programs. Total files: %d", totalFileCount)
176185
}
177186

178187
tsConfigResolver := utils.NewTsConfigResolver(fs, cwd)
179188

180-
for idx, fileConfig := range config.Files {
181-
if logLevel == utils.LogLevelDebug {
182-
log.Printf("[%d/%d] Processing file: %s", idx+1, len(config.Files), fileConfig.FilePath)
183-
}
189+
fileConfigs := make(map[string][]headlessRule, totalFileCount)
184190

185-
normalizedFilePath := tspath.NormalizeSlashes(fileConfig.FilePath)
191+
idx := 0
192+
for _, config := range payload.Configs {
193+
for _, filePath := range config.FilePaths {
194+
if logLevel == utils.LogLevelDebug {
195+
log.Printf("[%d/%d] Processing file: %s", idx+1, totalFileCount, filePath)
196+
}
197+
198+
normalizedFilePath := tspath.NormalizeSlashes(filePath)
186199

187-
tsconfig, found := tsConfigResolver.FindTsconfigForFile(normalizedFilePath, false)
188-
if logLevel == utils.LogLevelDebug {
189-
tsconfigStr := "<none>"
190-
if found {
191-
tsconfigStr = tsconfig
200+
tsconfig, found := tsConfigResolver.FindTsconfigForFile(normalizedFilePath, false)
201+
if logLevel == utils.LogLevelDebug {
202+
tsconfigStr := "<none>"
203+
if found {
204+
tsconfigStr = tsconfig
205+
}
206+
log.Printf("Got tsconfig for file %s: %s", normalizedFilePath, tsconfigStr)
192207
}
193-
log.Printf("Got tsconfig for file %s: %s", normalizedFilePath, tsconfigStr)
194-
}
195208

196-
if !found {
197-
workload.UnmatchedFiles = append(workload.UnmatchedFiles, normalizedFilePath)
198-
} else {
199-
workload.Programs[tsconfig] = append(workload.Programs[tsconfig], normalizedFilePath)
209+
if !found {
210+
workload.UnmatchedFiles = append(workload.UnmatchedFiles, normalizedFilePath)
211+
} else {
212+
workload.Programs[tsconfig] = append(workload.Programs[tsconfig], normalizedFilePath)
213+
fileConfigs[normalizedFilePath] = config.Rules
214+
}
215+
idx++
200216
}
201-
fileConfigs[normalizedFilePath] = fileConfig
202217
}
203218

204219
if logLevel == utils.LogLevelDebug {
@@ -279,12 +294,12 @@ func runHeadless(args []string) int {
279294
runtime.GOMAXPROCS(0),
280295
func(sourceFile *ast.SourceFile) []linter.ConfiguredRule {
281296
cfg := fileConfigs[sourceFile.FileName()]
282-
rules := make([]linter.ConfiguredRule, len(cfg.Rules))
297+
rules := make([]linter.ConfiguredRule, len(cfg))
283298

284-
for i, ruleName := range cfg.Rules {
285-
r, ok := allRulesByName[ruleName]
299+
for i, headlessRule := range cfg {
300+
r, ok := allRulesByName[headlessRule.Name]
286301
if !ok {
287-
panic(fmt.Sprintf("unknown rule: %v", ruleName))
302+
panic(fmt.Sprintf("unknown rule: %v", headlessRule.Name))
288303
}
289304
rules[i] = linter.ConfiguredRule{
290305
Name: r.Name,

e2e/snapshot.test.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,25 @@ async function getTestFiles(testPath: string): Promise<string[]> {
146146
}
147147

148148
function generateConfig(files: string[], rules: readonly (typeof ALL_RULES)[number][] = ALL_RULES): string {
149+
// Headless payload format:
150+
// ```json
151+
// {
152+
// "configs": [
153+
// {
154+
// "file_paths": ["/abs/path/a.ts", ...],
155+
// "rules": [ { "name": "rule-a" }, { "name": "rule-b" } ]
156+
// }
157+
// ]
158+
// }
159+
// ```
149160
const config = {
150-
files: files.map((filePath) => ({
151-
file_path: filePath,
152-
rules,
153-
})),
154-
};
161+
configs: [
162+
{
163+
file_paths: files,
164+
rules: rules.map((r) => ({ name: r })),
165+
},
166+
],
167+
} as const;
155168
return JSON.stringify(config);
156169
}
157170

@@ -194,13 +207,13 @@ describe('TSGoLint E2E Snapshot Tests', () => {
194207
const rustStylePath = testFile.replace(/\//g, '\\');
195208

196209
const config = {
197-
files: [
210+
configs: [
198211
{
199-
file_path: rustStylePath,
200-
rules: ['no-floating-promises'],
212+
file_paths: [rustStylePath],
213+
rules: [{ name: 'no-floating-promises' }],
201214
},
202215
],
203-
};
216+
} as const;
204217

205218
const env = { ...process.env, GOMAXPROCS: '1' };
206219

0 commit comments

Comments
 (0)