Skip to content

Put Arduino libs on top of the Library Manager #1541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions arduino-ide-extension/src/browser/library/library-list-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,32 @@ export class LibraryListWidget extends ListWidget<
{ timeout: 3000 }
);
}

protected override filterableListSort(
items: LibraryPackage[]
): LibraryPackage[] {
const isArduinoMaintainedComparator = (
left: LibraryPackage,
right: LibraryPackage
) => {
if (left.isArduinoMaintained && !right.isArduinoMaintained) {
return -1;
}

if (!left.isArduinoMaintained && right.isArduinoMaintained) {
return 1;
}

return 0;
};

return items.sort((left, right) => {
return (
isArduinoMaintainedComparator(left, right) ||
this.defaultSortComparator(left, right)
);
});
}
}

class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,7 @@ export class FilterableListContainer<
const { searchable } = this.props;
searchable
.search(searchOptions)
.then((items) => this.setState({ items: this.sort(items) }));
}

protected sort(items: T[]): T[] {
const { itemLabel, itemDeprecated } = this.props;
return items.sort((left, right) => {
// always put deprecated items at the bottom of the list
if (itemDeprecated(left)) {
return 1;
}

return itemLabel(left).localeCompare(itemLabel(right));
});
.then((items) => this.setState({ items: this.props.sort(items) }));
}

protected async install(
Expand All @@ -139,7 +127,7 @@ export class FilterableListContainer<
run: ({ progressId }) => install({ item, progressId, version }),
});
const items = await searchable.search(this.state.searchOptions);
this.setState({ items: this.sort(items) });
this.setState({ items: this.props.sort(items) });
}

protected async uninstall(item: T): Promise<void> {
Expand Down Expand Up @@ -167,7 +155,7 @@ export class FilterableListContainer<
run: ({ progressId }) => uninstall({ item, progressId }),
});
const items = await searchable.search(this.state.searchOptions);
this.setState({ items: this.sort(items) });
this.setState({ items: this.props.sort(items) });
}
}

Expand Down Expand Up @@ -204,6 +192,7 @@ export namespace FilterableListContainer {
progressId: string;
}) => Promise<void>;
readonly commandService: CommandService;
readonly sort: (items: T[]) => T[];
}

export interface State<T, S extends Searchable.Options> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ export abstract class ListWidget<
*/
protected firstActivate = true;

protected readonly defaultSortComparator: (left: T, right: T) => number;

constructor(protected options: ListWidget.Options<T, S>) {
super();
const { id, label, iconClass } = options;
const { id, label, iconClass, itemDeprecated, itemLabel } = options;
this.id = id;
this.title.label = label;
this.title.caption = label;
Expand All @@ -63,6 +65,17 @@ export abstract class ListWidget<
this.node.tabIndex = 0; // To be able to set the focus on the widget.
this.scrollOptions = undefined;
this.toDispose.push(this.searchOptionsChangeEmitter);

this.defaultSortComparator = (left, right): number => {
// always put deprecated items at the bottom of the list
if (itemDeprecated(left)) {
return 1;
}

return itemLabel(left).localeCompare(itemLabel(right));
};

this.filterableListSort = this.filterableListSort.bind(this);
}

@postConstruct()
Expand Down Expand Up @@ -128,6 +141,10 @@ export abstract class ListWidget<
return this.options.installable.uninstall({ item, progressId });
}

protected filterableListSort(items: T[]): T[] {
return items.sort(this.defaultSortComparator);
}

render(): React.ReactNode {
return (
<FilterableListContainer<T, S>
Expand All @@ -145,6 +162,7 @@ export abstract class ListWidget<
messageService={this.messageService}
commandService={this.commandService}
responseService={this.responseService}
sort={this.filterableListSort}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ArduinoComponent {
readonly availableVersions: Installable.Version[];
readonly installable: boolean;
readonly installedVersion?: Installable.Version;
readonly isArduinoMaintained?: boolean;
/**
* This is the `Type` in IDE (1.x) UI.
*/
Expand Down
1 change: 1 addition & 0 deletions arduino-ide-extension/src/node/library-service-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,5 +456,6 @@ function toLibrary(
summary: lib.getParagraph(),
category: lib.getCategory(),
types: lib.getTypesList(),
isArduinoMaintained: lib.getAuthor() === 'Arduino', // TODO check if .getMaintainer is more appropriate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This information is redundant, as it is already present in author. Would you please move this check (lib.getAuthor() === 'Arduino') inside the comparator function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be based on the types field:

https://arduino.github.io/arduino-cli/dev/rpc/commands/#library

We intentionally don't place any restrictions on specifying "Arduino" as author because this is appropriate to give attribution for forks of the official Arduino libraries.

We do have rules about the use of "Arduino" in the maintainer field:

https://arduino.github.io/arduino-lint/dev/rules/library/#maintainer-starts-with-arduino-lp027

But due to the legacy of not enforcing this over the history of the Arduino Library Manager violation of these rules are only warnings at the "permissive" compliance level used by the Library Manager indexer engine.

But the types field is under Arduino's complete control so we can be sure that when a library has the value Arduino, it is an official library (unfortunately this has not been applied consistently, so some official libraries also don't have this categorization, but that is something to fix in the registry, not in the IDE.

};
}