Introducing uploader "warnings", a first attempt to give users more feedback with complex uploads

This commit is contained in:
Federico Fissore 2013-07-10 09:44:49 +02:00
parent 39c032b490
commit f648715621
7 changed files with 51 additions and 59 deletions

View File

@ -61,8 +61,9 @@ public abstract class Uploader implements MessageConsumer {
"avrdude: error: buffered memory access not supported.");
}
protected final boolean verbose;
private String error;
protected boolean verbose;
protected boolean notFoundError;
protected Uploader() {
@ -71,7 +72,7 @@ public abstract class Uploader implements MessageConsumer {
this.notFoundError = false;
}
public abstract boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer) throws RunnerException;
public abstract boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer, List<String> warningsAccumulator) throws RunnerException;
public abstract boolean burnBootloader() throws RunnerException;
@ -84,7 +85,7 @@ public abstract class Uploader implements MessageConsumer {
}
protected boolean executeUploadCommand(Collection<String> command) throws RunnerException {
return executeUploadCommand(command.toArray(new String[0]));
return executeUploadCommand(command.toArray(new String[command.size()]));
}
protected boolean executeUploadCommand(String command[]) throws RunnerException {

View File

@ -5,7 +5,7 @@ import cc.arduino.packages.uploaders.SerialUploader;
import processing.app.*;
import processing.app.debug.TargetBoard;
public class UploaderFactory {
public class UploaderAndMonitorFactory {
public Uploader newUploader(TargetBoard board, String port) {
if ("true".equals(board.getPreferences().get("upload.via_ssh")) && Constants.IPV4_ADDRESS.matcher(port).find()) {

View File

@ -46,10 +46,9 @@ public class SSHUploader extends Uploader {
}
@Override
public boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer) throws RunnerException {
public boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer, List<String> warningsAccumulator) throws RunnerException {
if (usingProgrammer) {
System.err.println(_("Http upload using programmer not supported"));
return false;
throw new RunnerException(_("Network upload using programmer not supported"));
}
Session session = null;
@ -65,7 +64,7 @@ public class SSHUploader extends Uploader {
scp = new SCP(session);
SSH ssh = new SSH(session);
scpFiles(scp, ssh, sourcePath, buildPath, className, session);
scpFiles(scp, ssh, sourcePath, buildPath, className, warningsAccumulator);
return runAVRDude(ssh);
} catch (JSchException e) {
@ -103,14 +102,14 @@ public class SSHUploader extends Uploader {
return success;
}
private void scpFiles(SCP scp, SSH ssh, File sourcePath, String buildPath, String className, Session session) throws JSchException, IOException {
private void scpFiles(SCP scp, SSH ssh, File sourcePath, String buildPath, String className, List<String> warningsAccumulator) throws JSchException, IOException {
try {
scp.open();
scp.startFolder("tmp");
scp.sendFile(new File(buildPath, className + ".hex"), "sketch.hex");
scp.endFolder();
if (canUploadWWWFiles(sourcePath, ssh)) {
if (canUploadWWWFiles(sourcePath, ssh, warningsAccumulator)) {
scp.startFolder("www");
scp.startFolder("sd");
scp.startFolder(sourcePath.getName());
@ -124,17 +123,17 @@ public class SSHUploader extends Uploader {
}
}
private boolean canUploadWWWFiles(File sourcePath, SSH ssh) throws IOException, JSchException {
private boolean canUploadWWWFiles(File sourcePath, SSH ssh, List<String> warningsAccumulator) throws IOException, JSchException {
File www = new File(sourcePath, "www");
if (!www.exists() || !www.isDirectory()) {
return false;
}
if (!www.canExecute()) {
System.out.println("Problem accessing files in folder " + www);
warningsAccumulator.add(_("Problem accessing files in folder ") + www);
return false;
}
if (!ssh.execSyncCommand("special-storage-available")) {
System.out.println("Problem accessing board folder /www/sd");
warningsAccumulator.add(_("Problem accessing board folder /www/sd"));
return false;
}
return true;

View File

@ -28,27 +28,22 @@
package cc.arduino.packages.uploaders;
import static processing.app.I18n._;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import cc.arduino.packages.Uploader;
import processing.app.Base;
import processing.app.I18n;
import processing.app.Preferences;
import processing.app.Serial;
import processing.app.SerialException;
import processing.app.*;
import processing.app.debug.RunnerException;
import processing.app.debug.TargetPlatform;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.StringReplacer;
public class SerialUploader extends Uploader {
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer) throws RunnerException {
import static processing.app.I18n._;
public class SerialUploader extends Uploader {
public boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer, List<String> warningsAccumulator) throws RunnerException {
// FIXME: Preferences should be reorganized
TargetPlatform targetPlatform = Base.getTargetPlatform();
PreferencesMap prefs = Preferences.getMap();
@ -80,9 +75,7 @@ public class SerialUploader extends Uploader {
List<String> before = Serial.list();
if (before.contains(uploadPort)) {
if (verbose)
System.out
.println(_("Forcing reset using 1200bps open/close on port ") +
uploadPort);
System.out.println(_("Forcing reset using 1200bps open/close on port ") + uploadPort);
Serial.touchPort(uploadPort, 1200);
}
if (waitForUploadPort) {
@ -163,12 +156,12 @@ public class SerialUploader extends Uploader {
}
}
} catch (InterruptedException ex) {
// noop
}
return uploadResult;
}
private String waitForUploadPort(String uploadPort, List<String> before)
throws InterruptedException, RunnerException {
private String waitForUploadPort(String uploadPort, List<String> before) throws InterruptedException, RunnerException {
// Wait for a port to appear on the list
int elapsed = 0;
while (elapsed < 10000) {
@ -203,22 +196,18 @@ public class SerialUploader extends Uploader {
// come back, so use a longer time out before assuming that the
// selected
// port is the bootloader (not the sketch).
if (((!Base.isWindows() && elapsed >= 500) || elapsed >= 5000) &&
now.contains(uploadPort)) {
if (((!Base.isWindows() && elapsed >= 500) || elapsed >= 5000) && now.contains(uploadPort)) {
if (verbose)
System.out.println("Uploading using selected port: " +
uploadPort);
System.out.println("Uploading using selected port: " + uploadPort);
return uploadPort;
}
}
// Something happened while detecting port
throw new RunnerException(
_("Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."));
throw new RunnerException(_("Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."));
}
public boolean uploadUsingProgrammer(String buildPath, String className)
throws RunnerException {
public boolean uploadUsingProgrammer(String buildPath, String className) throws RunnerException {
TargetPlatform targetPlatform = Base.getTargetPlatform();
String programmer = Preferences.get("programmer");
@ -264,8 +253,7 @@ public class SerialUploader extends Uploader {
String programmer = Preferences.get("programmer");
if (programmer.contains(":")) {
String[] split = programmer.split(":", 2);
TargetPlatform platform = Base
.getCurrentTargetPlatformFromPackage(split[0]);
TargetPlatform platform = Base.getCurrentTargetPlatformFromPackage(split[0]);
programmer = split[1];
programmerPrefs = platform.getProgrammer(programmer);
} else {
@ -286,14 +274,11 @@ public class SerialUploader extends Uploader {
tool = split[1];
toolPrefs.putAll(platform.getTool(tool));
if (toolPrefs.size() == 0)
throw new RunnerException(
I18n.format(_("Could not find tool {0} from package {1}"), tool,
split[0]));
throw new RunnerException(I18n.format(_("Could not find tool {0} from package {1}"), tool, split[0]));
}
toolPrefs.putAll(targetPlatform.getTool(tool));
if (toolPrefs.size() == 0)
throw new RunnerException(I18n.format(_("Could not find tool {0}"),
tool));
throw new RunnerException(I18n.format(_("Could not find tool {0}"), tool));
// Merge tool with global configuration
prefs.putAll(toolPrefs);

View File

@ -22,6 +22,7 @@
package processing.app;
import cc.arduino.packages.UploaderAndMonitorFactory;
import com.jcraft.jsch.JSchException;
import processing.app.debug.*;
import processing.app.forms.PasswordAuthorizationDialog;
@ -47,7 +48,6 @@ import javax.swing.undo.*;
import cc.arduino.packages.BoardPort;
import cc.arduino.packages.Uploader;
import cc.arduino.packages.UploaderFactory;
import cc.arduino.packages.uploaders.SerialUploader;
/**
@ -209,7 +209,7 @@ public class Editor extends JFrame implements RunnerListener {
//sketchbook = new Sketchbook(this);
if (serialMonitor == null) {
serialMonitor = new UploaderFactory().newMonitor(Preferences.get("serial.port"), base);
serialMonitor = new UploaderAndMonitorFactory().newMonitor(Preferences.get("serial.port"), base);
serialMonitor.setIconImage(getIconImage());
}
@ -975,7 +975,7 @@ public class Editor extends JFrame implements RunnerListener {
// ignore
}
serialMonitor.setVisible(false);
serialMonitor = new UploaderFactory().newMonitor(Preferences.get("serial.port"), base);
serialMonitor = new UploaderAndMonitorFactory().newMonitor(Preferences.get("serial.port"), base);
onBoardOrPortChange();

View File

@ -23,10 +23,10 @@
package processing.app;
import cc.arduino.packages.UploaderAndMonitorFactory;
import org.apache.commons.codec.digest.DigestUtils;
import cc.arduino.packages.Uploader;
import cc.arduino.packages.UploaderFactory;
import processing.app.debug.*;
import processing.app.debug.Compiler;
import processing.app.forms.PasswordAuthorizationDialog;
@ -1519,8 +1519,8 @@ public class Sketch {
* Map an error from a set of processed .java files back to its location
* in the actual sketch.
* @param message The error message.
* @param filename The .java file where the exception was found.
* @param line Line number of the .java file for the exception (0-indexed!)
* @param dotJavaFilename The .java file where the exception was found.
* @param dotJavaLine Line number of the .java file for the exception (0-indexed!)
* @return A RunnerException to be sent to the editor, or null if it wasn't
* possible to place the exception to the sketch code.
*/
@ -1666,7 +1666,7 @@ public class Sketch {
TargetPlatform target = Base.getTargetPlatform();
String board = Preferences.get("board");
Uploader uploader = new UploaderFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
Uploader uploader = new UploaderAndMonitorFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
boolean success = false;
do {
@ -1683,14 +1683,21 @@ public class Sketch {
Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
}
List<String> warningsAccumulator = new LinkedList<String>();
try {
success = uploader.uploadUsingPreferences(getFolder(), buildPath, suggestedClassName, usingProgrammer);
success = uploader.uploadUsingPreferences(getFolder(), buildPath, suggestedClassName, usingProgrammer, warningsAccumulator);
} finally {
if (uploader.requiresAuthorization() && !success) {
Preferences.remove(uploader.getAuthorizationKey());
}
}
for (String warning : warningsAccumulator) {
System.out.print(_("Warning"));
System.out.print(": ");
System.out.println(warning);
}
} while (uploader.requiresAuthorization() && !success);
return success;

View File

@ -1,7 +1,7 @@
package processing.app.debug;
import cc.arduino.packages.Uploader;
import cc.arduino.packages.UploaderFactory;
import cc.arduino.packages.UploaderAndMonitorFactory;
import cc.arduino.packages.uploaders.SSHUploader;
import cc.arduino.packages.uploaders.SerialUploader;
import org.junit.Before;
@ -24,7 +24,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
@Test
public void shouldCreateAnInstanceOfSSHUploader() throws Exception {
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (yun)");
Uploader uploader = new UploaderAndMonitorFactory().newUploader(board, "192.168.0.1 (yun)");
assertTrue(uploader instanceof SSHUploader);
}
@ -32,7 +32,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
@Test
public void shouldCreateAnInstanceOfBasicUploaderWhenSSHIsUnsupported() throws Exception {
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (myyun)");
Uploader uploader = new UploaderAndMonitorFactory().newUploader(board, "192.168.0.1 (myyun)");
assertTrue(uploader instanceof SerialUploader);
}
@ -40,7 +40,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
@Test
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
Uploader uploader = new UploaderFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
Uploader uploader = new UploaderAndMonitorFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
assertTrue(uploader instanceof SerialUploader);
}