chris48s / v8r

✔️ A command-line JSON, YAML and TOML validator that's on your wavelength
https://chris48s.github.io/v8r/
MIT License
29 stars 5 forks source link

Add a CLI argument to specify the configuration file #512

Closed lvjp closed 3 weeks ago

lvjp commented 1 month ago

When you use a linter collection tool like MegaLinter, by default, we put all the configuration files into the folder .github/linters.

And thus, if you create .github/linters/.v8rrc.yml, this cannot be used by v8r because there is CLI argument to specify the configuration file.

chris48s commented 1 month ago

Firstly:

Is this effectively a duplicate of https://github.com/chris48s/v8r/issues/231 or are they 2 different issues.


Secondly:

One of the reasons why v8r only looks for the config file in the place where you're calling v8r is that v8r relies quite heavily on relative paths and glob patterns.

So if you imagine a repo with the following files in it:

You might write a config file that looks like this:

patterns: ['**/*.json']
customCatalog:
    schemas:
        - name: Schema for two.json
          fileMatch: ["documents/two.json"]
          location: schemas/custom-schema.json
plugins:
    - "file:./plugins/my-local-plugin.mjs"

and whether you think of those relative paths as being relative to the working directory you're in when you invoke v8r or relative to the path of the config file doesn't really matter. Makes sense either way because they are both the same path. Also the way I've implemented this internally is a bit inconsistent :grimacing: but that also that doesn't matter.

In a world where you can put the config file somewhere else (lets say .github/linters/.v8rrc.yml for example) our repo is now

and we invoke v8r --config .github/linters/.v8rrc.yml, it becomes ambiguous. One way you could do it is write the exact same config file, put it somewhere else, and resolve everything relative to the working directory you're in when you call v8r. I feel like that makes the config file less intuitive to write in some ways, but probably easier to implement.

The other thing you could do is say everything in the config file is relative to the location of the config file, so if you want to put your config file in .github/linters/.v8rrc.yml you now need to write.

patterns: ['../../**/*.json']
customCatalog:
    schemas:
        - name: Schema for two.json
          fileMatch: ["../../documents/two.json"]
          location: ../../schemas/custom-schema.json
plugins:
    - "file:../../plugins/my-local-plugin.mjs"

and then internally everything resolves relative to the config file location if you're using one. That feels nicer in some ways, and messier in others. I guess if you look at the config file in isolation it is perhaps more intuitive to read/write, but internally it means options specified in the config file need to be resolved differently from command line arguments and data from remote catalogs, which makes everything way harder.

As someone who would presumably want to use this feature if it existed, how would this make intuitive sense to you? Presumably you deal with other tools that run into some version of this problem. Do you have a link to a repo laid out like this with config files for some other tools that I can have a look at?

lvjp commented 1 month ago

I think that this issue is not like #231 since I focus on the way to retrieve the configuration file.

With the actual v8r implementation, you're right, the invocation v8r --config .github/linters/.v8rrc.yml is ambiguous. The root cause is that the configuration file settings depend on his location.

If we change the paradigm to break the relation with the file location, in all cases (i.e: .v8rrc.yml and .github/linters/.v8rrc.yml), we will have a simple configuration file :

patterns: ['**/*.json']
customCatalog:
    schemas:
        - name: Schema for two.json
          fileMatch: ["documents/two.json"]
          location: schemas/custom-schema.json
plugins:
    - "file:./plugins/my-local-plugin.mjs"

I think that generally, when you give a configuration file with the command line arguments, the settings depend on the current work directory when you invoke the tool.

You may want to see my fabulous project : https://github.com/lvjp/multi-linters/tree/issues/v8r-512

chris48s commented 1 month ago

I had a look over how some other tools handle this and it seems that there is very little consistency. That said, I think my conclusion is that making everything relative to CWD (even if the config file is loaded from elsewhere) is both the easiest thing to do and at least a defensible decision that can be documented. Here's an example of how ESLint documents their decisions on this https://eslint.org/docs/latest/use/configure/configuration-files#specifying-files-and-ignores I think I can also use verbose logging to make it a bit more explicit what is happening.

This does require some changes to both internals and docs though. It isn't just adding a flag.

chris48s commented 3 weeks ago

Hello. I've just released v8r version 4.2.0 which allows you to specify the config file location.

In the end, I didn't do this as a command line flag because plugins can register command line flags. That means we need to load plugins before we can parse args, which in turn means we have to parse the config file before we can parse args.

So in order to provide this, I made the setting an env var: V8R_CONFIG_FILE

Either way, you can use it to specify a location anywhere. There is a little more detail in https://chris48s.github.io/v8r/configuration/