diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java index 534b0dc2c74..16053b863f9 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoPreferences.java @@ -21,7 +21,8 @@ public class ArduinoPreferences { private static final String defaultHome = Paths.get(System.getProperty("user.home"), ".arduinocdt").toString(); //$NON-NLS-1$ //$NON-NLS-2$ private static final String defaultBoardUrls = "http://downloads.arduino.cc/packages/package_index.json" //$NON-NLS-1$ - + "\nhttp://arduino.esp8266.com/stable/package_esp8266com_index.json"; //$NON-NLS-1$ + + "\r\nhttp://arduino.esp8266.com/stable/package_esp8266com_index.json" //$NON-NLS-1$ + + "\r\nhttps://adafruit.github.io/arduino-board-index/package_adafruit_index.json"; //$NON-NLS-1$ private static IEclipsePreferences getPrefs() { return InstanceScope.INSTANCE.getNode(Activator.getId()); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java index 20a98296f0d..edf0f709380 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java @@ -19,6 +19,7 @@ import java.io.InputStream; import java.io.Reader; import java.lang.reflect.Type; import java.net.URL; +import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -68,20 +69,23 @@ public class ArduinoManager { public static final String AVR_TOOLCHAIN_ID = "org.eclipse.cdt.arduino.toolChain.avr"; //$NON-NLS-1$ public static final String LIBRARIES_URL = "http://downloads.arduino.cc/libraries/library_index.json"; //$NON-NLS-1$ + private List packageIndices; private LibraryIndex libraryIndex; public void loadIndices() { new Job(Messages.ArduinoBoardManager_0) { protected IStatus run(IProgressMonitor monitor) { - String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$ - packageIndices = new ArrayList<>(boardUrls.length); - for (String boardUrl : boardUrls) { - loadPackageIndex(boardUrl, true); - } + synchronized (ArduinoManager.this) { + String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$ + packageIndices = new ArrayList<>(boardUrls.length); + for (String boardUrl : boardUrls) { + loadPackageIndex(boardUrl, true); + } - loadLibraryIndex(true); - return Status.OK_STATUS; + loadLibraryIndex(true); + return Status.OK_STATUS; + } } }.schedule(); } @@ -270,83 +274,93 @@ public class ArduinoManager { public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath, IProgressMonitor monitor) { - try { - URL dl = new URL(url); - Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads"); //$NON-NLS-1$ - Files.createDirectories(dlDir); - Path archivePath = dlDir.resolve(archiveFileName); - Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING); - - boolean isWin = Platform.getOS().equals(Platform.OS_WIN32); - - // extract - ArchiveInputStream archiveIn = null; + Exception error = null; + for (int retries = 3; retries > 0 && !monitor.isCanceled(); --retries) { try { - String compressor = null; - String archiver = null; - if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$ - compressor = CompressorStreamFactory.BZIP2; - archiver = ArchiveStreamFactory.TAR; - } else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$ - compressor = CompressorStreamFactory.GZIP; - archiver = ArchiveStreamFactory.TAR; - } else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$ - compressor = CompressorStreamFactory.XZ; - archiver = ArchiveStreamFactory.TAR; - } else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$ - archiver = ArchiveStreamFactory.ZIP; - } + URL dl = new URL(url); + Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads"); //$NON-NLS-1$ + Files.createDirectories(dlDir); + Path archivePath = dlDir.resolve(archiveFileName); + URLConnection conn = dl.openConnection(); + conn.setConnectTimeout(10000); + conn.setReadTimeout(10000); + Files.copy(conn.getInputStream(), archivePath, StandardCopyOption.REPLACE_EXISTING); - InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile())); - if (compressor != null) { - in = new CompressorStreamFactory().createCompressorInputStream(compressor, in); - } - archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in); + boolean isWin = Platform.getOS().equals(Platform.OS_WIN32); - for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn.getNextEntry()) { - if (entry.isDirectory()) { - continue; + // extract + ArchiveInputStream archiveIn = null; + try { + String compressor = null; + String archiver = null; + if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$ + compressor = CompressorStreamFactory.BZIP2; + archiver = ArchiveStreamFactory.TAR; + } else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$ + compressor = CompressorStreamFactory.GZIP; + archiver = ArchiveStreamFactory.TAR; + } else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$ + compressor = CompressorStreamFactory.XZ; + archiver = ArchiveStreamFactory.TAR; + } else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$ + archiver = ArchiveStreamFactory.ZIP; } - Path entryPath = installPath.resolve(entry.getName()); - Files.createDirectories(entryPath.getParent()); + InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile())); + if (compressor != null) { + in = new CompressorStreamFactory().createCompressorInputStream(compressor, in); + } + archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in); - if (entry instanceof TarArchiveEntry) { - TarArchiveEntry tarEntry = (TarArchiveEntry) entry; - if (tarEntry.isLink()) { - Path linkPath = installPath.resolve(tarEntry.getLinkName()); - Files.createSymbolicLink(entryPath, entryPath.getParent().relativize(linkPath)); + for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn + .getNextEntry()) { + if (entry.isDirectory()) { + continue; + } + + Path entryPath = installPath.resolve(entry.getName()); + Files.createDirectories(entryPath.getParent()); + + if (entry instanceof TarArchiveEntry) { + TarArchiveEntry tarEntry = (TarArchiveEntry) entry; + if (tarEntry.isLink()) { + Path linkPath = installPath.resolve(tarEntry.getLinkName()); + Files.createSymbolicLink(entryPath, entryPath.getParent().relativize(linkPath)); + } else { + Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING); + } + if (!isWin) { + int mode = tarEntry.getMode(); + Files.setPosixFilePermissions(entryPath, toPerms(mode)); + } } else { Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING); } - if (!isWin) { - int mode = tarEntry.getMode(); - Files.setPosixFilePermissions(entryPath, toPerms(mode)); - } - } else { - Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING); + } + } finally { + if (archiveIn != null) { + archiveIn.close(); } } - } finally { - if (archiveIn != null) { - archiveIn.close(); - } - } - // Fix up directory - File[] children = installPath.toFile().listFiles(); - if (children.length == 1 && children[0].isDirectory()) { - // make that directory the install path - Path childPath = children[0].toPath(); - Path tmpPath = installPath.getParent().resolve("_t"); //$NON-NLS-1$ - Files.move(childPath, tmpPath); - Files.delete(installPath); - Files.move(tmpPath, installPath); + // Fix up directory + File[] children = installPath.toFile().listFiles(); + if (children.length == 1 && children[0].isDirectory()) { + // make that directory the install path + Path childPath = children[0].toPath(); + Path tmpPath = installPath.getParent().resolve("_t"); //$NON-NLS-1$ + Files.move(childPath, tmpPath); + Files.delete(installPath); + Files.move(tmpPath, installPath); + } + return Status.OK_STATUS; + } catch (IOException | CompressorException | ArchiveException e) { + error = e; + // retry } - return Status.OK_STATUS; - } catch (IOException | CompressorException | ArchiveException e) { - return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e); } + // out of retries + return new Status(IStatus.ERROR, Activator.getId(), "Download failed, please try again.", error); } private static Set toPerms(int mode) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java index 903933b9f3e..b3fac364591 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java @@ -31,7 +31,6 @@ import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; @@ -225,23 +224,11 @@ public class ArduinoPlatform { return Status.OK_STATUS; } - // Download platform archive - IStatus status = ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); - if (!status.isOK()) { - return status; - } - // Install the tools - MultiStatus mstatus = null; for (ToolDependency toolDep : toolsDependencies) { - status = toolDep.install(monitor); + IStatus status = toolDep.install(monitor); if (!status.isOK()) { - if (mstatus == null) { - mstatus = new MultiStatus(status.getPlugin(), status.getCode(), status.getMessage(), - status.getException()); - } else { - mstatus.add(status); - } + return status; } } @@ -256,14 +243,20 @@ public class ArduinoPlatform { makePath.toFile().setExecutable(true, false); } } catch (IOException e) { - mstatus.add(new Status(IStatus.ERROR, Activator.getId(), "downloading make.exe", e)); //$NON-NLS-1$ + return new Status(IStatus.ERROR, Activator.getId(), "Download failed, please try again.", e); } } + // Download platform archive + IStatus status = ArduinoManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor); + if (!status.isOK()) { + return status; + } + // Reload the library index to pick up platform libraries ArduinoManager.instance.loadLibraryIndex(false); - return mstatus != null ? mstatus : Status.OK_STATUS; + return Status.OK_STATUS; } @Override diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java index 65680e8fbe5..f6ddb310bbd 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/preferences/ArduinoBoardsPreferencePage.java @@ -7,12 +7,15 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.preferences; +import java.io.File; +import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; +import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard; import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; @@ -23,6 +26,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.ColumnWeightData; @@ -178,6 +182,24 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork @Override public boolean performOk() { + File acceptedFile = ArduinoPreferences.getArduinoHome().resolve(".accepted").toFile(); //$NON-NLS-1$ + if (!acceptedFile.exists()) { + String message = "Do you accept the licenses for the Arduino SDK and libraries? " + + "Information on the licenses can be found at arduino.cc web site."; + MessageDialog dialog = new MessageDialog(getShell(), "Arduino License", null, message, + MessageDialog.QUESTION, new String[] { "Accept", "Decline" }, 0); + int rc = dialog.open(); + if (rc == 0) { + try { + acceptedFile.createNewFile(); + } catch (IOException e) { + Activator.log(e); + } + } else { + return false; + } + } + new Job("Installing Arduino Board Platforms") { @Override protected IStatus run(IProgressMonitor monitor) {