diff --git a/CHANGELOG.md b/CHANGELOG.md index 636081d206c3..8509c065cfed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ New entries must be placed in a section entitled `Unreleased`. Read our [guidelines for writing a good changelog entry](https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#changelog). -## Unreleased +## v1.9.0 (2024-09-12) ### Analyzer @@ -287,6 +287,62 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ### Linter +#### Promoted rules + +New rules are incubated in the nursery group. +Once stable, we promote them to a stable group. + +The following CSS rules are promoted: + +- [a11y/useGenericFontNames](https://biomejs.dev/linter/rules/use-generic-font-names/) +- [correctness/noInvalidDirectionInLinearGradient](https://biomejs.dev/linter/rules/no-invalid-direction-in-linear-gradient/) +- [correctness/noInvalidGridAreas](https://biomejs.dev/linter/rules/no-invalid-grid-areas/) +- [correctness/noInvalidPositionAtImportRule](https://biomejs.dev/linter/rules/no-invalid-position-at-import-rule/) +- [correctness/noUnknownFunction](https://biomejs.dev/linter/rules/no-unknown-function/) +- [correctness/noUnknownMediaFeatureName](https://biomejs.dev/linter/rules/no-unknown-media-feature-name/) +- [correctness/noUnknownProperty](https://biomejs.dev/linter/rules/no-unknown-property/) +- [correctness/noUnknownUnit](https://biomejs.dev/linter/rules/no-unknown-unit/) +- [correctness/noUnmatchableAnbSelector](https://biomejs.dev/linter/rules/no-unmatchable-anb-selector/) +- [suspicious/noDuplicateAtImportRules](https://biomejs.dev/linter/rules/no-duplicate-at-import-rules/) +- [suspicious/noDuplicateFontNames](https://biomejs.dev/linter/rules/no-duplicate-font-names/) +- [suspicious/noDuplicateSelectorsKeyframeBlock](https://biomejs.dev/linter/rules/no-duplicate-selectors-keyframe-block/) +- [suspicious/noEmptyBlock](https://biomejs.dev/linter/rules/no-empty-block/) +- [suspicious/noImportantInKeyframe](https://biomejs.dev/linter/rules/no-important-in-keyframe/) +- [suspicious/noShorthandPropertyOverrides](https://biomejs.dev/linter/rules/no-shorthand-property-overrides/) + +The following JavaScript rules are promoted: + +- [a11y/noLabelWithoutControl](https://biomejs.dev/linter/rules/no-label-without-control/) +- [a11y/useFocusableInteractive](https://biomejs.dev/linter/rules/use-focusable-interactive/) +- [a11y/useSemanticElements](https://biomejs.dev/linter/rules/use-semantic-elements/) +- [complexity/noUselessStringConcat](https://biomejs.dev/linter/rules/no-useless-string-concat/) +- [complexity/noUselessUndefinedInitialization](https://biomejs.dev/linter/rules/no-useless-undefined-initialization/) +- [complexity/useDateNow](https://biomejs.dev/linter/rules/use-date-now/) +- [correctness/noUndeclaredDependencies](https://biomejs.dev/linter/rules/no-undeclared-dependencies/) +- [correctness/noInvalidBuiltinInstantiation](https://biomejs.dev/linter/rules/no-invalid-builtin-instantiation/) +- [correctness/noUnusedFunctionParameters](https://biomejs.dev/linter/rules/no-unused-function-parameters/) +- [correctness/useImportExtensions](https://biomejs.dev/linter/rules/use-import-extensions/) +- [performance/useTopLevelRegex](https://biomejs.dev/linter/rules/use-top-level-regex/) +- [style/noDoneCallback](https://biomejs.dev/linter/rules/no-done-callback/) +- [style/noYodaExpression](https://biomejs.dev/linter/rules/no-yoda-expression/) +- [style/useConsistentBuiltinInstantiation](https://biomejs.dev/linter/rules/use-consistent-builtin-instantiation/) +- [style/useDefaultSwitchClause](https://biomejs.dev/linter/rules/use-default-switch-clause/) +- [style/useExplicitLengthCheck](https://biomejs.dev/linter/rules/use-explicit-length-check/) +- [style/useThrowNewError](https://biomejs.dev/linter/rules/use-throw-new-error/) +- [style/useThrowOnlyError](https://biomejs.dev/linter/rules/use-throw-only-error/) +- [suspicious/noConsole](https://biomejs.dev/linter/rules/no-console/) +- [suspicious/noEvolvingTypes](https://biomejs.dev/linter/rules/no-evolving-types/) +- [suspicious/noMisplacedAssertion](https://biomejs.dev/linter/rules/no-misplaced-assertion/) +- [suspicious/noReactSpecificProps](https://biomejs.dev/linter/rules/no-react-specific-props/) +- [suspicious/useErrorMessage](https://biomejs.dev/linter/rules/use-error-message/) +- [suspicious/useNumberToFixedDigitsArgument](https://biomejs.dev/linter/rules/use-number-to-fixed-digits-argument/) + +#### Deprecated rules + +- `correctness/noInvalidNewBuiltin` is deprecated. Use [correctness/noInvalidBuiltinInstantiation](https://biomejs.dev/linter/rules/no-invalid-builtin-instantiation/) instead. +- `style/useSingleCaseStatement` is deprecated. Use [correctness/noSwitchDeclarations](https://biomejs.dev/linter/rules/no-switch-declarations/) instead. +- `suspicious/noConsoleLog` is deprecated. Use [suspicious/noConsole](https://biomejs.dev/linter/rules/no-console/) instead. + #### New features - Implement [css suppression action](https://github.com/biomejs/biome/issues/3278). Contributed by @togami2864 diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 416db04df981..5e68992a2456 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -416,7 +416,7 @@ pub enum BiomeCommand { sub_command: Option, }, - /// [EXPERIMENTAL] Searches for Grit patterns across a project. + /// EXPERIMENTAL: Searches for Grit patterns across a project. /// /// Note: GritQL escapes code snippets using backticks, but most shells /// interpret backticks as command invocations. To avoid this, it's best to diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index cb084537b1f3..2fb83088aa24 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -257,10 +257,7 @@ pub(crate) fn migrate_eslint_any_rule( results.has_inspired_rules = true; return false; } - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group.use_throw_only_error.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -357,10 +354,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "default-case" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group .use_default_switch_clause .get_or_insert(Default::default()); @@ -451,10 +445,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "jest/no-done-callback" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group.no_done_callback.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -492,10 +483,7 @@ pub(crate) fn migrate_eslint_any_rule( results.has_inspired_rules = true; return false; } - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .no_misplaced_assertion .get_or_insert(Default::default()); @@ -585,20 +573,14 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "jsx-a11y/interactive-supports-focus" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.a11y.get_or_insert_with(Default::default); let rule = group .use_focusable_interactive .get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } "jsx-a11y/label-has-associated-control" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.a11y.get_or_insert_with(Default::default); let rule = group .no_label_without_control .get_or_insert(Default::default()); @@ -682,10 +664,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "jsx-a11y/prefer-tag-over-role" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.a11y.get_or_insert_with(Default::default); let rule = group .use_semantic_elements .get_or_insert(Default::default()); @@ -759,12 +738,8 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "no-console" => { - if !options.include_inspired { - results.has_inspired_rules = true; - return false; - } let group = rules.suspicious.get_or_insert_with(Default::default); - let rule = group.no_console_log.get_or_insert(Default::default()); + let rule = group.no_console.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } "no-const-assign" => { @@ -983,7 +958,7 @@ pub(crate) fn migrate_eslint_any_rule( "no-new-native-nonconstructor" => { let group = rules.correctness.get_or_insert_with(Default::default); let rule = group - .no_invalid_new_builtin + .no_invalid_builtin_instantiation .get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -993,10 +968,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "no-new-wrappers" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group .use_consistent_builtin_instantiation .get_or_insert(Default::default()); @@ -1111,10 +1083,7 @@ pub(crate) fn migrate_eslint_any_rule( results.has_inspired_rules = true; return false; } - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group.use_throw_only_error.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -1126,14 +1095,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "no-undef-init" => { - if !options.include_inspired { - results.has_inspired_rules = true; - return false; - } - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.complexity.get_or_insert_with(Default::default); let rule = group .no_useless_undefined_initialization .get_or_insert(Default::default()); @@ -1196,10 +1158,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "no-useless-concat" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.complexity.get_or_insert_with(Default::default); let rule = group .no_useless_string_concat .get_or_insert(Default::default()); @@ -1413,10 +1372,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "solidjs/no-react-specific-props" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .no_react_specific_props .get_or_insert(Default::default()); @@ -1435,22 +1391,12 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "unicorn/error-message" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group.use_error_message.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } "unicorn/explicit-length-check" => { - if !options.include_inspired { - results.has_inspired_rules = true; - return false; - } - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group .use_explicit_length_check .get_or_insert(Default::default()); @@ -1468,12 +1414,9 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "unicorn/new-for-builtins" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.correctness.get_or_insert_with(Default::default); let rule = group - .use_consistent_builtin_instantiation + .no_invalid_builtin_instantiation .get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -1515,10 +1458,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "unicorn/prefer-date-now" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.complexity.get_or_insert_with(Default::default); let rule = group.use_date_now.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -1551,20 +1491,14 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "unicorn/require-number-to-fixed-digits-argument" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .use_number_to_fixed_digits_argument .get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } "unicorn/throw-new-error" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group.use_throw_new_error.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } @@ -1589,10 +1523,7 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "yoda" => { - if !options.include_nursery { - return false; - } - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.style.get_or_insert_with(Default::default); let rule = group.no_yoda_expression.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } diff --git a/crates/biome_cli/src/execute/migrate/eslint_eslint.rs b/crates/biome_cli/src/execute/migrate/eslint_eslint.rs index d078b4dfe82c..e12eab4a6de3 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_eslint.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_eslint.rs @@ -539,9 +539,9 @@ pub struct NoConsoleOptions { /// Allowed calls on the console object. pub allow: Vec, } -impl From for biome_js_analyze::lint::nursery::no_console::NoConsoleOptions { +impl From for biome_js_analyze::lint::suspicious::no_console::NoConsoleOptions { fn from(val: NoConsoleOptions) -> Self { - biome_js_analyze::lint::nursery::no_console::NoConsoleOptions { allow: val.allow } + biome_js_analyze::lint::suspicious::no_console::NoConsoleOptions { allow: val.allow } } } diff --git a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs index d5447215b370..4614c68be53d 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs @@ -210,7 +210,7 @@ fn migrate_eslint_rule( eslint_eslint::Rule::NoConsole(conf) => { if migrate_eslint_any_rule(rules, &name, conf.severity(), opts, results) { if let eslint_eslint::RuleConf::Option(severity, rule_options) = conf { - let group = rules.nursery.get_or_insert_with(Default::default); + let group = rules.suspicious.get_or_insert_with(Default::default); group.no_console = Some(biome_config::RuleFixConfiguration::WithOptions( biome_config::RuleWithFixOptions { level: severity.into(), diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_lint_files_by_when_enabled.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_lint_files_by_when_enabled.snap index dca1e1d0efce..00a7c255cccb 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_lint_files_by_when_enabled.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_lint_files_by_when_enabled.snap @@ -30,7 +30,7 @@ lint ━━━━━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -input.css:1:6 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +input.css:1:6 lint/suspicious/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ × An empty block isn't allowed. diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_lint_files_by_default.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_lint_files_by_default.snap index dca1e1d0efce..00a7c255cccb 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_lint_files_by_default.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_lint_files_by_default.snap @@ -30,7 +30,7 @@ lint ━━━━━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -input.css:1:6 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +input.css:1:6 lint/suspicious/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ × An empty block isn't allowed. diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/config_recommended_group.snap b/crates/biome_cli/tests/snapshots/main_commands_check/config_recommended_group.snap index 7116ca6fc29f..cc43e5ac2e80 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_check/config_recommended_group.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_check/config_recommended_group.snap @@ -37,16 +37,14 @@ check ━━━━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -check.js:1:1 lint/correctness/noInvalidNewBuiltin FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +check.js:1:1 lint/correctness/noInvalidBuiltinInstantiation FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × Symbol cannot be called as a constructor. + × Use Symbol() instead of new Symbol(). > 1 │ new Symbol(""); │ ^^^^^^^^^^^^^^ - i Calling Symbol with the new operator throws a TypeError. - - i Unsafe fix: Remove new. + i Unsafe fix: Remove new keyword. 1 │ new·Symbol(""); │ ---- diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/config_recommended_group.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/config_recommended_group.snap index 4acb1a802ff9..b0c4b636b300 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_lint/config_recommended_group.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/config_recommended_group.snap @@ -37,16 +37,14 @@ lint ━━━━━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -check.js:1:1 lint/correctness/noInvalidNewBuiltin FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +check.js:1:1 lint/correctness/noInvalidBuiltinInstantiation FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × Symbol cannot be called as a constructor. + × Use Symbol() instead of new Symbol(). > 1 │ new Symbol(""); │ ^^^^^^^^^^^^^^ - i Calling Symbol with the new operator throws a TypeError. - - i Unsafe fix: Remove new. + i Unsafe fix: Remove new keyword. 1 │ new·Symbol(""); │ ---- diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/no_unused_dependencies.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/no_unused_dependencies.snap index 35d1489f3afa..4b9f2278c118 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_lint/no_unused_dependencies.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/no_unused_dependencies.snap @@ -37,9 +37,9 @@ import "lodash"; # Termination Message ```block -lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +configuration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × Some errors were emitted while running checks. + × Biome exited because the configuration resulted in errors. Please fix them. @@ -48,23 +48,48 @@ lint ━━━━━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -fix.js:2:8 lint/nursery/noUndeclaredDependencies ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +biome.json:7:9 deserialize ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × The current dependency isn't specified in your package.json. + × Found an unknown key `noUndeclaredDependencies`. - 1 │ import "react"; - > 2 │ import "lodash"; - │ ^^^^^^^^ - 3 │ + 5 │ "all": false, + 6 │ "nursery": { + > 7 │ "noUndeclaredDependencies": "error" + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 8 │ } + 9 │ } - i This could lead to errors. + i Known keys: - i Add the dependency in your manifest. + - recommended + - all + - noCommonJs + - noDuplicateCustomProperties + - noDuplicateElseIf + - noDuplicatedFields + - noDynamicNamespaceImportAccess + - noEnum + - noExportedImports + - noIrregularWhitespace + - noRestrictedImports + - noRestrictedTypes + - noSecrets + - noStaticElementInteractions + - noSubstr + - noUnknownPseudoClass + - noUnknownPseudoElement + - noUselessEscapeInRegex + - noValueAtRule + - useAdjacentOverloadSignatures + - useAriaPropsSupportedByRole + - useConsistentCurlyBraces + - useConsistentMemberAccessibility + - useDeprecatedReason + - useImportRestrictions + - useSortedClasses + - useStrictMode + - useTrimStartEnd + - useValidAutocomplete ``` - -```block -Checked 1 file in