This question comes from previous experiences with svn.
We had a problem where our code was badly formatted, mainly because of the increase in developers at the time who did not adhere to our formatting guide for various reasons. So there was discrepancies in code formatting for quite a bit of time. Additionally the codebase was quite old as well, so it was probably going on for years.
Anyway, there was a suggestion to format all touched classes in new features into our agreed standard code formatting style. Other developers were against this mainly because:
You can't use an annotation style view of the code, so you can't see what features a particular line of code is related to.
In the end, we ended up rejecting this idea and only did formatting for newly introduced class files. For new code in existing classes, we only ensured that the lines that were edited were indented correctly.
We are mostly eclipse users, but I think that this feature is available in other ide's as well (just checked online for netbeans and intellij).
For an additional bit of context, the codebase in question was fairly mature and there was a fair balance between support work and new feature work. Sometimes new features were split into phases, so this is also something to consider.
So the question(s) are:
Was this the correct approach? Is it reasonable to reject "code formatting commits" just to preserve an annotated view of the code?
Are there better ways of doing this? My opinion here is that maybe there should have been a commit hook that does automatic formatting, not sure if something like this is exists or is even valid though?
You do not want to do this in a hook. Not only is it a really bad plan to have a hook edit the source in any way as it's in transit, but the error the user will get is going to suck (it would be impossible to tell the user all of the errors in a meaningful way on an error message). I'm not a fan of enforcing style in general.. but if you must, I recommend a three part plan
Define and document your coding style. What you come up with isn't as important as the discussion.
Export configs for editor and share with team. this will be editor dependent. you want to make it stupid easy so that the drudgery of indentation and other syntax things is handled automatically.
Have your CI enforce that style. If you really want to enforce it, you'll do it here. likely with something like checkstyle. This will generate a fancy report that will show and display all the errors.
I've worked on teams that did this really well... the standard was pretty flexible, everyone felt they had input so when the build failed there was no grumbling. We fixed it and moved on.
I did work on a team where an irrational fascist believed that the style was more important than the completeness or correctness of the code. It sucked.
Personally I'd stop at step two and see where that gets you before moving on to step 3.
In Eclipse, under Preferences > Save Actions, one can enable the Auto Formatter which formats the code on file save. You can configure a set of Formatting Rules and Export Preferences File to send to your developers (or have the leading developer do it) for them to Import Preferences File, so the code is automatically formatted as they are developing it.
A standardized auto-formatter would help eliminating the in-similarities in code style which causes non-codebase changes in the SVN.
I think it would be perfectly fine to do a one off code formatting commit for the old classes in your repo, it's definitelly better then having ill-formatted code all around the place.
As for IDE's Intellij and Eclipse can do formatting on save, but I'd be against doing it in a hook because it's not aware about what you're coding in, and wouldn't trust that on a script. But that can work as well but need to make sure that what you're using for formatting is well up to the task
Related
Is this possible? If so how do I do this?
The code is in C# and we are using TortoiseSVN.
I simply want to auto format the code on every checking.
Thanks a lot
With a pre-commit hook script, you could do that, yes.
But I'm sure that you will remove that script after the first commit because you'll get into big problems.
If you modify the data that gets committed, the client doesn't know about that. So after such a commit where your script 'fixes' the formatting of a file, the file content in the repository is different than the files in your working copy. But your working copy still thinks it's up to date with the repository (after all, it's modifications just got committed).
So on the next update, you'll get into hell - broken working copy, angry users, ...
And of course, you might break the build - auto formatting has that effect sometimes.
You can of course implement a hook script that checks for a correct formatting and returns an error if it doesn't, that's perfectly fine.
And since you're using TortoiseSVN, you can try doing the formatting in a client-side pre-commit hook.
You're touching on holy-war ground. Mussing with people's formatting is asking for pitchforks and torches.
My recommendation: Don't.
Not to mention, if you're talking C#, and your developers are using Visual Studio, VS has a lot of auto-formatting tools. Just by entering that closing curly-brace and VS can/will auto-format your code.
A better solution may be to get all your developers to use the same auto-formatting settings.
Tools -> Options, Text Editor -> C# ->Formatting
These settings are exportable, so if you can get the team to agree to use the same code-formatting settings in VS, you can avoid the trouble of performing it in your source control system which is better left to do what it does best.
If you're hell-bent on doing this, a pre-commit hook, like others have said, is the way to go. If you're SVN server is running on Windows, might I recommend CaptainHook for writing your hook scripts? Plugin-able hookscripts that you can write in any .NET language.
like most people here I agree adding a pre-commit-hook that rewrites their code is bad, however you can have a pre-commit hook that rejects code that is not formatted to your coding practices and inform the user of such error.
I think you can do this using a pre-commit hook in your repository.
Edit To the people who think this a bad idea (I'm not saying it isn't): It's not uncommon for organizations to enforce a specific code style or code formatting. Sometimes these rules can be quite pedantic and strictly enforced, and although they are usually human actions involved in this (i.e. formatting to the correct style before you commit anything to the repository), automating the process can sometimes be useful.
An alternative approach might be to do the verification automatically before the commit, but still allow the commit even if the check fails, but then only send an e-mail or some other notification to indicate that someone didn't follow the style.
I highly recommend it.
Use a pre-commit script or better still, find a way to do it automatically in your IDE (pre-commit will push the changed file to the client). Eclipse can auto format on save.
The rationale for this is that if developers format differently you'll find files which have commits on them where the commit is only a formatting change and it will cause endless confusion.
A common formatting pattern is a very good idea. It'll be hard to introduce, but it'll be worth it. All changes will be real changes, and not just formatting changes. In my experience developers will see the benefits and accept it.
I've worked with cvs and java and used jalopy to auto format. We were using a branching system so it was mandatory, and it worked very well.
It is possible, but also a very, very bad idea.
No automatic code formatters are perfect, and I can almost guarantee that it will tick people off.
That said, if you want to do it, look into using pre-commit hooks.
Is the SVN server running on a Windows or Linux system? And what code-formatter do you want to use?
I have a bloated JDialog class (~2000 lines) that displays two unrelated JTables. I want to split it into three classes (JDialog, Jtable1 and JTable2). I can study which variables and which methods are used by each table and move them to relevant classes, but this manual refactoring is going to be tedious.
Is there any way to automate such refactoring?
To achieve this a script should have an accumulator of tokens. First token is, for instance jTable2 from panel.add(jTable2). Now check all lines that have jTable2 in them and add tokens to accumulator. Repeat search for relevant tokens until new tokens are not discovered. Now for each token find lines that contain it. Expand selection to include brackets.
It is hard to believe that programmers of the arguably largest language haven't created such a tool yet. This should be pretty similar to find usages tool in IDE.
Automatic? No, thank goodness. Refactoring requires thought. Deep learning isn't there yet.
Most IDEs (e.g. IntelliJ from JetBrains, the best IDE on the market) has excellent refactoring support.
But it won't think for you.
One piece of advice: You'll have better luck if you have unit tests, do it in small incremental bites, and use a version control system. Write a test, make a change, show that the test still passes, commit the change, repeat.
You can always go back to the last working version that way. You won't make a bigger mess than a single incremental step.
I think you can do even better: look at moving listeners and processing code out of the UI, too. Swing apps end up with big classes because people learn to cram everything into the UI classes. If you decompose it you'll find that the code is easier to read, more modular, and easier to unit test.
In NetBeans you can use Refactor->move. It starts a wizard that conveniently displays relevant methods. You need to select them that you want to move, but you don't have to hunt in code. Other IDEs have similar functionality.
This way you still have to think, but the boring part of finding them is done for you by IDE.
Take a look at this post (How to refactor thousands of lines of Java code? Is there any tool available?) that asks a similar question.
Basically, there are some production quality tools that help you extract classes once you know what it is what you want to put in the classes. Notably, IntelliJ's IDEA has a good "extract class" refactoring.
The harder part is determining what should go into those classes. AFAIK, there are only research tools available for that.
In projects with many developers it is useful if all their IDEs are configured with identical code style settings, such that you won't get pseudo-differences due to changed formatting checked into version control whenever someone else changes your code. You can try to convince everybody to import project standard formatting settings, but they might forget to do that on creating a new workspace and forget to adapt them whenever a change is necessary, so this will get lost over time.
So, is there a simple way to automate things such that everybody has the same settings and gets his settings changed automatically if they need to be updated - without them taking any action on their own?
Many of these settings are stored in .settings/org.eclipse.jdt.ui.prefs if they are configured project local , so it would be feasible to checkin this file into version control but leave out the other files in .settings. Unfortunately the formatter settings are contained in the big bucket .settings/org.eclipse.jdt.core.prefs, so you would have to do more complicated things to update these. So I am wondering if there are simpler / other options.
Clarification: In my experience many developers ignore requests to adapt the various code style settings in eclipse since they consider them unimportant. So I want to make it at least extremely easy for them to use the project standard settings, at best the codes style adaption should work completely without their cooperation - especially on updates of the coding style. I am looking for tools to do that.
Warning: it's not a good idea to be too strict when it comes to code style. Many programmers have a strong own style. So be careful what you wish for.
The easiest method in Eclipse is to create an empty workspace and use that initially by simply copying it to the developer's machines. You could even copy Eclipse with all the plugins. This has the drawback of having to manually create changes. It is also the most restrictive option.
Another method is to export/import all the settings. This is a bit more work, but it is less restrictive. You would need to distribute the following settings: Formatter, Clean Up, Templates. Furthermore you still would have to set the max. line size in the general settings.
The best way to let people adhere to code practices is to create a document about the minimum requirements. Make sure you document your decissions and let people participate. Then check if people adhere to it; if you let let it slip programmers will go their own way. Management (unfortunately) has a role to play here.
The best way of enforcing the code style is to create a CheckStyle configuration and keep it as a read only file on disk. You can then use this as an external style sheet from the CheckStyle plugin. Make sure that the Eclipse formatter and clean up settings match though.
The same CheckStyle configuration may be used on an automated build environment to generate warnings and errors. These warnings and errors should be discussed during review. Make sure you have loopholes, rules should ne broken if the need arises.
Managing developers is "not unlike herding cats"
In my old company, we would create a "default" or "template" workspace where everything is configured according to personal taste (like key settings, view positions etc.) and according to the companies rules (formatter, compiler warnings, checkstyle, mandatory plugins etc.).
Every time I needed a new workspace, I just duplicated this template workspace.
Since starting from scratch with a new workplace is such a pain, people automatically got used to using the template, rather than creating a complete new workspace. So there was never a problem with people forgetting it.
I have just created a mid-sized web-application using Java, a custom MVC framework, javascript. My code will be reviewed before it's put in the productions servers (internal use).
The primary objective of building this app was to solve a small problem for internal use and understand the custom made MVC framework used by my employer. So, my app has gone through MANY iterations, feature changes and additions.
So, bottom line, the code is very very dirty and this is my first "product level" Java app.
What are your suggestions, what are some basic checks/refractoring I should do before the code review?
I am thinking about:
Java best practices (conventions)
Make the code simple to understand for the developer who will maintain it. (won't be me)
I noticed, I have created some unnecessary objects and used hashmaps/arraylists where could have easily used some other Data structure and achieved the solution. So, is that worth changing?
Update
Your Code Sucks and I Hate You: The Social Dynamics of Code Reviews
If you did not already, (assuming you use an IDE like eclipse)
get plugins checkstyle and findbugs
go through their configuration and tune to your style
run them on your code
resolve all issues reported
you can also tune the compiler warning setting of eclipse itself and possibly make them more strict in what is reported.
Look at code structure:
get plugin jdepend
investigate your package structure
Code against interfaces (Map, List, Set) instead of implementation classes (HashMap, ArrayList, TreeSet)
Complete your Javadoc and make check it is up to date after all refactorings.
Add JUnit tests; if you have no time left to test the whole application, at least create a test for every bug you find and solve from now on. This helps "growing" a test set as you go.
Next time design and build your application with the end goal in sight. Always assume that the next guy having to maintain your code will know how to find you :-)
Unit tests, and they should be automated as part of your build. You should already have these, but if not, do it now. It will definitely make the refactoring easier, as well improving your general confidence in the code (and the guy who will be maintaining it).
Logging.
One of the more overlooked things is the importance of logging. You need to have a decent logging methodology put in place. Even though this is an internal app, make sure that the basic logs can help regular users find issues and provide more detailed logging so that you (the developer) would know where to go.
Comment your code, explain why it's doing what it's doing and what assumptions have been made.
Try to reduce the amount of mutating state.
Try to remove any singletons you may have.
A co worker of mine asked me to review some of my code and he sent me a diff file. I'm not new to diffs or version control in general but the diff file was very difficult to read because of the changes he made. Specifically, he used the "extract method" feature and reordered some methods. Conceptually, very easy to understand but looking at the diff, it was very hard to tell what he had done. It was much easier for me to checkout the previous revision and use Eclipse's "compare" feature, but it was still quite clunky.
Is there any version control system that stores metadata related to refactoring. Of course, it would be IDE and Programming Language specific, but we all use Eclipse and Java! Perhaps there might be some standard on which IDEs and version control implementations can play nicely?
Eclipse can export refactoring history (see 3.2 release notes as well). You could then view the refactoring changes via preview in Eclipse.
I don't know of compare tools that do a good job when the file has been rearranged. In general, this is a bad idea because of this type of problem. All too often people do it to simply meet their own style, which is a bad, bad reason to change code. It can effectively destroy the history, just like reformatting the entire file, and should never be done unless necessary (i.e. it is already a mess and unreadable).
The other problem is that working code will likely get broken because of someones style preferences. If it ain't broken, don't fix it!
I asked a similar question a while ago and never did get a satisfactory answer. I'll be watching your question to see what people come up with.
For your particular situation, it might be best to review the latest version of the file, using the diff as a guide. That's what I have been doing in my situation too.
The Refactoring History feature is new to me, but I like the way it sounds. For a less tool-specific method, I like sending patch files. The person reviewing just applies the patch and reviews the results, and then they can revert to the version in version control when they're done.