From 6a09ee5eb667e6e19cead2cd430629482d7d12a3 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 09:51:25 +0200 Subject: [PATCH 01/27] Use an "action" enum when processing commandline arguments Previously, two separate booleans (doUpload and doVerify) were used. However, since it always makes sense to specify only one of them, it makes more sense to keep a single action enum variable, which slightly simplifies the code (especially when more actions are added later). Additionally, an error is now shown when both --verify and --upload are specified on the commandline. --- app/src/processing/app/Base.java | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4b7207780ff..ca0794f2276 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -268,6 +268,7 @@ static protected void initRequirements() { } + protected static enum ACTION { GUI, VERIFY, UPLOAD }; public Base(String[] args) throws Exception { platform.init(this); @@ -318,8 +319,7 @@ public Base(String[] args) throws Exception { // Setup board-dependent variables. onBoardOrPortChange(); - boolean doUpload = false; - boolean doVerify = false; + ACTION action = ACTION.GUI; boolean doVerboseBuild = false; boolean doVerboseUpload = false;; String selectBoard = null; @@ -327,14 +327,21 @@ public Base(String[] args) throws Exception { String currentDirectory = System.getProperty("user.dir"); List filenames = new LinkedList(); + // Map of possible actions and corresponding options + final Map actions = new HashMap(); + actions.put("--verify", ACTION.VERIFY); + actions.put("--upload", ACTION.UPLOAD); + // Check if any files were passed in on the command line for (int i = 0; i < args.length; i++) { - if (args[i].equals("--upload")) { - doUpload = true; - continue; - } - if (args[i].equals("--verify")) { - doVerify = true; + ACTION a = actions.get(args[i]); + if (a != null) { + if (action != ACTION.GUI) { + String[] valid = actions.keySet().toArray(new String[0]); + String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", ")); + showError(null, mess, 3); + } + action = a; continue; } if (args[i].equals("--verbose") || args[i].equals("-v")) { @@ -391,7 +398,7 @@ public Base(String[] args) throws Exception { filenames.add(args[i]); } - if ((doUpload || doVerify) && filenames.size() != 1) + if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) showError(null, _("Must specify exactly one sketch file"), 3); for (String path: filenames) { @@ -412,17 +419,17 @@ public Base(String[] args) throws Exception { path = new File(currentDirectory, path).getAbsolutePath(); } - if (handleOpen(path, nextEditorLocation(), !(doUpload || doVerify)) == null) { + if (handleOpen(path, nextEditorLocation(), !(action == ACTION.UPLOAD || action == ACTION.VERIFY)) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode - if (doUpload || doVerify) + if (action == ACTION.VERIFY || action == ACTION.UPLOAD) showError(null, mess, 2); else showWarning(null, mess, null); } } - if (doUpload || doVerify) { + if (action == ACTION.UPLOAD || action == ACTION.VERIFY) { // Set verbosity for command line build Preferences.set("build.verbose", "" + doVerboseBuild); Preferences.set("upload.verbose", "" + doVerboseUpload); @@ -432,7 +439,7 @@ public Base(String[] args) throws Exception { // Do board selection if requested processBoardArgument(selectBoard); - if (doUpload) { + if (action == ACTION.UPLOAD) { // Build and upload if (selectPort != null) editor.selectSerialPort(selectPort); From f3565a1bda4e157e218b84cda656fb2e8ee0a764 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:01:41 +0200 Subject: [PATCH 02/27] Invert decision on when to show the GUI Previously, the code showed an error when the given action was not upload or verify. This is now reversed: the GUI is shown when the action is "GUI" (which is the default when no action specified). Since the action enum only contains these three values, there is no change in behaviour, but this makes it easier to add new actions later. --- app/src/processing/app/Base.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index ca0794f2276..104d2818dee 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -419,7 +419,8 @@ public Base(String[] args) throws Exception { path = new File(currentDirectory, path).getAbsolutePath(); } - if (handleOpen(path, nextEditorLocation(), !(action == ACTION.UPLOAD || action == ACTION.VERIFY)) == null) { + boolean showEditor = (action == ACTION.GUI); + if (handleOpen(path, nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode if (action == ACTION.VERIFY || action == ACTION.UPLOAD) From 7548591d519e4d35151a1c6bba1ba0a86a022311 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:06:48 +0200 Subject: [PATCH 03/27] Improve commandline handling control flow This uses a switch on the action value, which makes it more clear what code runs when. No actual behaviour is changed, most of the changes in this commit are indentation changes. --- app/src/processing/app/Base.java | 76 +++++++++++++++++--------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 104d2818dee..016bd2b1f34 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -430,46 +430,50 @@ public Base(String[] args) throws Exception { } } - if (action == ACTION.UPLOAD || action == ACTION.VERIFY) { - // Set verbosity for command line build - Preferences.set("build.verbose", "" + doVerboseBuild); - Preferences.set("upload.verbose", "" + doVerboseUpload); - - Editor editor = editors.get(0); - - // Do board selection if requested - processBoardArgument(selectBoard); - - if (action == ACTION.UPLOAD) { - // Build and upload - if (selectPort != null) - editor.selectSerialPort(selectPort); - editor.exportHandler.run(); - } else { - // Build only - editor.runHandler.run(); - } - - // Error during build or upload - int res = editor.status.mode; - if (res == EditorStatus.ERR) - System.exit(1); + switch (action) { + case VERIFY: + case UPLOAD: + // Set verbosity for command line build + Preferences.set("build.verbose", "" + doVerboseBuild); + Preferences.set("upload.verbose", "" + doVerboseUpload); + + Editor editor = editors.get(0); + + // Do board selection if requested + processBoardArgument(selectBoard); + + if (action == ACTION.UPLOAD) { + // Build and upload + if (selectPort != null) + editor.selectSerialPort(selectPort); + editor.exportHandler.run(); + } else { + // Build only + editor.runHandler.run(); + } - // No errors exit gracefully - System.exit(0); - } + // Error during build or upload + int res = editor.status.mode; + if (res == EditorStatus.ERR) + System.exit(1); - // Check if there were previously opened sketches to be restored - restoreSketches(); + // No errors exit gracefully + System.exit(0); + break; + case GUI: + // Check if there were previously opened sketches to be restored + restoreSketches(); - // Create a new empty window (will be replaced with any files to be opened) - if (editors.isEmpty()) { - handleNew(); - } + // Create a new empty window (will be replaced with any files to be opened) + if (editors.isEmpty()) { + handleNew(); + } - // Check for updates - if (Preferences.getBoolean("update.check")) { - new UpdateCheck(this); + // Check for updates + if (Preferences.getBoolean("update.check")) { + new UpdateCheck(this); + } + break; } } From c0ab536b7b028b25112f4e50976b84e2374501bf Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:11:57 +0200 Subject: [PATCH 04/27] Add Base.selectSerialPort This method takes care of setting the serial.port preference to the given value, as well as deriving the serial.port.file preference. This should prevent duplicate code in the future. Note that a second copy of this code lives in SerialUploader, but that doesn't write to the global Preferences but a local prefs map. Since the global Preferences are currently static, there is no way to share code between these two copies. --- app/src/processing/app/Base.java | 7 +++++++ app/src/processing/app/Editor.java | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 016bd2b1f34..48a98e3a225 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1600,6 +1600,13 @@ private void selectBoard(TargetBoard targetBoard) { rebuildExamplesMenu(Editor.examplesMenu); } + public static void selectSerialPort(String port) { + Preferences.set("serial.port", port); + if (port.startsWith("/dev/")) + Preferences.set("serial.port.file", port.substring(5)); + else + Preferences.set("serial.port.file", port); + } public void rebuildProgrammerMenu(JMenu menu) { menu.removeAll(); diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 2138974d3af..3f2f7c601cc 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -965,11 +965,7 @@ protected void selectSerialPort(String name) { } if (selection != null) selection.setState(true); //System.out.println(item.getLabel()); - Preferences.set("serial.port", name); - if (name.startsWith("/dev/")) - Preferences.set("serial.port.file", name.substring(5)); - else - Preferences.set("serial.port.file", name); + Base.selectSerialPort(name); if (serialMonitor != null) { try { serialMonitor.close(); From 26ac897598fe04b1bfc2183c9ec259e9f64048c7 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 11:26:29 +0200 Subject: [PATCH 05/27] Fix indentation in the manpage --- build/shared/manpage.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 30f5072cdce..cf08b8c27b8 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -87,19 +87,19 @@ OPTIONS preferences is used (e.g., the last port selected in the IDE). *--verbose-build*:: - Enable verbose mode during build. If this option is not given, - verbose mode during build is disabled regardless of the current - preferences. + Enable verbose mode during build. If this option is not given, + verbose mode during build is disabled regardless of the current + preferences. *--verbose-upload*:: - Enable verbose mode during upload. If this option is not given, - verbose mode during upload is disabled regardless of the current - preferences. + Enable verbose mode during upload. If this option is not given, + verbose mode during upload is disabled regardless of the current + preferences. *-v, --verbose*:: Enable verbose mode during build and upload. - This option has the same effect of using both *--verbose-build* - and *--verbose-upload*. + This option has the same effect of using both *--verbose-build* + and *--verbose-upload*. *--preferences-file* __filename__:: Read and store preferences from the specified __filename__ instead From 7301b37c7e6a14c18714e73f84429f06270a6b1e Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 11:14:08 +0200 Subject: [PATCH 06/27] Added history section to the manpage This describes the versions where various options were introduced or changed. --- build/shared/manpage.adoc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index cf08b8c27b8..0ee60f654e0 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -211,6 +211,32 @@ re-use any previous build results in that directory. arduino --pref build.path=/path/to/sketch/build --verify /path/to/sketch/sketch.ino +HISTORY +------- +1.5.2:: + Added initial commandline support. This introduced *--verify*, + *--upload*, *--board*, *--port*, *--verbose* and *-v*. + +1.5.5:: + Added support for board-specific parameters to *--board*. + +{empty}:: + Sketch filenames are now interpreted relative to the current + directory instead of the location of the arduino command itself. + +1.5.6:: + Introduced *--pref*, *--preferences-file*, *--verbose-build* and + *--verbose-upload*. + +{empty}:: + Preferences set through --pref are remembered, preferences set + through *--board*, *--port* or the *--verbose* options are not. + +{empty}:: + When running with *--verify* or *--upload*, the full GUI is no + longer shown. Error messages still use a graphical popup and on + Windows, the splash screen is still shown. + RESOURCES --------- Web site: From d3e2208c0189ced313a737942727781f3ec67162 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:27:39 +0200 Subject: [PATCH 07/27] Process some commandline arguments earlier Previously, the --board and --port arguments were stored in a variable first and only processed later. Now, the arguments are processed right away. This does mean that the arguments are processed when the GUI is not yet initialized, which caused problems with calling onBoardOrPortChange and friends from selectBoard. However, since the GUI is not initialized, there is no real reason to call them either - if we just set the preferences to the right values, the GUI will be initialized correctly later. For this reason, selectBoard no longer calls the GUI update methods. Instead, those are called from the GUI code when the board is changed through the menu instead (e.g., after calling selectBoard). This commit slightly changes behaviour. Previously, --board and --port only worked in combination with --verify and --upload, but were ignored when just starting the IDE. Now, these are processed regardless of the other options present. Additionally, this commit causes all changed preferences to be saved. Previously, only changes with --pref were saved, --board and --port options were only active for the current run. This was caused because the saving of the preferences happened as a side effect of loading the file in the Editor, but only the --pref option was processed at that time. Note that the --verbose options are still only active for the current run and are only valid combined with --verify or --upload (since they default to non-verbose instead of the current preference). --- app/src/processing/app/Base.java | 20 +++++++------------- build/shared/manpage.adoc | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 48a98e3a225..4de136b0be1 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -361,14 +361,14 @@ public Base(String[] args) throws Exception { i++; if (i >= args.length) showError(null, _("Argument required for --board"), 3); - selectBoard = args[i]; + processBoardArgument(args[i]); continue; } if (args[i].equals("--port")) { i++; if (i >= args.length) showError(null, _("Argument required for --port"), 3); - selectPort = args[i]; + Base.selectSerialPort(args[i]); continue; } if (args[i].equals("--curdir")) { @@ -439,13 +439,8 @@ public Base(String[] args) throws Exception { Editor editor = editors.get(0); - // Do board selection if requested - processBoardArgument(selectBoard); - if (action == ACTION.UPLOAD) { // Build and upload - if (selectPort != null) - editor.selectSerialPort(selectPort); editor.exportHandler.run(); } else { // Build only @@ -1456,6 +1451,11 @@ private JRadioButtonMenuItem createBoardMenusAndCustomMenus( Action action = new AbstractAction(board.getName()) { public void actionPerformed(ActionEvent actionevent) { selectBoard((TargetBoard)getValue("b")); + filterVisibilityOfSubsequentBoardMenus((TargetBoard)getValue("b"), 1); + + onBoardOrPortChange(); + rebuildImportMenu(Editor.importMenu); + rebuildExamplesMenu(Editor.examplesMenu); } }; action.putValue("b", board); @@ -1592,12 +1592,6 @@ private void selectBoard(TargetBoard targetBoard) { File platformFolder = targetPlatform.getFolder(); Preferences.set("runtime.platform.path", platformFolder.getAbsolutePath()); Preferences.set("runtime.hardware.path", platformFolder.getParentFile().getAbsolutePath()); - - filterVisibilityOfSubsequentBoardMenus(targetBoard, 1); - - onBoardOrPortChange(); - rebuildImportMenu(Editor.importMenu); - rebuildExamplesMenu(Editor.examplesMenu); } public static void selectSerialPort(String port) { diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 0ee60f654e0..f35e34ce219 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -75,6 +75,8 @@ OPTIONS {empty}:: If this option is not passed, the value from the current preferences is used (e.g., the last board selected in the IDE). + If this option is given, the value passed is written to the + preferences file and rememberd for subsequent runs. *--port* __portname__:: Select the serial port to perform upload of the sketch. @@ -85,6 +87,8 @@ OPTIONS {empty}:: If this option is not passed, the value from the current preferences is used (e.g., the last port selected in the IDE). + If this option is given, the value passed is written to the + preferences file and rememberd for subsequent runs. *--verbose-build*:: Enable verbose mode during build. If this option is not given, @@ -108,16 +112,15 @@ OPTIONS *--pref* __name__=__value__:: Sets the preference __name__ to the given __value__. -{empty}:: - Currently the preferences set are saved to 'preferences.txt', but - this might change in the future (making them only active during - the current invocation). - {empty}:: Note that the preferences you set with this option are not validated: Invalid names will be set but never used, invalid values might lead to an error later on. +{empty}:: + If this option is given, the value passed is written to the + preferences file and rememberd for subsequent runs. + *--upload*:: Build and upload the sketch. @@ -237,6 +240,11 @@ HISTORY longer shown. Error messages still use a graphical popup and on Windows, the splash screen is still shown. +1.5.7:: + *--board* and *--port* options are now saved to the preferences + file, just like *--pref*. The *--verbose* options still only + apply to the current run. + RESOURCES --------- Web site: From e0c599d733db56b416d6200ce16d1b8e1965b2f2 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 11:47:04 +0200 Subject: [PATCH 08/27] Error when passing --verbose without --verify or --upload Since the handling of these options defaults to non-verbose (instead of the current preference), they make no sense when starting the IDE normally. Previously, these options would just be ignored in this case, now an error is shown. --- app/src/processing/app/Base.java | 3 +++ build/shared/manpage.adoc | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4de136b0be1..e0e9858d4f4 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -401,6 +401,9 @@ public Base(String[] args) throws Exception { if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) showError(null, _("Must specify exactly one sketch file"), 3); + if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload)) + showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3); + for (String path: filenames) { // Fix a problem with systems that use a non-ASCII languages. Paths are // being passed in with 8.3 syntax, which makes the sketch loader code diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index f35e34ce219..709676b804c 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -95,16 +95,28 @@ OPTIONS verbose mode during build is disabled regardless of the current preferences. +{empty}:: + This option is only valid together with *--verify* or + *--upload*. + *--verbose-upload*:: Enable verbose mode during upload. If this option is not given, verbose mode during upload is disabled regardless of the current preferences. +{empty}:: + This option is only valid together with *--verify* or + *--upload*. + *-v, --verbose*:: Enable verbose mode during build and upload. This option has the same effect of using both *--verbose-build* and *--verbose-upload*. +{empty}:: + This option is only valid together with *--verify* or + *--upload*. + *--preferences-file* __filename__:: Read and store preferences from the specified __filename__ instead of the default one. From bbd01286649abdd6c8f7d9b64221a5db7816780b Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:38:25 +0200 Subject: [PATCH 09/27] Explicitely save preferences on startup Before, the preferences were saved as a side effect of loading files in the Editor, but it seems better to explicitely save them as well (this should prevent problems later on, if the Editor class is no longer used in --verify or --upload mode). --- app/src/processing/app/Base.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index e0e9858d4f4..b8524f5f27f 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -433,6 +433,11 @@ public Base(String[] args) throws Exception { } } + // Save the preferences. For GUI mode, this happens in the quit + // handler, but for other modes we should also make sure to save + // them. + Preferences.save(); + switch (action) { case VERIFY: case UPLOAD: From 4452eb3850d331c5af24356e6f8e368f7d59acef Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 10:40:45 +0200 Subject: [PATCH 10/27] Add --no-save-prefs option This allows setting preferences for the current run only, without remembering them for the next run. This is especially useful when combined with --verify or --upload. --- app/src/processing/app/Base.java | 4 ++++ app/src/processing/app/Preferences.java | 8 ++++++++ build/shared/manpage.adoc | 15 ++++++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b8524f5f27f..4969bd2a5de 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -385,6 +385,10 @@ public Base(String[] args) throws Exception { processPrefArgument(args[i]); continue; } + if (args[i].equals("--no-save-prefs")) { + Preferences.setDoSave(false); + continue; + } if (args[i].equals("--preferences-file")) { i++; if (i >= args.length) diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 73b980ef52b..1196810865a 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -220,6 +220,7 @@ public String toString() { static Hashtable defaults; static Hashtable table = new Hashtable(); static File preferencesFile; + static boolean doSave = true; static protected void init(String args[]) { @@ -789,6 +790,7 @@ static public String[] loadStrings(InputStream input) { static protected void save() { + if (!doSave) return; // try { // on startup, don't worry about it // this is trying to update the prefs for who is open @@ -989,4 +991,10 @@ static public PreferencesMap getMap() return new PreferencesMap(table); } + // Decide wether changed preferences will be saved. When value is + // false, Preferences.save becomes a no-op. + static public void setDoSave(boolean value) + { + doSave = value; + } } diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 709676b804c..12d2bdba9a3 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -76,7 +76,8 @@ OPTIONS If this option is not passed, the value from the current preferences is used (e.g., the last board selected in the IDE). If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs. + preferences file and rememberd for subsequent runs (except when + *--no-save-prefs* is passed). *--port* __portname__:: Select the serial port to perform upload of the sketch. @@ -88,7 +89,8 @@ OPTIONS If this option is not passed, the value from the current preferences is used (e.g., the last port selected in the IDE). If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs. + preferences file and rememberd for subsequent runs (except when + *--no-save-prefs* is passed). *--verbose-build*:: Enable verbose mode during build. If this option is not given, @@ -131,7 +133,11 @@ OPTIONS {empty}:: If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs. + preferences file and rememberd for subsequent runs (except when + *--no-save-prefs* is passed). + +*--no-save-prefs*:: + Do not save any (changed) preferences to *preferences.txt*. *--upload*:: Build and upload the sketch. @@ -253,6 +259,9 @@ HISTORY Windows, the splash screen is still shown. 1.5.7:: + Introduced *--no-save-prefs*. + +{empty}:: *--board* and *--port* options are now saved to the preferences file, just like *--pref*. The *--verbose* options still only apply to the current run. From d6333f8f37b1b4c4038358a87b057832819a53ab Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 11:30:00 +0200 Subject: [PATCH 11/27] Don't save a new preferences file in Preferences.init Preferences.init would write out the default preferences when no preference file previously existed. This would cause a default preferences file to be written even when --no-save-prefs was passed, due to the ordering of things. However, since the Base constructor now already calls Preferences.save(), there is no need for Preferences.init to also do this. Since Base calls this after parsing the commandline, the --no-save-prefs option is now also properly respected. --- app/src/processing/app/Preferences.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 1196810865a..ca390084590 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -266,11 +266,7 @@ static protected void init(String args[]) { } } - if (!preferencesFile.exists()) { - // create a new preferences file if none exists - // saves the defaults out to the file - save(); - } else { + if (preferencesFile.exists()) { // load the previous preferences file try { load(new FileInputStream(preferencesFile)); From 7cb99ad7b852640d9ff31e046f4954440746da7e Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 11:51:09 +0200 Subject: [PATCH 12/27] Ensure --verbose is never saved to preferences.txt Previously, --verbose would be processed after the preferences were saved, which should usually mean that it should never influence the saved preferences. However, if for whatever reason Preferences.save() would be called later, the verbosity preferences would still be messed up. Since we now have a Preferences.setDoSave() method, we can make sure that these verbosity preferences (and any other preferences that are changed after the build started) are never saved. --- app/src/processing/app/Base.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 4969bd2a5de..e3fe238cac4 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -449,6 +449,10 @@ public Base(String[] args) throws Exception { Preferences.set("build.verbose", "" + doVerboseBuild); Preferences.set("upload.verbose", "" + doVerboseUpload); + // Make sure these verbosity preferences are only for the + // current session + Preferences.setDoSave(false); + Editor editor = editors.get(0); if (action == ACTION.UPLOAD) { From f745fff50bd6c69137e555cdabe3ec18c4bd7e8c Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 12:01:54 +0200 Subject: [PATCH 13/27] Add --noop option This option causes the IDE to process its commandline arguments and then quit. This allows setting preferences uses --pref, without having to also load the GUI or compile a sketch. --- app/src/processing/app/Base.java | 10 +++++++++- build/shared/manpage.adoc | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index e3fe238cac4..b692b11b867 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -268,7 +268,7 @@ static protected void initRequirements() { } - protected static enum ACTION { GUI, VERIFY, UPLOAD }; + protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP }; public Base(String[] args) throws Exception { platform.init(this); @@ -331,6 +331,7 @@ public Base(String[] args) throws Exception { final Map actions = new HashMap(); actions.put("--verify", ACTION.VERIFY); actions.put("--upload", ACTION.UPLOAD); + actions.put("--noop", ACTION.NOOP); // Check if any files were passed in on the command line for (int i = 0; i < args.length; i++) { @@ -405,6 +406,9 @@ public Base(String[] args) throws Exception { if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) showError(null, _("Must specify exactly one sketch file"), 3); + if (action == ACTION.NOOP && filenames.size() != 0) + showError(null, _("Cannot specify any sketch files"), 3); + if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload)) showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3); @@ -485,6 +489,10 @@ public Base(String[] args) throws Exception { new UpdateCheck(this); } break; + case NOOP: + // Do nothing (intended for only changing preferences) + System.exit(0); + break; } } diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 12d2bdba9a3..db52b2f5038 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -145,6 +145,10 @@ OPTIONS *--verify*:: Build the sketch. +*--noop*:: + Immediately quit after processing the commandline. This can be + used to just set preferences with *--pref*. + PREFERENCES ----------- Arduino keeps a list of preferences, as simple name and value pairs. @@ -232,6 +236,10 @@ re-use any previous build results in that directory. arduino --pref build.path=/path/to/sketch/build --verify /path/to/sketch/sketch.ino +Change the selected board and build path and do nothing else. + + arduino --pref build.path=/path/to/sketch/build --board arduino:avr:uno --noop + HISTORY ------- 1.5.2:: @@ -259,7 +267,7 @@ HISTORY Windows, the splash screen is still shown. 1.5.7:: - Introduced *--no-save-prefs*. + Introduced *--no-save-prefs* and *--noop*. {empty}:: *--board* and *--port* options are now saved to the preferences From e494f39255da9628181c53fa3685db4c3a5f103d Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 7 Apr 2014 12:19:22 +0200 Subject: [PATCH 14/27] Add --get-pref option This allows reading specific preferences from the commandline. --- app/src/processing/app/Base.java | 21 +++++++++++++++++++-- build/shared/manpage.adoc | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b692b11b867..d33490323da 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -268,7 +268,7 @@ static protected void initRequirements() { } - protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP }; + protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP, GET_PREF }; public Base(String[] args) throws Exception { platform.init(this); @@ -322,6 +322,7 @@ public Base(String[] args) throws Exception { ACTION action = ACTION.GUI; boolean doVerboseBuild = false; boolean doVerboseUpload = false;; + String getPref = null; String selectBoard = null; String selectPort = null; String currentDirectory = System.getProperty("user.dir"); @@ -332,6 +333,7 @@ public Base(String[] args) throws Exception { actions.put("--verify", ACTION.VERIFY); actions.put("--upload", ACTION.UPLOAD); actions.put("--noop", ACTION.NOOP); + actions.put("--get-pref", ACTION.GET_PREF); // Check if any files were passed in on the command line for (int i = 0; i < args.length; i++) { @@ -342,6 +344,12 @@ public Base(String[] args) throws Exception { String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", ")); showError(null, mess, 3); } + if (a == ACTION.GET_PREF) { + i++; + if (i >= args.length) + showError(null, _("Argument required for --get-pref"), 3); + getPref = args[i]; + } action = a; continue; } @@ -406,7 +414,7 @@ public Base(String[] args) throws Exception { if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) showError(null, _("Must specify exactly one sketch file"), 3); - if (action == ACTION.NOOP && filenames.size() != 0) + if ((action == ACTION.NOOP || action == ACTION.GET_PREF) && filenames.size() != 0) showError(null, _("Cannot specify any sketch files"), 3); if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload)) @@ -493,6 +501,15 @@ public Base(String[] args) throws Exception { // Do nothing (intended for only changing preferences) System.exit(0); break; + case GET_PREF: + String value = Preferences.get(getPref, null); + if (value != null) { + System.out.println(value); + System.exit(0); + } else { + System.exit(4); + } + break; } } diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index db52b2f5038..46a0b49462f 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -149,6 +149,11 @@ OPTIONS Immediately quit after processing the commandline. This can be used to just set preferences with *--pref*. +*--get-pref __preference__*:: + Prints the value of the given preference to the standard output + stream. When the value does not exist, nothing is printed and + the exit status is set (see EXIT STATUS below). + PREFERENCES ----------- Arduino keeps a list of preferences, as simple name and value pairs. @@ -185,6 +190,7 @@ EXIT STATUS *1*:: Build failed or upload failed *2*:: Sketch not found *3*:: Invalid (argument for) commandline option +*4*:: Preference passed to *--get-pref* does not exist FILES ----- From 9e17e52f63088b461dd447a51bb68f2aeb7afcc7 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 11:19:58 +0200 Subject: [PATCH 15/27] Parse --preferences-file in main instead of Preferences.init Parsing commandline arguments inside Preferences isn't very elegant, this is better suited for the main function. Also, this change prepares for taking --curdir into account for --preferences-file as well. --- app/src/processing/app/Base.java | 16 ++++++++++++++-- app/src/processing/app/Preferences.java | 17 +++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index d33490323da..0a505655428 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -139,8 +139,20 @@ static public void main(String args[]) throws Exception { if (!portableFolder.exists()) portableFolder = null; + File preferencesFile = null; + + // Do a first pass over the commandline arguments, the rest of them + // will be processed by the Base constructor. Note that this loop + // does not look at the last element of args, to prevent crashing + // when no parameter was specified to an option. Later, Base() will + // then show an error for these. + for (int i = 0; i < args.length - 1; i++) { + if (args[i].equals("--preferences-file")) + preferencesFile = new File(args[i + 1]); + } + // run static initialization that grabs all the prefs - Preferences.init(args); + Preferences.init(preferencesFile); try { File versionFile = getContentFile("lib/version.txt"); @@ -402,7 +414,7 @@ public Base(String[] args) throws Exception { i++; if (i >= args.length) showError(null, _("Argument required for --preferences-file"), 3); - // Argument should be already processed by Preferences.init(...) + // Argument should be already processed by Base.main(...) continue; } if (args[i].startsWith("--")) diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index ca390084590..3e0d564ebcd 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -223,7 +223,11 @@ public String toString() { static boolean doSave = true; - static protected void init(String args[]) { + static protected void init(File file) { + if (file != null) + preferencesFile = file; + else + preferencesFile = Base.getSettingsFile(Preferences.PREFS_FILE); // start by loading the defaults, in case something // important was deleted from the user prefs @@ -255,17 +259,6 @@ static protected void init(String args[]) { // clone the hash table defaults = new Hashtable(table); - // next load user preferences file - preferencesFile = Base.getSettingsFile(PREFS_FILE); - - // load a preferences file if specified on the command line - if (args != null) { - for (int i = 0; i < args.length - 1; i++) { - if (args[i].equals("--preferences-file")) - preferencesFile = new File(args[i + 1]); - } - } - if (preferencesFile.exists()) { // load the previous preferences file try { From cf4fb7d0e36261172e5831fd570d46828b035a65 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:07:20 +0200 Subject: [PATCH 16/27] Don't re-parse arguments to --preferences-file Previously, the argument to --preferences-file would be interpreted as a filename, but then also checked as an option as well (in the next loop iteration). This didn't really matter in practice (unless you would be using a file called "--preferences-file"), but better skip the argument anyway. --- app/src/processing/app/Base.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 0a505655428..92b41771351 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -147,8 +147,10 @@ static public void main(String args[]) throws Exception { // when no parameter was specified to an option. Later, Base() will // then show an error for these. for (int i = 0; i < args.length - 1; i++) { - if (args[i].equals("--preferences-file")) - preferencesFile = new File(args[i + 1]); + if (args[i].equals("--preferences-file")) { + ++i; + preferencesFile = new File(args[i]); + } } // run static initialization that grabs all the prefs From 87bdaa88cd286661ab65c46216c3ce6cd33052f9 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:11:08 +0200 Subject: [PATCH 17/27] Parse --curdir in Base.main() This shouldn't change any behaviour, but prepares for upcoming changes. --- app/src/processing/app/Base.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 92b41771351..23d72f0d3d2 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -117,6 +117,10 @@ public class Base { // Location for untitled items static File untitledFolder; + // Current directory to use for relative paths specified on the + // commandline + static String currentDirectory = System.getProperty("user.dir"); + // p5 icon for the window // static Image icon; @@ -150,6 +154,12 @@ static public void main(String args[]) throws Exception { if (args[i].equals("--preferences-file")) { ++i; preferencesFile = new File(args[i]); + continue; + } + if (args[i].equals("--curdir")) { + i++; + currentDirectory = args[i]; + continue; } } @@ -339,7 +349,6 @@ public Base(String[] args) throws Exception { String getPref = null; String selectBoard = null; String selectPort = null; - String currentDirectory = System.getProperty("user.dir"); List filenames = new LinkedList(); // Map of possible actions and corresponding options @@ -398,7 +407,7 @@ public Base(String[] args) throws Exception { i++; if (i >= args.length) showError(null, _("Argument required for --curdir"), 3); - currentDirectory = args[i]; + // Argument should be already processed by Base.main(...) continue; } if (args[i].equals("--pref")) { From 0798e1cf6f7382d15180f67e0a0ec742a6733d54 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:35:22 +0200 Subject: [PATCH 18/27] Pass around sketch File objects instead of filenames This saves a few conversions from File object to String and is generally cleaner. --- app/src/processing/app/Base.java | 45 ++++++++++--------- app/src/processing/app/Editor.java | 26 +++++------ app/src/processing/app/Sketch.java | 11 +++-- .../processing/app/macosx/ThinkDifferent.java | 4 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 23d72f0d3d2..5a948a24a97 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -462,7 +462,7 @@ public Base(String[] args) throws Exception { } boolean showEditor = (action == ACTION.GUI); - if (handleOpen(path, nextEditorLocation(), showEditor) == null) { + if (handleOpen(new File(path), nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode if (action == ACTION.VERIFY || action == ACTION.UPLOAD) @@ -654,7 +654,7 @@ protected boolean restoreSketches() throws Exception { location = nextEditorLocation(); } // If file did not exist, null will be returned for the Editor - if (handleOpen(path, location, true) != null) { + if (handleOpen(new File(path), location, true) != null) { opened++; } } @@ -812,7 +812,7 @@ protected int[] nextEditorLocation() { * @param shift whether shift is pressed, which will invert prompt setting * @param noPrompt disable prompt, no matter the setting */ - protected String createNewUntitled() throws IOException { + protected File createNewUntitled() throws IOException { File newbieDir = null; String newbieName = null; @@ -859,7 +859,7 @@ protected String createNewUntitled() throws IOException { throw new IOException(); } FileUtils.copyFile(new File(getContentFile("examples"), "01.Basics" + File.separator + "BareMinimum" + File.separator + "BareMinimum.ino"), newbieFile); - return newbieFile.getAbsolutePath(); + return newbieFile; } @@ -869,9 +869,9 @@ protected String createNewUntitled() throws IOException { */ public void handleNew() throws Exception { try { - String path = createNewUntitled(); - if (path != null) { - Editor editor = handleOpen(path); + File file = createNewUntitled(); + if (file != null) { + Editor editor = handleOpen(file); editor.untitled = true; } @@ -900,9 +900,9 @@ public void handleNewReplace() { protected void handleNewReplaceImpl() { try { - String path = createNewUntitled(); - if (path != null) { - activeEditor.handleOpenInternal(path); + File file = createNewUntitled(); + if (file != null) { + activeEditor.handleOpenInternal(file); activeEditor.untitled = true; } // return true; @@ -918,14 +918,14 @@ protected void handleNewReplaceImpl() { * Open a sketch, replacing the sketch in the current window. * @param path Location of the primary pde file for the sketch. */ - public void handleOpenReplace(String path) { + public void handleOpenReplace(File file) { if (!activeEditor.checkModified()) { return; // sketch was modified, and user canceled } // Close the running window, avoid window boogers with multiple sketches activeEditor.internalCloseRunner(); - boolean loaded = activeEditor.handleOpenInternal(path); + boolean loaded = activeEditor.handleOpenInternal(file); if (!loaded) { // replace the document without checking if that's ok handleNewReplaceImpl(); @@ -956,30 +956,30 @@ public void handleOpenPrompt() throws Exception { File inputFile = fd.getSelectedFile(); Preferences.set("last.folder", inputFile.getAbsolutePath()); - handleOpen(inputFile.getAbsolutePath()); + handleOpen(inputFile); } /** * Open a sketch in a new window. - * @param path Path to the pde file for the sketch in question + * @param file File to open * @return the Editor object, so that properties (like 'untitled') * can be set by the caller * @throws Exception */ - public Editor handleOpen(String path) throws Exception { - return handleOpen(path, nextEditorLocation(), true); + public Editor handleOpen(File file) throws Exception { + return handleOpen(file, nextEditorLocation(), true); } - protected Editor handleOpen(String path, int[] location, boolean showEditor) throws Exception { + protected Editor handleOpen(File file, int[] location, boolean showEditor) throws Exception { // System.err.println("entering handleOpen " + path); - File file = new File(path); if (!file.exists()) return null; // System.err.println(" editors: " + editors); // Cycle through open windows to make sure that it's not already open. + String path = file.getAbsolutePath(); for (Editor editor : editors) { if (editor.getSketch().getMainFilePath().equals(path)) { editor.toFront(); @@ -1003,7 +1003,7 @@ protected Editor handleOpen(String path, int[] location, boolean showEditor) thr // } // System.err.println(" creating new editor"); - Editor editor = new Editor(this, path, location); + Editor editor = new Editor(this, file, location); // Editor editor = null; // try { // editor = new Editor(this, path, location); @@ -1746,16 +1746,17 @@ private boolean addSketchesSubmenu(JMenu menu, String name, File folder, ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { String path = e.getActionCommand(); - if (new File(path).exists()) { + File file = new File(path); + if (file.exists()) { boolean replace = replaceExisting; if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) { replace = !replace; } if (replace) { - handleOpenReplace(path); + handleOpenReplace(file); } else { try { - handleOpen(path); + handleOpen(file); } catch (Exception e1) { e1.printStackTrace(); } diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 3f2f7c601cc..57785f1679d 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -155,7 +155,7 @@ public class Editor extends JFrame implements RunnerListener { Runnable exportAppHandler; - public Editor(Base ibase, String path, int[] location) throws Exception { + public Editor(Base ibase, File file, int[] location) throws Exception { super("Arduino"); this.base = ibase; @@ -310,7 +310,7 @@ public void windowDeactivated(WindowEvent e) { // System.out.println("t4"); // Open the document that was passed in - boolean loaded = handleOpenInternal(path); + boolean loaded = handleOpenInternal(file); if (!loaded) sketch = null; // System.out.println("t5"); @@ -2093,10 +2093,10 @@ protected boolean checkModified() { * Open a sketch from a particular path, but don't check to save changes. * Used by Sketch.saveAs() to re-open a sketch after the "Save As" */ - protected void handleOpenUnchecked(String path, int codeIndex, + protected void handleOpenUnchecked(File file, int codeIndex, int selStart, int selStop, int scrollPos) { internalCloseRunner(); - handleOpenInternal(path); + handleOpenInternal(file); // Replacing a document that may be untitled. If this is an actual // untitled document, then editor.untitled will be set by Base. untitled = false; @@ -2111,10 +2111,9 @@ protected void handleOpenUnchecked(String path, int codeIndex, * Second stage of open, occurs after having checked to see if the * modifications (if any) to the previous sketch need to be saved. */ - protected boolean handleOpenInternal(String path) { + protected boolean handleOpenInternal(File file) { // check to make sure that this .pde file is // in a folder of the same name - File file = new File(path); String fileName = file.getName(); File parent = file.getParentFile(); String parentName = parent.getName(); @@ -2128,10 +2127,10 @@ protected boolean handleOpenInternal(String path) { } else if (altPdeFile.exists()) { // user selected a .java from the same sketch, but open the .pde instead - path = altPdeFile.getAbsolutePath(); + file = altPdeFile; } else if (altInoFile.exists()) { - path = altInoFile.getAbsolutePath(); - } else if (!path.endsWith(".ino") && !path.endsWith(".pde")) { + file = altInoFile; + } else if (!fileName.endsWith(".ino") && !fileName.endsWith(".pde")) { Base.showWarning(_("Bad file selected"), _("Processing can only open its own sketches\n" + "and other files ending in .ino or .pde"), null); @@ -2180,19 +2179,18 @@ protected boolean handleOpenInternal(String path) { } // copy the sketch inside File properPdeFile = new File(properFolder, file.getName()); - File origPdeFile = new File(path); try { - Base.copyFile(origPdeFile, properPdeFile); + Base.copyFile(file, properPdeFile); } catch (IOException e) { Base.showWarning(_("Error"), _("Could not copy to a proper location."), e); return false; } // remove the original file, so user doesn't get confused - origPdeFile.delete(); + file.delete(); // update with the new path - path = properPdeFile.getAbsolutePath(); + file = properPdeFile; } else if (result == JOptionPane.NO_OPTION) { return false; @@ -2200,7 +2198,7 @@ protected boolean handleOpenInternal(String path) { } try { - sketch = new Sketch(this, path); + sketch = new Sketch(this, file); } catch (IOException e) { Base.showWarning(_("Error"), _("Could not create the sketch."), e); return false; diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 8cd95d7c4c3..4b2c6b44b4c 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -106,10 +106,10 @@ public class Sketch { * path is location of the main .pde file, because this is also * simplest to use when opening the file from the finder/explorer. */ - public Sketch(Editor editor, String path) throws IOException { + public Sketch(Editor editor, File file) throws IOException { this.editor = editor; - primaryFile = new File(path); + primaryFile = file; // get the name of the sketch by chopping .pde or .java // off of the main file name @@ -136,7 +136,7 @@ public Sketch(Editor editor, String path) throws IOException { tempBuildFolder = Base.getBuildFolder(); //Base.addBuildFolderToClassPath(); - folder = new File(new File(path).getParent()); + folder = new File(file.getParent()); //System.out.println("sketch dir is " + folder); load(); @@ -516,12 +516,11 @@ protected void nameCode(String newName) { // if successful, set base properties for the sketch File newMainFile = new File(newFolder, newName + ".ino"); - String newMainFilePath = newMainFile.getAbsolutePath(); // having saved everything and renamed the folder and the main .pde, // use the editor to re-open the sketch to re-init state // (unfortunately this will kill positions for carets etc) - editor.handleOpenUnchecked(newMainFilePath, + editor.handleOpenUnchecked(newMainFile, currentIndex, editor.getSelectionStart(), editor.getSelectionStop(), @@ -915,7 +914,7 @@ protected boolean saveAs() throws IOException { File newFile = new File(newFolder, newName + ".ino"); code[0].saveAs(newFile); - editor.handleOpenUnchecked(newFile.getPath(), + editor.handleOpenUnchecked(newFile, currentIndex, editor.getSelectionStart(), editor.getSelectionStop(), diff --git a/app/src/processing/app/macosx/ThinkDifferent.java b/app/src/processing/app/macosx/ThinkDifferent.java index 6448b1e9aab..0f226dd716a 100644 --- a/app/src/processing/app/macosx/ThinkDifferent.java +++ b/app/src/processing/app/macosx/ThinkDifferent.java @@ -26,6 +26,8 @@ import com.apple.eawt.*; +import java.io.File; + /** * Deal with issues related to thinking different. This handles the basic @@ -97,7 +99,7 @@ public void handleOpenFile(ApplicationEvent ae) { // System.out.println("got open file event " + ae.getFilename()); String filename = ae.getFilename(); try { - base.handleOpen(filename); + base.handleOpen(new File(filename)); } catch (Exception e) { e.printStackTrace(); } From 31fe4ac0c2859808339202eb8d1c172667d27f02 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:39:17 +0200 Subject: [PATCH 19/27] Add Base.absoluteFile method This method takes filenames as specified on the commandline and turns them into the right File object, taking into account the current directory passed through --curdir by the wrapper script. --- app/src/processing/app/Base.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5a948a24a97..d4b567fce33 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -291,6 +291,18 @@ static protected void initRequirements() { } } + // Returns a File object for the given pathname. If the pathname + // is not absolute, it is interpreted relative to the current + // directory when starting the IDE (which is not the same as the + // current working directory!). + static public File absoluteFile(String path) { + File file = new File(path); + if (!file.isAbsolute()) { + file = new File(currentDirectory, path); + } + return file; + } + protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP, GET_PREF }; public Base(String[] args) throws Exception { @@ -457,12 +469,11 @@ public Base(String[] args) throws Exception { } } - if (!new File(path).isAbsolute()) { - path = new File(currentDirectory, path).getAbsolutePath(); - } + // Correctly resolve relative paths + File file = absoluteFile(path); boolean showEditor = (action == ACTION.GUI); - if (handleOpen(new File(path), nextEditorLocation(), showEditor) == null) { + if (handleOpen(file, nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode if (action == ACTION.VERIFY || action == ACTION.UPLOAD) From f96d71f32d670d11ef1363443165922f8f5988f1 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:41:38 +0200 Subject: [PATCH 20/27] Fix --curdir on Windows On Windows, files are canonicalized to prevent issues with legacy 8.3 filenames. However, this canonicalization includes making the path absolute and this happened before applying --curdir to the path, making the latter a noop. By reversing the operations, this should allow both of them to do their work. --- app/src/processing/app/Base.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index d4b567fce33..5757b5a739d 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -456,22 +456,21 @@ public Base(String[] args) throws Exception { showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3); for (String path: filenames) { + // Correctly resolve relative paths + File file = absoluteFile(path); + // Fix a problem with systems that use a non-ASCII languages. Paths are // being passed in with 8.3 syntax, which makes the sketch loader code // unhappy, since the sketch folder naming doesn't match up correctly. // http://dev.processing.org/bugs/show_bug.cgi?id=1089 if (isWindows()) { try { - File file = new File(path); - path = file.getCanonicalPath(); + file = file.getCanonicalFile(); } catch (IOException e) { e.printStackTrace(); } } - // Correctly resolve relative paths - File file = absoluteFile(path); - boolean showEditor = (action == ACTION.GUI); if (handleOpen(file, nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); From 4f33d0851c0de227e640e10e6b214f17c2b5b316 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 8 Apr 2014 12:54:17 +0200 Subject: [PATCH 21/27] Fix opening a non-primary .ino file When a sketch looks like this: Blink/ Blink.ino Foo.ino The idea is that opening Foo.ino should open up the sketch. However, before this would show an error stating "The file Foo.ino needs to be inside a sketch folder named Foo" instead. This turned out to be due to a typo, which seems to have been present for a long time. Note that when the main sketch file was a .pde file, everything already worked as expected. --- app/src/processing/app/Editor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 57785f1679d..0d197a582d2 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2120,7 +2120,7 @@ protected boolean handleOpenInternal(File file) { String pdeName = parentName + ".pde"; File altPdeFile = new File(parent, pdeName); String inoName = parentName + ".ino"; - File altInoFile = new File(parent, pdeName); + File altInoFile = new File(parent, inoName); if (pdeName.equals(fileName) || inoName.equals(fileName)) { // no beef with this guy From cc773fb1e0f5c6b362f6b00e2369093209543ca0 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 9 Apr 2014 22:33:53 +0200 Subject: [PATCH 22/27] Take into account --curdir for all relative paths In a lot of places, (potentially) relative paths were passed to File without any processing, making them be resolved without taking into account --curdir. By passing them through Base.absoluteFile instead, these paths are resolved relative to the working directory before starting arduino (at least on Linux, which is currently the only platform supporting --curdir). This applies --curdir to the --preferences-file option and the build.path, settings.path, sketchbook.path preferences. For example, this now works as expected: arduino --pref build.path=build_dir --verify Blink.ino --- app/src/processing/app/Base.java | 17 +++++++++-------- build/shared/manpage.adoc | 7 +++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5757b5a739d..b483b2adac0 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -143,7 +143,7 @@ static public void main(String args[]) throws Exception { if (!portableFolder.exists()) portableFolder = null; - File preferencesFile = null; + String preferencesFile = null; // Do a first pass over the commandline arguments, the rest of them // will be processed by the Base constructor. Note that this loop @@ -153,7 +153,7 @@ static public void main(String args[]) throws Exception { for (int i = 0; i < args.length - 1; i++) { if (args[i].equals("--preferences-file")) { ++i; - preferencesFile = new File(args[i]); + preferencesFile = args[i]; continue; } if (args[i].equals("--curdir")) { @@ -164,7 +164,7 @@ static public void main(String args[]) throws Exception { } // run static initialization that grabs all the prefs - Preferences.init(preferencesFile); + Preferences.init(absoluteFile(preferencesFile)); try { File versionFile = getContentFile("lib/version.txt"); @@ -296,6 +296,8 @@ static protected void initRequirements() { // directory when starting the IDE (which is not the same as the // current working directory!). static public File absoluteFile(String path) { + if (path == null) return null; + File file = new File(path); if (!file.isAbsolute()) { file = new File(currentDirectory, path); @@ -320,7 +322,7 @@ public Base(String[] args) throws Exception { if (portableFolder != null) sketchbookFolder = new File(portableFolder, sketchbookPath); else - sketchbookFolder = new File(sketchbookPath); + sketchbookFolder = Base.absoluteFile(sketchbookPath); if (!sketchbookFolder.exists()) { Base.showWarning(_("Sketchbook folder disappeared"), _("The sketchbook folder no longer exists.\n" + @@ -2047,7 +2049,7 @@ static public File getSettingsFolder() { String preferencesPath = Preferences.get("settings.path"); if (preferencesPath != null) { - settingsFolder = new File(preferencesPath); + settingsFolder = absoluteFile(preferencesPath); } else { try { @@ -2086,8 +2088,7 @@ static public File getBuildFolder() { if (buildFolder == null) { String buildPath = Preferences.get("build.path"); if (buildPath != null) { - buildFolder = new File(buildPath); - + buildFolder = Base.absoluteFile(buildPath); } else { //File folder = new File(getTempFolder(), "build"); //if (!folder.exists()) folder.mkdirs(); @@ -2248,7 +2249,7 @@ static public String getPortableSketchbookFolder() { static public File getSketchbookFolder() { if (portableFolder != null) return new File(portableFolder, Preferences.get("sketchbook.path")); - return new File(Preferences.get("sketchbook.path")); + return absoluteFile(Preferences.get("sketchbook.path")); } diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 46a0b49462f..7af5a8c7ccf 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -280,6 +280,13 @@ HISTORY file, just like *--pref*. The *--verbose* options still only apply to the current run. +{empty}:: + A path passed to *--preferences-file*, or set in the + *build.path*, *preferences.path* or *settings.path* is now + interpreted relative to the current directory instead of the + location of the arduino command itself. + + RESOURCES --------- Web site: From c959388b3786d7d94c6c7926f99c43439ec018ef Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 5 Dec 2013 19:59:54 +0100 Subject: [PATCH 23/27] Let Editor::statusError print to stderr Before, these were only shown in the GUI, which makes a failing commandline build a bit puzzling. As a side effect, the error is now shown in the log area in addition to the status line above the log area, but that should be ok. --- app/src/processing/app/Editor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 0d197a582d2..953f9f44441 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2638,6 +2638,7 @@ public void handlePrint() { * Show an error int the status bar. */ public void statusError(String what) { + System.err.println(what); status.error(what); //new Exception("deactivating RUN").printStackTrace(); toolbar.deactivate(EditorToolbar.RUN); From f47ec35ebe47a81d0fc501ce6b1bf000d84649ba Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 9 Apr 2014 21:56:55 +0200 Subject: [PATCH 24/27] If build.path is specified, create it if needed When no build.path preference is present, a temporary directory is automatically created (and deleted). When a build.path was specified, but the directory does not exist, the IDE would show an error and fail to build, which is unexpected and not so friendly. This commit makes sure that the build directory is automatically created. --- app/src/processing/app/Base.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b483b2adac0..49f1d3f730e 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -2089,6 +2089,8 @@ static public File getBuildFolder() { String buildPath = Preferences.get("build.path"); if (buildPath != null) { buildFolder = Base.absoluteFile(buildPath); + if (!buildFolder.exists()) + buildFolder.mkdirs(); } else { //File folder = new File(getTempFolder(), "build"); //if (!folder.exists()) folder.mkdirs(); From 83ede8fdb44fd9997cbfe2944671afff9c071bde Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 10 Apr 2014 12:34:52 +0200 Subject: [PATCH 25/27] Fix preference directory opening in the GUI with --preferences-file In the preferences dialog, the name of the preferences file is shown for advanced editing. If the filename is clicked, the folder containing the file is opened. However, this always used Base.getSettingsFolder, which is the folder where the settings file _normally_ resides. But when the --preferences-file option is used, the actual preferences file might be somewhere else. This commit makes sure to always open up the parent directory of the actual preferences file in use, instead of always the default one. --- app/src/processing/app/Preferences.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 3e0d564ebcd..dc2b04b99fa 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -492,7 +492,7 @@ public void actionPerformed(ActionEvent e) { final JLabel clickable = label; label.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { - Base.openFolder(Base.getSettingsFolder()); + Base.openFolder(preferencesFile.getParentFile()); } public void mouseEntered(MouseEvent e) { From e3dc5e75e394dd6f650f52d93ac58b9694800f56 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 22 Aug 2014 14:24:21 +0200 Subject: [PATCH 26/27] Removed unused variables. Small cosmetic changes. --- app/src/processing/app/Base.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 49f1d3f730e..dbbc0ca0ebc 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -305,8 +305,8 @@ static public File absoluteFile(String path) { return file; } + protected static enum ACTION { GUI, NOOP, VERIFY, UPLOAD, GET_PREF }; - protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP, GET_PREF }; public Base(String[] args) throws Exception { platform.init(this); @@ -359,10 +359,8 @@ public Base(String[] args) throws Exception { ACTION action = ACTION.GUI; boolean doVerboseBuild = false; - boolean doVerboseUpload = false;; + boolean doVerboseUpload = false; String getPref = null; - String selectBoard = null; - String selectPort = null; List filenames = new LinkedList(); // Map of possible actions and corresponding options From ec1310e1bd54df18f66cdd7cb64016ccac78ac63 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 22 Aug 2014 15:39:33 +0200 Subject: [PATCH 27/27] Removed --no-op from CLI. Preferences now not-saved by default. See https://github.com/arduino/Arduino/pull/2000 for details. Close #2000 --- app/src/processing/app/Base.java | 22 ++++++++++++++---- build/shared/manpage.adoc | 38 ++++++++++---------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index dbbc0ca0ebc..45bc8aab206 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -360,6 +360,7 @@ public Base(String[] args) throws Exception { ACTION action = ACTION.GUI; boolean doVerboseBuild = false; boolean doVerboseUpload = false; + boolean forceSavePrefs = false; String getPref = null; List filenames = new LinkedList(); @@ -367,14 +368,13 @@ public Base(String[] args) throws Exception { final Map actions = new HashMap(); actions.put("--verify", ACTION.VERIFY); actions.put("--upload", ACTION.UPLOAD); - actions.put("--noop", ACTION.NOOP); actions.put("--get-pref", ACTION.GET_PREF); // Check if any files were passed in on the command line for (int i = 0; i < args.length; i++) { ACTION a = actions.get(args[i]); if (a != null) { - if (action != ACTION.GUI) { + if (action != ACTION.GUI && action != ACTION.NOOP) { String[] valid = actions.keySet().toArray(new String[0]); String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", ")); showError(null, mess, 3); @@ -391,14 +391,20 @@ public Base(String[] args) throws Exception { if (args[i].equals("--verbose") || args[i].equals("-v")) { doVerboseBuild = true; doVerboseUpload = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } if (args[i].equals("--verbose-build")) { doVerboseBuild = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } if (args[i].equals("--verbose-upload")) { doVerboseUpload = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } if (args[i].equals("--board")) { @@ -406,6 +412,8 @@ public Base(String[] args) throws Exception { if (i >= args.length) showError(null, _("Argument required for --board"), 3); processBoardArgument(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } if (args[i].equals("--port")) { @@ -413,6 +421,8 @@ public Base(String[] args) throws Exception { if (i >= args.length) showError(null, _("Argument required for --port"), 3); Base.selectSerialPort(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } if (args[i].equals("--curdir")) { @@ -427,10 +437,12 @@ public Base(String[] args) throws Exception { if (i >= args.length) showError(null, _("Argument required for --pref"), 3); processPrefArgument(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; continue; } - if (args[i].equals("--no-save-prefs")) { - Preferences.setDoSave(false); + if (args[i].equals("--save-prefs")) { + forceSavePrefs = true; continue; } if (args[i].equals("--preferences-file")) { @@ -472,6 +484,8 @@ public Base(String[] args) throws Exception { } boolean showEditor = (action == ACTION.GUI); + if (!forceSavePrefs) + Preferences.setDoSave(showEditor); if (handleOpen(file, nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc index 7af5a8c7ccf..176693c08f3 100644 --- a/build/shared/manpage.adoc +++ b/build/shared/manpage.adoc @@ -36,7 +36,7 @@ compiling and uploading sketches (programs) for Arduino Normally, running the arduino command starts the IDE, optionally loading any .ino files specified on the commandline. -Alternatively, if *--verify* or *--upload* is given, no graphical +Alternatively, if any of the following command line options is given, no graphical interface will be shown and instead a one-off verify (compile) or upload will be done. A single .ino file should be given. If the sketch contains multiple .ino files, any one can be specified on the commandline, but @@ -75,9 +75,6 @@ OPTIONS {empty}:: If this option is not passed, the value from the current preferences is used (e.g., the last board selected in the IDE). - If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs (except when - *--no-save-prefs* is passed). *--port* __portname__:: Select the serial port to perform upload of the sketch. @@ -88,13 +85,10 @@ OPTIONS {empty}:: If this option is not passed, the value from the current preferences is used (e.g., the last port selected in the IDE). - If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs (except when - *--no-save-prefs* is passed). *--verbose-build*:: Enable verbose mode during build. If this option is not given, - verbose mode during build is disabled regardless of the current + verbose mode during build is *disabled* regardless of the current preferences. {empty}:: @@ -103,7 +97,7 @@ OPTIONS *--verbose-upload*:: Enable verbose mode during upload. If this option is not given, - verbose mode during upload is disabled regardless of the current + verbose mode during upload is *disabled* regardless of the current preferences. {empty}:: @@ -131,13 +125,10 @@ OPTIONS validated: Invalid names will be set but never used, invalid values might lead to an error later on. -{empty}:: - If this option is given, the value passed is written to the - preferences file and rememberd for subsequent runs (except when - *--no-save-prefs* is passed). - -*--no-save-prefs*:: - Do not save any (changed) preferences to *preferences.txt*. +*--save-prefs*:: + Save any (changed) preferences to *preferences.txt*. In particular + *--board*, *--port*, *--pref*, *--verbose*, *--verbose-build* and + *--verbose-upload* may alter the current preferences. *--upload*:: Build and upload the sketch. @@ -145,10 +136,6 @@ OPTIONS *--verify*:: Build the sketch. -*--noop*:: - Immediately quit after processing the commandline. This can be - used to just set preferences with *--pref*. - *--get-pref __preference__*:: Prints the value of the given preference to the standard output stream. When the value does not exist, nothing is printed and @@ -244,7 +231,7 @@ re-use any previous build results in that directory. Change the selected board and build path and do nothing else. - arduino --pref build.path=/path/to/sketch/build --board arduino:avr:uno --noop + arduino --pref build.path=/path/to/sketch/build --board arduino:avr:uno --save-prefs HISTORY ------- @@ -272,13 +259,12 @@ HISTORY longer shown. Error messages still use a graphical popup and on Windows, the splash screen is still shown. -1.5.7:: - Introduced *--no-save-prefs* and *--noop*. +1.5.8:: + Introduced *--save-prefs*. {empty}:: - *--board* and *--port* options are now saved to the preferences - file, just like *--pref*. The *--verbose* options still only - apply to the current run. + *--pref* options are now not saved to the preferences file, just + like *--board* and *--port*, unless *--save-prefs* is specified. {empty}:: A path passed to *--preferences-file*, or set in the