Open joneshf opened 3 years ago
Looks like esbuild
provides a way to get the requires pretty easily: https://github.com/evanw/esbuild/issues/761.
Seems like we might be able to make this change to pkg/rules_purescript/internal/gazelle/purescript/language.go
:
diff --git a/pkg/rules_purescript/internal/gazelle/purescript/language.go b/pkg/rules_purescript/internal/gazelle/purescript/language.go
index e9381c4..6e1135a 100644
--- a/pkg/rules_purescript/internal/gazelle/purescript/language.go
+++ b/pkg/rules_purescript/internal/gazelle/purescript/language.go
@@ -17,6 +17,52 @@ import (
"github.com/bazelbuild/bazel-gazelle/repo"
"github.com/bazelbuild/bazel-gazelle/resolve"
"github.com/bazelbuild/bazel-gazelle/rule"
+ "github.com/evanw/esbuild/pkg/api"
+)
+
+var (
+ nodeJSBuiltinModuleMap = map[string]bool{
+ "assert": true,
+ "async_hooks": true,
+ "buffer": true,
+ "child_process": true,
+ "cluster": true,
+ "console": true,
+ "constants": true,
+ "crypto": true,
+ "dgram": true,
+ "dns": true,
+ "domain": true,
+ "events": true,
+ "fs": true,
+ "http": true,
+ "http2": true,
+ "https": true,
+ "inspector": true,
+ "module": true,
+ "net": true,
+ "os": true,
+ "path": true,
+ "perf_hooks": true,
+ "process": true,
+ "punycode": true,
+ "querystring": true,
+ "readline": true,
+ "repl": true,
+ "stream": true,
+ "string_decoder": true,
+ "timers": true,
+ "tls": true,
+ "trace_events": true,
+ "tty": true,
+ "url": true,
+ "util": true,
+ "v8": true,
+ "vm": true,
+ "wasi": true,
+ "worker_threads": true,
+ "zlib": true,
+ }
)
type pureScript struct {
@@ -41,6 +87,58 @@ func findImports(scanner *bufio.Scanner) []string {
return imports
}
+func findJSImportsPlugin(imports *[]string) api.Plugin {
+ return api.Plugin{
+ Name: "joneshf_rules_purescript",
+ Setup: func(pluginBuild api.PluginBuild) {
+ pluginBuild.OnResolve(
+ api.OnResolveOptions{
+ Filter: `.*`,
+ },
+ func(args api.OnResolveArgs) (api.OnResolveResult, error) {
+ if args.Importer != "" {
+ _, nodeJSBuiltin := nodeJSBuiltinModuleMap[args.Path]
+ if !nodeJSBuiltin {
+ // TODO(joneshf): Take the repo as an argument instead of assuming it will be `npm`.jj
+ label := label.New("npm", args.Path, args.Path)
+ *imports = append(*imports, label.String())
+ }
+ return api.OnResolveResult{
+ External: true,
+ Path: args.Path,
+ }, nil
+ }
+ return api.OnResolveResult{}, nil
+ },
+ )
+ },
+ }
+}
+
+func findJSImports(jsFilename string) ([]string, error) {
+ imports := []string{}
+
+ result := api.Build(api.BuildOptions{
+ Bundle: true,
+ EntryPoints: []string{
+ jsFilename,
+ },
+ Plugins: []api.Plugin{
+ findJSImportsPlugin(&imports),
+ },
+ Write: false,
+ })
+
+ if len(result.Errors) > 0 {
+ return nil, fmt.Errorf("Error finding imports from %s: %v", jsFilename, result.Errors)
+ }
+ if len(result.Warnings) > 0 {
+ return nil, fmt.Errorf("Warning finding imports from %s: %v", jsFilename, result.Warnings)
+ }
+
+ return imports, nil
+}
+
func findModule(scanner *bufio.Scanner) (string, bool) {
var module string
var ok bool
@@ -199,8 +297,9 @@ func (p *pureScript) purescriptLibraryKinds() rule.KindInfo {
"module",
},
MergeableAttrs: map[string]bool{
- "ffi": true,
- "src": true,
+ "data": true,
+ "ffi": true,
+ "src": true,
},
NonEmptyAttrs: map[string]bool{
"ffi": true,
@@ -338,6 +437,14 @@ func (p *pureScript) generatePureScriptRules(args language.GenerateArgs, pureScr
ffiFilename := fmt.Sprintf("%s.js", basename)
_, err = os.Stat(filepath.Join(args.Rel, ffiFilename))
if !os.IsNotExist(err) {
+ ffiDependencies, err := findJSImports(filepath.Join(args.Rel, ffiFilename))
+ if err != nil {
+ log.Print(err)
+ return
+ }
+ if len(ffiDependencies) > 0 {
+ r.SetAttr("data", ffiDependencies)
+ }
r.SetAttr("ffi", ffiFilename)
}
The
gazelle
Language
doesn't do any parsing of FFI files to determine what JavaScript dependencies they have. Even if it did do that, we wouldn't have any way to attach that information since thepurescript_library
rule doesn't support runfiles (or anydata
attribute for that matter).Seems like this is dependent on getting support for runfiles in the
purescript_library
rule.