randy3k / AutomaticPackageReloader

Automatically reload submodules while developing a Sublime Text package.
MIT License
38 stars 13 forks source link

How to reload a Sublime Text dependency? #12

Closed evandrocoan closed 5 years ago

evandrocoan commented 6 years ago

I am trying to reload my dependency with this, but when I open a dependency file like channel_manager.py and call the command Reload Current Package it just shows:

[Package Reloader] error: ChannelManager is not loaded.

The dependency is https://github.com/evandrocoan/SublimeChannelManager

If I open a file from the package which uses the dependency, and I call this command, it only reloads the package files, not the dependencies one:

[Package Reloader] begin ======================================================
reloading plugin StudioChannel.channel_commands
[Package Reloader] reloading |-- StudioChannel
[Package Reloader] reloading |-- StudioChannel.channel_commands
[Package Reloader] reloading | |-- StudioChannel.settings
[Package Reloader] reloading | |-- StudioChannel.installation_wizard
[Package Reloader] reloading | |-- StudioChannel.uninstallation_wizard
reloading plugin StudioChannel.installation_wizard
reloading plugin StudioChannel.settings
randy3k commented 6 years ago

APR does not currently reload PC dependencies as they are loaded to Sublime Text via PC loader. I personally do not have the interest to extend the applicability to PC dependencies, but any PR is welcome.

evandrocoan commented 6 years ago

I think it is easy to be implemented, I just figured out how to reload it on the package which requires the dependency. I just added:

from channel_manager.channel_manager import main as manager_main
sublime_plugin.reload_plugin( "channel_manager.channel_manager" )

I will see if I can pull together a pull request.

randy3k commented 6 years ago

Your code will not reload any sub modules of channel_manager. It is the reason of the existence of this package. APR reloads a given package as well as its sub modules.

evandrocoan commented 6 years ago

The channel_manager.channel_manager is actually a file called ChannelManager/all/channel_manager/channel_manager.py, so I think I just need to do the same thing for all files in the dependency as APR does for a package.

The difference is that I will be omitting the dependency top level name. For example, if the channel_manager.channel_manager was part of a package instead of a dependency, its full qualified name would be ChannelManager.all.channel_manager.channel_manager, but as it is a dependency, its folder ChannelManager/all is included on the sys.path. Then when importing the dependency I just need to do import channel_manager.channel_manager, instead of ChannelManager.all.channel_manager.channel_manager.

Then applying this logic for dependencies, instead of trying to reload the fully qualified name:

sublime_plugin.reload_plugin( ChannelManager.all.channel_manager.channel_manager )

I just need to reload:

sublime_plugin.reload_plugin( channel_manager.channel_manager )

This the code change I need to do on APR, when I detect a repository is a dependency rather than a package, I do the sublime_plugin.reload_plugin() calls omitting the ChannelManager.all name part.


I do this to reload a dependency file module like ChannelManager/all/channel_manager/channel_manager.py

import sublime_plugin
sublime_plugin.reload_plugin( "channel_manager.channel_manager" )

FichteFoll do says I shoul not use sublime_plugin to reload a dependency, but just works.

If you are interested, you can use the imp module:

import imp
import channel_manager.channel_manager
imp.reload( channel_manager.channel_manager )

I just put one of these codes on some plugin.py Sublime Text automatically reloads when I save it. Then every time I want to reload the dependency, I just re-save this plugin.py.

randy3k commented 6 years ago

The issue of sub modules is still there. In channel_manager.py, settings is imported relatively. Any changes in settings.py will not be reflected if only channel_manager is reloaded.

randy3k commented 6 years ago

A naive procedure of reloading all the modules may not work as well unless you know the actual loading order of the submodules. Inferencing the loading order of the submodules is nearly impossible for large projects. APR helps in this aspect by injecting a loader to python for intercepting all the import calls.

FichteFoll commented 6 years ago

Additionally, Python modules are not Sublime Text plugins by default. You should not be using sublime_plugin.reload_plugin and instead use the imp module.

All packages that use the dependency will have to be reloaded as well since they still hold references to the old modules.

Thom1729 commented 6 years ago

Is it as simple as this?

  1. Remove the dependency's modules from sys.path.
  2. Get a list of all packages that depend on it.
  3. Reload each of those packages (as currently implemented).
Thom1729 commented 5 years ago

Resolved by #20.