Skip to content
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

Loading user plugins from app data folder. #6551

Merged
merged 1 commit into from
May 20, 2019

Conversation

maraf
Copy link
Member

@maraf maraf commented May 12, 2019

Solves #6415.

In addition to standard plugin location, this change adds:

In portable mode: GE loads plugins from <GE>\UserPlugins.
In installed mode: GE loads plugins from <GEAppData>\UserPlugins.

Questions:

  • The implementation places user plugins in Roaming profile, where most of GE stuff is placed, but I have found that Local is also used by GE - window positions are saved there. Should user plugins be Roaming or Local?

  • Method ManagedExtensibility.SetUserPluginsPath should be internal, but needs to be called from PluginRegistry. Can I add AssemblyInternalsVisibleToAttribute?

@codecov
Copy link

codecov bot commented May 12, 2019

Codecov Report

Merging #6551 into master will increase coverage by 0.12%.
The diff coverage is 97.61%.

@@            Coverage Diff             @@
##           master    #6551      +/-   ##
==========================================
+ Coverage   47.17%   47.29%   +0.12%     
==========================================
  Files         698      701       +3     
  Lines       52668    52700      +32     
  Branches     6944     6943       -1     
==========================================
+ Hits        24844    24924      +80     
+ Misses      26497    26441      -56     
- Partials     1327     1335       +8
Flag Coverage Δ
#production 36.6% <97.14%> (+0.14%) ⬆️
#tests 97.63% <100%> (+0.03%) ⬆️

@mast-eu mast-eu added this to In progress in Move plugins via automation May 13, 2019
@mast-eu mast-eu self-assigned this May 13, 2019
Move plugins automation moved this from In progress to Review in progress May 14, 2019
Copy link
Member

@mast-eu mast-eu left a comment

Choose a reason for hiding this comment

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

  • The implementation places user plugins in Roaming profile, where most of GE stuff is placed, but I have found that Local is also used by GE - window positions are saved there. Should user plugins be Roaming or Local?

Please make Local the default for user plugins.

  • Method ManagedExtensibility.SetUserPluginsPath should be internal, but needs to be called from PluginRegistry. Can I add AssemblyInternalsVisibleToAttribute?

IMHO it's ok. But I would like to hear @RussKie on this point, since I'm not sure of what he thinks.

Plugins/GitUIPluginInterfaces/ManagedExtensibility.cs Outdated Show resolved Hide resolved
GitUI/Plugin/PluginRegistry.cs Outdated Show resolved Hide resolved
@mstv
Copy link
Member

mstv commented May 14, 2019

Please make Local the default for user plugins.

The intention of Roaming is that when I log on to another PC, my settings including my selected plugins do roam to this PC. So why not Roaming as the default?
(Window positions depend on the local monitor.)

@mast-eu
Copy link
Member

mast-eu commented May 14, 2019

So why not Roaming as the default?

Suppose you have 2 PCs with some GE version (say 3.2) and some PluginA.
Now you update 1 PC to GE version 4.0, which brings incompatible changes in the plugin API.
The PluginManager finds a new version of PluginA, already compatible with the new API, and installs it in Roaming.
Now you log into PC 2, which did not yet get GE update to version 4.0 (I think it is checking every 7 days for new updates). But the new version of PluginA has already been synced from PC 1 and you have a problem.

API changes will be frequent, at least while we're getting everything up and running.
We can save a lot of trouble by avoiding to sync plugins through roaming. The downside of having to install plugins on multiple PCs shouldn't be a big problem for the majority of our users.

@maraf
Copy link
Member Author

maraf commented May 15, 2019

Applied changes based on codereview.

  • Refactored Local profile path from WindowPositionList to AppSettings.
  • UserPlugins are loaded from Local profile.
  • Plugins are loaded recursively under plugins folders.

{
return GetGitExtensionsDirectory();
}
else
Copy link
Member

Choose a reason for hiding this comment

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

this else is redundant and should be removed to reduce nesting

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok

GitUI/WindowPositionList.cs Show resolved Hide resolved
}

return result;
}
Copy link
Member

Choose a reason for hiding this comment

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

  1. Tests?
  2. Do we need to load all *.dlls or only those matching a specific patten (e.g. GitExtensions.*.dll)?
  3. Is there a perf risk of searching for a looooooong time? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

  1. Yeah, tests. I'm sorry, I'm going to add them.
  2. I had a discussion with @mast-eu that GE org could reserve prefix GitExtensions.* on nuget.org, so that official/core plugins could be in this form and community plugins will have any other pattern.
  3. The idea is that there will only be 1 level of folder nesting.

Copy link
Member

Choose a reason for hiding this comment

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

  1. The current plugins have no common naming scheme. So, at least for the moment, we need to load all DLLs from defaultPluginPath. A decision about enforcing a naming scheme or not can be taken later.
  2. No, I don't expect a performance impact. I didn't perform any tests yet though.

Copy link
Member

Choose a reason for hiding this comment

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

GE org could reserve prefix GitExtensions.* on nuget.org

👍 Any hints how to do that?

3. The idea is that there will only be 1 level of folder nesting.

I'm afraid we can't assume that. We need to be strict in our implementation and don't go deeper than one level.

Copy link
Member Author

@maraf maraf May 17, 2019

Choose a reason for hiding this comment

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

GE org could reserve prefix GitExtensions.* on nuget.org

👍 Any hints how to do that?

Send email to account@nuget.org, documentation https://docs.microsoft.com/en-us/nuget/reference/id-prefix-reservation#id-prefix-reservation-application-process.

