I wish to do my best to attempt to remove my own personal biases from this decision so let me throw something out there for comment:
I have inherited a project using a webmin v1.310 based control panel
which has been extensively hacked up to be the control panel for an
appliance as well as a couple coders to work on it. A massive amount
of time and money has been poured into maintaining it over the last
few years which management will be very reluctant to walk away
from. However, due to lack of adherence to best practices it has
acquired a lot of what I call "technical debt".
Issues with this codebase:
1. It is now significantly diverged from the original webmin source
which makes migrating to new versions to take advantage of security
fixes pretty much impossible. So we are responsible for all of it now
with no community help.
2. It has duplication of files within the codebase. For example there are;
./wizard/lvm-lib.pl
./lvm2/lvm-lib.pl
which are mostly the same file except the one in lvm2 has an extra 15k
of code added to it.
3. Duplication of functions cut and pasted between various other modules.
4. No template language so html and code is intermingled everywhere.
5. There is CVS involved but it's a mess and full of redundant and
nonused files, HEAD and REL_CUR and constantly being inverted, there
is no single version really tagged as a release they just release to
production whatever was in HEAD when they built the box, and who knows
what else.
6. It contains stuff like:
# foreign_call(module, function, [arg]*)
# Call a function in another module
sub foreign_call
{
local $pkg = $_[0] ? $_[0] : "global";
$pkg =~ s/[^A-Za-z0-9]/_/g;
local @args = @_[2 .. @_-1];
$main::foreign_args = [EMAIL PROTECTED];
local @rv = eval <<EOF;
package $pkg;
&$_[1]([EMAIL PROTECTED]::foreign_args});
EOF
if ($@) { &error("$_[0]::$_[1] failed : $@"); }
return wantarray ? @rv : $rv[0];
}
Disregarding style/religious issues (braces, indents/lackthereof, etc)
what is this code supposed to be doing? As far as perl goes is this
decent? This is original webmin code. I know exactly what each
individual line does but as usual the comment says what it does, not
why it does it. There are many "foreign" functions in this codebase a
quick grep showing:
sub foreign_check
sub foreign_exists
sub foreign_available
sub foreign_require
sub foreign_call
sub foreign_config
sub foreign_installed
sub foreign_defined
and they all involve some sort of wrapping of functionality. Why would
this be needed to call a function in another module? I'm pretty sure
syntax for doing this already exists.
7. This codebase has support for lots of different operating systems
which is unnecessary for our project and adds a lot of
complication. It might even be the reason for the above foreign
functions.
8. These are more stylistic issues I guess but it looks like a cgi app
from 1998. It uses frames, often requires sideways scrolling, no
header/footer includes (top frame is like the header), etc.
And that's probably just the beginning. So there is a huge amount of
cleanup to be done to get this into any sort of decent shape.
Might it be better to start over?
How does one judge when to make the case for starting over vs. just
sucking it up and incrementally improving what we've got?
Making big changes to this codebase could easily cause collateral
damage as there s no test suite or anything. It seems that as time
goes on this codebase is requiring more and more resources to keep
going and has a very spotty history of reliability as it is.
I would like to get them out of the business of having to maintain so
much code to concentrate on what actually makes them money.
The big theme of my involvement here so far has been to push as much
maintenance work upstream as possible and do as little custom as
possible except that which very specifically adds value for us and so
far that is working out well.
If we moved to a different community maintained codebase more aligned
with what we really want this thing to do to implement the needed
functionality and it happened to be object oriented we could
inherit/override aspects of the original code we don't like with our
own code. Our much smaller amount of code could be kept and maintained
separately while still being able to drop in newer versions of the
code as they came from upstream and fix up whatever (hopefully minimal
but who knows) API incompatibilities occurred. Does this sort of thing
actually work in practice?
However this would require learning a new base framework and rewriting
some of our custom modules which the new framework does not already
provide. It would also incur some political risk in telling management
that they are trying to polish a turd with the current codebase and
ask them to invest even more. I just want to do what is best for the
client and therefore my career.
Comments?
--
Tracy Reed
http://tracyreed.org
pgpo8Xlgbiiqk.pgp
Description: PGP signature
-- [email protected] http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg
