Skip to content

Conversation

@Kashugoyal
Copy link
Contributor

@Kashugoyal Kashugoyal commented Oct 9, 2025

Resolves #159

This PR:

  1. Adds a JSON formatter to format JSON files
  2. Adds the CLI and env flags for enable the formatter
  3. Adds and updates relevant unit and functional tests
  4. Updates existing JSON files in the repository to match the format

Left for Future work:

  1. Support for formatting check of other file types
  2. Allow configuration for formatters. For example allow single vs double indent

@Kashugoyal Kashugoyal changed the title feat: add json formatter draft: feat: add json formatter Oct 9, 2025
@kehoecj kehoecj added OSS Community Contribution Contributions from the OSS Community waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers labels Oct 10, 2025
@kehoecj kehoecj self-requested a review October 10, 2025 14:27
@kehoecj
Copy link
Collaborator

kehoecj commented Oct 10, 2025

@Kashugoyal Thanks for the PR - please address all Golang-CI comments and fix failing unit tests

@kehoecj kehoecj added pr-action-requested PR is awaiting feedback from the submitting developer and removed waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers labels Oct 10, 2025
@Kashugoyal Kashugoyal marked this pull request as draft October 10, 2025 17:02
@Kashugoyal Kashugoyal force-pushed the json-formatter branch 2 times, most recently from dcf1526 to 2061a41 Compare October 15, 2025 00:18
@Kashugoyal Kashugoyal marked this pull request as ready for review October 15, 2025 00:57
@Kashugoyal
Copy link
Contributor Author

@Kashugoyal Thanks for the PR - please address all Golang-CI comments and fix failing unit tests

@kehoecj PR is ready for review.

@kehoecj kehoecj changed the title draft: feat: add json formatter feat: add json formatter Oct 15, 2025
@kehoecj kehoecj added waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers and removed pr-action-requested PR is awaiting feedback from the submitting developer labels Oct 15, 2025
Copy link
Collaborator

@kehoecj kehoecj left a comment

Choose a reason for hiding this comment

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

Works as advertised but needs some architectural changes

