forking plugins - comments?

Hi all,

I’ve been finding that I tend to want to “tweak” many of the plugins that I download. I’m wondering whether:

a) this is reasonable & I should maintain my own local plugins as such for just my projects (I assume I could just change the plugin directory name a bit) or

b) I should be trying to somehow override the plugin (see question below) instead

Also some general questions in this area:

c) With plugins can one override a particular method from the plugin by dropping a similar file/module/class in the app area with just that method?

d) Is there a “update plugins” type command? i.e. does one need to be careful if you make changes in the plugin directory that they might not be “blown away” via an update command?

Tks

} Hi all, } } I've been finding that I tend to want to "tweak" many of the plugins that I } download. I'm wondering whether: } } a) this is reasonable & I should maintain my own local plugins as such for } just my projects (I assume I could just change the plugin directory name a } bit) or

This is reasonable. Assuming license compatibility, once you include it into your project it is yours to do with as you will.

} b) I should be trying to somehow override the plugin (see question below) } instead

Kind of ugly, but possible. You'd have to do it in the plugin's init.rb, though, so it probably isn't worth it.

} Also some general questions in this area: } } c) With plugins can one override a particular method from the plugin by } dropping a similar file/module/class in the app area with just that method?

No. Class/module autoloading happens based on the class/module not being defined yet. Once it's defined, whether because the appropriate file was found in and loaded from the plugin or in lib, no other file will be automatically loaded to satisfy the need for the given class/module.

} d) Is there a "update plugins" type command? i.e. does one need to be } careful if you make changes in the plugin directory that they might not be } "blown away" via an update command?

The right way to handle this is with subversion and svnmerge. This assumes that you are using subversion for your project, of course. Instead of using script/plugin to get the plugin, you svn copy the plugin into place in your project and commit. You then svnmerge init (svnmerge is actually a Python script, and it makes merging much easier) and commit. Now whenever you want to update the plugin you can svnmerge merge, make sure you like all the changes, and commit.

Google for svnmerge to understand the details of the process. I have recently started using it and I am delighted with its functionality, if not its documentation.

} Tks --Greg

thanks Greg - can I clarify a couple of things please:

re d) “The right way to handle this is with subversion and svnmerge” - given I’ve already been using the plugin install method is there a way to migrate to the approach you’re suggesting? or should I just rename my plugin directories as a minimum to avoid the possibility of an accidental plugins update overwritting my changes?

re c) “classloading” - it would be great to have some sort of flowchart or cheat sheet that summarises how rails/ruby class loading works, and references various rails specific aspects such as: plugin aspects ( init.rb’s), engine, application.rb, environment etc etc. Do you know if such a thing exists - just asking as you seem to understand this area :slight_smile:

Many Thanks GregH

} thanks Greg - can I clarify a couple of things please: } } re d) "The right way to handle this is with subversion and svnmerge" - given } I've already been using the plugin install method is there a way to migrate } to the approach you're suggesting? or should I just rename my plugin } directories as a minimum to avoid the possibility of an accidental plugins } update overwritting my changes?

I'm assuming that you are asking this question because you actually are using subversion to manage your project, since otherwise it doesn't make sense to ask. In that case, what you should do is the following:

1) Check out your modified version of the plugin somewhere handy so you'll    be able to compare it to the current version of the plugin.

2) In a working copy of your project, svn remove your plugin.

3) In that same working copy, svn copy the plugin from its repository and    commit. (You may want to do all this in a branch if having the    unmodified plugin in your project repository will cause things to break    for other people.)

4) Prepare for merging with svnmerge init in the plugin directory. Commit    again.

5) Diff your modified version you checked out in step 1 with the copied    version.

6) Port your changes to the to the copied version, make sure things are    working as expected, and commit.

When you want a new version of the plugin, you'll use svnmerge merge to get it. If there's some change you don't like, find out which revision it was in and svnmerge block it, then merge.

} re c) "classloading" - it would be great to have some sort of flowchart or } cheat sheet that summarises how rails/ruby class loading works, and } references various rails specific aspects such as: plugin aspects (init.rb's), } engine, application.rb, environment etc etc. Do you know if such a thing } exists - just asking as you seem to understand this area :slight_smile:

The automatic loading of classes/modules occurs in the const_missing method, which Rails redefines. If you refer to a class/module that has not been loaded yet, const_missing is called with the constant. For example, suppose you have a module Foo::Bar::Baz and even the Foo namespace has not been loaded. The const_missing method is called on Object with "Foo" and it tries to require 'foo' first. If it succeeds, it's done, though if loading that file didn't define Bar then const_missing will be called on Foo with "Bar" next. If it fails, it will check to see if there is a directory named 'foo' in the $LOAD_PATH and, if so, create the Foo module and return. It's all based on the $LOAD_PATH, though, so if there are multiple foo.rb files in different parts of the $LOAD_PATH you can tell which one will be read by where its location appears in the $LOAD_PATH (p it from script/console).

} Many Thanks } GregH --Greg

thanks very much Greg - I’ll try this

Hello Greg,

thanks very much Greg - I'll try this

Greg's way will work. But you have two other options too:

1) Piston (http://piston.rubyforge.org/) 2) SVK (http://svk.elixus.org/)

Piston is geared towards vendor branch management (what you are doing here). SVK is geared towards completely going offline. But SVK also handles vendor branches very easily.

Hope that helps !

+1 for Piston, thanks for writing it! I still haven't gotten around to digging into svk, but Piston does what I need.

I've also started completely integrating plugins into my app if I start customizing them much, or if they're really important to my app.