biomejs / biome

A toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.
https://biomejs.dev
Apache License 2.0
14.99k stars 467 forks source link

📝 Biome does not respect license headers when sorting imports #4210

Closed aabmets closed 1 week ago

aabmets commented 1 week ago

Environment information

CLI:
  Version:                      1.9.3
  Color support:                true

Platform:
  CPU Architecture:             x86_64
  OS:                           windows

Environment:
  BIOME_LOG_PATH:               unset
  BIOME_LOG_PREFIX_NAME:        unset
  BIOME_CONFIG_PATH:            unset
  NO_COLOR:                     unset
  TERM:                         unset
  JS_RUNTIME_VERSION:           "v22.9.0"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         unset

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    false
  VCS disabled:                 false

Formatter:
  Format with errors:           false
  Indent style:                 Space
  Indent width:                 3
  Line ending:                  Lf
  Line width:                   100
  Attribute position:           Auto
  Bracket spacing:              BracketSpacing(true)
  Ignore:                       []
  Include:                      []

JavaScript Formatter:
  Enabled:                      true
  JSX quote style:              Double
  Quote properties:             AsNeeded
  Trailing commas:              All
  Semicolons:                   Always
  Arrow parentheses:            Always
  Bracket spacing:              unset
  Bracket same line:            false
  Quote style:                  Double
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Attribute position:           unset

JSON Formatter:
  Enabled:                      true
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Trailing Commas:              unset

CSS Formatter:
  Enabled:                      true
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Quote style:                  Double

GraphQL Formatter:
  Enabled:                      false
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Bracket spacing:              unset
  Quote style:                  unset

Workspace:
  Open Documents:               0

Configuration

{
   "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
   "vcs": {
      "enabled": true,
      "clientKind": "git",
      "useIgnoreFile": true,
      "defaultBranch": "main"
   },
   "organizeImports": {
      "enabled": true
   },
   "formatter": {
      "enabled": true,
      "indentStyle": "space",
      "indentWidth": 3,
      "lineEnding": "lf",
      "lineWidth": 100
   },
   "linter": {
      "enabled": true,
      "rules": {
         "recommended": true,
         "complexity": {
            "noExcessiveCognitiveComplexity": {
               "level": "error",
               "options": {
                  "maxAllowedComplexity": 25
               }
            },
            "noUselessStringConcat": "error",
            "noUselessUndefinedInitialization": "error",
            "noVoid": "error",
            "useDateNow": "error",
            "useSimplifiedLogicExpression": "error"
         },
         "correctness": {
            "noConstantMathMinMaxClamp": "error",
            "noInvalidBuiltinInstantiation": "error",
            "noUndeclaredDependencies": "error",
            "noUndeclaredVariables": "error",
            "noUnusedFunctionParameters": "warn",
            "noUnusedImports": "warn",
            "noUnusedPrivateClassMembers": "warn",
            "noUnusedVariables": "warn",
            "useArrayLiterals": "error",
            "useHookAtTopLevel": "error",
            "useImportExtensions": "error"
         },
         "performance": {
            "noBarrelFile": "error",
            "noReExportAll": "error"
         },
         "style": {
            "noDefaultExport": "off",
            "noDoneCallback": "error",
            "noImplicitBoolean": "error",
            "noNamespace": "error",
            "noNamespaceImport": "error",
            "noNegationElse": "error",
            "noParameterProperties": "error",
            "noShoutyConstants": "error",
            "noYodaExpression": "error",
            "useBlockStatements": "error",
            "useCollapsedElseIf": "error",
            "useConsistentArrayType": "error",
            "useConsistentBuiltinInstantiation": "error",
            "useDefaultSwitchClause": "error",
            "useExplicitLengthCheck": "error",
            "useFilenamingConvention": {
               "level": "error",
               "options": {
                  "strictCase": true,
                  "requireAscii": true
               }
            },
            "useForOf": "error",
            "useFragmentSyntax": "off",
            "useNamingConvention": {
               "level": "error",
               "options": {
                  "strictCase": true,
                  "requireAscii": true,
                  "conventions": [
                     {
                        "selector": {
                           "kind": "importAlias",
                           "scope": "any"
                        },
                        "match": "ReactDOM|(.*)",
                        "formats": ["PascalCase"]
                     },
                     {
                        "selector": {
                           "kind": "interface"
                        },
                        "match": "Window|I(.*)|(.*?)Error",
                        "formats": ["PascalCase"]
                     }
                  ]
               }
            },
            "useNodeAssertStrict": "error",
            "useShorthandAssign": "error",
            "useThrowNewError": "error",
            "useThrowOnlyError": "error"
         },
         "suspicious": {
            "noConsole": "warn",
            "noEmptyBlockStatements": "error",
            "noEvolvingTypes": "off",
            "noMisplacedAssertion": "error",
            "noReactSpecificProps": "off",
            "noSkippedTests": "error",
            "useAwait": "error",
            "useErrorMessage": "error",
            "useNumberToFixedDigitsArgument": "error"
         }
      }
   }
}

