Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove g:go_autodetect_gopath #1525

Merged
merged 10 commits into from
Nov 25, 2017
Merged

Remove g:go_autodetect_gopath #1525

merged 10 commits into from
Nov 25, 2017

Conversation

arp242
Copy link
Contributor

@arp242 arp242 commented Oct 19, 2017

Follow-up to #1461.

Needs a bit more testing.

let old_gopath = $GOPATH
let old_goroot = $GOROOT
let $GOPATH = go#path#Detect()
let $GOROOT = go#util#env("goroot")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not 100% sure about removing this particular case though. Need to carefully read that issue.

Copy link
Owner

Choose a reason for hiding this comment

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

this is needed for Go upgrades. Unfortunately gocode embeds the goroot into the binary instead of looking from env, after a Go upgrade gocode can be broken if the user has a version based path. i.e: /usr/lib/go/1.9.1/src.

Copy link
Owner

Choose a reason for hiding this comment

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

We should keep the goroot behavior but remove the gopath change.

@bhcleek
Copy link
Collaborator

bhcleek commented Oct 19, 2017

I like getting rid of all the code that this eliminates, and I agree that setting $GOPATH using events is better. But I'm not sure we should break people like this. Why not go ahead and add support for the events?

We'd need to handle a number of events:

  • BufNewFile
  • BufReadPre
  • BufFilePre
  • BufEnter

@arp242
Copy link
Contributor Author

arp242 commented Oct 19, 2017

Wouldn't just the FileType autocommand be enough?

@bhcleek
Copy link
Collaborator

bhcleek commented Oct 19, 2017

No, because environment variable are global within a Vim session. If two files with different detected gopaths were open, the last one to be opened would set the gopath that would take effect when running commands in the first unless $GOPATH were set when changing windows and buffers.

@arp242
Copy link
Contributor Author

arp242 commented Oct 19, 2017

Oh, right. That makes sense 👍

@arp242 arp242 added wip and removed wip labels Oct 30, 2017
@arp242
Copy link
Contributor Author

arp242 commented Nov 4, 2017

Okay, I added it back as autocommands.

I think just the BufEnter and BufLeave should be enough? That seems to work well in my tests anyway.

Copy link
Collaborator

@bhcleek bhcleek left a comment

Choose a reason for hiding this comment

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

I've started looking at this and testing it. I want to spend a bit more time with it, especially making sure that the autocmd events are complete.

\ join(a:args)
\ )

let result = go#util#System(cmd)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like a good time to convert this to go#util#Exec, but I won't object if you don't want to do it now.

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'd rather not, since much of this isn't tested and can introduce regressions. Unless we're very careful we may have issues with double shell quoting for example.

I want to add a test for every tool which tests stuff like filenames with spaces, directories that don't exist, etc. and also fix whatever is needed (add build tags, use #Exec(), and whatever else might be needed). This is why I made the changes to the testing script and removed all the GOPATH detection.

@bhcleek bhcleek self-requested a review November 6, 2017 01:20
@bhcleek bhcleek mentioned this pull request Nov 13, 2017
@arp242
Copy link
Contributor Author

arp242 commented Nov 17, 2017

I've started looking at this and testing it. I want to spend a bit more time with it, especially making sure that the autocmd events are complete.

Don't want to push you, but did you have a chance to look at this?

I tested with a whole bunch of different scenarios, and it seemed to work well in all of them.

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 17, 2017

Not yet. I should be able to get to it by next week (though probably this weekend).

Copy link
Collaborator

@bhcleek bhcleek left a comment

Choose a reason for hiding this comment

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

This mostly looks great. Thanks @Carpetsmoker.

I tested a couple of different ways.
Besides testing this PR as is, I also tested the firing of events: I added

autocmd BufEnter * echom "bufenter"
autocmd BufLeave * echom "bufleave"

