about summary refs log tree commit diff
path: root/nix
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-04-05T09·41+0200
committerProfpatsch <mail@profpatsch.de>2021-04-23T16·35+0000
commit2224731e0d007fbff27f31f4e1771aad723b603f (patch)
treec351da2b34ad1e97bac7e6f03f783bf5069fe87e /nix
parent77c09076eccf343e7f14ed389719c0866de3d649 (diff)
feat(nix/buildGo): add the import position to errmsg r/2535
When a foreign dep is missing a dependency, it is good to have a
context.

e.g. the `github.com/charmbracelet/bubblegum` package has a lot of
dependencies that are only used in its `examples/` dir; this is not
obvious, unless we also print where the imports come from.

New error message:

```
error: missing foreign dependency 'github.com/containerd/console' in 'github.com/charmbracelet/bubbletea, imported at /nix/store/0cry4sg6bzxqwk5zl2nxhas6k5663svg-source/tea.go:22:2'
```

Change-Id: If34a3c62b9d77d4aea108b5e011e16fbd03e8554
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2852
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'nix')
-rw-r--r--nix/buildGo/external/default.nix4
-rw-r--r--nix/buildGo/external/main.go29
2 files changed, 22 insertions, 11 deletions
diff --git a/nix/buildGo/external/default.nix b/nix/buildGo/external/default.nix
index de29df416456..6540faf04c36 100644
--- a/nix/buildGo/external/default.nix
+++ b/nix/buildGo/external/default.nix
@@ -56,8 +56,8 @@ let
         throw "missing local dependency '${lib.concatStringsSep "." d}' in '${path}'"
       ) self) entry.localDeps;
 
-      foreignDeps = map (d: lib.attrByPath [ d ] (
-        throw "missing foreign dependency '${d}' in '${path}'"
+      foreignDeps = map (d: lib.attrByPath [ d.path ] (
+        throw "missing foreign dependency '${d.path}' in '${path}, imported at ${d.position}'"
       ) depMap) entry.foreignDeps;
 
       args = {
diff --git a/nix/buildGo/external/main.go b/nix/buildGo/external/main.go
index 50c6c8589519..a77c43b371e9 100644
--- a/nix/buildGo/external/main.go
+++ b/nix/buildGo/external/main.go
@@ -29,13 +29,19 @@ var stdlibList string
 // Return information includes the local (relative from project root)
 // and external (none-stdlib) dependencies of this package.
 type pkg struct {
-	Name        string     `json:"name"`
-	Locator     []string   `json:"locator"`
-	Files       []string   `json:"files"`
-	SFiles      []string   `json:"sfiles"`
-	LocalDeps   [][]string `json:"localDeps"`
-	ForeignDeps []string   `json:"foreignDeps"`
-	IsCommand   bool       `json:"isCommand"`
+	Name        string       `json:"name"`
+	Locator     []string     `json:"locator"`
+	Files       []string     `json:"files"`
+	SFiles      []string     `json:"sfiles"`
+	LocalDeps   [][]string   `json:"localDeps"`
+	ForeignDeps []foreignDep `json:"foreignDeps"`
+	IsCommand   bool         `json:"isCommand"`
+}
+
+type foreignDep struct {
+	Path string `json:"path"`
+	// filename, column and line number of the import, if known
+	Position string `json:"position"`
 }
 
 // findGoDirs returns a filepath.WalkFunc that identifies all
@@ -88,7 +94,7 @@ func analysePackage(root, source, importpath string, stdlib map[string]bool) (pk
 	}
 
 	local := [][]string{}
-	foreign := []string{}
+	foreign := []foreignDep{}
 
 	for _, i := range p.Imports {
 		if stdlib[i] {
@@ -100,7 +106,12 @@ func analysePackage(root, source, importpath string, stdlib map[string]bool) (pk
 		} else if strings.HasPrefix(i, importpath+"/") {
 			local = append(local, strings.Split(strings.TrimPrefix(i, importpath+"/"), "/"))
 		} else {
-			foreign = append(foreign, i)
+			// The import positions is a map keyed on the import name.
+			// The value is a list, presumably because an import can appear
+			// multiple times in a package. Let’s just take the first one,
+			// should be enough for a good error message.
+			firstPos := p.ImportPos[i][0].String()
+			foreign = append(foreign, foreignDep{Path: i, Position: firstPos})
 		}
 	}