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

settings: repurpose indexer-related options #1003

Merged
merged 3 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions docs/SETTINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,30 @@ Path to the Terraform binary.
This is usually looked up automatically from `$PATH` and should not need to be
specified in majority of cases. Use this to override the automatic lookup.

## `rootModulePaths` (`[]string`)
## **DEPRECATED**: `rootModulePaths` (`[]string`)

This allows overriding automatic root module discovery by passing a static list
of absolute or relative paths to root modules (i.e. folders with `*.tf` files
which have been `terraform init`-ed). Conflicts with `ExcludeModulePaths` option.
This option is deprecated and ignored from v0.29+, it was used as an escape hatch
to force indexing of paths in cases where indexer wouldn't index them otherwise.
Indexer in 0.29.0 no longer limited to just initialized modules (folders with `.terraform`)
and instead indexes all directories with `*.tf` files in them.
Therefore this option is no longer relevant.

Relative paths are resolved relative to the directory opened in the editor.
If you previously used it to force indexing of a folder outside of a workspace,
you can just add that folder to the workspace and it will be indexed as usual.

Path separators are converted automatically to the match separators
of the target platform (e.g. `\` on Windows, or `/` on Unix),
symlinks are followed, trailing slashes automatically removed,
and `~` is replaced with your home directory.
## **DEPRECATED**: `excludeModulePaths` (`[]string`)

## `excludeModulePaths` (`[]string`)
Deprecated in favour of `ignorePaths`

This allows exclude root module path when automatic root module discovery by passing a static list
of absolute or relative paths to root modules (i.e. folders with `*.tf` files
which have been `terraform init`-ed). Conflicts with `rootModulePaths` option.
## `indexing.ignorePaths` (`[]string`)

Relative paths are resolved relative to the directory opened in the editor.
Paths to ignore when indexing the workspace on initialization. This can serve
as an escape hatch in large workspaces. Key side effect of ignoring a path
is that go-to-definition, go-to-references and generally most IntelliSense
related to local `module` blocks will **not** work until the target module code
is explicitly opened.

Relative paths are resolved relative to the root (workspace) path opened in the editor.

Path separators are converted automatically to the match separators
of the target platform (e.g. `\` on Windows, or `/` on Unix),
Expand All @@ -68,7 +72,11 @@ Or if left empty
This setting should be deprecated once the language server supports multiple workspaces,
as this arises in VS code because a server instance is started per VS Code workspace.

## `ignoreDirectoryNames` (`[]string`)
## **DEPRECATED**: `ignoreDirectoryNames` (`[]string`)

Deprecated in favour of `indexing.ignoreDirectoryNames`

## `indexing.ignoreDirectoryNames` (`[]string`)

This allows excluding directories from being indexed upon initialization by passing a list of directory names.

Expand Down
45 changes: 32 additions & 13 deletions internal/langserver/handlers/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ func getTelemetryProperties(out *settings.DecodedOptions) map[string]interface{}
"lsVersion": "",
}

properties["options.rootModulePaths"] = len(out.Options.ModulePaths) > 0
properties["options.rootModulePaths"] = len(out.Options.ModulePaths) > 0
properties["options.excludeModulePaths"] = len(out.Options.ExcludeModulePaths) > 0
properties["options.rootModulePaths"] = len(out.Options.XLegacyModulePaths) > 0
properties["options.excludeModulePaths"] = len(out.Options.XLegacyExcludeModulePaths) > 0
properties["options.commandPrefix"] = len(out.Options.CommandPrefix) > 0
properties["options.ignoreDirectoryNames"] = len(out.Options.IgnoreDirectoryNames) > 0
properties["options.indexing.ignoreDirectoryNames"] = len(out.Options.IgnoreDirectoryNames) > 0
properties["options.indexing.ignorePaths"] = len(out.Options.IgnorePaths) > 0
properties["options.experimentalFeatures.prefillRequiredFields"] = out.Options.ExperimentalFeatures.PrefillRequiredFields
properties["options.experimentalFeatures.validateOnSave"] = out.Options.ExperimentalFeatures.ValidateOnSave
properties["options.ignoreSingleFileWarning"] = out.Options.IgnoreSingleFileWarning
Expand Down Expand Up @@ -248,14 +248,33 @@ func (svc *service) setupWalker(ctx context.Context, params lsp.InitializeParams
return err
}

var excludeModulePaths []string
for _, rawPath := range options.ExcludeModulePaths {
if len(options.XLegacyModulePaths) != 0 {
jrpc2.ServerFromContext(ctx).Notify(ctx, "window/showMessage", &lsp.ShowMessageParams{
Type: lsp.Warning,
Message: fmt.Sprintf("rootModulePaths (%q) is deprecated (no-op), add a folder to workspace "+
"instead if you'd like it to be indexed", options.XLegacyModulePaths),
})
}
if len(options.XLegacyExcludeModulePaths) != 0 {
jrpc2.ServerFromContext(ctx).Notify(ctx, "window/showMessage", &lsp.ShowMessageParams{
Type: lsp.Warning,
Message: fmt.Sprintf("excludeModulePaths (%q) is deprecated (no-op), use indexing.ignorePaths instead",
options.XLegacyExcludeModulePaths),
})
}

var ignoredPaths []string
for _, rawPath := range options.IgnorePaths {
modPath, err := resolvePath(root.Path(), rawPath)
if err != nil {
svc.logger.Printf("Ignoring excluded module path %s: %s", rawPath, err)
jrpc2.ServerFromContext(ctx).Notify(ctx, "window/showMessage", &lsp.ShowMessageParams{
Type: lsp.Warning,
Message: fmt.Sprintf("Unable to ignore path (unsupported or invalid URI): %s: %s",
rawPath, err),
})
continue
}
excludeModulePaths = append(excludeModulePaths, modPath)
ignoredPaths = append(ignoredPaths, modPath)
}

err = svc.stateStore.WalkerPaths.EnqueueDir(root)
Expand All @@ -268,7 +287,7 @@ func (svc *service) setupWalker(ctx context.Context, params lsp.InitializeParams
if !uri.IsURIValid(folder.URI) {
jrpc2.ServerFromContext(ctx).Notify(ctx, "window/showMessage", &lsp.ShowMessageParams{
Type: lsp.Warning,
Message: fmt.Sprintf("Ignoring workspace folder (unsupport or invalid URI) %s."+
Message: fmt.Sprintf("Ignoring workspace folder (unsupported or invalid URI) %s."+
" This is most likely bug, please report it.", folder.URI),
})
continue
Expand All @@ -288,10 +307,10 @@ func (svc *service) setupWalker(ctx context.Context, params lsp.InitializeParams
}
}

svc.closedDirWalker.SetIgnoreDirectoryNames(options.IgnoreDirectoryNames)
svc.closedDirWalker.SetExcludeModulePaths(excludeModulePaths)
svc.openDirWalker.SetIgnoreDirectoryNames(options.IgnoreDirectoryNames)
svc.openDirWalker.SetExcludeModulePaths(excludeModulePaths)
svc.closedDirWalker.SetIgnoredDirectoryNames(options.IgnoreDirectoryNames)
svc.closedDirWalker.SetIgnoredPaths(ignoredPaths)
svc.openDirWalker.SetIgnoredDirectoryNames(options.IgnoreDirectoryNames)
svc.openDirWalker.SetIgnoredPaths(ignoredPaths)

return nil
}
Expand Down
2 changes: 1 addition & 1 deletion internal/langserver/handlers/initialize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func TestInitialize_ignoreDirectoryNames(t *testing.T) {
"rootUri": %q,
"processId": 12345,
"initializationOptions": {
"ignoreDirectoryNames": [%q]
"indexing.ignoreDirectoryNames": [%q]
}
}`, tmpDir.URI, "ignore")})
waitForWalkerPath(t, ss, wc, tmpDir)
Expand Down
13 changes: 5 additions & 8 deletions internal/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ type ExperimentalFeatures struct {
}

type Options struct {
// ModulePaths describes a list of absolute paths to modules to load
ModulePaths []string `mapstructure:"rootModulePaths"`
ExcludeModulePaths []string `mapstructure:"excludeModulePaths"`
CommandPrefix string `mapstructure:"commandPrefix"`
IgnoreDirectoryNames []string `mapstructure:"ignoreDirectoryNames"`
IgnoreDirectoryNames []string `mapstructure:"indexing.ignoreDirectoryNames"`
IgnorePaths []string `mapstructure:"indexing.ignorePaths"`

// ExperimentalFeatures encapsulates experimental features users can opt into.
ExperimentalFeatures ExperimentalFeatures `mapstructure:"experimentalFeatures"`
Expand All @@ -30,13 +28,12 @@ type Options struct {
TerraformExecPath string `mapstructure:"terraformExecPath"`
TerraformExecTimeout string `mapstructure:"terraformExecTimeout"`
TerraformLogFilePath string `mapstructure:"terraformLogFilePath"`

XLegacyModulePaths []string `mapstructure:"rootModulePaths"`
XLegacyExcludeModulePaths []string `mapstructure:"excludeModulePaths"`
}

func (o *Options) Validate() error {
if len(o.ModulePaths) != 0 && len(o.ExcludeModulePaths) != 0 {
return fmt.Errorf("at most one of `rootModulePaths` and `excludeModulePaths` could be set")
}

if o.TerraformExecPath != "" {
path := o.TerraformExecPath
if !filepath.IsAbs(path) {
Expand Down
14 changes: 7 additions & 7 deletions internal/settings/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ func TestDecodeOptions_nil(t *testing.T) {
}
opts := out.Options

if opts.ModulePaths != nil {
t.Fatalf("expected no options for nil, %#v given", opts.ModulePaths)
if opts.IgnoreDirectoryNames != nil {
t.Fatalf("expected no options for nil, %#v given", opts.IgnoreDirectoryNames)
}
}

func TestDecodeOptions_wrongType(t *testing.T) {
_, err := DecodeOptions(map[string]interface{}{
"rootModulePaths": "/random/path",
"indexing.ignorePaths": "/random/path",
})
if err == nil {
t.Fatal("expected decoding of wrong type to result in error")
Expand All @@ -32,14 +32,14 @@ func TestDecodeOptions_wrongType(t *testing.T) {

func TestDecodeOptions_success(t *testing.T) {
out, err := DecodeOptions(map[string]interface{}{
"rootModulePaths": []string{"/random/path"},
"indexing.ignorePaths": []string{"/random/path"},
})
if err != nil {
t.Fatal(err)
}
opts := out.Options
expectedPaths := []string{"/random/path"}
if diff := cmp.Diff(expectedPaths, opts.ModulePaths); diff != "" {
if diff := cmp.Diff(expectedPaths, opts.IgnorePaths); diff != "" {
t.Fatalf("options mismatch: %s", diff)
}
}
Expand All @@ -55,7 +55,7 @@ func TestValidate_IgnoreDirectoryNames_error(t *testing.T) {

for _, table := range tables {
out, err := DecodeOptions(map[string]interface{}{
"ignoreDirectoryNames": []string{table.input},
"indexing.ignoreDirectoryNames": []string{table.input},
})
if err != nil {
t.Fatal(err)
Expand All @@ -69,7 +69,7 @@ func TestValidate_IgnoreDirectoryNames_error(t *testing.T) {
}
func TestValidate_IgnoreDirectoryNames_success(t *testing.T) {
out, err := DecodeOptions(map[string]interface{}{
"ignoreDirectoryNames": []string{"directory"},
"indexing.ignoreDirectoryNames": []string{"directory"},
})
if err != nil {
t.Fatal(err)
Expand Down
34 changes: 17 additions & 17 deletions internal/walker/walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ type Walker struct {

cancelFunc context.CancelFunc

excludeModulePaths map[string]bool
ignoreDirectoryNames map[string]bool
ignoredPaths map[string]bool
ignoredDirectoryNames map[string]bool
}

type WalkFunc func(ctx context.Context, modHandle document.DirHandle) (job.IDs, error)
Expand All @@ -62,32 +62,32 @@ type ModuleStore interface {

func NewWalker(fs fs.ReadDirFS, pathStore PathStore, modStore ModuleStore, walkFunc WalkFunc) *Walker {
return &Walker{
fs: fs,
pathStore: pathStore,
modStore: modStore,
walkFunc: walkFunc,
logger: discardLogger,
ignoreDirectoryNames: skipDirNames,
fs: fs,
pathStore: pathStore,
modStore: modStore,
walkFunc: walkFunc,
logger: discardLogger,
ignoredDirectoryNames: skipDirNames,
}
}

func (w *Walker) SetLogger(logger *log.Logger) {
w.logger = logger
}

func (w *Walker) SetExcludeModulePaths(excludeModulePaths []string) {
w.excludeModulePaths = make(map[string]bool)
for _, path := range excludeModulePaths {
w.excludeModulePaths[path] = true
func (w *Walker) SetIgnoredPaths(ignoredPaths []string) {
w.ignoredPaths = make(map[string]bool)
for _, path := range ignoredPaths {
w.ignoredPaths[path] = true
}
}

func (w *Walker) SetIgnoreDirectoryNames(ignoreDirectoryNames []string) {
func (w *Walker) SetIgnoredDirectoryNames(ignoredDirectoryNames []string) {
if w.cancelFunc != nil {
panic("cannot set ignorelist after walking started")
}
for _, path := range ignoreDirectoryNames {
w.ignoreDirectoryNames[path] = true
for _, path := range ignoredDirectoryNames {
w.ignoredDirectoryNames[path] = true
}
}

Expand Down Expand Up @@ -154,12 +154,12 @@ func (w *Walker) collectJobIds(jobIds job.IDs) {
}

func (w *Walker) isSkippableDir(dirName string) bool {
_, ok := w.ignoreDirectoryNames[dirName]
_, ok := w.ignoredDirectoryNames[dirName]
return ok
}

func (w *Walker) walk(ctx context.Context, dir document.DirHandle) error {
if _, ok := w.excludeModulePaths[dir.Path()]; ok {
if _, ok := w.ignoredPaths[dir.Path()]; ok {
w.logger.Printf("skipping walk due to dir being excluded: %s", dir.Path())
return nil
}
Expand Down