Wednesday, 17 February 2010

Generated code from DBIx::Class and Test::Perl::Critic

We have hit an interesting thing in our ever changing code base.

We want to start managing the database schema and use the power of DBIx::Class to keep the code and database in sync by auto generation.

However, we also want to keep to coding standards by running Test::Perl::Critic at maximum severity over the code base.

Problem - the auto generated code fails tests, but if we modify above the comment line

#DO NOT MODIFY ANYTHING ABOVE THIS LINE

we lose the ability to run regeneration of the code if we make any database changes.

One solution is to say, don't run Perl::Critic over the resultset files. However, this means we need to separate out any manually written code, which should be here (running Catalyst, etc), or we never Test::Perl::Critic our own code. It also means additional maintenance to our auto test each time we add more files.

Another is never to be able to auto-regenerate and manually keep the database and code in sync.

So, has anyone come across any solutions to this problem? All comments gratefully received.

BTW - we understand that

1) TIMTOADY - some people write good maintainable code which doesn't follow Perl::Critic standards.
2) It would be very difficult for maintainers of code which generates code to constantly keep up with the latest Perl::Critic.

3 comments:

Robert 'phaylon' Sedlacek said...

There is a wishlist item in the DBIC:SL queue that would deal with this sort of problems. This should (AFAIU) allow you to add ## no critic and ## use critic comments before and after the auto-generated source, which would deactivate Perl::Critic for that segment of code.

If it's really annoying right now, the ticket above links to a stack overflow discussion that tells how to deactivate the md5sum checks during regeneration, so you can modify the code yourself at the moment. You can add those comments to the file manually then, but you'll have to re-add them everytime you regenerate the file.

thaljef said...

I'm not familiar with DBIx code generation. But if the code is generated from some kind of template and you're able to modify the template, then perhaps you could wrap the generated code with annotations, like this...

## no critic

...
Generated
Code
Here
...

## use critic

Personally, I would never mixed generated code with authored code in the same file, especially if it is going to be regenerated at some point. So I think it would be perfectly reasonable to have all the generated code go into a separate dedicated directory, and then configure Test::Perl::Critic to always ignore that directory.

Does that help at all?

-Jeff

Andy Brown - SetitesUK said...

Thanks for your responses guys, it is helpful to see what others think and do (and wishlist items).

I was beginning to wonder if I might need to take a look at the templating bit, to see if I could manage to add ## no/use critic statements in.

One problem with setting Test::Perl::Critic to ignore a directory is that we introduce a further maintenance overhead in our test critic file, which, although is potentially small, could obviously get larger.

Also, to our mindset, the (in this case) resultset classes are very much reminiscent of the model in our MVC framework, and so, it is the logical place to put code which transforms this data, although I accept that it does give clarity between generated code and authored code if they are in separate directories.

You have both given me lots to think about, and thanks again for your responses.

Andy