groupOutputPtr = flag.String("groupby", "", "Group output by filetype, directory, pass-fail. Supported for Standard and JSON reports")
quietPtr = flag.Bool("quiet", false, "If quiet flag is set. It doesn't print any output to stdout.")
globbingPrt = flag.Bool("globbing", false, "If globbing flag is set, check for glob patterns in the arguments.")
formatPtr = flag.Bool("format", false, "Format all supported file types in place. Only json is supported currently.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking ahead to when multiple types are supported:

  • Users need to be able to specify which config types they want to format. All can be the default but needs to be configurable
  • Need to think about how we'll allow users to specify formatting settings. I know you had identified it in future work but I think it needs to be part of this PR. I don't think we'll be able to specify this on the command line, will probably have to be a config file (or multiple config files)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we do flags like --format-all, --format-json, --format-yaml, etc?
format-xxx to enable formatter for a specific file type,
format-all for all
format-config to follow config specification, e.g. --format-config ./formatter_config.json

For the settings specification, it can be a JSON file with top level keys for file types.
e.g.:

"formatters": ["json", "yaml", ..],
"json": { "indent": 2},
"toml": {..}
...

The implementation for the config would be a larger change and maybe we can address as a separate PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What about passing options to -format? Example: -format=all OR -format=json,yaml,ini?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like the settings JSON - that makes sense to me. Agree that would be part of a larger change later, just wanted to ensure the initial design didn't constrain the later implementation

pkg/cli/cli.go Outdated
Comment on lines 123 to 127
if ShouldFormat {
if exitCode, err := formatFiles(filesToFormat); err != nil {
return exitCode, fmt.Errorf("unable to format files: %w", err)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

The design of this could be refactored to be more efficient:

  • Call the formatter in the initial foundFiles loop rather than adding it to a list then looping again.
  • The formatFiles function logic should be moved down into the formatter rather than in the CLI

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made the changes as requested. Please take another look.

@kehoecj kehoecj added pr-action-requested PR is awaiting feedback from the submitting developer and removed waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers labels Oct 15, 2025
@Kashugoyal Kashugoyal marked this pull request as draft October 17, 2025 23:59
@Kashugoyal Kashugoyal marked this pull request as ready for review October 18, 2025 05:45
@Kashugoyal
Copy link
Contributor Author

@ccoVeille PR is ready for another look

@ccoVeille
Copy link
Contributor

Instead of reviewing the PR, I have just shared my thoughts and concerns on the issue that this PR is about.

#159 (comment)

Your code is OK. I could review it. But for now, I prefered to step out.

Note to make it clear I'm not against what you coded or the way you coded, I just feel it shouldn't be added to the tool

@kehoecj
Copy link
Collaborator

kehoecj commented Oct 22, 2025

@Kashugoyal Please make the following changes to the implementation based off the discussion in #159 :

  1. Change the CLI --format flag to --check-format to be more explicit that it will simply validate the formatting against the defaults, not make any changes. Users should be able to scope this to list of config types, i.e. --check-format=json,yaml
  2. Passing --check-format should only validate the formatting, not make the formatting changes. That will be handled by a --fix flag that will be implemented later
  3. Add new code under pkg/validator to validate the formatting against the defaults if --check-format is passed

Let me know if that makes sense.

@kehoecj kehoecj added the hacktoberfest-accepted Valid PR Hacktoberfest PR label Oct 23, 2025
@Kashugoyal
Copy link
Contributor Author

Kashugoyal commented Oct 24, 2025

@Kashugoyal Please make the following changes to the implementation based off the discussion in #159 :

  1. Change the CLI --format flag to --check-format to be more explicit that it will simply validate the formatting against the defaults, not make any changes. Users should be able to scope this to list of config types, i.e. --check-format=json,yaml
  2. Passing --check-format should only validate the formatting, not make the formatting changes. That will be handled by a --fix flag that will be implemented later
  3. Add new code under pkg/validator to validate the formatting against the defaults if --check-format is passed

Let me know if that makes sense.

@kehoecj what design do you prefer? I can list a few options below:

  1. Add another method to the Validator interface.
    type Validator interface {
         Validate(b []byte) (bool, error)
         ValidateFormat(b []byte, options interface{}) (bool, error)
    }

    options is a future looking feature. Can be skipped for the first iteration.

  2. Add a parameter to the existing method
    type Validator interface {
         Validate(b []byte, checkFormat bool) (bool, error)
    }

@kehoecj
Copy link
Collaborator

kehoecj commented Oct 24, 2025

@Kashugoyal Please make the following changes to the implementation based off the discussion in #159 :

  1. Change the CLI --format flag to --check-format to be more explicit that it will simply validate the formatting against the defaults, not make any changes. Users should be able to scope this to list of config types, i.e. --check-format=json,yaml
  2. Passing --check-format should only validate the formatting, not make the formatting changes. That will be handled by a --fix flag that will be implemented later
  3. Add new code under pkg/validator to validate the formatting against the defaults if --check-format is passed

Let me know if that makes sense.

@kehoecj what design do you prefer? I can list a few options below:

  1. Add another method to the Validator interface.

    type Validator interface {
         Validate(b []byte) (bool, error)
         ValidateFormat(b []byte, options interface{}) (bool, error)
    }

    options is a future looking feature. Can be skipped for the first iteration.

  2. Add a parameter to the existing method

    type Validator interface {
         Validate(b []byte, checkFormat bool) (bool, error)
    }

Good timing, I am going through the same design decision now that I'm adding schema. I was leaning toward #1 but the downside is that the interface is now more complicated. I don't like #2 because it makes the interface definition more complicated and forces design decisions into the implementing functions.

I think I'm leaning toward interface composition:

type SyntaxValidator interface {
  ValidateSyntax(b []byte) (bool, error)
}

type FormatValidator interface {
  ValidateFormat(Validate(b []byte, options interface{}) (bool, error)
}

// coming in my Sarif PR
type SchemaValidator interface {
  ValidateSchema(Validate(b []byte, schemaDefinition interface{}) (bool, error)
}

type Validator interface {
  SyntaxValidator
  FormatValidator
  SchemaValidator
}

That way, when required, the different validator interfaces can be fulfilled and referenced. What do you think?

@Kashugoyal
Copy link
Contributor Author

@Kashugoyal Please make the following changes to the implementation based off the discussion in #159 :

  1. Change the CLI --format flag to --check-format to be more explicit that it will simply validate the formatting against the defaults, not make any changes. Users should be able to scope this to list of config types, i.e. --check-format=json,yaml
  2. Passing --check-format should only validate the formatting, not make the formatting changes. That will be handled by a --fix flag that will be implemented later
  3. Add new code under pkg/validator to validate the formatting against the defaults if --check-format is passed

Let me know if that makes sense.

@kehoecj what design do you prefer? I can list a few options below:

  1. Add another method to the Validator interface.

    type Validator interface {
         Validate(b []byte) (bool, error)
         ValidateFormat(b []byte, options interface{}) (bool, error)
    }

    options is a future looking feature. Can be skipped for the first iteration.

  2. Add a parameter to the existing method

    type Validator interface {
         Validate(b []byte, checkFormat bool) (bool, error)
    }

Good timing, I am going through the same design decision now that I'm adding schema. I was leaning toward #1 but the downside is that the interface is now more complicated. I don't like #2 because it makes the interface definition more complicated and forces design decisions into the implementing functions.

I think I'm leaning toward interface composition:

type SyntaxValidator interface {
  ValidateSyntax(b []byte) (bool, error)
}

type FormatValidator interface {
  ValidateFormat(Validate(b []byte, options interface{}) (bool, error)
}

// coming in my Sarif PR
type SchemaValidator interface {
  ValidateSchema(Validate(b []byte, schemaDefinition interface{}) (bool, error)
}

type Validator interface {
  SyntaxValidator
  FormatValidator
  SchemaValidator
}

That way, when required, the different validator interfaces can be fulfilled and referenced. What do you think?

I like your idea. Will do that!

@Kashugoyal Kashugoyal marked this pull request as draft October 24, 2025 03:59
@Kashugoyal Kashugoyal marked this pull request as ready for review October 28, 2025 05:53
@Kashugoyal Kashugoyal requested a review from a team as a code owner October 28, 2025 05:53
@Kashugoyal
Copy link
Contributor Author

@kehoecj marking the MR ready for review. It has been a lot of back and forth therefore I may have missed some things in my MR, please review 😄

@kehoecj kehoecj added waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers and removed pr-action-requested PR is awaiting feedback from the submitting developer labels Oct 28, 2025
@kehoecj kehoecj added pr-action-requested PR is awaiting feedback from the submitting developer and removed waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers labels Nov 17, 2025
Copy link
Collaborator

@kehoecj kehoecj left a comment

Choose a reason for hiding this comment

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

During functional testing the following issue was found:

When passing the --check-format, the provided path is not honored by the confi-file-validator tool and it instead scans the current working directory:

~/src/github.com/boeing/pr/formatting/config-file-validator$ ./validator --check-for
mat test/fixtures/bad_format.json 
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/dependabot.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/changelog.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/go.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/golangci-lint.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/goreportcard.yaml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/mega-linter.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/release.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/scorecard.yml

When I remove the --check-format flag, the tools works as expected

@Kashugoyal Kashugoyal marked this pull request as draft November 19, 2025 02:51
@Kashugoyal Kashugoyal marked this pull request as ready for review November 19, 2025 03:13
@Kashugoyal
Copy link
Contributor Author

During functional testing the following issue was found:

When passing the --check-format, the provided path is not honored by the confi-file-validator tool and it instead scans the current working directory:

~/src/github.com/boeing/pr/formatting/config-file-validator$ ./validator --check-for
mat test/fixtures/bad_format.json 
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/dependabot.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/changelog.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/go.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/golangci-lint.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/goreportcard.yaml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/mega-linter.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/release.yml
    ✓ /src/github.com/boeing/pr/formatting/config-file-validator/.github/workflows/scorecard.yml

When I remove the --check-format flag, the tools works as expected

In the above case, the check-format flag assumes the following string is the file type and not the path. I added a validation function for this case and also added a test case for this scenario.

@kehoecj kehoecj added waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers and removed pr-action-requested PR is awaiting feedback from the submitting developer labels Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hacktoberfest-accepted Valid PR Hacktoberfest PR OSS Community Contribution Contributions from the OSS Community waiting-on-maintainer-review PR is waiting to be reviewed and functionally tested by the maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add functionality to auto-format or enforce formatting rules for config files

4 participants