Add a plugin dependency missing warning

We should get a warning if a plugin has missing dependencies, this is easy to do with wikitext, but we need to write it once for each plugin that has dependencies

tags: $:/tags/StartupAction/PostRender

<$list filter="[[xxx-plugin-xxx]is[missing]]">
  <$action-sendmessage $message="tm-modal" $param="Warning Message"/>
</$list>
1 Like

Maybe after the new official plugin platform comes out, there will be no such problem

TW has no mechanism to resolve missing dependencies. You should have a look at GH if there is a similar issue. If not create one.

Installing via CPL won’t have this problem, and we have a help page about this on Chinese tutorial site https://tw-cn.netlify.app/#undefined%20widget%20xxx

1 Like

Hi @oeyoews

We should get a warning if a plugin has missing dependencies

That’s a good idea. Quite a few of the core plugins do their own dependency checking, but it would be great to have it standardised.

It would be interesting if it could be done in wikitext, but I’m not sure if that is possible.

It would be useful to make a ticket over at GitHub.

Would you like to work on this with a view to making a PR?

It would be great if this were declared inside plugin.info similarly to package.json dependencies. Unfortunately I don’t think there is a mechanism to enforce namespaces (no NPM, PIP, etc.), but that seems in the spirit of TW anyway. If you want to call your plugin core, well, we won’t stop you. (But please don’t! :stuck_out_tongue_winking_eye:)

I’m working on something that I would like to be able to distribute as a graph of dependent plugins and it would be very useful if $:/plugins/me/corge could note that it depends on $:/plugins/me/qux and $:/plugins/me/bar, that $:/plugins/me/qux and $:/plugins/me/bar depend on $:/plugins/me/foo and that $:/plugins/me/baz depends on $:/plugins/me/bar. But this would mean figuring out what to do with circular dependencies or how to forbid them. Also, I’ve been working from Node, and can easily modify plugin.info. I don’t know how easy it is to do from other workflows.

I am, confident it can. Looking at the fields in use in a large collection of plugins I see the following already in use “dependencies, requires and dependents”.

However we need not change the core if we adopt my suggestion here because the user could include the details in a readme eg $:/plugins/tiddlywiki/internals/readme or /dependencies etc…

  • This would allow a full wikitext and script to be used and include dependacies that are not even plugins eg Node implementation only, latest version available here, manual or user instructions, configurations settings etc…

An Import process improvement?

At a minimum we need a fieldname in plugins that lists the plugin tiddler name such as $:/plugins/tiddlywiki/internals $:/plugins/tiddlywiki/browser-sniff and then the plugin display can test for their existence.

  • The issue from there if you don’t have the plugin how do you find it?

An approach now possible, but may not be backwardly compatible is to allow the plugin tiddler to have a field added by the name of the plugin tiddler eg;
$:/plugins/tiddlywiki/internals which can then be given a note or additional wikitext such as
$:/plugins/tiddlywiki/internals="Core plugin - Internals"
or
$:/plugins/kookma/shiraz="Shiraz is Found in [[Kookma Plugin Library|https://plugins.tiddlyhost.com/#%24%3A%2Fconfig%2FKookmaPluginLibrary]]

  • Warning I experienced some performance issues with that link, opening plugins.

It is less complex if each required plugin once installed identifies its own dependencies.

  • If you have a complex package which has a complex set of dependencies you can encode this in a tiddler within the original plugin

Right that’s pretty much what I meant. The Periodic Table I’ve been working on would have at its base one plugin containing data tiddlers for the elements (as we’ve discussed elsewhere.) The Periodic Table itself would be a separate plugin that listed the Elements as a dependency. I would also like to have a self-annotations plugin that was layered atop one or the other of those two. And I would like to have training material as a plugin layered atop the periodic table one. Above it all would be an all-in-one version:

         Everything
         /    |
    +---'     +
Training       \
     \          \
    Table    Annotations
         \    /
        Elements

