One of the top 10 most voted Visual Basic 6 questions on Stack Overflow is this one: Stop Visual Basic 6 from changing my casing.
It's a problem that seems to affect a lot of people around the world. Well, not so much... after all, interest in this language is decreasing and it seems to be the most currently hated one. It makes sense, since Microsoft abandoned support for the IDE in 2008.
The version control system we use at Premium Minds is Git. For some time, we didn't really pay any special attention to the capitalization in our VB6 application. We had implemented code review procedures, but the commit noise created by this IDE behavior caused a major high-impact bug to make it through the review unnoticed.
The solutions proposed on that Stack Overflow question never seemed practical to me: create a dummy class or hide code with compiler directives.
Our solution is the adoption of a tool and some team discipline.
The tool is a script that compares the files on disk with the ones from the previous commit, creates a diff that ignores case changes and applies the resulting patch.
The team discipline is simply to invoke this script before each commit and reject any code review where the script did not run.
The content of the script is as follows:
cat git_ignore_case.sh
#!/bin/bash
set -e
#forms, classes and modules
for file in $(git status --porcelain | grep -E "^.{1}M" | grep -E -v "^R" | cut -c 4-| grep -e "\.frm" -e "\.bas" -e "\.cls" -e "\.Dsr"); do
ORIGFILE=$(mktemp)
PATCHFILE=$(mktemp)
git cat-file -p :$file > $ORIGFILE
diff -i --strip-trailing-cr $ORIGFILE $file > $PATCHFILE || true
patch -s $ORIGFILE < $PATCHFILE
cp $ORIGFILE $file
rm $ORIGFILE $PATCHFILE
unix2dos --quiet $file
done
#projects
for file in $(git status --porcelain | cut -c 4-| grep -e "\.vbp$"); do
echo $file
ORIGFILE=$(mktemp)
PATCHFILE=$(mktemp)
PROCESSEDFILE=$(mktemp)
echo $file $ORIGFILE $PATCHFILE $PROCESSEDFILE
git cat-file -p :$file > $ORIGFILE
cat $ORIGFILE | cut -d "#" -f 1-3 > $PROCESSEDFILE
diff -i --strip-trailing-cr $PROCESSEDFILE <(cat $file| cut -d "#" -f 1-3) > $PATCHFILE || true
patch -s $ORIGFILE < $PATCHFILE
cp $ORIGFILE $file
unix2dos --quiet $file
done
To illustrate the problem, imagine this event handler for button Command1
:
Private Sub Command1_Click()
Dim str As String
str = "Hello World!"
MsgBox str
End Sub
Let's add the files to git and commit:
git add Form1.frm Project1.vbp
git commit -m "first commit"
Now, we add a Command2
button with the following event handler:
Private Sub Command2_Click()
Dim Str As String
Str = "Hello World!"
MsgBox Str
End Sub
Note that we used Str
instead of str
, this time. If we look at the differences at this time, we have:
git diff Form1.frm
diff --git a/Form1.frm b/Form1.frm
index a77250e..f8563ce 100644
--- a/Form1.frm
+++ b/Form1.frm
@@ -44,7 +44,14 @@ Attribute VB_Exposed = False
Option Explicit
Private Sub Command1_Click()
- Dim str As String
- str = "Hello World!"
- MsgBox str
+ Dim Str As String
+ Str = "Hello World!"
+ MsgBox Str
End Sub
+
+Private Sub Command2_Click()
+ Dim Str As String
+ Str = "Hello World!"
+ MsgBox Str
+End Sub
+
The VB6 IDE altered Command1_Click
, which was not our intention, and as far as it is known, there is no option to turn this behavior off.
If we apply our script:
./git_ignore_case.sh
Evaluating our differences again:
git diff Form1.frm
diff --git a/Form1.frm b/Form1.frm
index a77250e..5abbb5d 100644
--- a/Form1.frm
+++ b/Form1.frm
@@ -48,3 +48,10 @@ Private Sub Command1_Click()
str = "Hello World!"
MsgBox str
End Sub
+
+Private Sub Command2_Click()
+ Dim Str As String
+ Str = "Hello World!"
+ MsgBox Str
+End Sub
+
We have only the changes we performed.
The script is not infalible, there are some scenarios where it fails, but it is the best solution to this problem I know of to this day.
Commits are cleaner, code reviews are smoother and the bugs caused by this IDE behavior have decreased or disappeared altogether.