dotnet / format

Home for the dotnet-format command
MIT License
1.94k stars 172 forks source link

Confusing error reports when using it in combination with husky, commitlint and lint-staged #1156

Open ithinkthisisnotreal opened 3 years ago

ithinkthisisnotreal commented 3 years ago

When using the tool in combination with husky, commitlint and lint-staged I get confusing error reports.

How to reproduce it:

dotnet format .\TheProject\TheProject.sln

It should work fine.

Setup the package.json file

npm init -y

Setup commitlint and husky as described here

https://commitlint.js.org/#/guides-local-setup?id=guide-local-setup

After that setup lint-staged as described here

https://github.com/okonet/lint-staged#installation-and-setup

Your package.json should be simliar to this

{
  "lint-staged": {
    "*.cs": "dotnet format ./TheProject/TheProject.sln"
  },
  "devDependencies": {
    "@commitlint/cli": "^12.1.1",
    "@commitlint/config-conventional": "^12.1.1",
    "husky": "^6.0.0",
    "lint-staged": "^10.5.4"
  },
  "scripts": {
    "prepare": "husky install"
  }
}

You should see this output

> git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.cs
[STARTED] dotnet format ./TheProject/TheProject.sln
[FAILED] dotnet format ./TheProject/TheProject.sln [FAILED]
[FAILED] dotnet format ./TheProject/TheProject.sln [FAILED]
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SKIPPED] Skipped because of errors from tasks.
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...

✖ dotnet format ./TheProject/TheProject.sln:
Unrecognized command or argument '/home/.../my-repository/TheProject/Assembly1/MyFile.cs'

dotnet-format
  dotnet-format

Usage:
  dotnet-format [options] [<workspace>]

Arguments:
  <workspace>  A path to a solution file, a project file, or a folder containing a solution or project file. If a path is not specified then the current directory is used. [default: ]

Options:
  --no-restore                                                             Doesn't execute an implicit restore before formatting.
  -f, --folder                                                             Whether to treat the `<workspace>` argument as a simple folder of files.
  -w, --fix-whitespace                                                     Run whitespace formatting. Run by default when not applying fixes.
  -s, --fix-style <error|info|warn>                                        Run code style analyzers and apply fixes.
  -a, --fix-analyzers <error|info|warn>                                    Run 3rd party analyzers and apply fixes.
  --diagnostics <diagnostics>                                              A space separated list of diagnostic ids to use as a filter when fixing code style or 3rd party issues. [default: ]
  --include <include>                                                      A list of relative file or folder paths to include in formatting. All files are formatted if empty. [default: ]
  --exclude <exclude>                                                      A list of relative file or folder paths to exclude from formatting. [default: ]
  --check                                                                  Formats files without saving changes to disk. Terminates with a non-zero exit code if any files were formatted.
  --report <report-path>                                                   Accepts a file path, which if provided, will produce a json report in the given directory.
  -v, --verbosity <d|detailed|diag|diagnostic|m|minimal|n|normal|q|quiet>  Set the verbosity level. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]
  --binarylog <binary-log-path>                                            Log all project or solution load information to a binary log file.
  --version                                                                Show version information
  -?, -h, --help                                                           Show help and usage information

husky - pre-commit hook exited with code 1 (error)

There are two questions coming to my mind

JoeRobich commented 3 years ago

@ithinkthisisnotreal Thanks for giving dotnet-format a try. Looking at your configuration, you need to also pass the --include options when invoking dotnet-format.

  "lint-staged": {
    "*.cs": "dotnet format ./TheProject/TheProject.sln --include"
  },

Another issue is that dotnet-format expects the include paths to be relative to the workspace (./TheProject/TheProject.sln). This means you will need to update the lint-staged invocation with the --relative flag.

This was a very helpful blog post about using dotnet-format and lint-staged - https://blog.johnnyreilly.com/2020/12/22/prettier-your-csharp-with-dotnet-format-and-lint-staged/#lint-staged-integration

ithinkthisisnotreal commented 3 years ago

@JoeRobich thanks a lot for your help! I updated my package.json, now it looks like

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged --relative"
    }
  },
  "lint-staged": {
    "*.cs": "dotnet format ./TheProject/TheProject.sln --include"
  },
  "devDependencies": {
    "@commitlint/cli": "^12.1.1",
    "@commitlint/config-conventional": "^12.1.1",
    "husky": "^6.0.0",
    "lint-staged": "^10.5.4"
  },
  "scripts": {
    "prepare": "husky install"
  }
}

I'm not sure if this is correct because I tried to commit the following code violating many C# rules (but I don't have custom rules, I'm using the default ones)

                        public void AMethod(

                            string foo

                        )
            {
                            if(foo == "bar") {  

                            } else {

                                                    }
                                                    }

        private int x = 0;

So this commit shouldn't pass right?

JoeRobich commented 3 years ago

@ithinkthisisnotreal I think this touches on the other issue, that paths should be relative to the workspace opened in dotnet-format, which is in the ./TheProject folder. This is a limitation we hope to fix in a following release.

lint-staged is likely passing paths relative to the root of your repo. You may be able to work around this by changing the "pre-commit" hook to invoke "./TheProject/lint-staged --relative".

matthiashermsen commented 3 years ago

@JoeRobich thanks! I tried your suggested workaround but unfortunately it didn't work for me (maybe for OP). Based on the sample package.json posted above I modified it to this

{
  "husky": {
    "hooks": {
      "pre-commit": "./TheProject/lint-staged --relative"
    }
  },
  "lint-staged": {
    "*.cs": "dotnet format ./TheProject/TheProject.sln --include"
  },
  "devDependencies": {
    "@commitlint/cli": "^12.1.1",
    "@commitlint/config-conventional": "^12.1.1",
    "husky": "^6.0.0",
    "lint-staged": "^10.5.4"
  },
  "scripts": {
    "prepare": "husky install"
  }
}

So should we stick to this

https://github.com/dotnet/format/issues/1156#issuecomment-848507819

solution and wait for the update? :)