Ideally Everything would list both Training and Annotation as its dependencies, Training could list Table as its dependency, and both Table and Annotations would list Elements.

I could live with leaving the recursive walking to the plug-in developer (so that Training would have to list both Table and Elements and Everything would need to list all the others) but it would be nicer if it could be automated. But now we’re into the world of dependency management tools. While they’re not overly difficult, I don’t know how we might support that. But we definitely could at a minimum do a check to see if all the (recursive) dependencies are included properly.

I don’t want to go there now, but this also might need to deal with version numbers – Training ^3.2.6 depends on Table ^2.7.0, which in turn depends on Elements ^4.1.0. That starts to get a bit uglier. While I could probably code this in JS, I couldn’t come close right now in wikitext.

I understand but careful design would make this unnecessary in the vast majority of cases, such as the latest is always distributed together, each has its own features, but each will work with previous versions. whatever version is installed visiting the plugin library will suggest all out of date are upgraded etc…

  • Perhaps the first step is ensuring each release has a new version number.
  • The all in one version, can contain minimum versions for each dependant plugin, but most likely lives with the latest version of all dependant plugins.
    • When looking for a missing plugin we are most likely to retrieve the latest.
    • When retrieving the latest it is the best time to “announce” a minimum version if it in fact demands one".

I just meant that as a general example. For this project, if I do deal with version numbers, I will probably synchronize them all; there’s no harm in that. But if my plugin required version X of Shiraz, version Y of Relink, version Z of Markdown, and then it turns out that Shiraz and Markdown required conflicting versions of Core, and Relink required a higher version of Markdown than my own plugin could support, we could start having real trouble.

But for the moment, I’m hoping we simply don’t need to deal with this. If we could simply check for the presence of the required plugins and report if they’re not matched, it would be a step in the right direction.

IMO none of those complexities is necessary. For me it implements complexity just for the sake of it.

Everything can be a TW edition, that contains everything as you describe it. If I download emtpy.html and drag & drop import everything.html I will see every element and can decide what I want to import.

Done. No extra complexity needed.


As a user, if I’m interested in the “periodic table plugin” I want to download exactly 1 plugin, which contains the table and the data.

The Table without any Elements is “just an empty table” and useless.
The Elements without any templates to view them are worth nothing because I cannot see them.

So from a users perspective they should be 1 thing. IMO splitting it only introduces complexity “because we can”. … Not very user friendly.


Annotations does not need any dependency at all. It should be it’s own functionality that can stand alone. Why are annotations limited to a periodic table plugin?

just my thoughts.

TW has a simple dependency handling if the plugins are part of the same library. eg:
The codemirror autocomplete function has 2 fields that define the dependency.

	"parent-plugin": "$:/plugins/tiddlywiki/codemirror",
	"dependents": ["$:/plugins/tiddlywiki/codemirror-mode-css"],

If you go to tiddlywiki.com and install the autocomplete plugin, it will also install “codemirror” and codemirror-mode-css because it needs it.

parent-plugin is also used to allow the import UI to display the info for the cm-plugin like this.

Since dependents use the full name of a plugin it would be possible to add other plugins too. … BUT in the end we would just recreate the same mess that NPM … with its dependency hell causes, without the financial background to make it secure in the slightest way.

So if we want dependency hell we can use NPM. They have enough money to be able to try to make it secure.

My part of this discussion is mostly about taking seriously what @TW_Tones discusses in Making use of data plugins. The element tiddlers are much more useful and versatile than the Periodic Table. A user might want to include just the elements in a given project. That separation made me realize that things I’m dreaming of for this do have the style of nesting I’m describing. But I’m not at all wedded to this idea, because of:

I think it will be quite easy to do this in a build process, creating editions for the various configurations, either by including multiple plug-ins in each edition or by combining the existing plug-ins into single ones as needed, one per edition.

