diff --git a/lib/rules/template-no-template-lint-directives.js b/lib/rules/template-no-template-lint-directives.js index 168efc52b9..041e6d9cea 100644 --- a/lib/rules/template-no-template-lint-directives.js +++ b/lib/rules/template-no-template-lint-directives.js @@ -69,6 +69,21 @@ module.exports = { }, }; +// ember-template-lint accepts quoted rule names in its directives and strips +// the quotes before matching, so `{{! template-lint-disable "no-log" }}` is a +// live directive. Mirror its `unquote` exactly: strip only when the first and +// last character are the same quote character. +function unquote(name) { + if (name.length < 3) { + return name; + } + const first = name[0]; + if (first === name.at(-1) && (first === '"' || first === "'")) { + return name.slice(1, -1); + } + return name; +} + function convertComment(rawComment) { const match = rawComment.match(DIRECTIVE_COMMENT); if (!match) { @@ -82,7 +97,7 @@ function convertComment(rawComment) { .trim() .split(/\s+/) .filter(Boolean) - .map((r) => `ember/template-${r}`) + .map((r) => `ember/template-${unquote(r)}`) .join(', '); const body = rules ? `eslint-${action} ${rules}` : `eslint-${action}`; // Emit symmetric markers regardless of what the source did. diff --git a/tests/lib/rules/template-no-template-lint-directives.js b/tests/lib/rules/template-no-template-lint-directives.js index 163902d6d9..51b3626beb 100644 --- a/tests/lib/rules/template-no-template-lint-directives.js +++ b/tests/lib/rules/template-no-template-lint-directives.js @@ -44,6 +44,37 @@ ruleTester.run('template-no-template-lint-directives', rule, { output: '', errors: [{ messageId: 'convert' }], }, + // ember-template-lint unquotes each rule name (single or double quotes), + // so quoted names are live directives in migrating codebases and must + // convert to bare eslint rule names. + { + code: '', + output: '', + errors: [{ messageId: 'convert' }], + }, + { + code: '', + output: '', + errors: [{ messageId: 'convert' }], + }, + { + code: '', + output: + '', + errors: [{ messageId: 'convert' }], + }, + { + code: '', + output: '', + errors: [{ messageId: 'convert' }], + }, + // Mismatched or lone quotes are not a quoted name — upstream's unquote + // only strips when the first and last character are the same quote. + { + code: '', + output: '', + errors: [{ messageId: 'convert' }], + }, // Directive inside an element's opening tag is lifted to before the // element so the eslint-disable scope covers the line where the // violation is reported.