Skip to content

New addon api versioning approach#9151

Merged
feerrenrut merged 37 commits into
masterfrom
newAddonAPIVersioningApproach
Jan 31, 2019
Merged

New addon api versioning approach#9151
feerrenrut merged 37 commits into
masterfrom
newAddonAPIVersioningApproach

Conversation

@feerrenrut

@feerrenrut feerrenrut commented Jan 13, 2019

Copy link
Copy Markdown
Contributor

Link to issue number:

Fixes #9055

Summary of the issue:

The approach to addon compatibility checks placed a large burden on both users and addon developers.

Description of how this pull request fixes the issue:

The compatibility check now relies on two values within NVDA, addonAPIVersion.CURRENT and addonAPIVersion.BACK_COMPAT_TO, as well as the two values expected in the addon manifest, lastTestedNVDAVersion and minimumNVDAVersion. There needs to be an overlap in these version ranges for the addon to be considered compatible.

The concept of "untested, but potentially still works" is no longer permitted. As such, the user is no longer able to "whitelist" an addon. When an addon is considered incompatible, the addon itself must be updated and re-installed. However, due to the introduction of a second value within NVDA (addonAPIVersion.BACK_COMPAT_TO) which will only need to be updated when there are breaking API changes (expected to happen rarely), there is no longer the requirement for the addons to be updated for each release.

This PR also stops the error sound from being heard on developer builds of the launcher (access denied error in audio ducking). This was quite distracting while testing and is essentially an expected error.

Testing performed:

  • Installed (modified) addons.
  • Checked NVDA installation with incompatible addons
  • Checked NVDA update check (manual & automatic) with incompatible addons.

Known issues with pull request:

  • There is no longer any warning about incompatible addons during the startup of NVDA. This means that if NVDA is updated from a second windows account (on a shared computer), then a user may have no warning that their addons are incompatible. For now, this will not be addressed.
  • The format for the API version string is now stricter (to reduce the chance of ambiguity in the API version being referred to), as such any Addons that were re-released and did not specify year.month.minor (with all parts present) will need to be re-released.

Change log entry:

The current changelog entry could be slightly modified from:

- Add-on authors now can enforce a minimum required NVDA version for their add-ons. Unsupported add-ons will not load or install. (#6275)
- Add-on authors must now specify the last version of NVDA the add-on has been tested against. Users will be warned against installing or enabling untested add-ons. (#6275)

to

- Add-on authors now can enforce a minimum required NVDA version for their add-ons. Unsupported add-ons will not load or install. (#6275, #9055)
- Add-on authors must now specify the last version of NVDA the add-on has been tested against. Along with the minimum required NVDA version a compatibility range is formed which must overlap with the range that NVDA supports for the addon to load or install. (#6275, #9055)

NVDA now uses two values to determine addon compatiblilty.
Read from addon manifest and validate and convert to tuple.
When checking for NVDA updates, convert to tuple and save state as
tuple.

This saves confusion about whether its a string or a tuple.
Fix a few other bugs.
…mnCheckListCtrl

Clean up of the accPropServices needs to happen when the control is
destroyed. The Destroy method is not called 
by the wx framework, but
we can register to receive the event.
wxWidgets/Phoenix#630
All usages of ConfirmAddon specify the argument with a keyword so its safe to do this.
It's not sensible to have a minRequiredVersion later than the version
tested against.
This is already checked (and an AddonError raised) when creating the Addon
@feerrenrut feerrenrut requested a review from LeonarddeR January 13, 2019 18:31
@LeonarddeR

LeonarddeR commented Jan 14, 2019

Copy link
Copy Markdown
Collaborator

Known issues with pull request:

* There is no longer any warning about incompatible addons during the startup of NVDA. This means that if NVDA is updated from a second windows account (on a shared computer), then a user may have no warning that their addons are incompatible. For now, this will not be addressed.

Have you considered that this case also applies when one manually downloads a new version of NVDA and runs the particular snapshot? I'm afraid this will happen:

  • One is at NVDA 2019.1
  • NVDA 2019.2 is manually downloaded, i.e. because a proxy blocks the automatic update approach. @BabbageCom has clients suffering from this.
  • The 2019.2 snapshot is launched and incompatible add-ons are disabled
  • The add-ons state is saved
  • When the launcher is closed and 2019.1 is started, the add-ons will still be disabled, since the launcher touched the add-on state.

Would it help to disable the add-ons manager on launcher copies altogether and disallow launcher copies to touch the state? Alternatively, we can just disable the enable/disable functionality from the add-ons manager when the launcher is active?

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not yet fully reviewed, will have more time later today.

Comment thread source/addonHandler/__init__.py
Comment thread source/addonHandler/__init__.py
Comment thread source/addonHandler/__init__.py
Comment thread source/addonHandler/__init__.py Outdated
Comment thread source/audioDucking.py
Comment thread source/gui/addonGui.py Outdated
Comment thread source/gui/addonGui.py Outdated
Comment thread source/gui/addonGui.py Outdated
Comment thread source/gui/addonGui.py Outdated
Comment thread source/gui/addonGui.py Outdated
Comment thread source/addonHandler/__init__.py
Comment thread source/gui/nvdaControls.py
Comment thread source/gui/nvdaControls.py Outdated
Comment thread source/updateCheck.py Outdated
Comment thread source/updateCheck.py Outdated
Comment thread user_docs/en/userGuide.t2t Outdated
@feerrenrut

Copy link
Copy Markdown
Contributor Author

since the launcher touched the add-on state.

Yes, thanks for reminding me. I'll look into what we can do about this.

More consistent initialisiation.
There is also nowhere that is checking for None
Review actions for #9151
Review actions for #9151
Ensure that a warning is put in the log for access denied errors when
setting audio ducking.
Use windows sounds for addon install warning / error.
@michaelDCurran

Copy link
Copy Markdown
Member

Recently we had a tech support request where the user stated that sayAll did not work unless restarting with add-ons disabled. However, the user actually had no add-ons installed. It ended up pointing to the fact that they probably had some very old stand-alone globalPlugins etc in their NVDA config directory.
As these directories were deprecated when we introduced add-ons, I strongly suggest we remove this functionality within this pr. Who knows what things users have got hanging around from 5 years ago. And disabling old add-ons with older vrsion numbers is meaningless if we then still allow completely arbitrary code which is most likely even older.
It was also confusing because this old code gets disabled if NVDA is restarted with add-ons disabled.
In short, calls to config.addConfigDirsToPythonPackagePath should be removed from appModuleHandler, braille, globalPluginHandler, and synthDriverHandler.

@michaelDCurran

Copy link
Copy Markdown
Member

If we feel this might be still used for development, then we could consider adding an extra commandline argument to enable this.

@LeonarddeR

LeonarddeR commented Jan 21, 2019

Copy link
Copy Markdown
Collaborator

If we feel this might be still used for development, then we could consider adding an extra commandline argument to enable this.

When scripting corporate applications for customers, I tend to throw the appModules directly in the %appdata%\nvda folder, since the creation of add-ons causes some overhead. Good to know that I misbehaved in that case😜.

Having said that, I prefer a configuration setting over a command line parameter, but would at least prefer either one of them.

In short, calls to config.addConfigDirsToPythonPackagePath should be removed from appModuleHandler, braille, globalPluginHandler, and synthDriverHandler.

Note that the addon subsystem relies on these calls, see the bottom of config.addConfigDirsToPythonPackagePath, where the paths are also added for every add-on.

@lukaszgo1

Copy link
Copy Markdown
Contributor

@michaelDCurran wrote:

If we feel this might be still used for development, then we could consider adding an extra commandline argument to enable this.

It is useful not only for development, but also for more advanced users, who wants to change default NVDA behavior. I've for example created global plugin which fixes #8600 until that would be addressed in the core. Disabling tis possibility would be very bad for users.

@michaelDCurran

michaelDCurran commented Jan 21, 2019 via email

Copy link
Copy Markdown
Member

@michaelDCurran

michaelDCurran commented Jan 21, 2019 via email

Copy link
Copy Markdown
Member

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Replying to @lukaszgo1

Regarding Alpha snapshot users you wrote on the development list :

For anyone else interested, this quote comes from the NVDA devel mailing list thread, specifically this message (I recommend downloading the message as HTML by the way, since there are many block quotes which are not displayed very well in sourceforge)

I believe this part of the problem needs to be solved before this goes to master because the entire fact of changed approach is ad least partially due to feedback of Alpha users.

No, I don't think the problem is as you are stating. The addons will only become incompatible when the internal NVDA API version is moved on.

  • This won't happen in the first release including this change (2019.1).
  • When it does happen, it means that the add-on is well and truly incompatible. For instance after NVDA is moved to Python 3.
  • The kind of changes that require us to update the version are very rare, so it's unlikely that this will happen often.

A solution could be found on the add-on distribution side allowing NVDA alpha users to be able to install an "alpha" version of the add-on. This add-on would be targeting the unreleased version of NVDA. This essentially becomes a distribution problem. This option is essentially:

Set the last tested value to the alpha version. I don't like this because it's essentially saying something not true, the alpha version is a moving target. An addon author would have to testing and re-releasing their addon almost constantly, and the users would have to installing the updates too to avoid instability.

Despite my dislike for this in the quoted email thread, I think it would be ok if this were very clearly alpha software, and not mixed with the stable add-ons that most would be installing.

Another possible solution might be to allow NVDA (only) users on the alpha update channel to "allow incompatible add-ons" from an advanced section of the NVDA preferences. We will have to think carefully about the implications and behavior of this.

Because there is no imminent cause for add-ons to become incompatible. I won't be addressing this concern in this PR. There is at least one full release cycle, likely more before there will be a change to the addon API version.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Replying to @michaelDCurran

In short, calls to config.addConfigDirsToPythonPackagePath should be removed from appModuleHandler, braille, globalPluginHandler, and synthDriverHandler.

I am totally on board with this. However I would prefer to do this in a follow up PR.

Comment thread source/gui/addonGui.py Outdated
- Allow the possibility of using a parent window other than the addon
  manager. Useful in the case of installing via a shell extension,
  where gui.mainframe should be the parent.
- Remove coupling between installing an Addon and addon manager
- Reduce nesting
- Moved methods to module level. These had no dependence on instance,
  or class level members.
@feerrenrut

Copy link
Copy Markdown
Contributor Author

Hi @LeonarddeR I have pushed a commit that I am fairly confident resolves the issue with installing addons from the shell integration. However, I think there are still issues with this when you are running an unsigned build. As such, please test with the following try build: https://ci.appveyor.com/project/NVAccess/nvda/builds/21975742/artifacts

In terms of unifying the way that versions are printed, I have decided to leave this as is for now. There are several different expectations for the version string formatting, trying to force these all to use the same function actually makes it unnecessarily complicated and error prone. Ideally, I would like to see the introduction of a "versionNumber" type, 4-part where build numbers matter, and 3 part elsewhere. But this is actually quite out of scope for the originally issue.

Comment thread source/gui/addonGui.py
# #4460: If we do this immediately, wx seems to drop the WM_QUIT sent if the user chooses to restart.
# This seems to have something to do with the wx.ProgressDialog.
# The CallLater seems to work around this.
wx.CallLater(1, self.Close)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I guess the context manager is the alternative approach for this? Are you sure that it won't introduce #4460 again?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Quite sure, this self.Close is for the AddonManger dialog. The call to wx.CallLater only happened when an instance of the AddonManager had to be created for the purpose of installing an addon from the shell integration. When there was an AddonManager dialog was already opened, or installation was triggered by the AddonManager then this wasn't hit. I expect part of the problem was in calling del progressDialog rather than Destroy as well. But either way, it's no longer necessary to destroy the progressDialog and the AddonManger at once.

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I vote for merging this as soon as possible, fixing possible regressions it may introduce into subsequent PRs.

One function is for outputting a full version string (including build part)
The other is for formatting a version string for the GUI (which will
remove the minor part when it is zero).
Clarified the name of the function to report that an addon is no longer
supported by NVDA. The addon is considered "too old". As opposed to NVDA
being "too old" for a newly developed addon.
@feerrenrut

Copy link
Copy Markdown
Contributor Author

@LeonarddeR I have pushed a couple of commits that hopefully simplify a few things. I would still like to see a unified approach to passing around a "version" concept. But it should not be part of this PR.

@michaelDCurran Unless you have any objections, I will merge this tomorrow.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

@feerrenrut Ugh, missed this again, but could you please update the developer guide according to the three integer versioning scheme for minimumRequired and lastTested API versions?

@feerrenrut

Copy link
Copy Markdown
Contributor Author

@feerrenrut Ugh, missed this again, but could you please update the developer guide according to the three integer versioning scheme for minimumRequired and lastTested API versions?

Oops, yes I will do that now.

Manifest value explanations needed updating to match the new validation requirements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revised approach to addon compatibility

7 participants