Playground link

https://biomejs.dev/playground/?code=LwAqAAoAIAAqACAAIAAgAEUAdQByAG8AcABlAGEAbgAgAFUAbgBpAG8AbgAgAFAAdQBiAGwAaQBjACAATABpAGMAZQBuAHMAZQAgADEALgAyAAoAIAAqAAoAIAAqACAAIAAgAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABjACkAIAAyADAAMgA0ACwAIABNAHkAIABDAG8AbQBwAGEAbgB5ACAATgBhAG0AZQAKACAAKgAKACAAKgAgACAAIABUAGgAZQAgAGMAbwBuAHQAZQBuAHQAcwAgAG8AZgAgAHQAaABpAHMAIABmAGkAbABlACAAYQByAGUAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIAB0AGUAcgBtAHMAIABhAG4AZAAgAGMAbwBuAGQAaQB0AGkAbwBuAHMAIABkAGUAZgBpAG4AZQBkACAAaQBuACAAdABoAGUAIABMAGkAYwBlAG4AcwBlAC4ACgAgACoAIAAgACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAdQBzAGUALAAgAG0AbwBkAGkAZgB5ACwAIABvAHIAIABkAGkAcwB0AHIAaQBiAHUAdABlACAAdABoAGkAcwAgAGYAaQBsAGUAIABlAHgAYwBlAHAAdAAgAGkAbgAgAGMAbwBtAHAAbABpAGEAbgBjAGUAIAB3AGkAdABoACAAdABoAGUAIABMAGkAYwBlAG4AcwBlAC4ACgAgACoACgAgACoAIAAgACAAUwBQAEQAWAAtAEwAaQBjAGUAbgBzAGUALQBJAGQAZQBuAHQAaQBmAGkAZQByADoAIABFAFUAUABMAC0AMQAuADIACgAgACoALwAKAGkAbQBwAG8AcgB0ACAAewAgAEYAcgBhAGcAbQBlAG4AdAAsACAAdAB5AHAAZQAgAFIAZQBhAGMAdABOAG8AZABlACAAfQAgAGYAcgBvAG0AIAAiAHIAZQBhAGMAdAAiADsACgBpAG0AcABvAHIAdAAgAEUAbABlAGMAdAByAG8AbgBMAG8AZwBvACAAZgByAG8AbQAgACIAQABhAHMAcwBlAHQAcwAvAGUAbABlAGMAdAByAG8AbgAuAHMAdgBnACIAOwAKAGkAbQBwAG8AcgB0ACAAVgBlAHIAcwBpAG8AbgBzACAAZgByAG8AbQAgACIALgAvAFYAZQByAHMAaQBvAG4AcwAuAHQAcwB4ACIAOwA%3D

Code of Conduct

aabmets commented 1 week ago

This is the invalid result when biome check --write is executed on a file which requires import sorting and contains a license header:

import ElectronLogo from "@assets/electron.svg";
/*
 *   European Union Public License 1.2
 *
 *   Copyright (c) 2024, My Company Name
 *
 *   The contents of this file are subject to the terms and conditions defined in the License.
 *   You may not use, modify, or distribute this file except in compliance with the License.
 *
 *   SPDX-License-Identifier: EUPL-1.2
 */
import { Fragment, type ReactNode } from "react";
import Versions from "./Versions.tsx";

This is the expected result:

/*
 *   European Union Public License 1.2
 *
 *   Copyright (c) 2024, My Company Name
 *
 *   The contents of this file are subject to the terms and conditions defined in the License.
 *   You may not use, modify, or distribute this file except in compliance with the License.
 *
 *   SPDX-License-Identifier: EUPL-1.2
 */
import ElectronLogo from "@assets/electron.svg";
import { Fragment, type ReactNode } from "react";
import Versions from "./Versions.tsx";
ematipico commented 1 week ago

This isn't a bug, but the expected result.

Your comment (because it's a comment, even though it is a fancy one) is technically attached to the import statement right after, because there aren't any newlines.

If want to have your comments to be "sticky", you have to add a newline after the comment.

This is called "group" and it's explained in the relative chapter of our docs: https://biomejs.dev/analyzer/import-sorting/#grouped-imports

If you feel strongly about this kind of comments, feel free to open a discussion with concrete ideas on how support these cases