Sublime Forum

Is it possible to make one package require another?

#1

I’m working on a package that uses YAML Macros to dynamically rebuild syntax files based on user settings. Without YAML Macros, this new package would be quite useless. I know how to specify that a package requires a dependency; is it possible to specify that a package requires another package? If not, then is there an established best practice? Ideas I’ve had:

  • Automatically install YAML Macros when the new package is installed. (Not sure if there’s an accepted method here.)
  • Factor all of the useful parts of YAML Macros into a dependency.
  • Nag the user to install YAML Macros themselves.
1 Like

#2

I do not think it is necessary to refactor the Yaml Macros package and create a dependency form its code, then the less troublesome alternative is, you can just show a pop up with sublime.message_dialog() asking the user to install the package, when:

  1. Attempting to use some of your package features,
  2. Or right after installing it.
1 Like

#3

It’s not currently possible to require packages like that, no. There is an issue for this on the Package Control issue tracker, though (In a nutshell, Will doesn’t plan on implementing that feature, although he does have an alternative idea):

I’m not sure if there is a best practices for this particular situation, or at least I was unable to find anything definitive when I looked into it myself.

Speaking only for myself I would rather either Package Control installs the package (automatically or manually via user intervention), or nothing does. In particular trying to come up with your own method to pull down and install a package sounds a lot like trying to replicate what Package Control is already doing, and you would probably want to do it in a way that wouldn’t step on PC’s toes.

I never really played around very much, but you might be able to trigger Package Control into installing a package for you by adding it to the list of packages.

In my case I’m working on something that is primarily meant to be a dependency but which should also behave generally like a regular package anyway, which is sort of coming at the same problem from the other direction.

1 Like

#4

The yes_no_cancel_dialog might be even better: install automatically upon installation, but give the user the chance to decline.

[quote=“OdatNurd, post:3, topic:33657”]Speaking only for myself I would rather either Package Control installs the package (automatically or manually via user intervention), or nothing does. In particular trying to come up with your own method to pull down and install a package sounds a lot like trying to replicate what Package Control is already doing, and you would probably want to do it in a way that wouldn’t step on PC’s toes.

I never really played around very much, but you might be able to trigger Package Control into installing a package for you by adding it to the list of packages.[/quote]

For the implementation itself, I expect I’d use the advanced_install_package command. I have not actually tried this.

2 Likes

#5

Ah yes, good call. I forgot all about that command. That was on my list of things to try before I changed my design idea and didn’t need to do this any longer.

I just manually invoked it and it seems to work a treat. I guess a more robust solution would have to also detect if Package Control is even installed first (unless you plan to not support manual installations) so that it could warn the user they need to manually install the dependency as well.

2 Likes

#6

There is a bug with this command:

  1. https://github.com/wbond/package_control/issues/1191

Which make is not work if you attempt to install several packages.

You can import package control and install a package just like this:

from package_control.package_manager import PackageManager
from package_control.package_disabler import PackageDisabler

package_manager  = PackageManager()
package_disabler = PackageDisabler()

packages_to_install        = [ ("YAML Macros", False) ]
packages_to_install_length = len( packages_to_install )

for package_name, is_dependency in packages_to_install:
    current_index += 1
    print( "\n\nInstalling %d of %d: %s (%s)" % ( current_index, packages_to_install_length, package_name, str( is_dependency ) ) )

    package_disabler.disable_packages( [package_name], "remove" )
    package_manager.install_package( package_name, is_dependency )

I wrote this when I wrote the Channel Manager:

  1. Channel Manager

But to make package control install several packages at once is very difficult. You would need to handle some problems which will happen. I handled these cases into the Channel Manager's plugin channel_installer.py, you can look into its code.

1 Like