Skip to content

Commit 49c22e0

Browse files
authored
fix for #1723 private libs added to a project are not recognized by sloeber and disapear
to reproduce add private lib to project close project open project select add lib to project (prvate lib will not be listed) Select OK Private lib is removed
2 parents c1c2dd0 + f0788b1 commit 49c22e0

File tree

5 files changed

+178
-34
lines changed

5 files changed

+178
-34
lines changed

io.sloeber.core/src/io/sloeber/arduinoFramework/api/LibraryManager.java

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import io.sloeber.core.common.InstancePreferences;
3939
import io.sloeber.core.core.DefaultInstallHandler;
4040
import io.sloeber.core.internal.ArduinoHardwareLibrary;
41-
import io.sloeber.core.internal.ArduinoPrivateLibraryVersion;
41+
import io.sloeber.core.internal.ArduinoPrivateHardwareLibraryVersion;
4242
import io.sloeber.core.internal.Example;
4343
import io.sloeber.core.tools.FileModifiers;
4444
import io.sloeber.core.tools.PackageManager;
@@ -87,6 +87,10 @@ public static String getPrivateLibraryPathsString() {
8787
return InstancePreferences.getPrivateLibraryPathsString();
8888
}
8989

90+
public static String[] getPrivateLibraryPaths() {
91+
return InstancePreferences.getPrivateLibraryPaths();
92+
}
93+
9094
public static void setPrivateLibraryPaths(String[] libraryPaths) {
9195
InstancePreferences.setPrivateLibraryPaths(libraryPaths);
9296

@@ -335,43 +339,59 @@ public static IStatus updateLibraries(Set<IArduinoLibraryVersion> toUnInstallLib
335339
return status;
336340
}
337341

342+
/**
343+
* A convenience (and downward compatibility method of
344+
* getLibrariesAll(BoardDescription boardDescriptor, true) {
345+
*
346+
* @param confDesc can be null
347+
* @return A map of FQN IArduinoLibraryVersion
348+
*/
349+
public static TreeMap<String, IArduinoLibraryVersion> getLibrariesAll(BoardDescription boardDescriptor) {
350+
return getLibrariesAll( boardDescriptor, true);
351+
}
352+
338353
/**
339354
* Given a sloeber configuration provide all the libraries that can be used by
340355
* this sketch This boils down to all libraries maintained by the Library
341356
* manager plus all the libraries provided by the core plus all the libraries
342357
* provided by the personal libraries
343358
*
344359
* @param confDesc can be null
345-
* @return
360+
* @return if keyIsFQN is true: A map of FQN IArduinoLibraryVersion
361+
* if keyIsFQN is false: A map of location IArduinoLibraryVersion
346362
*/
347-
public static TreeMap<String, IArduinoLibraryVersion> getLibrariesAll(BoardDescription boardDescriptor) {
363+
public static TreeMap<String, IArduinoLibraryVersion> getLibrariesAll(BoardDescription boardDescriptor, boolean keyIsFQN) {
348364
TreeMap<String, IArduinoLibraryVersion> libraries = new TreeMap<>();
349-
libraries.putAll(getLibrariesdManaged());
350-
libraries.putAll(getLibrariesPrivate());
365+
libraries.putAll(getLibrariesdManaged(keyIsFQN));
366+
libraries.putAll(getLibrariesPrivate(keyIsFQN));
351367
if (boardDescriptor != null) {
352-
libraries.putAll(getLibrariesHarware(boardDescriptor));
368+
libraries.putAll(getLibrariesHarware(boardDescriptor,keyIsFQN));
353369
}
354370
return libraries;
355371
}
356372

357-
private static Map<String, IArduinoLibraryVersion> getLibrariesdManaged() {
373+
private static Map<String, IArduinoLibraryVersion> getLibrariesdManaged(boolean keyIsFQN) {
358374
Map<String, IArduinoLibraryVersion> ret = new HashMap<>();
359375
for (IArduinoLibraryIndex libindex : libraryIndices) {
360376
for (IArduinoLibrary curLib : libindex.getLibraries()) {
361377
IArduinoLibraryVersion instVersion = curLib.getInstalledVersion();
362378
if (instVersion != null) {
363-
ret.put(instVersion.getFQN().toPortableString(), instVersion);
379+
if (keyIsFQN) {
380+
ret.put(instVersion.getFQN().toPortableString(), instVersion);
381+
} else {
382+
ret.put(instVersion.getInstallPath().toPortableString(), instVersion);
383+
}
364384
}
365385
}
366386
}
367387
return ret;
368388
}
369389

370-
private static Map<String, IArduinoLibraryVersion> getLibrariesPrivate() {
390+
private static Map<String, IArduinoLibraryVersion> getLibrariesPrivate(boolean keyIsFQN) {
371391
Map<String, IArduinoLibraryVersion> ret = new HashMap<>();
372392
String privateLibPaths[] = InstancePreferences.getPrivateLibraryPaths();
373393
for (String curLibPath : privateLibPaths) {
374-
ret.putAll(getLibrariesFromFolder(new Path(curLibPath), 2, false,true));
394+
ret.putAll(getLibrariesFromFolder(new Path(curLibPath), 2, false,true,keyIsFQN));
375395
}
376396
return ret;
377397

@@ -381,12 +401,13 @@ private static Map<String, IArduinoLibraryVersion> getLibrariesPrivate() {
381401
* for a given folder return all subfolders
382402
*
383403
* @param ipath the folder you want the subfolders off
404+
* @param keyIsFQN
384405
* @return The subfolders of the ipath folder. May contain empty values. This
385406
* method returns a key value pair of key equals foldername and value
386407
* equals full path.
387408
*/
388409
private static Map<String, IArduinoLibraryVersion> getLibrariesFromFolder(IPath ipath, int depth,
389-
boolean isHardwareLib,boolean isPrivate) {
410+
boolean isHardwareLib,boolean isPrivate, boolean keyIsFQN) {
390411
if (ConfigurationPreferences.getInstallationPathLibraries().isPrefixOf(ipath)) {
391412
System.err.println("The method findAllPrivateLibs should not be called on Library manager installed libs"); //$NON-NLS-1$
392413
}
@@ -405,13 +426,9 @@ private static Map<String, IArduinoLibraryVersion> getLibrariesFromFolder(IPath
405426
}
406427
String fileExt = (new Path(curChild)).getFileExtension();
407428
if (LIBRARY_INDICATION_FILES.contains(curChild) || CODE_EXTENSIONS.contains(fileExt)) {
408-
if (isHardwareLib) {
409-
IArduinoLibraryVersion retVersion = new ArduinoHardwareLibrary(ipath);
410-
ret.put(retVersion.getFQN().toPortableString(), retVersion);
411-
} else {
412-
IArduinoLibraryVersion retVersion = new ArduinoPrivateLibraryVersion(ipath);
413-
ret.put(retVersion.getFQN().toPortableString(), retVersion);
414-
}
429+
IArduinoLibraryVersion retVersion = isHardwareLib?new ArduinoHardwareLibrary(ipath):new ArduinoPrivateHardwareLibraryVersion(ipath);
430+
String key=keyIsFQN?retVersion.getFQN().toPortableString():retVersion.getInstallPath().toPortableString();
431+
ret.put(key, retVersion);
415432

416433
return ret;
417434
}
@@ -425,7 +442,7 @@ private static Map<String, IArduinoLibraryVersion> getLibrariesFromFolder(IPath
425442
IPath LibPath = ipath.append(curFolder);
426443
File LibPathFile = LibPath.toFile();
427444
if (LibPathFile.isDirectory() && !LibPathFile.isHidden()) {
428-
ret.putAll(getLibrariesFromFolder(LibPath, depth - 1, isHardwareLib,isPrivate));
445+
ret.putAll(getLibrariesFromFolder(LibPath, depth - 1, isHardwareLib,isPrivate,keyIsFQN));
429446
}
430447
}
431448
return ret;
@@ -435,21 +452,22 @@ private static Map<String, IArduinoLibraryVersion> getLibrariesFromFolder(IPath
435452
* Searches all the hardware dependent libraries of a project. If this is a
436453
* board referencing a core then the libraries of the referenced core are added
437454
* as well
455+
* @param keyIsFQN
438456
*
439457
* @param project the project to find all hardware libraries for
440458
* @return all the library folder names. May contain empty values.
441459
*/
442-
public static Map<String, IArduinoLibraryVersion> getLibrariesHarware(BoardDescription boardDescriptor) {
460+
public static Map<String, IArduinoLibraryVersion> getLibrariesHarware(BoardDescription boardDescriptor, boolean keyIsFQN) {
443461
Map<String, IArduinoLibraryVersion> ret = new HashMap<>();
444462
// first add the referenced
445463
IPath libPath = boardDescriptor.getReferencedCoreLibraryPath();
446464
if (libPath != null) {
447-
ret.putAll(getLibrariesFromFolder(libPath, 1, true,boardDescriptor.isPrivate()));
465+
ret.putAll(getLibrariesFromFolder(libPath, 1, true,boardDescriptor.isPrivate(),keyIsFQN));
448466
}
449467
// then add the referencing
450468
libPath = boardDescriptor.getReferencingLibraryPath();
451469
if (libPath != null) {
452-
ret.putAll(getLibrariesFromFolder(libPath, 1, true,boardDescriptor.isPrivate()));
470+
ret.putAll(getLibrariesFromFolder(libPath, 1, true,boardDescriptor.isPrivate(),keyIsFQN));
453471
}
454472
return ret;
455473
}
@@ -458,17 +476,39 @@ public static IArduinoLibraryVersion getLibraryVersionFromLocation(IFolder libFo
458476
if (boardDescriptor != null) {
459477
IPath libPath=boardDescriptor.getReferencedCoreLibraryPath();
460478
if(libPath!=null && libPath.isPrefixOf(libFolder.getLocation())) {
461-
String FQNLibName=ArduinoHardwareLibrary.calculateFQN(libFolder.getName()).toString();
462-
return getLibrariesHarware(boardDescriptor).get(FQNLibName);
479+
return getLibrariesHarware(boardDescriptor,false).get(libFolder.getLocation().toPortableString());
463480
}
464481
}
465482

466483
if(ConfigurationPreferences.getInstallationPathLibraries().isPrefixOf(libFolder.getLocation())) {
467-
String FQNLibName= ArduinoLibraryVersion.calculateFQN(libFolder.getName()).toString();
468-
return getLibrariesdManaged().get(FQNLibName);
484+
return getLibrariesdManaged(false).get(libFolder.getLocation().toPortableString());
469485
}
470486

471-
return getLibrariesPrivate().get(libFolder.getName());
487+
return getLibrariesPrivate(false).get(libFolder.getLocation().toPortableString());
488+
}
489+
490+
public static IArduinoLibraryVersion getLibraryVersionFromFQN(String FQNLibName, BoardDescription boardDescriptor) {
491+
String[] fqnParts = FQNLibName.split(SLACH);
492+
if (fqnParts.length < 3) {
493+
return null;
494+
}
495+
if (!SLOEBER_LIBRARY_FQN.equals(fqnParts[0])) {
496+
// this is not a library
497+
return null;
498+
}
499+
if (MANAGED.equals(fqnParts[1])) {
500+
if (BOARD.equals(fqnParts[2])) {
501+
if (boardDescriptor == null) {
502+
return null;
503+
}
504+
return getLibrariesHarware(boardDescriptor,true).get(FQNLibName);
505+
}
506+
return getLibrariesdManaged(true).get(FQNLibName);
507+
}
508+
if (PRIVATE.equals(fqnParts[1])) {
509+
return getLibrariesPrivate(true).get(FQNLibName);
510+
}
511+
return null;
472512
}
473513

474514
/**

io.sloeber.core/src/io/sloeber/core/api/SloeberProject.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import io.sloeber.core.Messages;
5252
import io.sloeber.core.api.CompileDescription.SizeCommands;
5353
import io.sloeber.core.internal.ArduinoHardwareLibrary;
54-
import io.sloeber.core.internal.ArduinoPrivateLibraryVersion;
54+
import io.sloeber.core.internal.ArduinoPrivateHardwareLibraryVersion;
5555
import io.sloeber.core.internal.SloeberConfiguration;
5656
import io.sloeber.core.listeners.IndexerController;
5757
import io.sloeber.core.natures.SloeberNature;
@@ -241,7 +241,7 @@ public void run(IProgressMonitor internalMonitor) throws CoreException {
241241
continue;
242242
}
243243

244-
IPath privateLibFQN = ArduinoPrivateLibraryVersion.calculateFQN(curLibName);
244+
IPath privateLibFQN = ArduinoPrivateHardwareLibraryVersion.calculateFQN(curLibName);
245245
foundLib = availableLibs.get(privateLibFQN.toString());
246246
if (foundLib != null) {
247247
toInstallLibs.add(foundLib);

io.sloeber.core/src/io/sloeber/core/internal/ArduinoPrivateLibraryVersion.java renamed to io.sloeber.core/src/io/sloeber/core/internal/ArduinoPrivateHardwareLibraryVersion.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212
import io.sloeber.core.api.VersionNumber;
1313
import io.sloeber.core.common.InstancePreferences;
1414

15-
public class ArduinoPrivateLibraryVersion implements IArduinoLibraryVersion {
15+
public class ArduinoPrivateHardwareLibraryVersion implements IArduinoLibraryVersion {
1616
private IPath myInstallPath;
1717
private String myName;
1818
private IPath myFQN;
1919

20-
public ArduinoPrivateLibraryVersion(IPath installPath) {
20+
public ArduinoPrivateHardwareLibraryVersion(IPath installPath) {
2121
myInstallPath = installPath;
2222
myName = myInstallPath.lastSegment();
2323
myFQN= calculateFQN(getName());
2424
}
2525

26-
public ArduinoPrivateLibraryVersion(String curSaveString) {
26+
public ArduinoPrivateHardwareLibraryVersion(String curSaveString) {
2727
String[] parts=curSaveString.split(SEMI_COLON);
2828
myName=parts[parts.length-1];
2929
myFQN= calculateFQN(getName());

io.sloeber.core/src/io/sloeber/core/internal/SloeberConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ private void upDateHardwareLibraries() {
611611
}
612612
}
613613
if (!hardwareLibsFQN.isEmpty()) {
614-
Map<String, IArduinoLibraryVersion> boardLibs = LibraryManager.getLibrariesHarware(boardDesc);
614+
Map<String, IArduinoLibraryVersion> boardLibs = LibraryManager.getLibrariesHarware(boardDesc,true);
615615
for (IPath curReplaceLibFQN : hardwareLibsFQN) {
616616
IArduinoLibraryVersion newLib = boardLibs.get(curReplaceLibFQN.toPortableString());
617617
if (newLib != null) {

io.sloeber.tests/src/io/sloeber/core/BuildTests.java

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44

5-
5+
import static io.sloeber.core.api.Const.*;
66
import java.io.File;
77
import java.util.Arrays;
88
import java.util.Collection;
@@ -15,6 +15,8 @@
1515
import java.util.TreeMap;
1616
import java.util.stream.Stream;
1717
import java.net.URI;
18+
import java.nio.file.Files;
19+
import java.nio.file.StandardOpenOption;
1820

1921
import org.apache.commons.io.FileUtils;
2022

@@ -25,8 +27,10 @@
2527
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
2628
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
2729
import org.eclipse.core.resources.IFile;
30+
import org.eclipse.core.resources.IFolder;
2831
import org.eclipse.core.resources.IProject;
2932
import org.eclipse.core.resources.IWorkspace;
33+
import org.eclipse.core.resources.IWorkspaceRoot;
3034
import org.eclipse.core.resources.IncrementalProjectBuilder;
3135
import org.eclipse.core.resources.ResourcesPlugin;
3236
import org.eclipse.core.runtime.CoreException;
@@ -801,4 +805,104 @@ public void NightlyBoardPatron(String name, MCUBoard boardID, Example example, C
801805

802806
}
803807

808+
809+
/**
810+
* Use private lib from the workspace.
811+
* Close project
812+
* open project
813+
* Is the lib still there (as does project still build)
814+
*
815+
* @throws Exception
816+
*/
817+
@Test
818+
public void issue1723() throws Exception {
819+
final String projectName = "private_lib";
820+
final String privateLibFolderName = "an_private_lib";
821+
final String privateLibName = "a_private_lib";
822+
final String libHeaderContent=("int aFunction();")+System.lineSeparator();
823+
String libCodeContent=("#include \""+privateLibName+".h\"")+System.lineSeparator();
824+
libCodeContent=libCodeContent+("int aFunction(){")+System.lineSeparator();
825+
libCodeContent=libCodeContent+("}")+System.lineSeparator();
826+
String libRefContent=("#include \""+privateLibName+".h\"")+System.lineSeparator();
827+
libRefContent=libRefContent+("int aRefFunction(){")+System.lineSeparator();
828+
libRefContent=libRefContent+("aFunction();")+System.lineSeparator();
829+
libRefContent=libRefContent+("}")+System.lineSeparator();
830+
831+
832+
//create a basic arduino project
833+
BoardDescription unoBoardid = Arduino.uno().getBoardDescriptor();
834+
IProject theTestProject = null;
835+
836+
IPath templateFolder = Shared.getTemplateFolder("CreateAndCompileTest");
837+
CodeDescription codeDescriptor = CodeDescription.createCustomTemplate(templateFolder);
838+
theTestProject = SloeberProject.createArduinoProject(projectName, null, unoBoardid, codeDescriptor,
839+
new CompileDescription(), new NullProgressMonitor());
840+
Shared.waitForIndexer(theTestProject);
841+
842+
//create a private library project
843+
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
844+
IWorkspaceRoot root = workspace.getRoot();
845+
IProject theLibProject= root.getProject("PrivateLibs");
846+
theLibProject.create(new NullProgressMonitor());
847+
theLibProject.open(new NullProgressMonitor());
848+
IFolder libFolder = theLibProject.getFolder(privateLibFolderName);
849+
libFolder.create(true, true, new NullProgressMonitor());
850+
IFile libHeaderFile=libFolder.getFile(privateLibName+".h");
851+
IFile libSourceFile=libFolder.getFile(privateLibName+".cpp");
852+
853+
Files.write(libHeaderFile.getLocation().toPath(), libHeaderContent.getBytes(), StandardOpenOption.TRUNCATE_EXISTING,
854+
StandardOpenOption.CREATE);
855+
Files.write(libSourceFile.getLocation().toPath(), libCodeContent.getBytes(), StandardOpenOption.TRUNCATE_EXISTING,
856+
StandardOpenOption.CREATE);
857+
858+
859+
//build project (should work)
860+
theTestProject.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
861+
assertNull(Shared.hasBuildErrors(theTestProject),"Created Project does not build.");
862+
863+
864+
//Add code to project that uses private lib
865+
IFolder srcFolder = theTestProject.getFolder("src");
866+
IFile referingFile=srcFolder.getFile("privateLibUser.cpp");
867+
Files.write(referingFile.getLocation().toPath(), libRefContent.getBytes(), StandardOpenOption.TRUNCATE_EXISTING,
868+
StandardOpenOption.CREATE);
869+
870+
//build project (should fail)
871+
theTestProject.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
872+
assertNotNull(Shared.hasBuildErrors(theTestProject),"Lib should be missing; build should fail.");
873+
874+
875+
//add private libs project to the sloeber preferences private libs
876+
List<String> privateLibList= new LinkedList<>();
877+
privateLibList.add(theLibProject.getLocation().toOSString());
878+
privateLibList.addAll( Arrays.asList( LibraryManager.getPrivateLibraryPaths()));
879+
LibraryManager.setPrivateLibraryPaths(privateLibList.toArray(new String[privateLibList.size()]));
880+
881+
882+
883+
//add the private lib to the project
884+
IArduinoLibraryVersion privateArduinoLib=LibraryManager.getLibraryVersionFromFQN(SLOEBER_LIBRARY_FQN+SLACH+PRIVATE+SLACH+libFolder.getName(), null);
885+
Collection<IArduinoLibraryVersion> myPrivateLibs =new LinkedList<>();
886+
myPrivateLibs.add(privateArduinoLib);
887+
888+
ISloeberConfiguration sloeberConf=ISloeberConfiguration.getActiveConfig(theTestProject, true);
889+
sloeberConf.addLibraries(myPrivateLibs);
890+
891+
//build project (should work)
892+
theTestProject.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
893+
assertNull(Shared.hasBuildErrors(theTestProject),"lib added build should succeed");
894+
895+
//open and close the project to clear the cache
896+
theTestProject.close(null);
897+
// just wait a while
898+
Thread.sleep(1000);
899+
900+
theTestProject.open(new NullProgressMonitor());
901+
902+
//There should be 1 lib in the project
903+
sloeberConf=ISloeberConfiguration.getActiveConfig(theTestProject, true);
904+
Map<IPath, IArduinoLibraryVersion> usedLibs=sloeberConf.getUsedLibraries();
905+
assertEquals(1,usedLibs.size(),"Private Lib not found");
906+
907+
}
804908
}

0 commit comments

Comments
 (0)