coderaiser / putout

🐊 Pluggable and configurable JavaScript Linter, code transformer and formatter, drop-in ESLint superpower replacement 💪 with built-in support for js, jsx, typescript, flow, markdown, yaml and json. Write declarative codemods in a simplest possible way 😏
https://putout.cloudcmd.io/
MIT License
705 stars 40 forks source link

Option to configure printer overrides from #213

Closed MatthewScholefield closed 3 months ago

MatthewScholefield commented 3 months ago

I can't seem to find a way to configure tab size with putout. I see there are overrides within putoutjs/printer that can be specified like "format": {"indent": " "}. However, it doesn't look like these overrides are being passed through from the putout config. I tried adding the following in my package.json:

  "putout": {
    "format": {
      "indent": "  "
    }
  }

And of course this fails indicating the field isn't valid:

.putout.json: format: must NOT have additional properties
error: "putout" exited with code 12

It'd be nice to allow customizing this so we could change indent size.

MatthewScholefield commented 3 months ago

Hmm, actually I see this comment indicates it should theoretically work like this:

  "putout": {
    "printer": [
      "putout",
      {
        "format": {
          "indent": "  "
        }
      }
    ]
  }

While this doesn't error saying invalid config, it also doesn't seem to change the behavior of indentations.

coderaiser commented 3 months ago

Create .putout.json with:

{
    "printer": ["putout", {
        "format": {
            "indent": "  "
        }
    }]
}

Is it works for you?

MatthewScholefield commented 3 months ago

Hmm, that doesn't work either. Here is a full example:

$ cat > example.js
function testFn() {
return 123;
}
testFn();

$ cat > .putout.json
{"printer":["putout",{"format":{"indent":"  "}}]}

$ putout example.js --fix
$ cat example.js
function testFn() {
    return 123;
}

testFn();
$ putout --version
v35.37.1
MatthewScholefield commented 3 months ago

Haven't gotten time to finish investigating but I'll drop what I found so far. After running off of a git clone I'm seeing:

$ node ../putout/packages/putout/bin/putout.mjs example.js
🐊 .putout.json: printer: must NOT have more than 2 items

And the config it's evaluating has:

...
printer: [ 'putout', { format: [Object] }, { format: [Object] } ],
...

So it looks like maybe the default config's array is getting merged with the provided config's array?

coderaiser commented 3 months ago

Just fixed in 🐊Putout v36. Is it works for you?

MatthewScholefield commented 3 months ago

Thanks so much for the quick response! Actually, it still didn't work with v36. Upon further investigation, the problem seems to be that I somehow have a file ~/.putout.json which is causing this issue. After removing it, the problem is resolved. But of course a user-level config shouldn't mess with a repo config so the root cause should still probably be addressed.

I think a hacky solution might be to modify arrayUnion to check if typeof a[0] == 'string' && typeof a[1] == 'object' and do special merge logic under this condition. But in general, I wonder if changing the config paradigm from (pseudocode) x || [x, options] to x || {value: x, options: options} would be better. It's a little more verbose but then config merging could use standard recursive merge. However to keep backwards compatibility might be a bit clunky since it needs to then have all three (x || [x, params] || {value: x, options: options}).

By the way, thanks so much for the quick response / change!

coderaiser commented 3 months ago

What did you have in your ~/.putout.json file?

MatthewScholefield commented 3 months ago

The exact same content:

{"printer":["putout",{"format":{"indent":"  "}}]}
coderaiser commented 3 months ago

You can add additional merging options to merge.js with a test. Are you up for a PR?

coderaiser commented 3 months ago

Just fixed, please re-install 🐊Putout, is it works for you?