Learned Number 55
in Version
1 Deep Dive
Lessons Learned in Version Control,
Part 2
Doug Hennig
Control, 6 VFP
Seamlessly Read/Edit/Save numeric
Part 2
data of variable precision
Pradip Acharya
8 VFPX
Continuous Integration with
Doug Hennig Jenkins and Visual FoxPro
Eric Selje
do (_screen.cThorFolder + ;
'Tools\Thor_Tool_Repository_' + ;
ferences in MainForm.scx and sct because they’re
'FoxBin2PrgConvertProjectToText.prg') binary files. In this case, it doesn’t matter whether
run /n0 thg commit we choose Take Local or Take Other since we’re
going to regenerate the two files from MainForm.
Thor_Tool_Repository_FoxBin2PrgConvert- sc2 in a moment.
ProjectToText.prg is the Thor tool FoxBin2PRG
After the update, Peggy uses the hotkey she
installs to convert the binary files in a project to text
assigned to generate binary files from the text files.
files.
When she then edits MainForm.scx, she sees both
To add my tool to Thor, simply copy Thor_ of our changes.
Tool_Convert2PRGAndCommit.prg (included
One of the things you’ll note is that when I
in the downloads for this article) to the Thor\
open the project, I’m prompted to change the home
Tools\My Tools folder of wherever you have Thor
directory. After I push changes and Peggy pulls
installed. Choose Configure from the Thor menu
them, she’s prompted to change the home direc-
and assign a hotkey to this tool if you wish.
tory when she opens the project. This gets a little
It’s important to generate text files for the bina- annoying after a while, so we’ll see how to resolve
ries in the project, add them to version control, this next.
push them to the central repository, and pull them
into all developers’ repositories only when all other What should go in the
changes have been synchronized in all repositories.
Otherwise, merging the changes can be a mess.
repository?
If you look at the list of files in the repository, you’ll
To see this in action, I generate text files for the notice I added everything in the project folder hier-
binaries in the project, add them to the repository, archy, including FXP and EXE files. Is that neces-
and push to the server; Peggy pulls from the server sary or desirable? Not really:
and updates so she has the latest version. Then I
• The larger the repository, the longer it
modify the code in the Click method of the existing
takes to clone, commit, push, pull, etc.
button in the form while Peggy adds another but-
ton to the same form. I commit and push, then she • Even if you don’t change the source
commits, pulls, and merges with her local changes. code, rebuilding a project may regener-
Because we both made changes in the same form, ate FXP and other generated files. As a
there are several merge conflicts that need to be result, it looks like you have to commit
resolved (Figure 1). Tool Resolve handles the differ- and push and other developers have to
ences in MainForm.sc2 but it can’t resolve the dif- pull and merge even though nothing’s
really changed.
FoxRockX™(ISSN-1866-4563)
FoxRockX, FoxTalk 2.0, FoxTalk, Visual Extend and Silverswitch are trademarks of ISYS GmbH. All product
names or services identified throughout this journal are trademarks or registered trademarks of their
respective companies.
Numeric data of Integer and Floating Point types, the limiting values by 2 or even add 1. Instead we
are commonly edited and saved using some have arbitrarily chosen to use the square root of the
derived class based on the Textbox baseclass, then upper limiting value as practical usable range for
setting a Format mask and so on. Integer fields will our xNumeric class and it works out very well.
have no decimal point and floating point fields will The practical limits used for the class are:
have a precision of 2 decimals digits. Now consider
-9.480751908109E-153
the constant Pi which is 3.14 to 2 decimal digits and
9.480751908109E+153
3.1415926536 to 11 decimal digit precision. How
would you like to read in 3.14 from the table field,
type in 3.1415926536, save, and read it back just as The Demo
saved. Chemical, Physical and analytical work or At load time, the Demo Load method creates a tem-
chemical, mathematical or other entities are all of porary cursor with a random file name. When the
variable precision. Example are Hg concentration demo ends. This cursor is closed i.e. Deleted.
in drinking water or engineering tolerances. The As a side discussion, let's talk about creating a
required xNumericbox class and demo program truly random cursor name generation. The RAND()
are outlined in the article. The limiting constraint is function is used for this purpose. This function is
the maximum precision of 14 decimal places in VFP seeded with an initial call in the form RAND(5). If
64-bit double field type on good days. On bad days, you use the same initial seed, the generated num-
it can degrade to 13 decimal places. bers are the same for the same inputargument.
Numeric Data are saved in four types of data For the purpose of this article, we randomize
fields in VFP – I, B and F/N, I for integer, B for the seed which is a combination of a part of Today's
Double floating binary and F/N for 4-byte fixed date and Seconds() of the current time. This creates
decimal point floating point. The method outlined a random file stem which is unlikely to repeat.
here applies only to Double B editing because the Here is the code for random file name genera-
F & N types are permanently stamped with fixed tion:
nFieldwith and nPrecision attributes, and not in ?"_"+ RIGHT(TRANS(DAY(DATE())),3)+;
pure Mantissa and Exponent bit pattern. RIGHT(TRANS(INT(SECONDS())),3)
Since this class does not enforce any fixed An example of such a random name as the file
Format mask, this class is not to be used for han- stem would be _27679.
dling every day Money or Integer or fixed Decimal The demo is in two parts. In the first part, you
fields. will load a preset into the B field value in the cur-
sor, which this case is 3.14 which is the value of Pi
Numeric data Precision Limits two decimal places. Now type in additional digits
The 8 byte D field has a usable precision limit of 14 to the right to make 3.1415926536E0 and click on
decimal digits and a magnitude limit of: save. Reload. You will see the field value of D in
the edit box 3.1415926536E0. If you close the demo
4.940656458413E-324
form and reload, You'll be loading in the initial
8.9884656743114E307
value of 3.14.
52 bits are allocated to the Mantissa and 12 bits are
reserved for the Exponent.
The Demo - Part 2
The limiting numeric range in VFP shown Here we will create an external user table and save
above is only of academic interest. It is of little edited data. Come back, and check the edited value
practical value since you cannot even multiply by reloading the field in the xNumeric box.
This article discusses improving the Software mers did. He started hearing words he didn’t
Development Lifecycle for Visual FoxPro devel- understand, like “Git” when there were no horses
opers. We'll begin by reviewing the typical devel- around, and “Mercurial” when there were no
opment cycle, and show ways to improve and thermometers. He started seeing applications that
automate our current process using a Continuous would automatically update themselves while the
Integration server and open source tools from VFPX user was still running them, and “Nightly Builds”
such as Automated Build, FoxUnit, and source con- dropping onto servers at times when all the devel-
trol tools. opers should long have been home in bed.
When Eric finally discovered the powerful con-
A Typical Day in the Life of a VFP cept of “Continuous Integration,” his mind was
blown. This was a concept that would once again
Programmer change the way he developed forever – if he could
Eric (his name has been changed to protect his get it all to work in Visual FoxPro.
identity) is a typical Visual FoxPro developer. Eric
A True Story
got on board very early with the Fox. He learned
It’s the middle of the night. Your phone rings once,
very quickly in the late 80s that dBase was great twice…on the third ring you pick it up. It’s your boss
but FoxBase was far better. Eric was very excited (or best client, whichever is applicable to you).
to when FoxPro came out, and when Visual Fox-
Groggily you say “Hello?” while hearing a sigh from
Pro 3.0 arrived in 1995, his development careeer
your tossing spouse.”
changed forever.
“Hey!” you hear, causing you to pull the phone two
But in some ways Eric’s Visual FoxPro career inches away from your ear. “All of our nightly reports
hadn’t changed much since. New version of Visual are crashing! Fix it!”
FoxPro arrived regularly (up until recently), but the
Now slightly awake, you see it’s 3 a.m. The reports
basic way he created applications was consistent
just kicked in and immediately failed. You try to get
throughout.
it together enough to recollect what you may have
The Project Manager was always Visual Fox- done that day that would have caused this failure, and
Pro’s command center for development. When you’re actually hoping it was your fault because if it
Eric wanted to work on an application, he’d fire up was another developer then you’re going to have to
Visual FoxPro, open the project in the Project Man- murder someone on your team and then have to go
ager, and do what needed doing. Testing involved through the trouble of finding a replacement.
running the application and verifying it “did what Eventually your synapses recall that one small opti-
it was supposed to do.” Version control meant mization you made to the function that most of the
hopefully remembering to backup the application’s reports use. Yes, that’s it. Easy fix…I’ll just put that
source code directory. Deploying meant building change back. Since your company doesn’t reliably use
an EXE and copying to someplace where the users version control, you’ll hopefully remember what the
could get at it, and likely meant kicking everybody code looked like before and put it back right.
out of the application so the update could be cop- You fire up the laptop, make the change, build it, log
ied. It happened so often the users didn’t think onto your VPN, call the office, wait while everyone is
twice about it, assuming this was just the way it out of the app, and copy the new EXE to the three or
had to be. Eric too thought this was the way all pro- four different places it needs to go for everything to
grammers did it. Perhaps you do too? run smoothly until you get to your desk in… only 3
hours?!
It doesn’t have to be this way.
That “one little fix” took very little time to actually fix
Eric’s slow realization of this truth came when
but quite a bit of time to build and deploy. You hope
he left the insular world of Visual FoxPro devel-
it works, but you’ll find out if it failed when the phone
opment and was exposed to what other program- rings again just as you’re drifting back to sleep.
Commercial Offerings
Team Foundation Server (TFS): This is
Microsoft’s official offering. It’s much
more than just a CI server, it is also the
successor to Visual SourceSafe for ver-
sion control, has a facility for project
task list tracking, and reporting. This is
commonly used in Microsoft-only shops
and, in my experience, rarely used else-
where.
TeamCity: This program from Jet-
Brains, the Resharper folks, is the most
common name I hear when I ask which
Continuous Integration product other
developers are using. It is built to be
language-agnostic so it works well with
.Net, Java, Ruby, etc., and with plug-ins
can be modified to work with Visual
FoxPro as well. While I’ve listed here as
Commercial, it’s actually free for “small Figure 1. The Continuous Integration Cycle
teams.”
March 2017 FoxRockX Page 9
developers are notified, and the cycle starts again. F1Utils.
The question then becomes, to borrow a title from a If you prefer to do version control from the Win-
classic, “Will the Circle Be Unbroken?” dows filesystem, you can use the fine Tortoise tools
for Subversion or Mercurial. Tortoise integrates
Setting up a Continuous right into Windows Explorer. Tortoise doesn’t seri-
alize the binaries for you automatically though, so
Integration Server you will need to be sure to take care of that manu-
To start, let’s set up a CI Server. This can be on your ally using one of the tools mentioned above. SubFox
development machine (which is the way I do it), does have some nice hooks into Tortoise that auto-
a Windows server on your network, or a virtual mates the process.
machine in “the cloud.” It really doesn’t matter
The problem with all of these tools however is
where it’s physically located, but if it’s on your
that invoking the serializer/deserializer is a man-
development machine you are limiting the scale
ual process (SubFox’s hooks do deserialize binaries
to just one developer. If you think there’s a chance
automatically when you check out files from the
you’ll ever involve more than one developer, or
Tortoise interface, so it may have potential to from
you feel more comfortable putting your eggs in dif-
a command line, but this needs further investiga-
ferent baskets, consider putting the CI Server some-
tion into the source code. The other tools could have
where else.
wrappers written that allow them to do it as well.),
You might imagine that a CI service needs to be and with Continuous Integration we need things
running on a powerful server somewhere but this to run automatically. Whichever of those tools you
definitely not the case. It can run on any machine use, some customization will be necessary in order
that has access to the source control as well as any to get them to run from the Windows shell in order
additional tools required to do its job such as the to be integrated into Continuous Integration.
Build tool. It does have to be a Windows machine
For this reason, I recommend that you do check
though, because Visual FoxPro projects are Win-
in the binaries into your version control system
dows-only and require a Windows machine to
along with the serialized version. That way they
build them.
won’t need to be deserialized when you run an
automated build, saving you this manual step.
Step 1: Use Source Control The exception to this rule is the PJX/PJT files:
Version control, while not absolutely necessary, is Do not check those into version control. Automated
preferred because CI servers have the ability to Build, in the next step, will recreate the PJX file
monitor repositories of the most popular types, from the “PJM” file that’s generated. Just be sure to
and usually a source code check-in is the trigger check in your PJM file!
that fires the entire CI process. Hopefully by now
you’ve begun taking advantage of version control!
Even if you don’t work with other developers, you Step 2: Install Automated Build
need to be doing this. This is the utility that takes your source control and
creates an EXE out of it. Visual FoxPro developers
If you don’t have an offline repository yet, just
have always had to do this manually by clicking on
search the web for any number of free/cheap ones.
the Build button in the Project Manager. Now we
In this figure I setup a free repo on ProjectLocker
also have Automated Build, another VFPX tool, to
and joined my test project to it in less than five min-
compile EXEs from the command line.
utes.
Automated Build was written by Markus
Serial Killer Winhard. It’s actually just one PRG, BuildProject.
One quirk of Visual FoxPro is that much of the prg along with a few supporting files. See the full
source code is stored in binary files (actually VFP documentation on VFPX, but the installation is
tables themselves) rather than text files. Binary files basically just copying the files needed to a folder.
are problematic for version control systems because Tip: You might be tempted to create an EXE so
it’s rather difficult to “diff” them. The solution for you run Automated Build without needing a full
VFP developers then as always been to serialize the VFP deployment; However Automated Build uses
table, i.e. turn it into an equivalent ASCII text file. the command BUILD PROJECT, which is unsup-
Projects that have been “Joined to Source Con- ported in the VFP Runtime. You’ll have to copy the
trol” using Visual FoxPro’s built-in functionality minimum files needed to run the full Visual Fox-
automatically get their binaries serialized via the Pro onto your CI server. This means you’ll need a
native SCCText.prg. This is an inferior program fully licensed copy of VFP for your CI server if it’s a
and has long been superseded by any number of separate machine than your development machine.
projects, including VFPX’s SubFox and SCCTextX, If you use CruiseControl.Net as your CI server,
Christof Wollenhaupt’s TwoFox, or Toni Feltman’s Automated Build has sample configuration plug-in
the build from constantly firing every time a new you’d rather just do a build on a regular schedule
submission comes in. In Figure 8 (Advanced Job or create a build manually. If that’s the case just
options) I’ve throttled Jenkins to at most do one select “None” for source control and you can set
build every 10 minutes (6,000 seconds). your development folder as your Workspace. You
By default, the “workspace” for a build is in a will lose a lot of scalability doing things this way,
folder underneath the default Jenkins install folder but it might be all you need.
(e.g. C:\Program Files (x86)\Jenkins\jobs\<project If you checked your binaries (VCX, SCX, FRX,
name>\workspace). You might want it to be etc) into source control as I suggested, you now
somewhere else though, especially on Windows have an extra step: You have to deserialize the
machines so you don’t succumb to the virtualiza- text files back into binaries before you can do the
tion issues that come with writing files under C:\ build because VFP unfortunately can’t build based
Program Files. I prefer creating my workspaces on the serialized version (which is unfortunate
under C:\ProgramData. really, because one would think that internally
it’s reserializing the binaries before it does its
Configuring Your Source Control compilation anyway). There are a variety of ways
The next step is to tell Jenkins where your source to do that depending on how they were serialized
code is checked in (Figure 9). Out of the box (I guess but most would involve writing a wrapper around
that expression doesn’t really apply these days) whichever technique you used to serialize in the
Jenkins supports CVS and Subversion, but there first place. There is a lot of opportunity for some VFPX
are plug-ins for Mercurial, Git, and probably just volunteer work to be done here.
about any other version control system out there.
Note again that linking your CI Server to your Set Up the Build
source control isn’t absolutely necessary. If you The most important step is to actually build the
choose not to link them, you will lose the abil- EXE (or DLL) from our project. That means telling
ity to do a build automatically when source code Jenkins when to build and how to do it. Using the
is checked in. That may not be an issue for you if Build Triggers (Figure 10), you can instruct Jenkins
Figure 11. Build manually anytime by queueing up a build with this button
to poll the Source Control repository if you set one Once you’ve got your Build action described,
up in the previous step, build periodically using go ahead and test it by clicking on the icon to queue
a very flexible syntax, or build after other Jenkins up a build immediately (Figure 11). You should see
projects get successfully built, which is great for the “Last Success” time update automatically and a
projects that are dependent on other projects. pretty sun icon to indicate all is well. Clouds would
You don’t have to schedule the build at all. Any- indicate things aren’t going so well. Clearly the
time you want to build you can fire up the Jenkins developers of Jenkins aren’t goth.
dashboard and click on the “Schedule Build” icon.
That will queue up a build to begin immediately. Failed Builds
If an Automated Build fails, perhaps because of a
Tip: Hover over that icon and look at the address
syntax error or a missing file or anything else that
bar on the bottom of the browser. Because Jenkins
can cause a build to fail, it currently just sits there
is web-based and has a well-written API, you can
and doesn’t exit properly. Markus is aware of this
use that same URL to invoke a build (e.g. http://
problem and we’ve spent some time trying to fig-
(CI_Server):8080/job/(Project)/build?delay=0sec).
ure out quite why it’s happening, but it turns out
Just add a button to your VFP Developer Toolbar
there’s a nice workaround in Jenkins for this so it
(which is very easy if you use Thor) that calls that
doesn’t break things at all.
URL (simple with a RUN /N CURL.exe or either
WestWind IP Stuff or VFP2C32) and you can have If you go back to the root of the dashboard
a build fire at the push of a button. and choose “Manage Jenkins” and then “Manage
Plugins” (or type http://<CIServer>:8080/plugin-
The last step in scheduling a build is telling
Manager/? into your browser’s address bar) you
Jenkins how to do the build (again, Figure 10).
can select from over 300 plug-ins currently avail-
Here we’re using the full version of VFP (because
able for Jenkins. One of them is called the “Jenkins
we need to use the BUILD PROJECT command) to
Build Timeout Plugin” and it’s just what we need.
call automated build (BuildProject.prg). The syntax
Install that plugin to add a new option on the Job
for BuildProject is
Configuration page called Build Environment (Fig-
BuildProject.prg PJMFile [ManifestType, EXE ure 12).
Name]
The plugin is nicely configurable, allowing us
PJMFile is the name of the serialized PJX file to specify an absolute time to abort the build, an
created with either GenPJM or our source control elastic time based on how long previous builds
tool if you’ve joined your project to source control. took, or a “likely stuck” time based on some algo-
ManifestType is either ADMIN or USER to rithms built into the plugin. Here I’ve chosen to say
indicate the execution level (default is USER). “Abort the build if it takes more than 150% of the
time that the last 3 builds took; if there haven’t been
3 builds yet then abort after 2 minutes.”
DOWNLOAD
Subscribers can download FR201703code.zip in the SourceCode sub directory of the document
portal. It contains the following files:
doughennig201703_code.zip
Source code for the article “Lessons Learned in Version Control, Part 2” from Doug Hennig
pradipacharya201703_code.zip
Source code for the article “Seamlessly Read/Edit/Save numeric data of variable precision”
from Pradip Acharya
christofwollenhaupt201703_code.zip
Source code for the article “With abbreviations to success” fromChristof Wollenhaupt
TLAs put into Practice: Object Andy Kramek repeated this over and over in his
sessions about OOP in the 90ties. Many develop-
Oriented Principles in VFP ers have followed this rule, yet, most Visual FoxPro
TDD, OCP, LSP, ISP, DIP, DRY, IoC, LOC, SRP, code violates the Single Responsibility Principle
DbC, CDD, DDD: Our world is filled with three in dramatic ways. SRP applies to the class, not the
letter acronyms that are meant to make our lives method. Let’s look at typical examples:
easier, if only we could remember what each of
Define Class Customer As Custom
them means.
Procedure MoveNext
* moves the record pointer to the next
TLAs explained * customer record
In this article we cover many of the acronyms used EndProc
in object oriented programming, especially in clean
Procedure IsValid
code development. The purpose of this section is
* validates customer data before saving
to act as a reference which you can consult from * them
time to time to refresh some of the principles and EndProc
approaches. You should be able to read each section
Procedure GetInvoices (tnYear)
just by itself.
* Returns a collection of invoice
* objects for the current customer and
* the requested year.
SOLID EndProc
SOLID is neither a principle, nor a three letter
abbreviation. Much like LISA G. in the Visual EndDefine
FoxPro community, SOLID acts as a shortcut for
remembering the order of events during launch- In many frameworks - not just in the Visual
ing a form (Load, Init, Show, Activate, GotFocus). FoxPro world - but also in Java, .NET and other
SOLID’s main purpose is to reinforce some of the languages, business objects act as a dumpster for
more important principles. Those are: about almost everything that is not data related or
• Single Responsibility Principle (SRP) clearly UI. Everything that is loosely related to the
customer or the technical representation of the cus-
• Open-Closed Principle (OCP)
tomer in our application is put into the one single
• Liskov-Substitution Principle (LSP) class called the customer business object.
• Interface Segregation Principle (ISP)
So what’s wrong with that?
• Dependency Inversion Principle (DIP)
Quite a bit, actually.
Certainly I don’t need to point out that the first Can you imagine placing an order on the phone
letter of each principle adds to word SOLID. They and having the operator ask you: Does this order
are important principles, yet not the only impor- exceed your order limit? Probably not. Yet, when
tant ones. Principles such as SoC and DRY play in we model this process in software, we don’t think
the same league as those five. Obviously, Robert C. twice about adding a GetCreditLimit method to
Martin - who came up with the name SOLID - had our customer object. In the real world, we wouldn’t
to pick those that fitted. ask the customer to provide all invoices we have
sent him in the past year. In our software world
SRP - Single Responsibility Principle that’s however often a key function of a customer
To quote Robert C. Martin: business object.
A class should have one, and only one, reason to change. What do a nail and your maintenance budget
A variation of this principle has been known have in common? Both are required to keep your
to the Visual FoxPro community for some time: A house intact. Normally, though, you wouldn’t
method should do one thing and one thing only. think of them as going together.