Skip to content

x/tools/imports: ability to customize behavior without needing to fork #12696

Closed
@dmitshur

Description

@dmitshur

Currently, the golang.org/x/tools/imports features some internal configuration options to make it possible to adjust it to run (in a limited capacity) in environments where there is no raw filesystem access (for example, App Engine):

// importPathToName returns the package name for the given import path.
var importPathToName = importPathToNameGoPath

// loadExports returns a list exports for a package.
var loadExports = loadExportsGoPath

// findImport searches for a package with the given symbols.
// If no package is found, findImport returns "".
// Declared as a variable rather than a function so goimports can be easily
// extended by adding a file with an init function.
var findImport = findImportGoPath

There's a few code generation files like mkindex.go to help pre-compute static indices of packages for such environments.

However, since those variables are unexported, the only current way to make changes there is to fork the entire golang.org/x/tools/imports package.

It's slightly more convenient in that a new file can be added with init() that overrides the internal variables, but the rest of the package will still be a fork that needs to be maintained and kept up to date.

Feature Request

What do you think about adding a means to override those internal configuration funcs (or provide your own implementations) and pre-computed indices. Perhaps via:

// Or "Context" or "Configuration" or whatever name works best.
type Config struct {
    ImportPathToName func(importPath string) (packageName string)
    LoadExports      func(dir string) map[string]bool
    FindImport       func(pkgName string, symbols map[string]bool) (string, bool, error)
    Stdlib           map[string]string
}

func (c *Config) Process(filename string, src []byte, opt *Options) ([]byte, error) { ... }

// Process formats and adjusts imports for the provided file.
// If opt is nil the defaults are used.
func Process(filename string, src []byte, opt *Options) ([]byte, error) {
    return defaultConfig.Process(filename, src, opt)
}

Or something like that, to make it possible to import golang.org/x/tools/imports and configure it to one's needs, without needing to fork it.

Additionally, it'd be great if the findImport, etc. implementations that currently rely on raw filesystem access and import low level packages like os could be moved into a separate file with a build tag like // +build !nacl to prevent them from being included on systems where those low level packages are not available.

Some context on where I'd like to use this can seen in gopherjs/gopherjs.github.io@40f830c, where I had to fork imports and customize for the GopherJS Playground. Since the code runs in a browser, a static index is used, and unused code importing os and sync is removed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.FrozenDueToAgeToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions