Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit caa2b16

Browse files
committedJan 28, 2019
Merge remote-tracking branch 'mega/libs-cli-inception' into ide-1.9.x-beta
2 parents 39ee234 + 59c9fb9 commit caa2b16

23 files changed

+230
-390
lines changed
 

‎app/src/cc/arduino/contributions/ContributionsSelfCheck.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
package cc.arduino.contributions;
3131

3232
import cc.arduino.contributions.libraries.LibraryInstaller;
33-
import cc.arduino.contributions.libraries.filters.UpdatableLibraryPredicate;
3433
import cc.arduino.contributions.packages.ContributionInstaller;
3534
import cc.arduino.contributions.packages.filters.UpdatablePlatformPredicate;
3635
import cc.arduino.view.NotificationPopup;
@@ -130,7 +129,7 @@ static boolean checkForUpdatablePlatforms() {
130129

131130
static boolean checkForUpdatableLibraries() {
132131
return BaseNoGui.librariesIndexer.getIndex().getLibraries().stream()
133-
.anyMatch(new UpdatableLibraryPredicate());
132+
.anyMatch(r -> r.getInstalled().isPresent() && !r.getLatest().isLibraryInstalled());
134133
}
135134

136135
@Override

‎app/src/cc/arduino/contributions/libraries/filters/UpdatableLibraryPredicate.java

-62
This file was deleted.

‎app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellEditor.java

+11-14
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,16 @@
3636
import java.util.Collections;
3737
import java.util.LinkedList;
3838
import java.util.List;
39+
import java.util.Map;
3940
import java.util.Optional;
4041

4142
import javax.swing.JComboBox;
4243
import javax.swing.JTable;
4344

44-
import cc.arduino.contributions.DownloadableContributionVersionComparator;
4545
import cc.arduino.contributions.VersionComparator;
4646
import cc.arduino.contributions.libraries.ContributedLibrary;
4747
import cc.arduino.contributions.libraries.ContributedLibraryReleases;
4848
import cc.arduino.contributions.ui.InstallerTableCell;
49-
import cc.arduino.utils.ReverseComparator;
5049

5150
@SuppressWarnings("serial")
5251
public class ContributedLibraryTableCellEditor extends InstallerTableCell {
@@ -67,12 +66,11 @@ public Component getTableCellEditorComponent(JTable table, Object value,
6766

6867
editorCell = new ContributedLibraryTableCellJPanel(table, value, true);
6968
editorCell.installButton
70-
.addActionListener(e -> onInstall(editorValue.getSelected(),
71-
editorValue.getInstalled()));
69+
.addActionListener(e -> onInstall(editorValue.getSelected()));
7270
editorCell.downgradeButton.addActionListener(e -> {
7371
JComboBox chooser = editorCell.downgradeChooser;
7472
ContributedLibrary lib = (ContributedLibrary) chooser.getSelectedItem();
75-
onInstall(lib, editorValue.getInstalled());
73+
onInstall(lib);
7674
});
7775
editorCell.versionToInstallChooser.addActionListener(e -> {
7876
editorValue.select((ContributedLibrary) editorCell.versionToInstallChooser.getSelectedItem());
@@ -83,24 +81,24 @@ public Component getTableCellEditorComponent(JTable table, Object value,
8381

8482
setEnabled(true);
8583

86-
final Optional<ContributedLibrary> mayInstalled = editorValue.getInstalled();
84+
Map<String, ContributedLibrary> releases = editorValue.getReleases();
85+
List<ContributedLibrary> notInstalled = new LinkedList<>(releases.values());
8786

88-
List<ContributedLibrary> releases = editorValue.getReleases();
89-
List<ContributedLibrary> notInstalled = new LinkedList<>(releases);
87+
final Optional<ContributedLibrary> mayInstalled = editorValue.getInstalled();
9088
if (mayInstalled.isPresent()) {
91-
notInstalled.remove(editorValue.getInstalled().get());
89+
notInstalled.remove(mayInstalled.get());
9290
}
9391

94-
Collections.sort(notInstalled, new ReverseComparator<>(
95-
new DownloadableContributionVersionComparator()));
92+
Collections.sort(notInstalled, VersionComparator::compareTo);
93+
Collections.reverse(notInstalled);
9694

9795
editorCell.downgradeChooser.removeAllItems();
9896
editorCell.downgradeChooser.addItem(tr("Select version"));
9997

10098
final List<ContributedLibrary> notInstalledPrevious = new LinkedList<>();
10199
final List<ContributedLibrary> notInstalledNewer = new LinkedList<>();
102100

103-
notInstalled.stream().forEach(input -> {
101+
notInstalled.forEach(input -> {
104102
if (!mayInstalled.isPresent()
105103
|| VersionComparator.greaterThan(mayInstalled.get(), input)) {
106104
notInstalledPrevious.add(input);
@@ -142,8 +140,7 @@ protected void onRemove(ContributedLibrary selected) {
142140
// Empty
143141
}
144142

145-
protected void onInstall(ContributedLibrary selected,
146-
Optional<ContributedLibrary> mayInstalled) {
143+
protected void onInstall(ContributedLibrary selected) {
147144
// Empty
148145
}
149146

‎app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCellJPanel.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import javax.swing.text.html.HTMLDocument;
2424
import javax.swing.text.html.StyleSheet;
2525

26-
import cc.arduino.contributions.DownloadableContributionVersionComparator;
26+
import cc.arduino.contributions.VersionComparator;
2727
import cc.arduino.contributions.libraries.ContributedLibrary;
2828
import cc.arduino.contributions.libraries.ContributedLibraryReleases;
2929
import cc.arduino.contributions.ui.InstallerTableCell;
@@ -126,8 +126,7 @@ public ContributedLibraryTableCellJPanel(JTable parentTable, Object value,
126126
upgradable = false;
127127
} else {
128128
installable = false;
129-
upgradable = new DownloadableContributionVersionComparator()
130-
.compare(selected, mayInstalled.get()) > 0;
129+
upgradable = VersionComparator.greaterThan(selected, mayInstalled.get());
131130
}
132131
if (installable) {
133132
installButton.setText(tr("Install"));
@@ -165,7 +164,7 @@ public ContributedLibraryTableCellJPanel(JTable parentTable, Object value,
165164

166165
// ...version.
167166
if (mayInstalled.isPresent()) {
168-
String installedVer = mayInstalled.get().getParsedVersion();
167+
String installedVer = mayInstalled.get().getVersion();
169168
if (installedVer == null) {
170169
desc += " " + tr("Version unknown");
171170
} else {

‎app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java

+1-44
Original file line numberDiff line numberDiff line change
@@ -158,51 +158,8 @@ private boolean filterCondition(ContributedLibraryReleases lib) {
158158
return true;
159159
}
160160

161-
public void updateLibrary(ContributedLibrary lib) {
162-
// Find the row interested in the change
163-
int row = -1;
164-
for (ContributedLibraryReleases releases : contributions) {
165-
if (releases.shouldContain(lib))
166-
row = contributions.indexOf(releases);
167-
}
168-
169-
updateContributions();
170-
171-
// If the library is found in the list send update event
172-
// or insert event on the specific row...
173-
for (ContributedLibraryReleases releases : contributions) {
174-
if (releases.shouldContain(lib)) {
175-
if (row == -1) {
176-
row = contributions.indexOf(releases);
177-
fireTableRowsInserted(row, row);
178-
} else {
179-
fireTableRowsUpdated(row, row);
180-
}
181-
return;
182-
}
183-
}
184-
// ...otherwise send a row deleted event
185-
fireTableRowsDeleted(row, row);
186-
}
187-
188-
private List<ContributedLibraryReleases> rebuildContributionsFromIndex() {
189-
List<ContributedLibraryReleases> res = new ArrayList<>();
190-
BaseNoGui.librariesIndexer.getIndex().getLibraries(). //
191-
forEach(lib -> {
192-
for (ContributedLibraryReleases contribution : res) {
193-
if (!contribution.shouldContain(lib))
194-
continue;
195-
contribution.add(lib);
196-
return;
197-
}
198-
199-
res.add(new ContributedLibraryReleases(lib));
200-
});
201-
return res;
202-
}
203-
204161
private void updateContributions() {
205-
List<ContributedLibraryReleases> all = rebuildContributionsFromIndex();
162+
List<ContributedLibraryReleases> all = BaseNoGui.librariesIndexer.getIndex().getLibraries();
206163
contributions.clear();
207164
all.stream().filter(this::filterCondition).forEach(contributions::add);
208165
Collections.sort(contributions,

‎app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java

+4-9
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.Collections;
4040
import java.util.LinkedList;
4141
import java.util.List;
42-
import java.util.Optional;
4342
import java.util.function.Predicate;
4443

4544
import javax.swing.Box;
@@ -81,12 +80,8 @@ protected TableCellRenderer createCellRenderer() {
8180
protected InstallerTableCell createCellEditor() {
8281
return new ContributedLibraryTableCellEditor() {
8382
@Override
84-
protected void onInstall(ContributedLibrary selectedLibrary, Optional<ContributedLibrary> mayInstalledLibrary) {
85-
if (mayInstalledLibrary.isPresent() && selectedLibrary.isIDEBuiltIn()) {
86-
onRemovePressed(mayInstalledLibrary.get());
87-
} else {
88-
onInstallPressed(selectedLibrary, mayInstalledLibrary);
89-
}
83+
protected void onInstall(ContributedLibrary selectedLibrary) {
84+
onInstallPressed(selectedLibrary);
9085
}
9186

9287
@Override
@@ -213,12 +208,12 @@ protected void onUpdatePressed() {
213208
installerThread.start();
214209
}
215210

216-
public void onInstallPressed(final ContributedLibrary lib, final Optional<ContributedLibrary> mayReplaced) {
211+
public void onInstallPressed(final ContributedLibrary lib) {
217212
clearErrorMessage();
218213
installerThread = new Thread(() -> {
219214
try {
220215
setProgressVisible(true, tr("Installing..."));
221-
installer.install(lib, mayReplaced, this::setProgress);
216+
installer.install(lib, this::setProgress);
222217
// TODO: Do a better job in refreshing only the needed element
223218
if (contribTable.getCellEditor() != null) {
224219
contribTable.getCellEditor().stopCellEditing();

‎app/src/processing/app/Base.java

+5-14
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public Base(String[] args) throws Exception {
289289
pdeKeywords.reload();
290290

291291
contributionInstaller = new ContributionInstaller(BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
292-
libraryInstaller = new LibraryInstaller(BaseNoGui.getPlatform());
292+
libraryInstaller = new LibraryInstaller();
293293

294294
parser.parseArgumentsPhase2();
295295

@@ -368,26 +368,17 @@ public Base(String[] args) throws Exception {
368368
}
369369
selected = indexer.getIndex().find(libraryToInstallParts[0], version.get().toString());
370370
} else if (libraryToInstallParts.length == 1) {
371-
List<ContributedLibrary> librariesByName = indexer.getIndex().find(libraryToInstallParts[0]);
372-
Collections.sort(librariesByName, new DownloadableContributionVersionComparator());
373-
if (!librariesByName.isEmpty()) {
374-
selected = librariesByName.get(librariesByName.size() - 1);
371+
ContributedLibraryReleases releases = indexer.getIndex().find(libraryToInstallParts[0]);
372+
if (releases != null) {
373+
selected = releases.getLatest();
375374
}
376375
}
377376
if (selected == null) {
378377
System.out.println(tr("Selected library is not available"));
379378
System.exit(1);
380379
}
381380

382-
Optional<ContributedLibrary> mayInstalled = indexer.getIndex().getInstalled(libraryToInstallParts[0]);
383-
if (mayInstalled.isPresent() && selected.isIDEBuiltIn()) {
384-
System.out.println(tr(I18n
385-
.format("Library {0} is available as built-in in the IDE.\nRemoving the other version {1} installed in the sketchbook...",
386-
library, mayInstalled.get().getParsedVersion())));
387-
libraryInstaller.remove(mayInstalled.get(), progressListener);
388-
} else {
389-
libraryInstaller.install(selected, mayInstalled, progressListener);
390-
}
381+
libraryInstaller.install(selected, progressListener);
391382
}
392383

393384
System.exit(0);

‎app/test/cc/arduino/contributions/UpdatableLibraryTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void testUpdatableLibrary() throws Exception {
4141

4242
ContributedLibrary sdLib = indexer.getIndex().getInstalled("SD").get();
4343
assertTrue("SD lib is installed", sdLib.isLibraryInstalled());
44-
assertEquals("SD installed version", "1.1.1", sdLib.getParsedVersion());
44+
assertEquals("SD installed version", "1.1.1", sdLib.getVersion());
4545

4646
assertTrue(ContributionsSelfCheck.checkForUpdatableLibraries());
4747

@@ -50,7 +50,7 @@ public void testUpdatableLibrary() throws Exception {
5050

5151
sdLib = indexer.getIndex().getInstalled("SD").get();
5252
assertTrue("SD lib is installed", sdLib.isLibraryInstalled());
53-
assertEquals("SD installed version", "1.2.1", sdLib.getParsedVersion());
53+
assertEquals("SD installed version", "1.2.1", sdLib.getVersion());
5454

5555
assertFalse(ContributionsSelfCheck.checkForUpdatableLibraries());
5656
}
@@ -68,7 +68,7 @@ public void testUpdatableLibraryWithBundled() throws Exception {
6868

6969
ContributedLibrary l = indexer.getIndex().getInstalled("Bridge").get();
7070
assertTrue("Bridge lib is installed", l.isLibraryInstalled());
71-
assertEquals("Bridge installed version", "1.6.3", l.getParsedVersion());
71+
assertEquals("Bridge installed version", "1.6.3", l.getVersion());
7272

7373
assertTrue(ContributionsSelfCheck.checkForUpdatableLibraries());
7474

@@ -77,7 +77,7 @@ public void testUpdatableLibraryWithBundled() throws Exception {
7777

7878
l = indexer.getIndex().getInstalled("Bridge").get();
7979
assertTrue("Bridge lib is installed", l.isLibraryInstalled());
80-
assertEquals("Bridge installed version", "1.7.0", l.getParsedVersion());
80+
assertEquals("Bridge installed version", "1.7.0", l.getVersion());
8181

8282
assertFalse(ContributionsSelfCheck.checkForUpdatableLibraries());
8383
}

‎arduino-core/src/cc/arduino/contributions/VersionComparator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ public static ContributedLibrary max(ContributedLibrary a, ContributedLibrary b)
7575
}
7676

7777
public static boolean greaterThan(ContributedLibrary a, ContributedLibrary b) {
78-
return greaterThan(a.getParsedVersion(), b.getParsedVersion());
78+
return greaterThan(a.getVersion(), b.getVersion());
7979
}
8080

8181
public static int compareTo(ContributedLibrary a, ContributedLibrary b) {
82-
return compareTo(a.getParsedVersion(), b.getParsedVersion());
82+
return compareTo(a.getVersion(), b.getVersion());
8383
}
8484
}

‎arduino-core/src/cc/arduino/contributions/libraries/ContributedLibrary.java

+19-38
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@
2929

3030
package cc.arduino.contributions.libraries;
3131

32-
import cc.arduino.contributions.DownloadableContribution;
33-
import processing.app.I18n;
34-
import processing.app.packages.UserLibrary;
32+
import static processing.app.I18n.tr;
3533

36-
import java.util.Comparator;
3734
import java.util.List;
3835
import java.util.Optional;
3936

40-
import static processing.app.I18n.tr;
37+
import processing.app.I18n;
38+
import processing.app.packages.UserLibrary;
4139

42-
public abstract class ContributedLibrary extends DownloadableContribution {
40+
public abstract class ContributedLibrary {
4341

44-
public abstract String getName();
42+
public String getName() {
43+
return releases.getName();
44+
}
4545

4646
public abstract String getMaintainer();
4747

@@ -59,6 +59,8 @@ public abstract class ContributedLibrary extends DownloadableContribution {
5959

6060
public abstract String getSentence();
6161

62+
public abstract String getVersion();
63+
6264
public abstract List<String> getArchitectures();
6365

6466
public abstract List<String> getTypes();
@@ -67,10 +69,10 @@ public abstract class ContributedLibrary extends DownloadableContribution {
6769

6870
public abstract List<String> getProvidesIncludes();
6971

70-
public static final Comparator<ContributedLibrary> CASE_INSENSITIVE_ORDER = (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName());
71-
7272
private Optional<UserLibrary> installedLib = Optional.empty();
7373

74+
private ContributedLibraryReleases releases;
75+
7476
public Optional<UserLibrary> getInstalledLibrary() {
7577
return installedLib;
7678
}
@@ -123,16 +125,16 @@ public boolean supportsArchitecture(List<String> reqArchs) {
123125

124126
@Override
125127
public String toString() {
126-
return I18n.format(tr("Version {0}"), getParsedVersion());
128+
return I18n.format(tr("Version {0}"), getVersion());
127129
}
128130

129131
public String info() {
130132
String res = "";
131133
res += " ContributedLibrary : " + getName() + "\n";
132134
res += " author : " + getAuthor() + "\n";
133135
res += " maintainer : " + getMaintainer() + "\n";
134-
res += " version : " + getParsedVersion() + "\n";
135-
res += " website : " + getUrl() + "\n";
136+
res += " version : " + getVersion() + "\n";
137+
res += " website : " + getWebsite() + "\n";
136138
res += " category : " + getCategory() + "\n";
137139
res += " license : " + getLicense() + "\n";
138140
res += " descrip : " + getSentence() + "\n";
@@ -150,35 +152,14 @@ public String info() {
150152
res += " " + r;
151153
}
152154
res += "\n";
153-
154-
// DownloadableContribution
155-
res += super.toString();
156-
157155
return res;
158156
}
159157

160-
@Override
161-
public boolean equals(Object obj) {
162-
if (!(obj instanceof ContributedLibrary)) {
163-
return false;
164-
}
165-
ContributedLibrary other = (ContributedLibrary) obj;
166-
String thisVersion = getParsedVersion();
167-
String otherVersion = other.getParsedVersion();
168-
169-
boolean versionEquals = (thisVersion != null && otherVersion != null
170-
&& thisVersion.equals(otherVersion));
171-
172-
// Important: for legacy libs, versions are null. Two legacy libs must
173-
// always pass this test.
174-
if (thisVersion == null && otherVersion == null)
175-
versionEquals = true;
176-
177-
String thisName = getName();
178-
String otherName = other.getName();
179-
180-
boolean nameEquals = thisName == null || otherName == null || thisName.equals(otherName);
158+
public void setReleases(ContributedLibraryReleases releases) {
159+
this.releases = releases;
160+
}
181161

182-
return versionEquals && nameEquals;
162+
public ContributedLibraryReleases getReleases() {
163+
return releases;
183164
}
184165
}

‎arduino-core/src/cc/arduino/contributions/libraries/ContributedLibraryReleases.java

+17-46
Original file line numberDiff line numberDiff line change
@@ -29,56 +29,23 @@
2929

3030
package cc.arduino.contributions.libraries;
3131

32+
import java.util.Map;
33+
import java.util.Optional;
34+
3235
import cc.arduino.contributions.VersionComparator;
3336
import processing.app.packages.UserLibraryFolder.Location;
3437

35-
import java.util.LinkedList;
36-
import java.util.List;
37-
import java.util.Optional;
38+
public abstract class ContributedLibraryReleases {
3839

39-
public class ContributedLibraryReleases {
40+
public abstract String getName();
41+
42+
public abstract Map<String, ContributedLibrary> getReleases();
4043

41-
private List<ContributedLibrary> releases = new LinkedList<>();
42-
private List<String> versions = new LinkedList<>();
4344
private ContributedLibrary latest = null;
4445
private ContributedLibrary selected = null;
4546

46-
public ContributedLibraryReleases(ContributedLibrary library) {
47-
add(library);
48-
}
49-
50-
public ContributedLibraryReleases(List<ContributedLibrary> libraries) {
51-
libraries.forEach(this::add);
52-
}
53-
54-
public List<ContributedLibrary> getReleases() {
55-
return releases;
56-
}
57-
58-
public boolean shouldContain(ContributedLibrary lib) {
59-
if (latest == null) {
60-
return true;
61-
}
62-
return lib.getName().equals(latest.getName());
63-
}
64-
65-
public void add(ContributedLibrary library) {
66-
if (latest == null) {
67-
latest = library;
68-
}
69-
releases.add(library);
70-
String version = library.getParsedVersion();
71-
if (version != null) {
72-
versions.add(version);
73-
}
74-
if (VersionComparator.greaterThan(version, latest.getParsedVersion())) {
75-
latest = library;
76-
}
77-
selected = latest;
78-
}
79-
8047
public Optional<ContributedLibrary> getInstalled() {
81-
return releases.stream() //
48+
return getReleases().values().stream() //
8249
.filter(ContributedLibrary::isLibraryInstalled) //
8350
.reduce((x, y) -> {
8451
Location lx = x.getInstalledLibrary().get().getLocation();
@@ -91,19 +58,23 @@ public Optional<ContributedLibrary> getInstalled() {
9158
}
9259

9360
public ContributedLibrary getLatest() {
61+
if (latest == null) {
62+
String latestVersion = getReleases().keySet().stream().reduce(VersionComparator::max).orElse(null);
63+
latest = getReleases().get(latestVersion);
64+
}
9465
return latest;
9566
}
9667

9768
public ContributedLibrary getSelected() {
69+
if (selected == null) {
70+
selected = getLatest();
71+
}
9872
return selected;
9973
}
10074

10175
public void select(ContributedLibrary lib) {
102-
for (ContributedLibrary r : releases) {
103-
if (r == lib) {
104-
selected = r;
105-
return;
106-
}
76+
if (getReleases().containsValue(lib)) {
77+
selected = lib;
10778
}
10879
}
10980
}

‎arduino-core/src/cc/arduino/contributions/libraries/EmptyLibrariesIndex.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434

3535
public class EmptyLibrariesIndex extends LibrariesIndex {
3636

37-
private List<ContributedLibrary> list = new ArrayList<>();
37+
private List<ContributedLibraryReleases> list = new ArrayList<>();
3838

3939
@Override
40-
public List<ContributedLibrary> getLibraries() {
40+
public List<ContributedLibraryReleases> getLibraries() {
4141
return list;
4242
}
4343

‎arduino-core/src/cc/arduino/contributions/libraries/LibrariesIndex.java

+29-28
Original file line numberDiff line numberDiff line change
@@ -29,73 +29,74 @@
2929

3030
package cc.arduino.contributions.libraries;
3131

32+
import java.util.ArrayList;
3233
import java.util.Collection;
3334
import java.util.Collections;
3435
import java.util.HashSet;
35-
import java.util.LinkedList;
3636
import java.util.List;
3737
import java.util.Optional;
38-
import java.util.stream.Collectors;
3938

4039
public abstract class LibrariesIndex {
4140

42-
public abstract List<ContributedLibrary> getLibraries();
41+
public abstract List<ContributedLibraryReleases> getLibraries();
4342

44-
public List<ContributedLibrary> find(final String name) {
43+
public ContributedLibraryReleases find(final String name) {
4544
return getLibraries().stream() //
46-
.filter(l -> name.equals(l.getName())) //
47-
.collect(Collectors.toList());
45+
.filter(l -> l.getName().equals(name)) //
46+
.findAny() //
47+
.orElse(null);
4848
}
4949

5050
public ContributedLibrary find(String name, String version) {
51-
if (name == null || version == null) {
51+
if (version == null || name == null) {
5252
return null;
5353
}
54-
for (ContributedLibrary lib : find(name)) {
55-
if (version.equals(lib.getParsedVersion())) {
56-
return lib;
57-
}
54+
ContributedLibraryReleases releases = find(name);
55+
if (releases == null) {
56+
return null;
5857
}
59-
return null;
58+
return releases.getReleases().get(version);
6059
}
6160

6261
@Override
6362
public String toString() {
6463
StringBuilder sb = new StringBuilder();
65-
for (ContributedLibrary library : getLibraries()) {
64+
for (ContributedLibraryReleases library : getLibraries()) {
6665
sb.append(library.toString());
6766
}
6867
return sb.toString();
6968
}
7069

7170
public List<String> getCategories() {
72-
List<String> categories = new LinkedList<>();
73-
for (ContributedLibrary lib : getLibraries()) {
74-
if (lib.getCategory() != null && !categories.contains(lib.getCategory())) {
75-
categories.add(lib.getCategory());
76-
}
77-
}
71+
List<String> categories = new ArrayList<>();
72+
getLibraries().forEach(r -> {
73+
r.getReleases().forEach((v, lib) -> {
74+
if (lib.getCategory() != null && !categories.contains(lib.getCategory())) {
75+
categories.add(lib.getCategory());
76+
}
77+
});
78+
});
7879
Collections.sort(categories);
79-
8080
return categories;
8181
}
8282

8383
public List<String> getTypes() {
8484
Collection<String> typesAccumulator = new HashSet<>();
85-
for (ContributedLibrary lib : getLibraries()) {
86-
if (lib.getTypes() != null) {
87-
typesAccumulator.addAll(lib.getTypes());
88-
}
89-
}
85+
getLibraries().forEach(r -> {
86+
r.getReleases().forEach((v, lib) -> {
87+
if (lib.getTypes() != null) {
88+
typesAccumulator.addAll(lib.getTypes());
89+
}
90+
});
91+
});
9092

91-
List<String> types = new LinkedList<>(typesAccumulator);
93+
List<String> types = new ArrayList<>(typesAccumulator);
9294
Collections.sort(types);
9395

9496
return types;
9597
}
9698

9799
public Optional<ContributedLibrary> getInstalled(String name) {
98-
ContributedLibraryReleases rel = new ContributedLibraryReleases(find(name));
99-
return rel.getInstalled();
100+
return find(name).getInstalled();
100101
}
101102
}

‎arduino-core/src/cc/arduino/contributions/libraries/LibrariesIndexer.java

+36-42
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,31 @@
2929

3030
package cc.arduino.contributions.libraries;
3131

32-
import cc.arduino.Constants;
33-
import cc.arduino.contributions.packages.ContributedPlatform;
32+
import static processing.app.I18n.format;
33+
import static processing.app.I18n.tr;
34+
35+
import java.io.File;
36+
import java.io.IOException;
37+
import java.io.InputStream;
38+
import java.util.ArrayList;
39+
import java.util.Collections;
40+
import java.util.List;
41+
import java.util.Optional;
42+
43+
import org.apache.commons.compress.utils.IOUtils;
3444

3545
import com.fasterxml.jackson.core.JsonParseException;
3646
import com.fasterxml.jackson.databind.DeserializationFeature;
3747
import com.fasterxml.jackson.databind.JsonMappingException;
48+
import com.fasterxml.jackson.databind.MapperFeature;
3849
import com.fasterxml.jackson.databind.ObjectMapper;
3950
import com.fasterxml.jackson.module.mrbean.MrBeanModule;
40-
import org.apache.commons.compress.utils.IOUtils;
51+
52+
import cc.arduino.Constants;
53+
import cc.arduino.contributions.packages.ContributedPlatform;
4154
import processing.app.BaseNoGui;
4255
import processing.app.I18n;
56+
import processing.app.helpers.ProcessUtils;
4357
import processing.app.helpers.filefilters.OnlyDirs;
4458
import processing.app.packages.LegacyUserLibrary;
4559
import processing.app.packages.LibraryList;
@@ -48,62 +62,50 @@
4862
import processing.app.packages.UserLibraryFolder.Location;
4963
import processing.app.packages.UserLibraryPriorityComparator;
5064

51-
import java.io.File;
52-
import java.io.FileInputStream;
53-
import java.io.IOException;
54-
import java.io.InputStream;
55-
import java.util.ArrayList;
56-
import java.util.Collections;
57-
import java.util.List;
58-
import java.util.Optional;
59-
60-
import static processing.app.I18n.format;
61-
import static processing.app.I18n.tr;
62-
6365
public class LibrariesIndexer {
6466

6567
private LibrariesIndex index;
6668
private final LibraryList installedLibraries = new LibraryList();
6769
private List<UserLibraryFolder> librariesFolders;
68-
private final File indexFile;
69-
private final File stagingFolder;
7070

7171
private final List<String> badLibNotified = new ArrayList<>();
7272

7373
public LibrariesIndexer(File preferencesFolder) {
74-
indexFile = new File(preferencesFolder, "library_index.json");
75-
stagingFolder = new File(new File(preferencesFolder, "staging"), "libraries");
74+
// TODO: use specified preferencesFolder when running cli
7675
}
7776

7877
public void parseIndex() throws IOException {
7978
index = new EmptyLibrariesIndex(); // Fallback
8079

81-
if (!indexFile.exists()) {
82-
return;
83-
}
84-
85-
parseIndex(indexFile);
80+
Process process = ProcessUtils.exec(new String[] {
81+
BaseNoGui.getArduinoCliPath(), "lib", "search", "--format", "json" });
8682

87-
// TODO: resolve libraries inner references
88-
}
89-
90-
private void parseIndex(File file) throws IOException {
9183
InputStream indexIn = null;
9284
try {
93-
indexIn = new FileInputStream(file);
85+
indexIn = process.getInputStream();
9486
ObjectMapper mapper = new ObjectMapper();
9587
mapper.registerModule(new MrBeanModule());
9688
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
9789
mapper.configure(DeserializationFeature.EAGER_DESERIALIZER_FETCH, true);
9890
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
91+
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
9992
LibrariesIndex newIndex = mapper.readValue(indexIn, LibrariesIndex.class);
10093

101-
newIndex.getLibraries()
102-
.stream()
94+
newIndex.getLibraries().forEach(r -> {
95+
r.getReleases().values().stream()
10396
.filter(library -> library.getCategory() == null || "".equals(library.getCategory()) || !Constants.LIBRARY_CATEGORIES.contains(library.getCategory()))
10497
.forEach(library -> library.setCategory("Uncategorized"));
98+
});
10599

100+
// Populate ContributedLibraries inner cross-references
101+
newIndex.getLibraries().forEach(r -> {
102+
r.getReleases().forEach((v, l) -> {
103+
l.setReleases(r);
104+
});
105+
});
106106
index = newIndex;
107+
} catch (NullPointerException e) {
108+
e.printStackTrace();
107109
} catch (JsonParseException | JsonMappingException e) {
108110
System.err.println(
109111
format(tr("Error parsing libraries index: {0}\nTry to open the Library Manager to update the libraries index."),
@@ -152,9 +154,9 @@ public void rescanLibraries() {
152154
return;
153155
}
154156

155-
for (ContributedLibrary lib : index.getLibraries()) {
156-
lib.unsetInstalledUserLibrary();
157-
}
157+
index.getLibraries().forEach(r -> {
158+
r.getReleases().forEach((v, lib) -> lib.unsetInstalledUserLibrary());
159+
});
158160

159161
// Rescan libraries
160162
for (UserLibraryFolder folderDesc : librariesFolders) {
@@ -255,12 +257,4 @@ public LibrariesIndex getIndex() {
255257
public LibraryList getInstalledLibraries() {
256258
return new LibraryList(installedLibraries);
257259
}
258-
259-
public File getStagingFolder() {
260-
return stagingFolder;
261-
}
262-
263-
public File getIndexFile() {
264-
return indexFile;
265-
}
266260
}

‎arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java

+51-77
Original file line numberDiff line numberDiff line change
@@ -29,55 +29,32 @@
2929

3030
package cc.arduino.contributions.libraries;
3131

32-
import cc.arduino.Constants;
33-
import cc.arduino.contributions.DownloadableContributionsDownloader;
34-
import cc.arduino.contributions.GZippedJsonDownloader;
32+
import static processing.app.I18n.tr;
33+
34+
import java.util.Optional;
35+
3536
import cc.arduino.contributions.ProgressListener;
36-
import cc.arduino.utils.ArchiveExtractor;
3737
import cc.arduino.utils.MultiStepProgress;
3838
import processing.app.BaseNoGui;
3939
import processing.app.I18n;
40-
import processing.app.Platform;
41-
import processing.app.helpers.FileUtils;
42-
43-
import java.io.File;
44-
import java.io.IOException;
45-
import java.net.URL;
46-
import java.util.Optional;
47-
48-
import static processing.app.I18n.tr;
40+
import processing.app.helpers.ProcessUtils;
4941

5042
public class LibraryInstaller {
5143

52-
private final Platform platform;
53-
54-
public LibraryInstaller(Platform platform) {
55-
this.platform = platform;
56-
}
57-
5844
public synchronized void updateIndex(ProgressListener progressListener) throws Exception {
5945
final MultiStepProgress progress = new MultiStepProgress(3);
6046

61-
DownloadableContributionsDownloader downloader = new DownloadableContributionsDownloader(BaseNoGui.librariesIndexer.getStagingFolder());
62-
// Step 1: Download index
63-
File outputFile = BaseNoGui.librariesIndexer.getIndexFile();
64-
File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp");
65-
try {
66-
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(Constants.LIBRARY_INDEX_URL), new URL(Constants.LIBRARY_INDEX_URL_GZ));
67-
gZippedJsonDownloader.download(tmpFile, progress, tr("Downloading libraries index..."), progressListener);
68-
} catch (InterruptedException e) {
69-
// Download interrupted... just exit
70-
return;
71-
}
47+
progress.setStatus(tr("Updating library index"));
7248
progress.stepDone();
49+
progressListener.onProgress(progress);
7350

74-
// TODO: Check downloaded index
75-
76-
// Replace old index with the updated one
77-
if (outputFile.exists())
78-
outputFile.delete();
79-
if (!tmpFile.renameTo(outputFile))
51+
Process pr = ProcessUtils.exec(new String[] { //
52+
BaseNoGui.getArduinoCliPath(), "lib", "update-index" });
53+
int exitCode = pr.waitFor();
54+
if (exitCode != 0) {
8055
throw new Exception(tr("An error occurred while updating libraries index!"));
56+
}
57+
progress.stepDone();
8158

8259
// Step 2: Parse index
8360
BaseNoGui.librariesIndexer.parseIndex();
@@ -86,65 +63,55 @@ public synchronized void updateIndex(ProgressListener progressListener) throws E
8663
rescanLibraryIndex(progress, progressListener);
8764
}
8865

89-
public synchronized void install(ContributedLibrary lib, Optional<ContributedLibrary> mayReplacedLib, ProgressListener progressListener) throws Exception {
66+
public synchronized void install(ContributedLibrary lib, ProgressListener progressListener) throws Exception {
67+
if (lib.isIDEBuiltIn()) {
68+
// If the desired library is available as builtin in the IDE just remove
69+
// the other installed in sketchbook...
70+
Optional<ContributedLibrary> current = lib.getReleases().getInstalled();
71+
if (current.isPresent()) {
72+
System.out.println(
73+
I18n.format(tr("Library {0} is available as built-in in the IDE.\nRemoving the other version {1} installed in the sketchbook..."),
74+
lib.getName() + ":" + lib.getVersion(), current.get().getVersion()));
75+
remove(current.get(), progressListener);
76+
return;
77+
}
78+
// ...otherwise output "library already installed"
79+
}
80+
9081
if (lib.isLibraryInstalled()) {
91-
System.out.println(I18n.format(tr("Library is already installed: {0}:{1}"), lib.getName(), lib.getParsedVersion()));
82+
System.out.println(I18n.format(tr("Library is already installed: {0}:{1}"), lib.getName(), lib.getVersion()));
9283
return;
9384
}
9485

95-
DownloadableContributionsDownloader downloader = new DownloadableContributionsDownloader(BaseNoGui.librariesIndexer.getStagingFolder());
96-
9786
final MultiStepProgress progress = new MultiStepProgress(3);
9887

9988
// Step 1: Download library
100-
try {
101-
downloader.download(lib, progress, I18n.format(tr("Downloading library: {0}"), lib.getName()), progressListener);
102-
} catch (InterruptedException e) {
103-
// Download interrupted... just exit
104-
return;
89+
String libTag = lib.getName() + "@" + lib.getVersion();
90+
Process pr = ProcessUtils.exec(new String[] { //
91+
BaseNoGui.getArduinoCliPath(), "lib", "install", libTag });
92+
int exitCode = pr.waitFor();
93+
if (exitCode != 0) {
94+
throw new Exception(tr("An error occurred while installing library!"));
10595
}
10696

107-
// TODO: Extract to temporary folders and move to the final destination only
108-
// once everything is successfully unpacked. If the operation fails remove
109-
// all the temporary folders and abort installation.
110-
11197
// Step 2: Unpack library on the correct location
112-
progress.setStatus(I18n.format(tr("Installing library: {0}:{1}"), lib.getName(), lib.getParsedVersion()));
113-
progressListener.onProgress(progress);
114-
File libsFolder = BaseNoGui.getSketchbookLibrariesFolder().folder;
115-
File tmpFolder = FileUtils.createTempFolder(libsFolder);
116-
try {
117-
new ArchiveExtractor(platform).extract(lib.getDownloadedFile(), tmpFolder, 1);
118-
} catch (Exception e) {
119-
if (tmpFolder.exists())
120-
FileUtils.recursiveDelete(tmpFolder);
121-
}
122-
progress.stepDone();
123-
124-
// Step 3: Remove replaced library and move installed one to the correct location
125-
// TODO: Fix progress bar...
126-
if (mayReplacedLib.isPresent()) {
127-
remove(mayReplacedLib.get(), progressListener);
128-
}
129-
File destFolder = new File(libsFolder, lib.getName().replaceAll(" ", "_"));
130-
tmpFolder.renameTo(destFolder);
13198
progress.stepDone();
13299

133-
// Step 4: Rescan index
100+
// Step 3: Rescan index
134101
rescanLibraryIndex(progress, progressListener);
135102
}
136103

137-
public synchronized void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException {
138-
if (lib.isIDEBuiltIn()) {
139-
return;
140-
}
141-
104+
public synchronized void remove(ContributedLibrary lib, ProgressListener progressListener) throws Exception {
142105
final MultiStepProgress progress = new MultiStepProgress(2);
143106

144107
// Step 1: Remove library
145-
progress.setStatus(I18n.format(tr("Removing library: {0}:{1}"), lib.getName(), lib.getParsedVersion()));
146-
progressListener.onProgress(progress);
147-
FileUtils.recursiveDelete(lib.getInstalledLibrary().get().getInstalledFolder());
108+
String libTag = lib.getName() + "@" + lib.getVersion();
109+
Process pr = ProcessUtils.exec(new String[] { //
110+
BaseNoGui.getArduinoCliPath(), "lib", "uninstall", libTag });
111+
int exitCode = pr.waitFor();
112+
if (exitCode != 0) {
113+
throw new Exception(tr("An error occurred while uninstalling library!"));
114+
}
148115
progress.stepDone();
149116

150117
// Step 2: Rescan index
@@ -157,4 +124,11 @@ private void rescanLibraryIndex(MultiStepProgress progress, ProgressListener pro
157124
BaseNoGui.librariesIndexer.rescanLibraries();
158125
progress.stepDone();
159126
}
127+
128+
// TODO: legacy messages already translated, keeping here until reused
129+
static {
130+
I18n.format(tr("Downloading library: {0}"), "libname");
131+
I18n.format(tr("Installing library: {0}:{1}"), "libname", "libversion");
132+
I18n.format(tr("Removing library: {0}:{1}"), "libname", "libversion");
133+
}
160134
}

‎arduino-core/src/processing/app/BaseNoGui.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ static public File getContentFile(String name) {
239239
return new File(installationFolder, name);
240240
}
241241

242+
static public String getArduinoCliPath() {
243+
return getContentFile("arduino-cli").getAbsolutePath();
244+
}
245+
242246
static public TargetPlatform getCurrentTargetPlatformFromPackage(String pack) {
243247
return getTargetPlatform(pack, PreferencesData.get("target_platform"));
244248
}
@@ -551,8 +555,7 @@ static public void initPackages() throws Exception {
551555
try {
552556
librariesIndexer.parseIndex();
553557
} catch (JsonProcessingException e) {
554-
File librariesIndexFile = librariesIndexer.getIndexFile();
555-
FileUtils.deleteIfExists(librariesIndexFile);
558+
e.printStackTrace();
556559
}
557560

558561
if (discoveryManager == null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
18f6669f8a3c328f6a096eb6709a2c1e4c9cdeae
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1309e3bf1685ec5cefbb46cb6397e7c452ac293a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2fd4bd6f4c196e45fa08bb1b6eae27494378708a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a4977a3dffb2268eee3328bfa362aa31e8bfbbe9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
47f1beae490e214d2cbde36089fe45e91cc4bd21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
30d454fb2d76bf08dd40f61414b809f3538a8d31

‎build/build.xml

+34
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<property name="portable" value="false" />
101101

102102
<property name="ARDUINO-BUILDER-VERSION" value="1.4.3" />
103+
<property name="ARDUINO-CLI-VERSION" value="0.3.4-alpha.preview" />
103104
<property name="LIBLISTSERIAL-VERSION" value="1.4.2" />
104105
<property name="SERIALDISCOVER-VERSION" value="0.0.3" />
105106
<property name="MDNSDISCOVER-VERSION" value="0.0.1" />
@@ -512,6 +513,7 @@
512513
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../tools/mdns-discovery" />
513514

514515
<antcall target="build-arduino-builder" />
516+
<antcall target="build-arduino-cli" />
515517

516518
<antcall target="portable-${portable}">
517519
<param name="parentdir" value="macosx/work/${staging_hardware_folder}/.." />
@@ -770,6 +772,7 @@
770772
</antcall>
771773

772774
<antcall target="build-arduino-builder" />
775+
<antcall target="build-arduino-cli" />
773776

774777
<antcall target="avr-toolchain-bundle">
775778
<param name="unpack_target" value="untar"/>
@@ -831,6 +834,7 @@
831834
</antcall>
832835

833836
<antcall target="build-arduino-builder" />
837+
<antcall target="build-arduino-cli" />
834838

835839
<antcall target="avr-toolchain-bundle">
836840
<param name="unpack_target" value="untar"/>
@@ -849,6 +853,7 @@
849853
</antcall>
850854

851855
<antcall target="build-arduino-builder" />
856+
<antcall target="build-arduino-cli" />
852857

853858
<antcall target="avr-toolchain-bundle">
854859
<param name="unpack_target" value="untar"/>
@@ -867,6 +872,7 @@
867872
</antcall>
868873

869874
<antcall target="build-arduino-builder" />
875+
<antcall target="build-arduino-cli" />
870876

871877
<antcall target="avr-toolchain-bundle">
872878
<param name="unpack_target" value="untar"/>
@@ -915,6 +921,20 @@
915921
<exec executable="./linux/work/arduino" spawn="false" failonerror="true"/>
916922
</target>
917923

924+
<target name="build-arduino-cli" unless="no_arduino_cli">
925+
<delete dir="${staging_folder}/arduino-cli-${platform}" includeemptydirs="true"/>
926+
<mkdir dir="${staging_folder}/arduino-cli-${platform}"/>
927+
<antcall target="untar">
928+
<param name="archive_file" value="./arduino-cli-${ARDUINO-CLI-VERSION}-${platform}.tar.bz2" />
929+
<param name="archive_url" value="https://downloads.arduino.cc/arduino-cli/arduino-cli-${ARDUINO-CLI-VERSION}-${platform}.tar.bz2" />
930+
<param name="final_folder" value="${staging_folder}/arduino-cli-${platform}/arduino-cli" />
931+
<param name="dest_folder" value="${staging_folder}/arduino-cli-${platform}" />
932+
</antcall>
933+
<copy file="${staging_folder}/arduino-cli-${platform}/arduino-cli-${ARDUINO-CLI-VERSION}-${platform}" tofile="${staging_folder}/work/${staging_hardware_folder}/../arduino-cli" />
934+
<chmod perm="755" file="${staging_folder}/work/${staging_hardware_folder}/../arduino-cli" />
935+
<delete dir="${staging_folder}/arduino-cli-${platform}" includeemptydirs="true"/>
936+
</target>
937+
918938
<target name="build-arduino-builder" unless="no_arduino_builder">
919939
<delete dir="${staging_folder}/arduino-builder-${platform}" includeemptydirs="true"/>
920940
<mkdir dir="${staging_folder}/arduino-builder-${platform}"/>
@@ -1189,6 +1209,20 @@
11891209
</copy>
11901210
<delete dir="${staging_folder}/arduino-builder-windows" includeemptydirs="true"/>
11911211

1212+
<delete dir="${staging_folder}/arduino-cli-windows" includeemptydirs="true"/>
1213+
<mkdir dir="${staging_folder}/arduino-cli-windows"/>
1214+
<antcall target="unzip-with-ant-task">
1215+
<param name="archive_file" value="./arduino-cli-${ARDUINO-CLI-VERSION}-windows.zip" />
1216+
<param name="archive_url" value="https://downloads.arduino.cc/arduino-cli/arduino-cli-${ARDUINO-CLI-VERSION}-windows.zip" />
1217+
<param name="final_folder" value="${staging_folder}/arduino-cli-windows/arduino-cli-${ARDUINO-CLI-VERSION}-windows.exe" />
1218+
<param name="dest_folder" value="${staging_folder}/arduino-cli-windows" />
1219+
</antcall>
1220+
<copy file="${staging_folder}/arduino-cli-windows/arduino-cli-${ARDUINO-CLI-VERSION}-windows.exe" tofile="windows/work/arduino-cli.exe" />
1221+
<antcall target="make-file-executable">
1222+
<param name="file" value="windows/work/arduino-cli.exe" />
1223+
</antcall>
1224+
<delete dir="${staging_folder}/arduino-cli-windows" includeemptydirs="true"/>
1225+
11921226
<exec executable="unzip" failonerror="true">
11931227
<arg value="-q" />
11941228
<arg value="-n" />

0 commit comments

Comments
 (0)
Please sign in to comment.