Add --format-only flag
MODIFY
packages/@romejs/core/common/bridges/WorkerBridge.ts
packages/@romejs/core/common/bridges/WorkerBridge.ts
@@ -59,6 +59,8 @@ export type WorkerAnalyzeDependencyResult = AnalyzeDependencyResult & {
export type WorkerLintOptions = {
compilerOptions?: LintCompilerOptions;
prefetchedModuleSignatures: PrefetchedModuleSignatures;
+ formatOnly: boolean;
+ save: boolean;
fix: boolean;
};
@@ -104,7 +106,7 @@ export type WorkerFormatResult = {
};
export type WorkerLintResult = {
- fixed: boolean;
+ saved: boolean;
diagnostics: Diagnostics;
suppressions: DiagnosticSuppressions;
};

MODIFY
packages/@romejs/core/common/fileHandlers.ts
packages/@romejs/core/common/fileHandlers.ts
@@ -332,6 +332,7 @@ function buildJSHandler(
// Run the compiler in lint-mode which is where all the rules are actually ran
const res = await compiler.lint({
+ formatOnly: options.formatOnly,
ref,
options: {
lint: options.compilerOptions,

MODIFY
packages/@romejs/core/master/commands/ci.ts
packages/@romejs/core/master/commands/ci.ts
@@ -61,6 +61,7 @@ export default createMasterCommand({
reporter.heading('Running lint');
await runChildCommand(req, async () => {
await lint.callback(req, {
+ formatOnly: false,
decisions: [],
fix: flags.fix,
changed: undefined,

MODIFY
packages/@romejs/core/master/commands/lint.ts
packages/@romejs/core/master/commands/lint.ts
@@ -17,6 +17,7 @@ type Flags = {
decisions: Array<string>;
fix: boolean;
changed: undefined | string;
+ formatOnly: boolean;
};
export default createMasterCommand<Flags>({
@@ -32,6 +33,7 @@ export default createMasterCommand<Flags>({
(item) => item.asString(),
),
fix: consumer.get('fix').asBoolean(false),
+ formatOnly: consumer.get('formatOnly').asBoolean(false),
changed: consumer.get('changed').asStringOrVoid(),
};
},
@@ -88,6 +90,7 @@ export default createMasterCommand<Flags>({
hasDecisions: flags.decisions.length > 0,
compilerOptionsPerFile,
fixLocation,
+ formatOnly: flags.formatOnly,
args,
};

MODIFY
packages/@romejs/core/master/linter/Linter.ts
packages/@romejs/core/master/linter/Linter.ts
@@ -36,9 +36,10 @@ type LintWatchChanges = Array<{
}>;
export type LinterOptions = {
- fixLocation?: DiagnosticLocation;
+ fixLocation: undefined | DiagnosticLocation;
args?: Array<string>;
- hasDecisions?: boolean;
+ hasDecisions: boolean;
+ formatOnly: boolean;
compilerOptionsPerFile?: Dict<Required<LintCompilerOptions>>;
};
@@ -58,7 +59,7 @@ type WatchResults = {
runner: LintRunner;
evictedPaths: AbsoluteFilePathSet;
changes: LintWatchChanges;
- fixedCount: number;
+ savedCount: number;
totalCount: number;
};
@@ -72,15 +73,15 @@ function createDiagnosticsPrinter(
request: MasterRequest,
processor: DiagnosticsProcessor,
totalCount: number,
- fixedCount: number,
+ savedCount: number,
): DiagnosticsPrinter {
const printer = request.createDiagnosticsPrinter(processor);
printer.onBeforeFooterPrint(
(reporter, isError) => {
- if (fixedCount > 0) {
+ if (savedCount > 0) {
reporter.success(
- `<number emphasis>${fixedCount}</number> <grammarNumber plural="files" singular="file">${fixedCount}</grammarNumber> fixed`,
+ `<number emphasis>${savedCount}</number> <grammarNumber plural="files" singular="file">${savedCount}</grammarNumber> updated`,
);
}
@@ -150,12 +151,18 @@ class LintRunner {
async runLint({
evictedPaths: changedPaths,
processor,
- }: LintRunOptions): Promise<{fixedCount: number}> {
- let fixedCount = 0;
+ }: LintRunOptions): Promise<{savedCount: number}> {
+ let savedCount = 0;
const {master} = this.request;
- const {fixLocation, compilerOptionsPerFile, hasDecisions} = this.options;
+ const {
+ fixLocation,
+ compilerOptionsPerFile,
+ hasDecisions,
+ formatOnly,
+ } = this.options;
const shouldFix = fixLocation !== undefined;
+ const shouldSave = shouldFix || hasDecisions || formatOnly;
const queue: WorkerQueue<void> = new WorkerQueue(master);
@@ -182,16 +189,18 @@ class LintRunner {
const {
diagnostics,
suppressions,
- fixed,
+ saved,
} = await this.request.requestWorkerLint(path, {
+ save: shouldSave,
+ formatOnly,
fix: shouldFix,
compilerOptions,
});
processor.addSuppressions(suppressions);
processor.addDiagnostics(diagnostics);
this.compilerDiagnosticsCache.set(path, {suppressions, diagnostics});
- if (fixed) {
- fixedCount++;
+ if (saved) {
+ savedCount++;
}
progress.popText(text);
@@ -205,7 +214,7 @@ class LintRunner {
await queue.spin();
progress.end();
- return {fixedCount};
+ return {savedCount};
}
async runGraph({
@@ -354,13 +363,13 @@ class LintRunner {
async run(opts: LintRunOptions): Promise<WatchResults> {
this.events.onRunStart();
- const {fixedCount} = await this.runLint(opts);
+ const {savedCount} = await this.runLint(opts);
const validatedDependencyPaths = await this.runGraph(opts);
const changes = await this.computeChanges(opts, validatedDependencyPaths);
return {
evictedPaths: opts.evictedPaths,
changes,
- fixedCount,
+ savedCount,
totalCount: validatedDependencyPaths.size,
runner: this,
};
@@ -466,12 +475,12 @@ export default class Linter {
return reporter.progress(opts);
},
- onChanges: ({evictedPaths, changes, totalCount, fixedCount, runner}) => {
+ onChanges: ({evictedPaths, changes, totalCount, savedCount, runner}) => {
printer = createDiagnosticsPrinter(
request,
this.createDiagnosticsProcessor(evictedPaths, runner),
totalCount,
- fixedCount,
+ savedCount,
);
// Update our diagnostics with the changes

MODIFY
packages/@romejs/core/master/lsp/LSPServer.ts
packages/@romejs/core/master/lsp/LSPServer.ts
@@ -369,7 +369,11 @@ export default class LSPServer {
const req = this.createFakeMasterRequest('lsp_project', [path.join()]);
await req.init();
- const linter = new Linter(req, {});
+ const linter = new Linter(req, {
+ fixLocation: undefined,
+ hasDecisions: false,
+ formatOnly: false,
+ });
const subscription = await linter.watch({
onRunStart: () => {},

MODIFY
packages/@romejs/core/worker/WorkerAPI.ts
packages/@romejs/core/worker/WorkerAPI.ts
@@ -234,7 +234,7 @@ export default class WorkerAPI {
const {lint} = handler;
if (lint === undefined && handler.format === undefined) {
return {
- fixed: false,
+ saved: false,
diagnostics: [],
suppressions: [],
};
@@ -261,7 +261,7 @@ export default class WorkerAPI {
// These are fatal diagnostics
if (res.diagnostics !== undefined) {
return {
- fixed: false,
+ saved: false,
suppressions: [],
diagnostics: res.diagnostics,
};
@@ -270,7 +270,7 @@ export default class WorkerAPI {
// `format` could have return undefined
if (res.value === undefined) {
return {
- fixed: false,
+ saved: false,
diagnostics: [],
suppressions: [],
};
@@ -289,24 +289,28 @@ export default class WorkerAPI {
);
// If the file has pending fixes
- const needsFix = formatted !== sourceText;
+ const needsSave = formatted !== sourceText;
// Autofix if necessary
- if (options.fix && needsFix) {
+ if (options.save && needsSave) {
// Save the file and evict it from the cache
await this.worker.writeFile(ref.real, formatted);
// Relint this file without fixing it, we do this to prevent false positive error messages
return {
- ...(await this.lint(ref, {...options, fix: false}, parseOptions)),
- fixed: true,
+ ...(await this.lint(
+ ref,
+ {...options, formatOnly: false, fix: false},
+ parseOptions,
+ )),
+ saved: true,
};
}
// If there's no pending fix then no need for diagnostics
- if (!needsFix) {
+ if (!needsSave) {
return {
- fixed: false,
+ saved: false,
diagnostics,
suppressions,
};
@@ -314,7 +318,7 @@ export default class WorkerAPI {
// Add pending autofix diagnostic
return {
- fixed: false,
+ saved: false,
suppressions,
diagnostics: [
...diagnostics,
@@ -322,7 +326,11 @@ export default class WorkerAPI {
location: {
filename: ref.uid,
},
- description: descriptions.LINT.PENDING_FIXES(sourceText, formatted),
+ description: descriptions.LINT.PENDING_FIXES(
+ ref.relative.join(),
+ sourceText,
+ formatted,
+ ),
},
],
};

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
- */
-
-import {
+ */import {
DiagnosticAdvice,
+ DiagnosticAdviceAction,
DiagnosticBlessedMessage,
DiagnosticDescription,
DiagnosticLocation,
@@ -296,7 +295,11 @@ export const descriptions = createMessages(
// @romejs/js-compiler
LINT: {
- PENDING_FIXES: (original: string, formatted: string) => ({
+ PENDING_FIXES: (
+ relativeFilename: string,
+ original: string,
+ formatted: string,
+ ) => ({
category: 'lint/pendingFixes',
message: 'Pending autofixes and formatting',
advice: [
@@ -309,6 +312,28 @@ export const descriptions = createMessages(
category: 'info',
message: 'Run <command>rome lint --fix</command> to apply',
},
+ ({
+ type: 'action',
+ hidden: true,
+ command: 'lint',
+ instruction: 'To format this file without fixes run',
+ noun: 'Format file',
+ args: [relativeFilename],
+ commandFlags: {
+ formatOnly: true,
+ },
+ } as DiagnosticAdviceAction),
+ ({
+ type: 'action',
+ hidden: true,
+ command: 'lint',
+ instruction: 'To format and fix this file run',
+ noun: 'Fix file',
+ args: [relativeFilename],
+ commandFlags: {
+ fix: true,
+ },
+ } as DiagnosticAdviceAction),
],
}),

MODIFY
packages/@romejs/js-compiler/lib/Cache.ts
packages/@romejs/js-compiler/lib/Cache.ts
@@ -24,8 +24,11 @@ export default class Cache<Result> {
cache: WeakMap<Program, Map<string, Result>>;
- static buildQuery(req: TransformRequest, options?: JSONObject): CacheQuery {
- const {ast, project} = req;
+ static buildQuery(
+ req: TransformRequest,
+ additionalOptions?: JSONObject,
+ ): CacheQuery {
+ const {ast, project, options} = req;
const keyParts: Array<string> = [];
let projectId = projectToId.get(project);
@@ -38,8 +41,12 @@ export default class Cache<Result> {
keyParts.push(String(projectId));
// Add options if they exist
- if (options !== undefined && Object.keys(options).length > 0) {
- keyParts.push(JSON.stringify(options));
+ const extra = {
+ ...options,
+ ...additionalOptions,
+ };
+ if (Object.keys(extra).length > 0) {
+ keyParts.push(JSON.stringify(extra));
}
return {

MODIFY
packages/@romejs/js-compiler/lint/index.ts
packages/@romejs/js-compiler/lint/index.ts
*/
import {DiagnosticSuppressions, Diagnostics} from '@romejs/diagnostics';
-import {TransformRequest} from '../types';
+import {LintRequest} from '../types';
import {lintTransforms} from './rules/index';
import {Cache, CompilerContext} from '@romejs/js-compiler';
import {formatJS} from '@romejs/js-formatter';
@@ -20,8 +20,8 @@ export type LintResult = {
const lintCache: Cache<LintResult> = new Cache();
-export default async function lint(req: TransformRequest): Promise<LintResult> {
- const {ast, sourceText, project, options} = req;
+export default async function lint(req: LintRequest): Promise<LintResult> {
+ const {ast, sourceText, project, formatOnly, options} = req;
const query = Cache.buildQuery(req);
const cached = lintCache.get(query);
@@ -42,8 +42,11 @@ export default async function lint(req: TransformRequest): Promise<LintResult> {
},
});
- let formatAst = formatContext.reduceRoot(ast, lintTransforms);
+ let formatAst = ast;
+ if (!formatOnly) {
+ formatAst = formatContext.reduceRoot(ast, lintTransforms);
formatAst = addSuppressions(formatContext, formatAst);
+ }
const generator = formatJS(formatAst, {
typeAnnotations: true,
sourceMaps: true,

MODIFY
packages/@romejs/js-compiler/lint/testHelpers.ts
packages/@romejs/js-compiler/lint/testHelpers.ts
@@ -69,6 +69,7 @@ export async function testLint(
});
const res = await lint({
+ formatOnly: false,
options: {},
ast,
sourceText: input,

MODIFY
packages/@romejs/js-compiler/types.ts
packages/@romejs/js-compiler/types.ts
@@ -54,9 +54,12 @@ export type TransformVisitor = {
export type TransformVisitors = Array<TransformVisitor>;
-//
export type CompileRequest = TransformRequest & {inputSourceMap?: SourceMap};
+export type LintRequest = TransformRequest & {
+ formatOnly: boolean;
+};
+
export type TransformProjectDefinition = {
config: ProjectConfig;
folder: undefined | AbsoluteFilePath;

Add --format-only flag