The rest of my ideas here were simply conditioned on TW wanting to get more serious about plugin dependency management. If all we want to do is warn that one plug-in’s declared dependency is missing, that’s a much easier problem (says the guy who still knows nothing about the core or the plugin-loading mechanism. :wink: ) But if we want to follow up on further implications, we can do so. As I said:


Agreed.

Here I disagree. The user could build all sorts of wikis atop the Element tiddlers without my implementation of the Periodic Table. This to me is the whole idea of data plugins.

That’s why the table depends on the elements, but not the reverse.

I didn’t explain that well. My idea was that I would layer atop the elements a way to add my own data. @TiddlyTweeter suggested:

I can see a lot of sense in that. Technically, this only depends on the Elements, and I could imagine an edition which offers these two together. But there should probably be one more in my chart which includes the Annotations and the Table (and hence the Elements), but not the Training material. Again, I’m not worried about the ability to do that. I can figure this out with some build steps (which one day I’ll get into GitHub actions; but it’s a low priority right now.)

Thank you. I hadn’t seen these. That solves a fair bit of this problem already; and there’s a good chance we wouldn’t ever want to solve the cross-library problem. I’m a little confused by what seems to be two-directional linking, but I can read up on it.

That’s interesting. I’ve been in dependency hell in many different environments, (DLL, Maven, Haskell, and others) but NPM has always seemed like a breath of fresh air. Yes, there are still issues, but the model has seemed fairly clean. The granularity people choose to publish (left-pad, anyone?) seems a little crazy to me, but I haven’t had the sorts of issues you seem to have had.


In any case, again, my contributions are mostly along the lines of, “If we want to do more dependency management, here’s how we might.” If we don’t want to, I’m entirely fine with that.

Just to make sure it’s not missed as a way to tackle dependencies is to use @pmario’s bundler or my more direct JSON packaging process.

  • Download and open an empty.html
  • Drag all plugins and tiddlers to be part of your “package”, don’t import any
  • Rename $:/Import to packagename and change plugin-type to plugin
    • DO NOT Update $:/Import to Package in the tags and list fields of other tiddlers
    • Remove unwanted fields, save.
  • Drag this package of plugins and all their dependencies to install.
    • Or export as a plugin tiddler.

I’m not sure if this is directed at me. If so, I’m developing on Node, and only exporting the single-file wiki to publish. There it’s been trivial so far to segregate the plugin code; it might become a bit more work if I start the nesting structure I’m describing, but not much more.

Yes, It was for you @Scott_Sauyet

All I am pointing out it is easy to make a JSON package, even a plugin containing multiple tiddlers and plugins and distribute them together. Such that you need not bother setting dependencies (although I think we will work towards it) because they all come in the same package.

  • You can also package them as an Import tiddler so if there are any version clashes in will block installing an older component.

Thanks. So far my build process has been fairly simple for me, and I think I can easily extend it for the more sophisticated cases, but perhaps it will be a problem. If so, I might look at this technique, but this step scares me a bit:

There are right now 118 Element tiddlers. Based on a private-channel conversation with @telumire I will probably adding 100+ additional Compound tiddlers. Right now there are about a dozen other implementation tiddlers, but a refactoring I want to do will likely bring that closer to 20, and additional features will likely add a few dozen addition ones. Dragging them all manually would get ugly fast. I imagine there’s some simple way to automate this inside a TW with a few filters, but I can already comfortably automate this from the Node end.

But the bigger point is that this is much-inspired by the work you and @springer did with elements in a data plugin, and I’d like to keep that focus. That means I would like to keep the Element data together in its own plugin, or at the very least offer that data as a plugin people can use.

In the end, I think I might end up with a few different editions with various combinations of data-plugins and UI-tiddlers. But first I need to develop the features.

Indeed, but remember that dragging a tag-pill drags everything so tagged. So it should be easy to work with any complex set so long as your tag structure is consistent.

-Springer

Ah, okay, that would help a lot. I don’t have my UI tiddlers jointly tagged with anything, but I could easily add tags. Thanks!

1 Like