Pub-dev: How to resolve missed platform classifications?

Created on 22 Dec 2017  Â·  19Comments  Â·  Source: dart-lang/pub-dev

We have a couple of interesting cases open:

The common theme in all of these is the difference between the use of the library and the target platform of the app that is built using it.

I can see a couple of ways to go ahead:

1. No action in the classification.

There are packages that do provide build and code generation utilities, and are not mis-categorized (e.g. pwa generates code, but all of that lives in bin/, so there is no hint that it would be a server package).

If we identify these patterns, and give guidance to package authors, eventually most of these will be corrected.

Related questions:

  • What is the ideal pattern (besides hiding the dart:io code in bin/)?
  • Shall we add a suggestion for it in pana (e.g. detecting somebody relies on source_gen)?

2. Metadata from pubspec.yaml.

Keywords (https://github.com/dart-lang/pub-dartlang-dart/issues/368), categories (https://github.com/dart-lang/pub-dartlang-dart/issues/367) or a property for platforms could be coming from pubspec.yaml, and the UI could display it along the ones we are detecting.

Related questions:

  • How to display them if they are not the same? (colors, format, order, icon.. ?)
  • Which of it takes preference (e.g. in search)?
  • Should this affect the score or ranking in any way?

3. Hand-coded exception in the pana analysis.

We could assume that if a library uses certain helper libraries (through transitive dependencies), than it is a build-utility or a nodejs library. If/when dart:io is used only through them, the package could be classified as generic, unless other API use restrict it.

Related questions:

  • Is it the case really that if something is a build tool, it can be applied to every platform? I can't think of a counter-example, but there may be one.
  • Shall we put NodeJs support in a different category? It is an outlier compared to the build tools.

4. New platform for build utilities.

We could also introduce a new platform, that is exclusively build- or other toolchain-related utilities. These packages could be listed for Flutter or web too, but would be bearing the tool or build or something similar platform label.

Related questions:

  • Is it really a platform, or a sub-platform / category?
  • NodeJs is still an outlier here, same question for a different category.

Most helpful comment

+1 for allowing users to explicitly override the categorization for their packages.

All 19 comments

/cc @kevmoo @mkustermann @kwalrath @matanlurey @jakemac53 @natebosch @mit-mit @filiph @sethladd @nex3 @mikemitterer @zoechi @pulyaevskiy @mbullington

My feeling on this is we allow package authors to explicitly state their platforms via pubspec.yaml and that would override whatever auto-detection we do by default.

The impact of bad actors is minimal imo, and if it really became an issue we could add some sort of mechanism that would result in a negative impact to the packages score if they improperly declare their platform support.

Fwiw - this is what we do in bazel. We have a platforms attribute on dart_library that is contagious - you can't depend on packages with incompatible platforms and your platforms (if not specified) become the intersection of the platforms from the packages you depend on. We do not attempt any auto-detection logic for platforms by default, although there are some tools which try to do that for basic cases.

The impact of bad actors is minimal imo

I think mistakes are more likely than bad intent. I think we need to resolve the open questions around what it means to publish a "tool" which can be used on a web _or_ vm _or_ flutter project. Today that shows up as vm/flutter because that's where it runs, but that doesn't mean that web projects won't be interested in discovering it.

The risk, I think, is that someone publishing a "tool" meant to help with web stuff will tag their package as web platform, but someone writing web code can't safely import anything from it.

I think mistakes are more likely than bad intent

I agree, but I also think that these issues will resolve themselves quickly. For any package with sufficient visibility somebody will notice the error and file an issue or maybe even send pull requests to update the field since it would be trivial to do so even entirely through github itself.

Woooo. Long thread.

@jakemac53:

My feeling on this is we allow package authors to explicitly state their platforms

👍. Let's just let folks do what they wanted to do for a long time. We already have the concept of platforms in the Bazel rules_dart (https://github.com/dart-lang/rules_dart/commit/6bc0a5777089ec61bace0b3576b82c1edc0692e7, compliments of @grouma), having a similar concept in pubspec.yaml can only be useful, even if we don't act on it for anything other than tagging today.

(Ultimately we will need something like "targets", but let's punt on that conversation)


My 2 cents: The easiest thing to do without needing consensus is add the ability to label packages as "tools", i.e. neither for the server, web, or flutter specifically (though the role of the tool might lead itself to not be useful on certain platforms).

One way to do that _might_ be detecting executables: ..., which sort of leads that the package is meant to be used via pub run or pub global activate. This might mis-classify some packages like dart_style or build_runner, which does both, but those tend to be in the minority, right?

@isoos:

Shall we put NodeJs support in a different category?

I don't know that this is important today. NodeJs specific packages are <0.1% of all packages, and we don't formally support this consistently anyway. If we ever add the concept of "platforms", I'd be supportive of adding "node" as a platform. Until then, I think we should punt.

@natebosch:

The risk, I think, is that someone publishing a "tool" meant to help with web stuff will tag their package as web platform, but someone writing web code can't safely import anything from it.

This is a bug in our development story, not pub-dartlang-dart. The analyzer should know you are building a web project and prevent you from importing packages that won't build, instead of being VM centric.

+1 to the idea of labeling something as a tool

On Fri, Dec 22, 2017, 12:13 Matan Lurey notifications@github.com wrote:

Woooo. Long thread.

@jakemac53 https://github.com/jakemac53:

My feeling on this is we allow package authors to explicitly state their
platforms

👍. Let's just let folks do what they wanted to do for a long time. We
already have the concept of platforms in the Bazel rules_dart (
dart-lang/rules_dart@6bc0a57
https://github.com/dart-lang/rules_dart/commit/6bc0a5777089ec61bace0b3576b82c1edc0692e7,
compliments of @grouma https://github.com/grouma), having a similar
concept in pubspec.yaml can only be useful, even if we don't act on it
for anything other than tagging today.

(Ultimately we will need something like "targets", but let's punt on that

conversation)

My 2 cents: The easiest thing to do without needing consensus is add the
ability to label packages as "tools", i.e. neither for the server, web, or
flutter specifically (though the role of the tool might lead itself to not
be useful on certain platforms).

One way to do that might be detecting executables: ..., which sort of
leads that the package is meant to be used via pub run or pub global
activate. This might mis-classify some packages like dart_style or
build_runner, which does both, but those tend to be in the minority,
right?

@isoos https://github.com/isoos:

Shall we put NodeJs support in a different category?

I don't know that this is important today. NodeJs specific packages are
<0.1% of all packages, and we don't formally support this consistently
anyway. If we ever add the concept of "platforms", I'd be supportive of
adding "node" as a platform. Until then, I think we should punt.

@natebosch https://github.com/natebosch:

The risk, I think, is that someone publishing a "tool" meant to help with
web stuff will tag their package as web platform, but someone writing web
code can't safely import anything from it.

This is a bug in our development story, not pub-dartlang-dart. The
analyzer should know you are building a web project and prevent you from
importing packages that won't build, instead of being VM centric.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/pub-dartlang-dart/issues/858#issuecomment-353667677,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABCisE6XQLn7VtE-YUptKY2R03CE1tLks5tDA1MgaJpZM4RLBCm
.

If we ever add the concept of "platforms", I'd be supportive of adding "node" as a platform.

What are the chances of getting there?

If I understand it correctly at least test package already supports node as a platform (we can pub run test -p node).
It also seems like the language itself is aware of it, looking at this file in Dart SASS:
https://github.com/sass/dart-sass/blob/master/lib/src/io.dart
(though I'm really not sure what's the status of this feature, it doesn't seem to be documented anywhere).

Regardless, for the NodeJS packages, I feel like categorizing them under "server" would be a good first step.

I had a suggestion to check if there is a dependency on node_preamble which seems to be used in many NodeJS-related packages.

One more things we can try is to change classification rules for "web" to require dart:html in dependencies. As I understood from #709 it currently only tracks dart:js and dart:js_util which both can be used on the server side.

If we ever add the concept of "platforms", I'd be supportive of adding "node" as a platform.

What are the chances of getting there?

I wouldn't count on it in the immediate future. There's just so much more to do right now.

I'm also on-board with being able to classify a package's platforms and it's purpose as a tool in the pubspec. 👍 Since being a tool really isn't a platform, there could be a platforms list and a tool boolean?

If you choose to implement this in the future (going off of @matanlurey , this is reasonably a lower priority than other things), I think "node" should be a valid platform, especially if it's already recognized by the language as shown by @pulyaevskiy .

Even though these packages are an incredibly small part of the pub ecosystem, in the issue's spirit of increasing overall clarity I think a "node" platform is the best option. Labeling these packages as "web" has definite problems, but I feel "server" may mislead new users into associating it with the standalone Dart VM.

In the mean time, from my knowledge as node_preamble maintainer, most if not all of the libraries that target Node.js use the preamble. An issue I've seen is that some packages copy and modify it slightly. However, this is really negligible, and on occasion I try to reach out to these devs to see how we can work their changes upstream. I wouldn't see much issue with checking the immediate dependency tree for node_preamble.

Small correction, Dart doesn't know anything about node.

Dart SASS just uses a "definition variable" for this purpose at compile-time:
https://github.com/sass/dart-sass/blob/master/tool/grind.dart#L78

You can use any arbitrary string.

Just for educational purposes are there any docs about this feature (conditional export?) and what’s the status of it (experimental, stable, deprecated)?

I’d definitely like to use it in node_interop so that it can be used to swap io implementation from Dart vm to node and vice versa.

It is an experimental language feature without official support at this time. There are complications in implementing it in AOT-environments that require incremental recompilation, so there is no guarantee the current implementation will officially ship.

One more things we can try is to change classification rules for "web" to require dart:html in dependencies. As I understood from #709 it currently only tracks dart:js and dart:js_util which both can be used on the server side.

pana tracks many packages to associate something as web-only. package:js exports dart:js, and with that, we classify it as web-only.

@isoos
In this case it would mean removing dart:js and dart:js_util from the _webPackages list. Not sure if this would cause issues with any web-only packages, but in general if a package provides js bindings it doesn’t mean web-only necessarily.

Maybe there needs to be a separate js-only category.

@matanlurey
Thanks for the details. Hope it finds its way to stable release in some form.

@pulyaevskiy: Maybe there needs to be a separate js-only category.

This is something to consider, thanks for bringing it up.

+1 for allowing users to explicitly override the categorization for their packages.

Starting with the Node-support, as it is simpler: we could detect libraries that depend only on dart:js and not on dart:html. We could classify them either of the following:

  • both server and web, or
  • as a separate platform like javascript.

For either case, we would include the package in both of the server and web listings. Whether we want a “temporary tab” for it may depend on how we handle the build tools.

Now to the more complex case: We could detect build-related tools (transformers, things that use source_gen…) via the most commonly used libraries, and if only they are used (and no additional dart:io outside of these libs), then we could classify it as tool, build_tool or build.

I believe this is the first real use-case where we really seek input from the developer: we want to know their target platform. If nothing is specified, we can assume that the tool is for all platforms, otherwise we could use the developer-provided target platforms.

Because it is only applied on tool or build packages, this reduces the confusion/mishandling aspects, and we can have a clear message on the UI: “This is a build tool, which targets the following platforms: web”, instead of the “We think this is server, but the developer claims it is web.”

The classification of this feature could drive its configuration and display, therefore it is important what we think about such tools: what are they:

  • a separate platform,
  • a category (and what are the other categories?), or
  • a special flag/property of a package?

Depending on the answer, we could:

  • have a separate platform tab for it (temporary or always-on)
  • display separate list in search and listing (filter/flag in search)
  • use additional icon or different color

I believe this could cover the “we want to specify the target platforms” use cases, keeping a good balance between pub being a trusted analysis source and also allowing developers to provide valuable input. What do you think about it?

I don't know if it makes sense to try to sniff Node support yet. It's not consistently supported by the Dart team, which means that any uses are inherently kind of hacky, and baking in knowledge of those hacks doesn't seem like a great idea.

We've deployed a new tagging mechanism which details the runtime (of Dart SDK) and the platform of (Flutter SDK). I think this is more forward-looking than the previous platform classification, and allows better, fine-grained approach for platform nuances.

I'm closing this issue now, as many parts of it became obsolete. Please open separate issues on how to improve the current tagging (and what to detect).

Was this page helpful?
0 / 5 - 0 ratings