hugoattal / eslint-plugin-sort-keys-custom-order

18 stars 2 forks source link

Sorting a large object or type takes too many rounds #2

Open tukusejssirs opened 2 years ago

tukusejssirs commented 2 years ago

I tried to sort a large interface (34 properties), as well as an object created from it, however, your plugin didn’t sort it in one run (running once eslint_d --fix $file), however, it took five rounds.

When I tried to do the same with an object with the same structure, it took six rounds!

Moreover, it does not append a comma. I don’t use trailing commas (never), however, when your plugins sort the properties, it leave the property which was originally the last one, without comma and the property which is currently the last one, with comma.

interface
interface: orig ```ts export interface I { PSQL_ADMIN_PASS: string, PSQL_ADMIN_USER: string, PSQL_DB_NAME_CS: string, PSQL_HOST: string, PSQL_PORT: number, PSQL_MAX_CONN: number, CACHE_PORT: number, CERT_CA: string, CERT_CERT: string, CERT_KEY: string, LIGHT_INDICATOR_TCP_PORT: number, LOG_LEVEL: string, LOG_LEVEL_ORM: boolean | undefined, MODBUS_PORT: number, MODBUS_TCP_PORT: number, MONGO_DATABASE_FANUC: string, MONGO_DATABASE_WS: string, MONGO_HOST: string MONGO_PASS: string, MONGO_PORT: number, MONGO_USER: string, MACHINE_TCP_PORT: number, MQTT_MQTT_HOST: string, MQTT_MQTT_PORT: number, MQTT_MQTT_PROTOCOL: string, MQTT_TCP_PORT: number, MQTT_WS_HOST: string, MQTT_WS_PORT: number, MQTT_WS_PROTOCOL: string, NEST_PORT: number, POWER_ON_PORT: number, REDIS_HOST: string, REDIS_PORT: number, TIMEZONE: string, } ```
interface: after first run ```ts export interface I { CACHE_PORT: number, CERT_CA: string, CERT_CERT: string, CERT_KEY: string, PSQL_ADMIN_PASS: string, LIGHT_INDICATOR_TCP_PORT: number, PSQL_ADMIN_USER: string, LOG_LEVEL: string, PSQL_DB_NAME_CS: string, LOG_LEVEL_ORM: boolean | undefined, PSQL_HOST: string, MACHINE_TCP_PORT: number, PSQL_MAX_CONN: number, MODBUS_PORT: number, PSQL_PORT: number, MODBUS_TCP_PORT: number, MONGO_DATABASE_FANUC: string, MONGO_DATABASE_WS: string MONGO_HOST: string, MONGO_PASS: string, MONGO_PORT: number, MONGO_USER: string, MQTT_MQTT_HOST: string, MQTT_MQTT_PORT: number, MQTT_MQTT_PROTOCOL: string, MQTT_TCP_PORT: number, MQTT_WS_HOST: string, MQTT_WS_PORT: number, MQTT_WS_PROTOCOL: string, NEST_PORT: number, POWER_ON_PORT: number, REDIS_HOST: string, REDIS_PORT: number, TIMEZONE: string, } ```
interface: after second run ```ts export interface I { CACHE_PORT: number, CERT_CA: string, CERT_CERT: string, CERT_KEY: string, LIGHT_INDICATOR_TCP_PORT: number, LOG_LEVEL: string, LOG_LEVEL_ORM: boolean | undefined, MACHINE_TCP_PORT: number, MODBUS_PORT: number, MODBUS_TCP_PORT: number, MONGO_DATABASE_FANUC: string, MONGO_DATABASE_WS: string, MONGO_HOST: string, MONGO_PASS: string, PSQL_ADMIN_PASS: string, MONGO_PORT: number, PSQL_ADMIN_USER: string, MONGO_USER: string PSQL_DB_NAME_CS: string, MQTT_MQTT_HOST: string, PSQL_HOST: string, MQTT_MQTT_PORT: number, PSQL_MAX_CONN: number, MQTT_MQTT_PROTOCOL: string, PSQL_PORT: number, MQTT_TCP_PORT: number, MQTT_WS_HOST: string, MQTT_WS_PORT: number, MQTT_WS_PROTOCOL: string, NEST_PORT: number, POWER_ON_PORT: number, REDIS_HOST: string, REDIS_PORT: number, TIMEZONE: string, } ```
interface: after third run ```ts export interface I { CACHE_PORT: number, CERT_CA: string, CERT_CERT: string, CERT_KEY: string, LIGHT_INDICATOR_TCP_PORT: number, LOG_LEVEL: string, LOG_LEVEL_ORM: boolean | undefined, MACHINE_TCP_PORT: number, MODBUS_PORT: number, MODBUS_TCP_PORT: number, MONGO_DATABASE_FANUC: string, MONGO_DATABASE_WS: string, MONGO_HOST: string, MONGO_PASS: string, MONGO_PORT: number, MONGO_USER: string, MQTT_MQTT_HOST: string, MQTT_MQTT_PORT: number MQTT_MQTT_PROTOCOL: string, MQTT_TCP_PORT: number, MQTT_WS_HOST: string, MQTT_WS_PORT: number, MQTT_WS_PROTOCOL: string, NEST_PORT: number, PSQL_ADMIN_PASS: string, POWER_ON_PORT: number, PSQL_ADMIN_USER: string, PSQL_DB_NAME_CS: string, PSQL_HOST: string, PSQL_MAX_CONN: number, PSQL_PORT: number, REDIS_HOST: string, REDIS_PORT: number, TIMEZONE: string, } ```
interface: after fourth run ```ts export interface I { CACHE_PORT: number, CERT_CA: string, CERT_CERT: string, CERT_KEY: string, LIGHT_INDICATOR_TCP_PORT: number, LOG_LEVEL: string, LOG_LEVEL_ORM: boolean | undefined, MACHINE_TCP_PORT: number, MODBUS_PORT: number, MODBUS_TCP_PORT: number, MONGO_DATABASE_FANUC: string, MONGO_DATABASE_WS: string, MONGO_HOST: string, MONGO_PASS: string, MONGO_PORT: number, MONGO_USER: string, MQTT_MQTT_HOST: string, MQTT_MQTT_PORT: number MQTT_MQTT_PROTOCOL: string, MQTT_TCP_PORT: number, MQTT_WS_HOST: string, MQTT_WS_PORT: number, MQTT_WS_PROTOCOL: string, NEST_PORT: number, POWER_ON_PORT: number, PSQL_ADMIN_PASS: string, PSQL_ADMIN_USER: string, PSQL_DB_NAME_CS: string, PSQL_HOST: string, PSQL_MAX_CONN: number, PSQL_PORT: number, REDIS_HOST: string, REDIS_PORT: number, TIMEZONE: string, } ```
object
object: orig ```ts const a = { PSQL_ADMIN_PASS: '', PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', PSQL_HOST: '', PSQL_PORT: 1, PSQL_MAX_CONN: 1, CACHE_PORT: 1, CERT_CA: '', CERT_CERT: '', CERT_KEY: '', LIGHT_INDICATOR_TCP_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, MODBUS_PORT: 1, MODBUS_TCP_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', MONGO_HOST: '', MONGO_PASS: '', MONGO_PORT: 1, MONGO_USER: '', MACHINE_TCP_PORT: 1, MQTT_MQTT_HOST: '', MQTT_MQTT_PORT: 1, MQTT_MQTT_PROTOCOL: '', MQTT_TCP_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, MQTT_WS_PROTOCOL: '', NEST_PORT: 1, POWER_ON_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '', } ```
object: after first run ```ts const a = { CACHE_PORT: 1, CERT_CA: '', PSQL_ADMIN_PASS: '', CERT_CERT: '', PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', CERT_KEY: '', PSQL_HOST: '', PSQL_MAX_CONN: 1, LIGHT_INDICATOR_TCP_PORT: 1, PSQL_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, MACHINE_TCP_PORT: 1, MODBUS_PORT: 1, MODBUS_TCP_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', MONGO_HOST: '', MONGO_PASS: '', MONGO_PORT: 1, MONGO_USER: '', MQTT_MQTT_HOST: '', MQTT_MQTT_PORT: 1, MQTT_MQTT_PROTOCOL: '', MQTT_TCP_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, MQTT_WS_PROTOCOL: '', NEST_PORT: 1, POWER_ON_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '' } ```
object: after second run ```ts const a = { CACHE_PORT: 1, CERT_CA: '', CERT_CERT: '', CERT_KEY: '', LIGHT_INDICATOR_TCP_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, PSQL_ADMIN_PASS: '', MACHINE_TCP_PORT: 1, PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', MODBUS_PORT: 1, PSQL_HOST: '', PSQL_MAX_CONN: 1, MODBUS_TCP_PORT: 1, PSQL_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', MONGO_HOST: '', MONGO_PASS: '', MONGO_PORT: 1, MONGO_USER: '', MQTT_MQTT_HOST: '', MQTT_MQTT_PORT: 1, MQTT_MQTT_PROTOCOL: '', MQTT_TCP_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, MQTT_WS_PROTOCOL: '', NEST_PORT: 1, POWER_ON_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '' } ```
object: after third run ```ts const a = { CACHE_PORT: 1, CERT_CA: '', CERT_CERT: '', CERT_KEY: '', LIGHT_INDICATOR_TCP_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, MACHINE_TCP_PORT: 1, MODBUS_PORT: 1, MODBUS_TCP_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', PSQL_ADMIN_PASS: '', MONGO_HOST: '', PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', MONGO_PASS: '', PSQL_HOST: '', PSQL_MAX_CONN: 1, MONGO_PORT: 1, PSQL_PORT: 1, MONGO_USER: '', MQTT_MQTT_HOST: '', MQTT_MQTT_PORT: 1, MQTT_MQTT_PROTOCOL: '', MQTT_TCP_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, MQTT_WS_PROTOCOL: '', NEST_PORT: 1, POWER_ON_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '' } ```
object: after fourth run ```ts const a = { CACHE_PORT: 1, CERT_CA: '', CERT_CERT: '', CERT_KEY: '', LIGHT_INDICATOR_TCP_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, MACHINE_TCP_PORT: 1, MODBUS_PORT: 1, MODBUS_TCP_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', MONGO_HOST: '', MONGO_PASS: '', MONGO_PORT: 1, MONGO_USER: '', MQTT_MQTT_HOST: '', PSQL_ADMIN_PASS: '', MQTT_MQTT_PORT: 1, PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', MQTT_MQTT_PROTOCOL: '', PSQL_HOST: '', PSQL_MAX_CONN: 1, MQTT_TCP_PORT: 1, PSQL_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, MQTT_WS_PROTOCOL: '', NEST_PORT: 1, POWER_ON_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '' } ```
object: after fifth run ```ts const a = { CACHE_PORT: 1, CERT_CA: '', CERT_CERT: '', CERT_KEY: '', LIGHT_INDICATOR_TCP_PORT: 1, LOG_LEVEL: '', LOG_LEVEL_ORM: true, MACHINE_TCP_PORT: 1, MODBUS_PORT: 1, MODBUS_TCP_PORT: 1, MONGO_DATABASE_FANUC: '', MONGO_DATABASE_WS: '', MONGO_HOST: '', MONGO_PASS: '', MONGO_PORT: 1, MONGO_USER: '', MQTT_MQTT_HOST: '', MQTT_MQTT_PORT: 1, MQTT_MQTT_PROTOCOL: '', MQTT_TCP_PORT: 1, MQTT_WS_HOST: '', MQTT_WS_PORT: 1, PSQL_ADMIN_PASS: '', MQTT_WS_PROTOCOL: '', PSQL_ADMIN_USER: '', PSQL_DB_NAME_CS: '', NEST_PORT: 1, PSQL_HOST: '', PSQL_MAX_CONN: 1, POWER_ON_PORT: 1, PSQL_PORT: 1, REDIS_HOST: '', REDIS_PORT: 1, TIMEZONE: '' } ```
hugoattal commented 1 year ago

Thanks for opening the issue! I admit I didn't have much time to look into for now...

The way it's working is that it compares two adjacent properties and swaps them if they are not in the correct order. (Now that I think of it, it's a freaking bubble sort, but with one round per run 😅) It would be far better to sort everything in one go, but I didn't find a good way to do it like this.

I keep these two problems in the back of my head and will fix it if I find some time for this: I don't consider it to be critical, as I think the ESLint fix should happen in the IDE, and those problems are super easy to manually fix. But it's still a bug.

Also, if someone wants to try it out, I accept PR of course 🙂

Gautam-Arora24 commented 1 year ago

I don't consider it to be critical, as I think the ESLint fix should happen in the IDE, and those problems are super easy to manually fix. But it's still a bug.

I, in one of my project sort the localisation keys using lint-staged i.e while committing the staged files. We usually, don't want the ESLint fix to run while the dev save because it will allow loosing context in which line the dev actually was. Therefore, sorting the labels in one go is a must have for us.

askew07 commented 1 year ago

@hugoattal Your plugin is incredible useful! Please find time to fix it :)

Besides the "too many rounds" report above, there is another important bug I just found:

Example:

const customObject = {
  /**
   * This is prop4
   */
  prop4: 'value4',
  /**
   * This is prop2
   */
  prop2: 'value2',
  /**
   * This is prop3
   */
  prop3: 'value3',
  /**
   * This is prop1
   */
  prop1: 'value1',
}

Becomes:

const customObject = {
  /**
   * This is prop4
   */
  prop1: 'value1',
  /**
   * This is prop2
   */
  prop2: 'value2',
  /**
   * This is prop3
   */
  prop3: 'value3',
  /**
   * This is prop1
   */
  prop4: 'value4',
}