Skip to content

Commit 2e12f86

Browse files
committed
cue/load: keep the module root of dependency instances
A build instance for a package in a dependency module gets its Root set to that module's own root directory when the instance is created. importPkg then clobbered it via rewriteFiles, which unconditionally reset Root to the main module root, and setFSLoc re-derived RootLoc from that. The embed injector rejects files outside an instance's RootLoc, so @embed inside a dependency module only worked when the dependency's files happened to sit below the main module root: it broke for modules replaced with a local directory via replaceWith, reporting a spurious "cannot embed files from a file outside of the current module" error, or panicking in v0.17.1. Move the Root assignment from rewriteFiles to its call sites, keeping an already-set Root, and make setFSLoc only derive RootLoc once, mirroring how Dir/DirLoc are already handled. rewriteFiles also loses its unused isLocal parameter. Fixes #4439. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: Ia80a77b5d4f017ffe55d9bef08290a9603a2b8ed Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1242404 TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Reviewed-by: Roger Peppe <rogpeppe@gmail.com> Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
1 parent 242338f commit 2e12f86

4 files changed

Lines changed: 20 additions & 24 deletions

File tree

cmd/cue/cmd/testdata/script/embed_mod_replace_dir.txtar

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
# Issue: https://cuelang.org/issue/4439
77

88
cd app
9-
10-
# TODO: this should succeed and print the contents of $WORK/out/export.
11-
! exec cue export
12-
cmp stderr $WORK/out/export-stderr
9+
exec cue export
10+
cmp stdout $WORK/out/export
1311

1412
-- dep/cue.mod/module.cue --
1513
module: "example.com/dep@v0"
@@ -23,7 +21,6 @@ scripts: _ @embed(glob=*.sh, type=text)
2321

2422
-- dep/assets/hello.sh --
2523
echo hello
26-
2724
-- app/cue.mod/module.cue --
2825
module: "main.org@v0"
2926
language: version: "v0.17.0"
@@ -38,9 +35,6 @@ package app
3835
import "example.com/dep/assets"
3936

4037
out: assets.scripts
41-
-- out/export-stderr --
42-
@embed: cannot embed files from a file outside of the current module:
43-
../dep/assets/assets.cue:4:12
4438
-- out/export --
4539
{
4640
"out": {

cue/load/import.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,12 @@ func (l *loader) importPkg(pos token.Pos, p *build.Instance) []*build.Instance {
210210
continue
211211
}
212212
all = append(all, p)
213-
rewriteFiles(p, cfg.ModuleRoot, false, cfg.pathOS)
213+
// Instances for packages in dependency modules already have their
214+
// own module root; the rest belong to the main module.
215+
if p.Root == "" {
216+
p.Root = cfg.ModuleRoot
217+
}
218+
rewriteFiles(p, cfg.pathOS)
214219
setFSLoc(cfg, p)
215220
if errs := fp.finalize(p); errs != nil {
216221
p.ReportError(errs)

cue/load/loader.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package load
2020
// - go/build
2121

2222
import (
23+
"cmp"
24+
2325
"cuelang.org/go/cue/build"
2426
"cuelang.org/go/cue/errors"
2527
"cuelang.org/go/cue/parser"
@@ -102,11 +104,8 @@ func (l *loader) cueFilesPackage(files []*build.File) *build.Instance {
102104
pkg.ModuleVersion, _ = module.NewVersion(l.cfg.Module, "")
103105
}
104106
pkg.ModuleFile = l.cfg.modFile
105-
root := l.cfg.Dir
106-
if l.cfg.ModuleRoot != "" {
107-
root = l.cfg.ModuleRoot
108-
}
109-
rewriteFiles(pkg, root, true, l.cfg.pathOS)
107+
pkg.Root = cmp.Or(l.cfg.ModuleRoot, l.cfg.Dir)
108+
rewriteFiles(pkg, l.cfg.pathOS)
110109
setFSLoc(l.cfg, pkg)
111110
for _, err := range errors.Errors(fp.finalize(pkg)) { // ImportDir(&ctxt, dir, 0)
112111
var x *NoFilesError

cue/load/loader_common.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ type excludeError struct {
5555

5656
func (e excludeError) Is(err error) bool { return err == errExclude }
5757

58-
func rewriteFiles(p *build.Instance, root string, isLocal bool, os pkgpath.OS) {
59-
p.Root = root
60-
58+
func rewriteFiles(p *build.Instance, os pkgpath.OS) {
6159
normalizeFiles(p.BuildFiles, os)
6260
normalizeFiles(p.IgnoredFiles, os)
6361
normalizeFiles(p.OrphanedFiles, os)
@@ -70,9 +68,7 @@ func rewriteFiles(p *build.Instance, root string, isLocal bool, os pkgpath.OS) {
7068
// maps Dir/Root to display paths.
7169
//
7270
// Dir/Root must hold loader-internal paths when this is called.
73-
// DirLoc is only set on the first call (Dir is set once and not
74-
// overwritten). RootLoc is always updated because rewriteFiles
75-
// may reset Root between calls.
71+
// setFSLoc is idempotent: locations already set are left untouched.
7672
func setFSLoc(c *Config, p *build.Instance) {
7773
if c.FS != nil {
7874
if p.DirLoc.IsZero() {
@@ -81,16 +77,18 @@ func setFSLoc(c *Config, p *build.Instance) {
8177
p.Dir = c.FromFSPath(p.Dir)
8278
}
8379
}
84-
p.RootLoc = makeFSLoc(c.FS, p.Root, c.FromFSPath)
85-
if c.FromFSPath != nil {
86-
p.Root = c.FromFSPath(p.Root)
80+
if p.RootLoc.IsZero() {
81+
p.RootLoc = makeFSLoc(c.FS, p.Root, c.FromFSPath)
82+
if c.FromFSPath != nil {
83+
p.Root = c.FromFSPath(p.Root)
84+
}
8785
}
8886
} else {
8987
ov, _ := c.fileSystem.(*overlayFileSystem)
9088
if p.DirLoc.IsZero() && p.Dir != "" {
9189
p.DirLoc = makeOSFSLoc(p.Dir, c.pathOS, ov)
9290
}
93-
if p.Root != "" {
91+
if p.RootLoc.IsZero() && p.Root != "" {
9492
p.RootLoc = makeOSFSLoc(p.Root, c.pathOS, ov)
9593
}
9694
}

0 commit comments

Comments
 (0)