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.