Unfortunately I have already pushed some packages matching GitExtensions.*, so I would need to unlist them and tranfer to GE org (which I'm ok with). Just let me know when GE org nuget account is ready.

  1. The idea is that there will only be 1 level of folder nesting.

I'm afraid we can't assume that. We need to be strict in our implementation and don't go deeper than one level.

Ok than.

Copy link
Member

@mast-eu mast-eu left a comment

Choose a reason for hiding this comment

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

2 minor comments.

GitUI/Plugin/PluginRegistry.cs Outdated Show resolved Hide resolved
GitUI/WindowPositionList.cs Outdated Show resolved Hide resolved
@maraf
Copy link
Member Author

maraf commented May 16, 2019

@RussKie What do you think about this?

Method ManagedExtensibility.SetUserPluginsPath should be internal, but needs to be called from PluginRegistry. Can I add AssemblyInternalsVisibleToAttribute?

@RussKie
Copy link
Member

RussKie commented May 17, 2019

@RussKie What do you think about this?

Method ManagedExtensibility.SetUserPluginsPath should be internal, but needs to be called from PluginRegistry. Can I add AssemblyInternalsVisibleToAttribute?

Do you see any problems with ManagedExtensibility.SetUserPluginsPath remaining public?

@maraf
Copy link
Member Author

maraf commented May 17, 2019

@RussKie What do you think about this?

Method ManagedExtensibility.SetUserPluginsPath should be internal, but needs to be called from PluginRegistry. Can I add AssemblyInternalsVisibleToAttribute?

Do you see any problems with ManagedExtensibility.SetUserPluginsPath remaining public?

Only that any plugin can call it, but if it's ok for you, I'm ok with it.

@ghost ghost assigned maraf May 17, 2019
@maraf
Copy link
Member Author

maraf commented May 17, 2019

Resolved notes from code review vol.2.
Not sure about the unit test, is it ok this way?
Should I squash the commits?

@RussKie
Copy link
Member

RussKie commented May 17, 2019 via email

@maraf
Copy link
Member Author

maraf commented May 17, 2019

Can we make so that once it is initialized it can't be changed?

Sure.

Move plugins automation moved this from Review in progress to Reviewer approved May 17, 2019
@mast-eu
Copy link
Member

mast-eu commented May 17, 2019

Just browsed through the unit tests. They look ok.

@mast-eu
Copy link
Member

mast-eu commented May 17, 2019

I think commits should be squashed before merging.

@RussKie
Copy link
Member

RussKie commented May 18, 2019 via email

[TestFixture]
public class PluginsPathScannerTests
{
[TestCase(@"..\..\PathScanningData", "PluginInRootDir.dll", "PluginInOwnDir.dll")]
Copy link
Member

Choose a reason for hiding this comment

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

Could you clarify it for me (I'm a bit slow, sorry).

Plugins are stored in c:\Users\<user>\Local\GitExtensions\GitExtensions\UserPlugins folder:

UserPlugins
  \Plugin1
      \Plugin1.dll
      \Plugin1.config
  \Plugin2
      \Plugin2.dll
      \Plugin2.config

In this scenario this looks like:

PathScanningData
  \PluginInRootDir
      \PluginInRootDir.dll
  \NotFoundPlugin
      \SubDir
          \NotFoundPlugin.dll1.dll
  \PluginInRootDir.dll

Why are we expecting to load PluginInRootDir.dll?

Copy link
Member Author

Choose a reason for hiding this comment

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

Backward compatibility. I'm using the method for both core and user plugins. Is it ok? Also PM now extracts plugins in a single directory.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, makes sense, thank you.
all good

@maraf
Copy link
Member Author

maraf commented May 18, 2019

I'm this weekend away, so I'm going to squash them on Monday.

{
DirectoryInfo directory = new DirectoryInfo(pluginsPath);

result = Enumerable.Concat(result, directory.GetFiles("*.dll"));
Copy link
Member

Choose a reason for hiding this comment

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

I would add a paragraph explaining why we are loading two levels of assemblies.
E.g. load plugins located in the folder to provide back compat, and load new style plugin...
Maybe even add a structure to help visualise

UserPlugins
  \OldPlugin1.dll
  \OldPlugin2.dll
  \OldPlugin2.config
  \NewPlugin1
      \Plugin1.dll
      \Plugin1.config
  \NewPlugin2
      \Plugin2.dll
      \Plugin2.config

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok

@mast-eu
Copy link
Member

mast-eu commented May 18, 2019

Will merge after squash.

@mast-eu mast-eu mentioned this pull request May 20, 2019
37 tasks
In portable mode it loads plugins from <GE>\UserPlugins.
In installed mode it loads plugins from <GEAppData>\UserPlugins.
@maraf
Copy link
Member Author

maraf commented May 20, 2019

Squashed commits and added detailed comment to the PluginsPathScanner.cs.

@maraf
Copy link
Member Author

maraf commented May 20, 2019

Any hint on what is wrong with the build?
All GitUITests failed..

@mast-eu mast-eu closed this May 20, 2019
Move plugins automation moved this from Reviewer approved to Done May 20, 2019
@mast-eu mast-eu reopened this May 20, 2019
Move plugins automation moved this from Done to In progress May 20, 2019
@mast-eu
Copy link
Member

mast-eu commented May 20, 2019

Any hint on what is wrong with the build?

Like with most software, sometimes AppVeyor builds just need to be restarted ... 😉

@mast-eu mast-eu merged commit 706e248 into gitextensions:master May 20, 2019
Move plugins automation moved this from In progress to Done May 20, 2019
@mast-eu
Copy link
Member

mast-eu commented May 20, 2019

Thank you.

@maraf maraf deleted the issue-6415 branch May 24, 2019 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Move plugins
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants