Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Run on-save tools for entire workspace #1023

Merged
merged 7 commits into from
Jun 8, 2017

Conversation

vapourismo
Copy link
Contributor

Changes the default behavior from running lint/vet/build for the package of the current active file to running it for the entire workspace.

Potential downside is not having a flag which allows the behavior to be changed between current package and workspace (as with #830). Something for the future.

@msftclas
Copy link

msftclas commented Jun 7, 2017

@vapourismo,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by Microsoft. We will now review your pull request.
Thanks,
Microsoft Pull Request Bot

@ramya-rao-a
Copy link
Contributor

ramya-rao-a commented Jun 7, 2017

We do need a flag to control current package vs whole workspace.

In #830 we talked about a setting go.multiPackage, but thinking more on this, something like the below would be better instead of adding another setting.

 "go.buildOnSave": {
          "type":"string",
          "enum": [            
            "currentPackage",
            "currentWorkspace"
          ],
          "default": "currentPackage",
          "description": "Run 'go build'/'go test -c' on save on either the current package or the current workspace."
        }

With this, people who have set go.buildOnSave to true or false beforehand, will get a linting error

image

In the code, we can continue to honor either of true, false as well as the new values so that we are backward compatible.

Copy link
Contributor

@ramya-rao-a ramya-rao-a left a comment

Choose a reason for hiding this comment

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

Please add the setting to control package vs workspace

@vapourismo
Copy link
Contributor Author

Which value should you set, if you want it to be disabled? null or "nothing"?

@ramya-rao-a
Copy link
Contributor

How about off ?

@vapourismo
Copy link
Contributor Author

vapourismo commented Jun 7, 2017

Okay, I added these options as workspace, package and off.

There are those two failed tests in the CI which only occur for macOS. Seems to be something with gometalinter. They seem odd to me, since I didn't modify how the linter is invoked.

@vapourismo
Copy link
Contributor Author

Nevermind, it is just the tip line that is failing. And it seems unrelated to this PR.

src/goCheck.ts Outdated

if (buildWorkspace) {
buildWorkDir = vscode.workspace.rootPath;
args.push('./...');
Copy link
Contributor

Choose a reason for hiding this comment

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

When the current file that is open is a test file, this will end up running go test -i ./... which will run the tests in the workspace instead of trying to compile them

For compiling test files, we need to use go test -c and -c cannot be used on multi-package.

@rakyll @campoy @mattetti Do you know of a way to compile test files under a directory?

@vapourismo
Copy link
Contributor Author

How about this? Original behavior with package should be the same, I think.

src/goCheck.ts Outdated
* This ignores hidden directories and their sub-directories.
* @param dirPath Directory in which to start searching
*/
function findTestDirectories(dirPath: string): string[] {
Copy link
Contributor

@ramya-rao-a ramya-rao-a Jun 8, 2017

Choose a reason for hiding this comment

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

I appreciate the work here. Consider this

  • User with a very large workspace with deeply nested directories
  • User with auto-save on

The directories check here is synchronous.
We later wait for all promises (build, lint, vet) to finish before showing diagnostics to the user.

So you can imagine for each save, this might delay results more than needed.
Note: We have #1015 tracking to find a way to optimize this.

Also, I'd much rather prefer a better way to compile test files from Go itself.

Until then, we can skip trying to compile the test files in the whole workspace.

if (buildOnSave is not 'off') {
    if (buildWorkspace)
        `go build -i -o ./...`
    
   if (current file is test file)
       `go test -i -c -o <import path>`
   else if (!buildWorkspace)
      `go build -i -o <import-path>`
}

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've had the exact same thought, but I've come to the conclusion that it doesn't matter. If you set it to build the entire workspace, you should expect that to happen. In case somebody uses a big workspace, they can set it to build only the current package in the workspace-local settings.

Additionally, even though the directory traversal uses synchronous functions, it is way faster than the lint/vet/etc jobs. It appears that the extension accumulates the results of all "check"-Promises anyway, so delaying some for a couple milliseconds doesn't really hurt.

I understand and agree that this is not a particularly smart solution, but it should work for most use cases.

Also, I'd much rather prefer a better way to compile test files from Go itself.

Not sure, if that is going to happen. The only smart alternative is to run go test -run ! ./..., which will check the test files, but won't run any since they don't match the pattern. Could you work with that?

Copy link
Contributor

Choose a reason for hiding this comment

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

go test -run ! ./...

Lets give this a try. I was initially not in favor of this as the output is different (lots of "no test files" followed by a "build failed" on the pkg which has error) and we will have to write a different regex to do the problem matching.

But taking a closer look, there is also a line in there which matches our expectation and our current regex should work.

screen shot 2017-06-08 at 12 12 22 pm

@vapourismo
Copy link
Contributor Author

vapourismo commented Jun 8, 2017

go test -run ! ./.. works, sort of. It also checks the packages, so there are duplicates from go build.

Interestingly, it also checks packages that do not contain tests. So theoretically go build and go test can be merged, in the check function.

Sets the current working directory to the workspace root when linting
and vetting. Also appends the './...' argument which causes the tools to
traverse the workspace recursively. Other tools are not affected.

Additionally, this will utilize 'go vet' instead of 'go tool vet'.
Sets working directory for 'go build' command to workspace root. Also
adds './...', so the entire workspace is traversed.
This modifies settings 'buildOnSave', 'lintOnSave' and 'vetOnSave'. The
new options are 'workspace', 'package' or 'off' which will cause the
respective on-save tools to run in the determined scope.

Old values will still work as they did before.
'buildOnSave' compiles the test for the current package if the saved
file is a test unit, no matter if it is set to 'workspace' or 'package'.
If 'buildOnSave' is set to 'workspace', the check function will traverse
the workspace in order to find sub-packages that can be tested and
subsequently compiles those tests.
Utilize 'go test' to check all tests in the workspace without actually
running them.
Utilize 'go test -run=^$ ./...' when building entire workspace, 'go build'
for current package and 'go test -c' for the current package when the
current file is a test file.
@vapourismo
Copy link
Contributor Author

Latest commit prevents duplicates.

Copy link
Contributor

@ramya-rao-a ramya-rao-a left a comment

Choose a reason for hiding this comment

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

Thanks for all the work!

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

Successfully merging this pull request may close these issues.

3 participants