to my vimrc and then I opened three windows. Two of the windows had the same buffer loaded, and the third window had a second buffer loaded. I then opened a new tab with a third buffer loaded. Finally, I moved between the windows and did a variety of moving between the windows, tabs, loading other buffers (for both new and existing files), splitting, and running :bufdo. After each test I checked :messages to make sure it contained what I expected. Before each test I ran :messages clear to make sure the messages after the next test would contain only the messages caused by entering and leaving the buffers for that test.

Among other things that I documented inline,
I also noticed that if $HOME/src exists, and the user is someplace in$HOME/go/src/ with g:go_autodetect_gopath on and GOPATH unset , $HOME and $HOME/src get added to $GOPATH it's not clear to me if that's an existing issue or not; I'll leave it to you to figure out if it's an existing issue and whether or not to fix it in this PR if it is. If it is introduced by this PR, then I'd ask that it be fixed before merging this PR.

plugin/go.vim Outdated
\ if get(g:, 'go_autodetect_gopath', 0)
\| let $GOPATH = b:old_gopath
\| endif
augroup end
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the rare case when a user changes g:go_autotdetect_gopath, BufLeave will not behave as expected. Instead of if get(g: 'go_autodetect_gopath', 0), if exists(b:old_gopath) will guard restoring GOPATH correctly. We should also unset b:old_gopath...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point; I've updated the PR with this issue and the other small issues you found.

plugin/go.vim Outdated
\| endif
autocmd BufLeave *.go
\ if get(g:, 'go_autodetect_gopath', 0)
\| let $GOPATH = b:old_gopath
Copy link
Collaborator

Choose a reason for hiding this comment

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

(nit) When the old GOPATH was not set, restoring GOPATH to an empty string does not faithfully restore the state to what it was. As a pragmatic matter, all the go tooling will handle this case correctly, but users may have other scripts, etc. that do not. As I see it, vim-go should restore GOPATH to its state prior to entering the buffer.

@@ -260,6 +260,16 @@ augroup vim-go
" in the same window doesn't highlight the most recently matched
" identifier's positions.
autocmd BufWinEnter *.go call go#guru#ClearSameIds()
augroup END

autocmd BufEnter *.go
Copy link
Collaborator

Choose a reason for hiding this comment

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

I saw some cases where BufEnter gets fired twice, but I was unable to duplicate it when I tried to.

In any event, it caused me to realize that if vim fires BufEnter twice, the second event will cause b:old_gopath to be overwritten with the current $GOPATH, and then when the buffer is left, BufLeave cannot assign the original value of GOPATH. Can we add protection for this case by only checking g:go_autodetect_gopath when if !exists('b:old_gopath')

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 24, 2017

Did you mean to duplicate the changelog message in BACKWARDS INCOMPATIBILITIES and IMPROVEMENTS?

@arp242
Copy link
Contributor Author

arp242 commented Nov 24, 2017

Oops, no; that was just a merge error.

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 25, 2017

Don't forget to unlet b:old_gopath in the BufLeave after restoring `$GOPATH, too.

And this still didn't handle the situation I mentioned in #1525 (comment)

@arp242
Copy link
Contributor Author

arp242 commented Nov 25, 2017

Don't forget to unlet b:old_gopath in the BufLeave after restoring `$GOPATH, too.

Ah, right. Fixed.

And this still didn't handle the situation I mentioned in #1525 (comment)

I believe it should, as it checks for if get(b:, 'old_gopath', '') isnot ''.

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 25, 2017

I believe it should, as it checks for if get(b:, 'old_gopath', '') isnot ''.

On my system, GOPATH is not set, so in BufEnter, let b:old_gopath = $GOPATH will set b:old_gopath to the empty string., then in BufLeave, instead of unlet $GOPATH, GOPATH is set to the empty string using let $GOPATH = b:old_gopath. Unfortunately, Vim doesn't seem to have a way to unset an environment variable: vim/vim#1116.

Can you add a comment in the BufLeave, though, documenting this edge case?

Also, now that unlet b:old_gopath is used in BufLeave, its guard should use if exists(b:old_gopath), otherwise for people whose GOPATH is the empty string (which will be everyone after the BufLeave executes after BufEnter where GOPATH was not set!), GOPATH will never be set to the empty string.

arp242 added a commit that referenced this pull request Nov 25, 2017
Deals better with some errors, add some commandline flags, and improve
output.

It will now also run tests from all directories, instead of the autoload
directory. I wanted to add a test for #1525, and putting it in
`autoload/go/` seemed wrong to me.

Would also be nice to be able to run just one test with e.g.
`-r tags_test.vim:Test_Foo`. I'll add that when I need it I guess.

Regular:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.146627s / 2 tests
	ok   fillstruct_test.vim        0.685770s / 1 tests
	ok   tool_test.vim              0.083538s / 2 tests
	ok   def_test.vim               0.018329s / 2 tests
	ok   fmt_test.vim               0.023622s / 3 tests

	All tests PASSED

Test failure:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.117528s / 2 tests
	ok   fillstruct_test.vim        0.772903s / 1 tests
	ok   tool_test.vim              0.043084s / 2 tests
	--- FAIL Test_jump_to_declaration_guru (0.000698s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007922s / 2 tests
	ok   fmt_test.vim               0.021428s / 3 tests

	Some tests FAILED

Syntax error (would prevously keep Vim open!):

	[~/.vim/pack/plugins/start/vim-go](test)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.169554s / 2 tests
	--- FAIL Test_fillstruct (0.845644s)
			Vim:E492: Not an editor command:     asd
	FAIL fillstruct_test.vim        0.846325s / 1 tests
	ok   tool_test.vim              0.060288s / 2 tests
	ok   def_test.vim               0.023219s / 2 tests
	ok   fmt_test.vim               0.026293s / 3 tests

	Some tests FAILED

Verbose:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -v vim-8.0

	=== RUN  Test_add_tags
	--- PASS Test_add_tags (0.084296s)
	=== RUN  Test_remove_tags
	--- PASS Test_remove_tags (0.086975s)
	ok  tags_test.vim              0.172008s / 2 tests

	=== RUN  Test_fillstruct
	--- PASS Test_fillstruct (0.792921s)
	ok  fillstruct_test.vim        0.793609s / 1 tests

	=== RUN  Test_ExecuteInDir
	--- PASS Test_ExecuteInDir (0.044198s)
	=== RUN  Test_ExecuteInDir_nodir
	--- PASS Test_ExecuteInDir_nodir (0.003989s)
	ok  tool_test.vim              0.048599s / 2 tests

	=== RUN  Test_jump_to_declaration_godef
	--- PASS Test_jump_to_declaration_godef (0.006618s)
	=== RUN  Test_jump_to_declaration_guru
	--- FAIL Test_jump_to_declaration_guru (0.000832s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007953s / 2 tests

	=== RUN  Test_goimports
	--- PASS Test_goimports (0.013912s)
	=== RUN  Test_run_fmt
	--- PASS Test_run_fmt (0.006824s)
	=== RUN  Test_update_file
	--- PASS Test_update_file (0.000501s)
	ok  fmt_test.vim               0.021532s / 3 tests

	Some tests FAILED

Running just one test file:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -r tags_test.vim vim-8.0
	ok   tags_test.vim              0.093540s / 2 tests

	All tests PASSED
arp242 added a commit that referenced this pull request Nov 25, 2017
Deals better with some errors, add some commandline flags, and improve
output.

It will now also run tests from all directories, instead of the autoload
directory. I wanted to add a test for #1525, and putting it in
`autoload/go/` seemed wrong to me.

Would also be nice to be able to run just one test with e.g.
`-r tags_test.vim:Test_Foo`. I'll add that when I need it I guess.

Regular:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.146627s / 2 tests
	ok   fillstruct_test.vim        0.685770s / 1 tests
	ok   tool_test.vim              0.083538s / 2 tests
	ok   def_test.vim               0.018329s / 2 tests
	ok   fmt_test.vim               0.023622s / 3 tests

	All tests PASSED

Test failure:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.117528s / 2 tests
	ok   fillstruct_test.vim        0.772903s / 1 tests
	ok   tool_test.vim              0.043084s / 2 tests
	--- FAIL Test_jump_to_declaration_guru (0.000698s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007922s / 2 tests
	ok   fmt_test.vim               0.021428s / 3 tests

	Some tests FAILED

Syntax error (would prevously keep Vim open!):

	[~/.vim/pack/plugins/start/vim-go](test)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.169554s / 2 tests
	--- FAIL Test_fillstruct (0.845644s)
			Vim:E492: Not an editor command:     asd
	FAIL fillstruct_test.vim        0.846325s / 1 tests
	ok   tool_test.vim              0.060288s / 2 tests
	ok   def_test.vim               0.023219s / 2 tests
	ok   fmt_test.vim               0.026293s / 3 tests

	Some tests FAILED

Verbose:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -v vim-8.0

	=== RUN  Test_add_tags
	--- PASS Test_add_tags (0.084296s)
	=== RUN  Test_remove_tags
	--- PASS Test_remove_tags (0.086975s)
	ok  tags_test.vim              0.172008s / 2 tests

	=== RUN  Test_fillstruct
	--- PASS Test_fillstruct (0.792921s)
	ok  fillstruct_test.vim        0.793609s / 1 tests

	=== RUN  Test_ExecuteInDir
	--- PASS Test_ExecuteInDir (0.044198s)
	=== RUN  Test_ExecuteInDir_nodir
	--- PASS Test_ExecuteInDir_nodir (0.003989s)
	ok  tool_test.vim              0.048599s / 2 tests

	=== RUN  Test_jump_to_declaration_godef
	--- PASS Test_jump_to_declaration_godef (0.006618s)
	=== RUN  Test_jump_to_declaration_guru
	--- FAIL Test_jump_to_declaration_guru (0.000832s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007953s / 2 tests

	=== RUN  Test_goimports
	--- PASS Test_goimports (0.013912s)
	=== RUN  Test_run_fmt
	--- PASS Test_run_fmt (0.006824s)
	=== RUN  Test_update_file
	--- PASS Test_update_file (0.000501s)
	ok  fmt_test.vim               0.021532s / 3 tests

	Some tests FAILED

Running just one test file:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -r tags_test.vim vim-8.0
	ok   tags_test.vim              0.093540s / 2 tests

	All tests PASSED
arp242 added a commit that referenced this pull request Nov 25, 2017
Deals better with some errors, add some commandline flags, and improve
output.

It will now also run tests from all directories, instead of the autoload
directory. I wanted to add a test for #1525, and putting it in
`autoload/go/` seemed wrong to me.

Would also be nice to be able to run just one test with e.g.
`-r tags_test.vim:Test_Foo`. I'll add that when I need it I guess.

Regular:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.146627s / 2 tests
	ok   fillstruct_test.vim        0.685770s / 1 tests
	ok   tool_test.vim              0.083538s / 2 tests
	ok   def_test.vim               0.018329s / 2 tests
	ok   fmt_test.vim               0.023622s / 3 tests

	All tests PASSED

Test failure:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.117528s / 2 tests
	ok   fillstruct_test.vim        0.772903s / 1 tests
	ok   tool_test.vim              0.043084s / 2 tests
	--- FAIL Test_jump_to_declaration_guru (0.000698s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007922s / 2 tests
	ok   fmt_test.vim               0.021428s / 3 tests

	Some tests FAILED

Syntax error (would prevously keep Vim open!):

	[~/.vim/pack/plugins/start/vim-go](test)% ./scripts/test vim-8.0
	ok   tags_test.vim              0.169554s / 2 tests
	--- FAIL Test_fillstruct (0.845644s)
			Vim:E492: Not an editor command:     asd
	FAIL fillstruct_test.vim        0.846325s / 1 tests
	ok   tool_test.vim              0.060288s / 2 tests
	ok   def_test.vim               0.023219s / 2 tests
	ok   fmt_test.vim               0.026293s / 3 tests

	Some tests FAILED

Verbose:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -v vim-8.0

	=== RUN  Test_add_tags
	--- PASS Test_add_tags (0.084296s)
	=== RUN  Test_remove_tags
	--- PASS Test_remove_tags (0.086975s)
	ok  tags_test.vim              0.172008s / 2 tests

	=== RUN  Test_fillstruct
	--- PASS Test_fillstruct (0.792921s)
	ok  fillstruct_test.vim        0.793609s / 1 tests

	=== RUN  Test_ExecuteInDir
	--- PASS Test_ExecuteInDir (0.044198s)
	=== RUN  Test_ExecuteInDir_nodir
	--- PASS Test_ExecuteInDir_nodir (0.003989s)
	ok  tool_test.vim              0.048599s / 2 tests

	=== RUN  Test_jump_to_declaration_godef
	--- PASS Test_jump_to_declaration_godef (0.006618s)
	=== RUN  Test_jump_to_declaration_guru
	--- FAIL Test_jump_to_declaration_guru (0.000832s)
			function Test_jump_to_declaration_guru line 13: Expected 'oh' but got 'noes'
	FAIL def_test.vim               0.007953s / 2 tests

	=== RUN  Test_goimports
	--- PASS Test_goimports (0.013912s)
	=== RUN  Test_run_fmt
	--- PASS Test_run_fmt (0.006824s)
	=== RUN  Test_update_file
	--- PASS Test_update_file (0.000501s)
	ok  fmt_test.vim               0.021532s / 3 tests

	Some tests FAILED

Running just one test file:

	[~/.vim/pack/plugins/start/vim-go](master)% ./scripts/test -r tags_test.vim vim-8.0
	ok   tags_test.vim              0.093540s / 2 tests

	All tests PASSED
@arp242
Copy link
Contributor Author

arp242 commented Nov 25, 2017

On my system, GOPATH is not set, so in BufEnter, let b:old_gopath = $GOPATH will set b:old_gopath to the empty string
GOPATH is set to the empty string using let $GOPATH = b:old_gopath

How would this happen? Right now the code is:

  autocmd BufLeave *.go
        \  if get(b:, 'old_gopath', '') isnot ''
        \|   let $GOPATH = b:old_gopath
        \| endif

So I don't see how it will ever set $GOPATH to an empty string?

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 25, 2017

Load vim with GOPATH unset or null and enable GOPATH autodetection:

$> GOPATH= vim
:let g:go_autodetect_gopath = 1

Then edit two files:

:e  $HOME/src/gb-project/bar.go
:e $HOME/go/src/quux/foo.go

When bar.go was entered, its b:old_gopath was set to the empty string and GOPATH was set to the detected value. When bar.go was left, it should have restored GOPATH to the empty string, but did not, because b:old_gopath is empty. The mere existence of b:old_gopath is what should trigger the restoration of GOPATH, not the value of b:old_gopath.

@arp242
Copy link
Contributor Author

arp242 commented Nov 25, 2017

Okay; I pushed an update which should handle all cases I think. We can't unlet $GOPATH but exists('$GOPATH') does work correct.

@bhcleek
Copy link
Collaborator

bhcleek commented Nov 25, 2017

LGTM, but setting b:old_gopath to -1 and checking for that value is extraneous.

@arp242
Copy link
Contributor Author

arp242 commented Nov 25, 2017

LGTM, but setting b:old_gopath to -1 and checking for that value is extraneous.

Without that it will run let $GOPATH = go#path#Detect() on a second BufEnter event as exists('b:old_gopath') is false. Not a huge deal, but better to not do it, I think.

@arp242 arp242 merged commit 974b289 into fatih:master Nov 25, 2017
@arp242 arp242 deleted the gopath-detect branch November 25, 2017 23:41
@arp242 arp242 mentioned this pull request Apr 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants