@@ -698,16 +698,85 @@ func validBuildConfiguration(folder span.URI, ws *workspaceInformation, modFiles
698
698
// The user may have a multiple directories in their GOPATH.
699
699
// Check if the workspace is within any of them.
700
700
for _ , gp := range filepath .SplitList (ws .gopath ) {
701
- if isSubdirectory (filepath .Join (gp , "src" ), folder .Filename ()) {
701
+ if inDir (filepath .Join (gp , "src" ), folder .Filename ()) {
702
702
return true
703
703
}
704
704
}
705
705
return false
706
706
}
707
707
708
- func isSubdirectory (root , leaf string ) bool {
709
- rel , err := filepath .Rel (root , leaf )
710
- return err == nil && ! strings .HasPrefix (rel , ".." )
708
+ // Copied and slightly adjusted from go/src/cmd/go/internal/search/search.go.
709
+ //
710
+ // inDir checks whether path is in the file tree rooted at dir.
711
+ // If so, InDir returns an equivalent path relative to dir.
712
+ // If not, InDir returns an empty string.
713
+ // InDir makes some effort to succeed even in the presence of symbolic links.
714
+ func inDir (dir , path string ) bool {
715
+ if rel := inDirLex (path , dir ); rel != "" {
716
+ return true
717
+ }
718
+ xpath , err := filepath .EvalSymlinks (path )
719
+ if err != nil || xpath == path {
720
+ xpath = ""
721
+ } else {
722
+ if rel := inDirLex (xpath , dir ); rel != "" {
723
+ return true
724
+ }
725
+ }
726
+
727
+ xdir , err := filepath .EvalSymlinks (dir )
728
+ if err == nil && xdir != dir {
729
+ if rel := inDirLex (path , xdir ); rel != "" {
730
+ return true
731
+ }
732
+ if xpath != "" {
733
+ if rel := inDirLex (xpath , xdir ); rel != "" {
734
+ return true
735
+ }
736
+ }
737
+ }
738
+ return false
739
+ }
740
+
741
+ // Copied from go/src/cmd/go/internal/search/search.go.
742
+ //
743
+ // inDirLex is like inDir but only checks the lexical form of the file names.
744
+ // It does not consider symbolic links.
745
+ // TODO(rsc): This is a copy of str.HasFilePathPrefix, modified to
746
+ // return the suffix. Most uses of str.HasFilePathPrefix should probably
747
+ // be calling InDir instead.
748
+ func inDirLex (path , dir string ) string {
749
+ pv := strings .ToUpper (filepath .VolumeName (path ))
750
+ dv := strings .ToUpper (filepath .VolumeName (dir ))
751
+ path = path [len (pv ):]
752
+ dir = dir [len (dv ):]
753
+ switch {
754
+ default :
755
+ return ""
756
+ case pv != dv :
757
+ return ""
758
+ case len (path ) == len (dir ):
759
+ if path == dir {
760
+ return "."
761
+ }
762
+ return ""
763
+ case dir == "" :
764
+ return path
765
+ case len (path ) > len (dir ):
766
+ if dir [len (dir )- 1 ] == filepath .Separator {
767
+ if path [:len (dir )] == dir {
768
+ return path [len (dir ):]
769
+ }
770
+ return ""
771
+ }
772
+ if path [len (dir )] == filepath .Separator && path [:len (dir )] == dir {
773
+ if len (path ) == len (dir )+ 1 {
774
+ return "."
775
+ }
776
+ return path [len (dir )+ 1 :]
777
+ }
778
+ return ""
779
+ }
711
780
}
712
781
713
782
// getGoEnv gets the view's various GO* values.
0 commit comments