mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-07 01:54:26 +01:00
Installed libraries are now detected via GPRC calls
This commit is contained in:
parent
7da6bd91aa
commit
56bd779288
@ -32,6 +32,7 @@ import cc.arduino.contributions.libraries.ContributedLibraryRelease;
|
||||
import cc.arduino.contributions.libraries.LibrariesIndexer;
|
||||
import cc.arduino.contributions.libraries.LibraryInstaller;
|
||||
import cc.arduino.contributions.libraries.LibraryOfSameTypeComparator;
|
||||
import cc.arduino.contributions.libraries.LibraryTypeComparator;
|
||||
import cc.arduino.contributions.libraries.ui.LibraryManagerUI;
|
||||
import cc.arduino.contributions.packages.ContributedPlatform;
|
||||
import cc.arduino.contributions.packages.ContributionInstaller;
|
||||
|
@ -38,7 +38,7 @@ public abstract class DownloadableContribution {
|
||||
|
||||
public abstract String getUrl();
|
||||
|
||||
public abstract String getVersion();
|
||||
public abstract String getVersion(); // TODO: Move outside of DownloadableContribution
|
||||
|
||||
public abstract String getChecksum();
|
||||
|
||||
|
@ -34,18 +34,19 @@ import static processing.app.I18n.tr;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import cc.arduino.cli.ArduinoCoreInstance;
|
||||
import cc.arduino.cli.commands.Lib.InstalledLibrary;
|
||||
import cc.arduino.cli.commands.Lib.Library;
|
||||
import cc.arduino.contributions.packages.ContributedPlatform;
|
||||
import io.grpc.StatusException;
|
||||
import processing.app.BaseNoGui;
|
||||
import processing.app.I18n;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
import processing.app.packages.LegacyUserLibrary;
|
||||
import processing.app.debug.TargetPlatform;
|
||||
import processing.app.helpers.FileUtils;
|
||||
import processing.app.packages.LibraryList;
|
||||
import processing.app.packages.UserLibrary;
|
||||
import processing.app.packages.UserLibraryFolder;
|
||||
@ -58,7 +59,6 @@ public class LibrariesIndexer {
|
||||
private final LibraryList installedLibraries = new LibraryList();
|
||||
private List<UserLibraryFolder> librariesFolders;
|
||||
|
||||
private final List<String> badLibNotified = new ArrayList<>();
|
||||
private ArduinoCoreInstance core;
|
||||
|
||||
public LibrariesIndexer(ArduinoCoreInstance core) {
|
||||
@ -100,6 +100,7 @@ public class LibrariesIndexer {
|
||||
|
||||
// format(tr("Error parsing libraries index: {0}\nTry to open the Library Manager to update the libraries index."),
|
||||
// System.err.println(format(tr("Error reading libraries index: {0}"),
|
||||
rescanLibraries();
|
||||
}
|
||||
|
||||
public void setLibrariesFolders(List<UserLibraryFolder> folders) {
|
||||
@ -118,18 +119,16 @@ public class LibrariesIndexer {
|
||||
private Comparator<UserLibrary> priorityComparator = new UserLibraryPriorityComparator(
|
||||
null);
|
||||
|
||||
public void addToInstalledLibraries(UserLibrary lib) {
|
||||
public void addToInstalledLibraries(UserLibrary lib) throws IOException {
|
||||
UserLibrary toReplace = installedLibraries.getByName(lib.getName());
|
||||
if (toReplace == null) {
|
||||
installedLibraries.add(lib);
|
||||
return;
|
||||
}
|
||||
if (priorityComparator.compare(toReplace, lib) >= 0) {
|
||||
} else if (priorityComparator.compare(toReplace, lib) >= 0) {
|
||||
// The current lib has priority, do nothing
|
||||
return;
|
||||
} else {
|
||||
installedLibraries.remove(toReplace);
|
||||
installedLibraries.add(lib);
|
||||
}
|
||||
installedLibraries.remove(toReplace);
|
||||
installedLibraries.add(lib);
|
||||
}
|
||||
|
||||
public void setArchitecturePriority(String arch) {
|
||||
@ -144,17 +143,109 @@ public class LibrariesIndexer {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ContributedLibrary lib : index.getLibraries()) {
|
||||
for (ContributedLibraryRelease libRelease : lib.getReleases()) {
|
||||
libRelease.unsetInstalledUserLibrary();
|
||||
index.getLibraries().forEach(l -> {
|
||||
l.getReleases().forEach(r -> {
|
||||
r.unsetInstalledUserLibrary();
|
||||
});
|
||||
});
|
||||
|
||||
// Rescan libraries
|
||||
List<InstalledLibrary> installedLibsMeta;
|
||||
try {
|
||||
installedLibsMeta = core.libraryList(true);
|
||||
} catch (StatusException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
File coreLibsDir = null;
|
||||
File refcoreLibsDir = null;
|
||||
Optional<TargetPlatform> targetPlatform = BaseNoGui.getTargetPlatform();
|
||||
if (targetPlatform.isPresent()) {
|
||||
String buildCore = BaseNoGui.getBoardPreferences().get("build.core", "arduino");
|
||||
if (buildCore.contains(":")) {
|
||||
String referencedCore = buildCore.split(":")[0];
|
||||
Optional<TargetPlatform> referencedPlatform = BaseNoGui.getTargetPlatform(referencedCore, targetPlatform.get().getId());
|
||||
if (referencedPlatform.isPresent()) {
|
||||
File referencedPlatformFolder = referencedPlatform.get().getFolder();
|
||||
// Add libraries folder for the referenced platform
|
||||
refcoreLibsDir = new File(referencedPlatformFolder, "libraries");
|
||||
}
|
||||
}
|
||||
File platformFolder = targetPlatform.get().getFolder();
|
||||
// Add libraries folder for the selected platform
|
||||
coreLibsDir = new File(platformFolder, "libraries");
|
||||
}
|
||||
|
||||
for (InstalledLibrary meta : installedLibsMeta) {
|
||||
Library l = meta.getLibrary();
|
||||
|
||||
// Skip platform-related libraries that are not part of the currently
|
||||
// selected platform/board.
|
||||
if (l.getLocation().equals("platform")) {
|
||||
File libDir = new File(l.getInstallDir());
|
||||
boolean isCoreLib = (coreLibsDir != null)
|
||||
&& FileUtils.isSubDirectory(coreLibsDir, libDir);
|
||||
boolean isRefCoreLib = (refcoreLibsDir != null) //
|
||||
&& FileUtils.isSubDirectory(refcoreLibsDir,
|
||||
libDir);
|
||||
if (!isCoreLib && !isRefCoreLib) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
UserLibrary lib = new UserLibrary( //
|
||||
new File(l.getInstallDir()), //
|
||||
l.getName(), //
|
||||
l.getVersion(), //
|
||||
l.getAuthor(), //
|
||||
l.getMaintainer(), //
|
||||
l.getSentence(), //
|
||||
l.getParagraph(), //
|
||||
l.getWebsite(), //
|
||||
l.getCategory(), //
|
||||
l.getLicense(), //
|
||||
l.getArchitecturesList(), //
|
||||
l.getLayout(), //
|
||||
l.getTypesList(), //
|
||||
false, // TODO: onGoingDevelopment
|
||||
null, // TODO: includes
|
||||
l.getLocation() //
|
||||
);
|
||||
|
||||
try {
|
||||
String[] headers = BaseNoGui
|
||||
.headerListFromIncludePath(lib.getSrcFolder()); // TODO: Obtain from the CLI?
|
||||
if (headers.length == 0) {
|
||||
throw new IOException(format(tr("no headers files (.h) found in {0}"),
|
||||
lib.getSrcFolder()));
|
||||
}
|
||||
|
||||
Location loc = lib.getLocation();
|
||||
if (loc != Location.CORE && loc != Location.REFERENCED_CORE) {
|
||||
// Check if we can find the same library in the index
|
||||
// and mark it as installed
|
||||
index.find(lib.getName(), lib.getVersion()).ifPresent(foundLib -> {
|
||||
foundLib.setInstalledUserLibrary(lib);
|
||||
lib.setTypes(foundLib.getTypes());
|
||||
});
|
||||
}
|
||||
|
||||
if (lib.getTypes().isEmpty() && loc == Location.SKETCHBOOK) {
|
||||
lib.setTypes(lib.getDeclaredTypes());
|
||||
}
|
||||
|
||||
if (lib.getTypes().isEmpty()) {
|
||||
lib.setTypes(Collections.singletonList("Contributed"));
|
||||
}
|
||||
|
||||
addToInstalledLibraries(lib);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Rescan libraries
|
||||
for (UserLibraryFolder folderDesc : librariesFolders) {
|
||||
scanInstalledLibraries(folderDesc);
|
||||
}
|
||||
|
||||
// TODO: Should be done on the CLI?
|
||||
installedLibraries.stream() //
|
||||
.filter(l -> l.getTypes().contains("Contributed")) //
|
||||
.filter(l -> l.getLocation() == Location.CORE
|
||||
@ -169,85 +260,15 @@ public class LibrariesIndexer {
|
||||
});
|
||||
}
|
||||
|
||||
private void scanInstalledLibraries(UserLibraryFolder folderDesc) {
|
||||
File list[] = folderDesc.folder.listFiles(OnlyDirs.ONLY_DIRS);
|
||||
// if a bad folder or something like that, this might come back null
|
||||
if (list == null)
|
||||
return;
|
||||
// String mess = I18n.format(
|
||||
// tr("The library \"{0}\" cannot be used.\n"
|
||||
// + "Library folder names must start with a letter or number, followed by letters,\n"
|
||||
// + "numbers, dashes, dots and underscores. Maximum length is 63 characters."),
|
||||
// subfolderName);
|
||||
// BaseNoGui.showMessage(tr("Ignoring library with bad name"), mess);
|
||||
|
||||
for (File subfolder : list) {
|
||||
String subfolderName = subfolder.getName();
|
||||
if (!BaseNoGui.isSanitaryName(subfolderName)) {
|
||||
|
||||
// Detect whether the current folder name has already had a
|
||||
// notification.
|
||||
if (!badLibNotified.contains(subfolderName)) {
|
||||
|
||||
badLibNotified.add(subfolderName);
|
||||
|
||||
String mess = I18n.format(
|
||||
tr("The library \"{0}\" cannot be used.\n"
|
||||
+ "Library folder names must start with a letter or number, followed by letters,\n"
|
||||
+ "numbers, dashes, dots and underscores. Maximum length is 63 characters."),
|
||||
subfolderName);
|
||||
BaseNoGui.showMessage(tr("Ignoring library with bad name"), mess);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
scanLibrary(new UserLibraryFolder(subfolder, folderDesc.location));
|
||||
} catch (IOException e) {
|
||||
System.out.println(I18n.format(tr("Invalid library found in {0}: {1}"),
|
||||
subfolder, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanLibrary(UserLibraryFolder folderDesc) throws IOException {
|
||||
// A library is considered "legacy" if it doesn't contains
|
||||
// a file called "library.properties"
|
||||
File check = new File(folderDesc.folder, "library.properties");
|
||||
if (!check.exists() || !check.isFile()) {
|
||||
// Create a legacy library and exit
|
||||
LegacyUserLibrary lib = LegacyUserLibrary.create(folderDesc);
|
||||
String[] headers = BaseNoGui
|
||||
.headerListFromIncludePath(lib.getSrcFolder());
|
||||
if (headers.length == 0) {
|
||||
throw new IOException(format(tr("no headers files (.h) found in {0}"),
|
||||
lib.getSrcFolder()));
|
||||
}
|
||||
addToInstalledLibraries(lib);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a regular library
|
||||
UserLibrary lib = UserLibrary.create(folderDesc);
|
||||
String[] headers = BaseNoGui.headerListFromIncludePath(lib.getSrcFolder());
|
||||
if (headers.length == 0) {
|
||||
throw new IOException(
|
||||
format(tr("no headers files (.h) found in {0}"), lib.getSrcFolder()));
|
||||
}
|
||||
addToInstalledLibraries(lib);
|
||||
|
||||
Location loc = lib.getLocation();
|
||||
if (loc != Location.CORE && loc != Location.REFERENCED_CORE) {
|
||||
// Check if we can find the same library in the index
|
||||
// and mark it as installed
|
||||
index.find(lib.getName(), lib.getVersion()).ifPresent(foundLib -> {
|
||||
foundLib.setInstalledUserLibrary(lib);
|
||||
lib.setTypes(foundLib.getTypes());
|
||||
});
|
||||
}
|
||||
|
||||
if (lib.getTypes().isEmpty() && loc == Location.SKETCHBOOK) {
|
||||
lib.setTypes(lib.getDeclaredTypes());
|
||||
}
|
||||
|
||||
if (lib.getTypes().isEmpty()) {
|
||||
lib.setTypes(Collections.singletonList("Contributed"));
|
||||
}
|
||||
}
|
||||
// System.out.println(I18n.format(tr("Invalid library found in {0}: {1}"),
|
||||
// subfolder, e.getMessage()));
|
||||
|
||||
public LibrariesIndex getIndex() {
|
||||
return index;
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2014 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
package processing.app.packages;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class LegacyUserLibrary extends UserLibrary {
|
||||
|
||||
private String name;
|
||||
|
||||
public static LegacyUserLibrary create(UserLibraryFolder folderDesc) {
|
||||
// construct an old style library
|
||||
LegacyUserLibrary res = new LegacyUserLibrary();
|
||||
res.installedFolder = folderDesc.folder;
|
||||
res.layout = LibraryLayout.FLAT;
|
||||
res.name = folderDesc.folder.getName();
|
||||
res.setTypes(Arrays.asList("Contributed"));
|
||||
res.setCategory("Uncategorized");
|
||||
res.location = folderDesc.location;
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArchitectures() {
|
||||
return Arrays.asList("*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LegacyLibrary:" + name + "\n";
|
||||
}
|
||||
|
||||
}
|
@ -70,7 +70,7 @@ public class UserLibrary {
|
||||
|
||||
public static UserLibrary create(UserLibraryFolder libFolderDesc) throws IOException {
|
||||
File libFolder = libFolderDesc.folder;
|
||||
Location location = libFolderDesc.location;
|
||||
String location = libFolderDesc.location.toString();
|
||||
|
||||
// Parse metadata
|
||||
File propertiesFile = new File(libFolder, "library.properties");
|
||||
@ -98,15 +98,15 @@ public class UserLibrary {
|
||||
throw new IOException("Missing '" + p + "' from library");
|
||||
|
||||
// Check layout
|
||||
LibraryLayout layout;
|
||||
String layout;
|
||||
File srcFolder = new File(libFolder, "src");
|
||||
|
||||
if (srcFolder.exists() && srcFolder.isDirectory()) {
|
||||
// Layout with a single "src" folder and recursive compilation
|
||||
layout = LibraryLayout.RECURSIVE;
|
||||
layout = "recursive";
|
||||
} else {
|
||||
// Layout with source code on library's root and "utility" folders
|
||||
layout = LibraryLayout.FLAT;
|
||||
layout = "flat";
|
||||
}
|
||||
|
||||
// Warn if root folder contains development leftovers
|
||||
@ -159,26 +159,74 @@ public class UserLibrary {
|
||||
format(tr("Invalid version '{0}' for library in: {1}"), declaredVersion, libFolder.getAbsolutePath()));
|
||||
}
|
||||
|
||||
UserLibrary res = new UserLibrary();
|
||||
res.installedFolder = libFolder;
|
||||
res.name = properties.get("name").trim();
|
||||
res.version = version.isPresent() ? version.get().toString() : declaredVersion;
|
||||
res.author = properties.get("author").trim();
|
||||
res.maintainer = properties.get("maintainer").trim();
|
||||
res.sentence = properties.get("sentence").trim();
|
||||
res.paragraph = properties.get("paragraph").trim();
|
||||
res.website = properties.get("url").trim();
|
||||
res.category = category.trim();
|
||||
res.license = license.trim();
|
||||
res.architectures = archs;
|
||||
res.layout = layout;
|
||||
res.declaredTypes = typesList;
|
||||
res.onGoingDevelopment = Files.exists(Paths.get(libFolder.getAbsolutePath(), Constants.LIBRARY_DEVELOPMENT_FLAG_FILE));
|
||||
res.includes = includes;
|
||||
res.location = location;
|
||||
UserLibrary res = new UserLibrary( //
|
||||
libFolder, //
|
||||
properties.get("name").trim(), //
|
||||
version.isPresent() ? version.get().toString() : declaredVersion, //
|
||||
properties.get("author").trim(), //
|
||||
properties.get("maintainer").trim(), //
|
||||
properties.get("sentence").trim(), //
|
||||
properties.get("paragraph").trim(), //
|
||||
properties.get("url").trim(), //
|
||||
category.trim(), //
|
||||
license.trim(), //
|
||||
archs, //
|
||||
layout, //
|
||||
typesList, //
|
||||
Files.exists(Paths.get(libFolder.getAbsolutePath(), Constants.LIBRARY_DEVELOPMENT_FLAG_FILE)), //
|
||||
includes, //
|
||||
location //
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
public UserLibrary(File installedFolder, String name, String version,
|
||||
String author, String maintainer, String sentence,
|
||||
String paraghraph, String website, String category,
|
||||
String license, Collection<String> architectures,
|
||||
String layout, Collection<String> declaredTypes,
|
||||
boolean onGoingDevelopment, Collection<String> includes,
|
||||
String location) {
|
||||
this.installedFolder = installedFolder;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.author = author;
|
||||
this.maintainer = maintainer;
|
||||
this.sentence = sentence;
|
||||
this.paragraph = paraghraph;
|
||||
this.website = website;
|
||||
this.category = category;
|
||||
this.license = license;
|
||||
this.architectures = architectures;
|
||||
switch (layout) {
|
||||
case "recursive":
|
||||
this.layout = LibraryLayout.RECURSIVE;
|
||||
break;
|
||||
case "flat":
|
||||
this.layout = LibraryLayout.FLAT;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid library layout: " + layout);
|
||||
}
|
||||
this.declaredTypes = declaredTypes;
|
||||
this.onGoingDevelopment = onGoingDevelopment;
|
||||
this.includes = includes;
|
||||
switch (location) {
|
||||
case "ide":
|
||||
this.location = Location.IDE_BUILTIN;
|
||||
break;
|
||||
case "sketchbook":
|
||||
this.location = Location.SKETCHBOOK;
|
||||
break;
|
||||
case "platform":
|
||||
this.location = Location.CORE;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid library location: " + location);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user