Open sbleon opened 12 years ago
Looks like this might be a solution https://github.com/blahutka/sprinkle_packages/blob/master/lib/sprinkle_packages/capistrano.rb
More specifically, a quick monkeypatch in your policy file (install.rb commonly), before your packages are required:
#Monkey patch...
module Sprinkle::Package
class Package
@@capistrano = {}
def self.set_variables=(set)
@@capistrano = set
end
def self.fetch(name)
@@capistrano[name]
end
def self.exists?(name)
@@capistrano.key?(name)
end
end
end
then, in your deploy.rb add:
Sprinkle::Package::Package.set_variables = self.variables
and access set :user, 'bob'
from packages with: Package.fetch(:user)
One note: the deployment {...} block in the policy file (again, typically install.rb), must precede requiring the packages and policy {...} block. If you have the deployment block after the packages/policies everything will compile, but you'll be pulling nil values for the variables.
@phillbaker, thanks for the suggestion! That worked pretty nicely.
Is this possible without monkeypatching in the newer versions of Sprinkle?
Are you wanting to read or change them? I'm not sure packages should be changing Capistrano settings (without a monkey patch), though I can see the desire to read them. No great way to do this yet since Package doesn't have access to the actor until policy passes it during the actual installs.
It seems very weird to have retrieval methods in package that only work with a single actor though. How would this work with other actors?
Once the actual logistics were worked out I think the Cap actor would have to monkey patch (via module) Package itself to add the functionality to access the Cap config.
Yeah, changing would seem weird, but reading the Cap config vars would be appropriate I think. Do you have time to look at this in more detail? Otherwise I could have a look at the code and see if I could implement something.
I don't have time right now. I think making Deployment a singleton would be one approach... then inside package (via module) you'd just have something like:
def cap_config; Deployment::Deployment.instance.style.config; end
Otherwise you have to inject deployment into the package options as package instances are spooled up, which seems icky to me. Though that would never support someone doing something crazy-cool with multiple deployments... problem is packages are kind of designed to be discrete things that do not know about how they are being deployed - and this request kind of wants to draw a bridge across that boundary.
Actually perhaps it should be passed... and in Policy#process
the inner block would still call Package#instance
but perhaps instance shouldn't eval the block... but rather when Package#process
is called @deployment is set locally and then the block is evaled, and then the rest of process happens. That would require reworking some tests though but would preserve maximum flexibility to using the Sprinkle library to do cool crap.
Just some ideas.
I had a look at the code and I have to admit this is a bit over my head... sorry I can't help you with implementing this. :( I will continue to use the monkeypatch for now.
We really need our own settings API that all actors could take advantage of... Capistrano can't monkey patch Package itself because we don't know what actor we're using until after all the packages are defined... so any type of method like cap_config would have always be available (for all actors), which is messy. But if you had a settings API then the Capistrano actor could hook into that to expose the Capistrano settings, and other actors could provide their own settings interfaces.
Some of my packages need to know where I'm deploying my Rails app to so that they can create directories, write config files, etc. I can't figure out how to refer to Capistrano's "deploy_to" variable from inside my packages.
I can reference "deploy_to" from within the deployment definition as @style.config.fetch(:deploy_to). It also looks like the instance of Deployment (that contains @style) is passed into Package#process (http://rubydoc.info/gems/sprinkle/0.4.2/Sprinkle/Package/Package:process).
Is there a good way (or even a bad way, frankly) to refer to "deploy_to" and other Cap variables?