Skip to content

Sort and Format JSONC Build Files #1970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

Bashamega
Copy link
Contributor

Overview

This pull request introduces a script that formats and sorts JSONC (JSON with comments) files alphabetically. The script is designed to enhance the readability and maintainability of build configuration files by ensuring that the keys within these files are consistently ordered.

Changes Made

  • Added a sorting function: A helper function sortObjectKeys has been implemented to recursively sort the keys of an object. This function ensures that all nested objects are also sorted, providing a comprehensive sorting solution.
  • File processing: The sortFiles function reads specified JSONC files, parses them while preserving comments, sorts their keys, and then writes the sorted content back to the original files.

Code Explanation

The script is implemented in TypeScript and utilizes the fs module for file operations and the comment-json package to handle JSONC parsing and stringification. Below is a breakdown of the key components:

  1. sortObjectKeys Function:

    • This function takes an object as input and checks if it is indeed an object and not an array.
    • It sorts the keys of the object alphabetically and recursively applies the same sorting to any nested objects.
    • If the input is not an object, it returns the input as is.
    function sortObjectKeys<T>(obj: T): T {
      if (obj && typeof obj === "object" && !Array.isArray(obj)) {
        const sorted = {} as any;
        Object.keys(obj)
          .sort()
          .forEach((key) => {
            sorted[key] = sortObjectKeys((obj as any)[key]);
          });
        return sorted;
      }
      return obj;
    }
  2. sortFiles Function:

    • This function defines an array of file names that need to be processed.
    • It constructs the file path for each JSONC file, reads its content, and parses it while preserving comments.
    • The parsed object is then sorted using the sortObjectKeys function.
    • Finally, the sorted object is converted back to JSONC format and written back to the original file.
    export function sortFiles() {
      const files = ["overridingTypes", "removedTypes", "addedTypes"];
      files.forEach((file) => {
        const filePath = new URL(`../../inputfiles/${file}.jsonc`, import.meta.url);
        const fileContent = fs.readFileSync(filePath, "utf-8");
        const parsed = commentJson.parse(fileContent, undefined, true);
        const sortedObject = sortObjectKeys(parsed);
        const sortedJsonC = commentJson.stringify(sortedObject, null, 2);
        fs.writeFileSync(filePath, sortedJsonC, "utf-8");
      });
      console.log("JSONC file keys sorted successfully.");
    }

Usage

To use this script, simply call the sortFiles function. Ensure that the specified JSONC files are located in the correct directory as indicated in the file path construction.

Benefits

  • Improved Readability: Sorting keys alphabetically makes it easier to locate specific entries within the JSONC files.
  • Consistency: Ensures that the structure of the configuration files remains consistent across different environments and updates.

Next Steps

  • Review the code for any potential improvements or optimizations.
  • Consider adding unit tests to verify the functionality of the sorting and formatting process.

Thank you for reviewing this pull request! I look forward to your feedback.

@@ -0,0 +1,41 @@
import * as fs from "fs";
import commentJson from "comment-json";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already use jsonc-parser, should be able to use here.

The important thing is that the comments should be there, while it's all being stripped out in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need to check in a full sorter, it should be enough to check whether it's sorted and throw error if not when linting.

Copy link
Contributor

@saschanaz saschanaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What code did you use to sort it one-time though? Might be nice to be able to validate one-time.

src/build.ts Outdated
@@ -396,3 +397,4 @@ async function emitDom() {
}

await emitDom();
sortFiles();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be part of build, it should rather be part of npm run lint.

return foundTrailingComma;
}

export function sortFiles(): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about sorting anymore, it's about verifying it's sorted. And it's not sorting "files", it's sorting fields.

}
return sorted as T;
}
return obj;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This do not need to return an object, maybe do not return anything and throw if it's not sorted.

"enum": {
"InsertPosition": {
"name": "InsertPosition",
"mixins": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something is definitely off here; this is indented by 2 spaces, but the rets by 4 spaces (expected).

@Bashamega
Copy link
Contributor Author

Bashamega commented Apr 12, 2025

Hello @saschanaz
I'm sorry, your requests fell out of my inbox.
I will fix it today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants