Skip to content

Commit 62bcf0e

Browse files
committed
Interpret local library paths relative to the sketch folder
Previously a local library path would be relative to the sketch folder if you passed a folder path to compile, but if you passed a path to a sketch .ino file, it would be considered relative to that. This change makes it so that relative paths will consistently be interpreted relative to the folder whether you specify a .ino file or not.
1 parent d5ef61d commit 62bcf0e

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

commands/instances.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,11 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
371371
if libraryRef.InstallDir != nil {
372372
libDir := libraryRef.InstallDir
373373
if !libDir.IsAbs() {
374-
libDir = paths.New(req.GetSketchPath()).JoinPath(libraryRef.InstallDir)
374+
sk, err := sketch.New(paths.New(req.GetSketchPath()))
375+
if err != nil {
376+
return &cmderrors.InvalidArgumentError{Cause: err}
377+
}
378+
libDir = sk.FullPath.JoinPath(libraryRef.InstallDir)
375379
}
376380
if !libDir.IsDir() {
377381
return &cmderrors.InvalidArgumentError{

internal/cli/compile/compile.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,9 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer
332332
libDir := paths.New(lib.GetInstallDir())
333333
// If the library is installed in the sketch path, we want to output the relative path
334334
// to the sketch path, so that the sketch is portable.
335-
if ok, err := libDir.IsInsideDir(sketchPath); err == nil && ok {
336-
if ref, err := libDir.RelFrom(sketchPath); err == nil {
335+
sketchDir := paths.New(sk.LocationPath)
336+
if ok, err := libDir.IsInsideDir(sketchDir); err == nil && ok {
337+
if ref, err := libDir.RelFrom(sketchDir); err == nil {
337338
libDir = paths.New(filepath.ToSlash(ref.String()))
338339
}
339340
}

internal/integrationtest/sketch/profiles_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,75 @@ profiles:
9797
{"name": "MyLibOutside", "install_dir": ` + string(libOutsideJson) + `}
9898
]`)
9999
}
100+
101+
func TestRelativeLocalLib(t *testing.T) {
102+
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
103+
t.Cleanup(env.CleanUp)
104+
105+
// Prepare the sketch with libraries
106+
tmpDir, err := paths.MkTempDir("", "")
107+
require.NoError(t, err)
108+
t.Cleanup(func() { _ = tmpDir.RemoveAll })
109+
110+
sketchTemplate, err := paths.New("testdata", "SketchWithLibrary").Abs()
111+
require.NoError(t, err)
112+
113+
sketch := tmpDir.Join("SketchWithLibrary")
114+
libInside := sketch.Join("libraries", "MyLib")
115+
err = sketchTemplate.CopyDirTo(sketch)
116+
require.NoError(t, err)
117+
118+
libOutsideTemplate := sketchTemplate.Join("..", "MyLibOutside")
119+
libOutside := sketch.Join("..", "MyLibOutside")
120+
err = libOutsideTemplate.CopyDirTo(libOutside)
121+
require.NoError(t, err)
122+
123+
// Install the required core and libraries
124+
_, _, err = cli.Run("core", "install", "arduino:[email protected]")
125+
require.NoError(t, err)
126+
_, _, err = cli.Run("lib", "install", "Adafruit [email protected]", "--no-overwrite")
127+
require.NoError(t, err)
128+
_, _, err = cli.Run("lib", "install", "Adafruit GFX [email protected]", "--no-overwrite")
129+
require.NoError(t, err)
130+
_, _, err = cli.Run("lib", "install", "Adafruit [email protected]", "--no-overwrite")
131+
require.NoError(t, err)
132+
133+
// Check if the profile dump:
134+
// - keeps libraries in the sketch with a relative path to the folder, not the .ino
135+
out, _, err := cli.Run("compile", "-b", "arduino:avr:uno",
136+
"--library", libInside.String(),
137+
"--library", libOutside.String(),
138+
"--dump-profile",
139+
sketch.Join("SketchWithLibrary.ino").String())
140+
require.NoError(t, err)
141+
require.Equal(t, strings.TrimSpace(`
142+
profiles:
143+
uno:
144+
fqbn: arduino:avr:uno
145+
platforms:
146+
- platform: arduino:avr (1.8.6)
147+
libraries:
148+
- dir: libraries/MyLib
149+
- dir: `+libOutside.String()+`
150+
- Adafruit SSD1306 (2.5.14)
151+
- Adafruit GFX Library (1.12.1)
152+
- Adafruit BusIO (1.17.1)
153+
`), strings.TrimSpace(string(out)))
154+
155+
outRelative := strings.Replace(string(out), libOutside.String(), "../MyLibOutside", 1)
156+
157+
// Dump the profile in the sketch directory and compile with it again
158+
err = sketch.Join("sketch.yaml").WriteFile([]byte(outRelative))
159+
require.NoError(t, err)
160+
out, _, err = cli.Run("compile", "-m", "uno", "--json", sketch.Join("SketchWithLibrary.ino").String())
161+
require.NoError(t, err)
162+
// Check if local libraries are picked up correctly
163+
libInsideJson, _ := json.Marshal(libInside.String())
164+
libOutsideJson, _ := json.Marshal(libOutside.String())
165+
j := requirejson.Parse(t, out).Query(".builder_result.used_libraries")
166+
j.MustContain(`
167+
[
168+
{"name": "MyLib", "install_dir": ` + string(libInsideJson) + `},
169+
{"name": "MyLibOutside", "install_dir": ` + string(libOutsideJson) + `}
170+
]`)
171+
}

0 commit comments

Comments
 (0)