Tuesday, February 06, 2018

PowerBuilder 2017 R2 New Feature: Subversion (SVN) source control support

PowerBuilder's initial support for version control systems required drivers for specific vendors (e.g., PVCS) and often for specific versions of that vendor's products.  It was not unusual to find that you needed to wait to upgrade your source control product until PowerBuilder released an updated driver for it.  And if your source control provider wasn't supported by PowerBuilder you were simply out of luck.





That changed with PowerBuilder 6.  With that release, PowerBuilder abandoned the vendor specific drivers in favor of the recently introduced Microsoft Source Code Control Interface (MSSCCI).  Essentially an ODBC for version control, it freed the IDE from vendor lock-in.  Provide the source control provide provides an MSSCCI complaint interface, or there was a 'bridge' product available that could convert MSSCCI calls into the source control providers native API calls, PowerBuilder could use the product.

That worked well for some time.  However, the source control landscape has changed significantly since then.  In particular, open source version control systems dominate the market now, primarily Subversion (SVN) and Git.  Fortunately for PowerBuilder users, there are 'bridge' products out there for those source control systems, but they have some limitations or are not well supported.

In order to address those issues, Appeon introduced native support for Subversion and Git in PowerBuilder 2017 R2.  We're going to look at using the new Subversion support in this article.

Setting up Subversion

For this demo I'm going to use VisualSVN for the Subversion server.  I like that particular product because it provides a GUI server manager, saving me from having to manage the server via command prompt.

Also, because the PowerBuilder IDE currently doesn't support a full set of the SVN options (e.g., show log, repo browser, etc.) I'm going to install TortoiseSVN in order to use those features.  Once again I could use the subversion command line client to do this, but I prefer having the options available to me through a GUI, in this case Windows Explorer.

Creating a Repository

Using the VisualSVN Admin tool, just right click on the Repositories and select "Create New Repository..."


On the first page of the dialog, select the default "Regular FSDS repository" option and click Next.


In the second page of the dialog, give the repository a name and click Next.


In the third page of the dialog, select the non-default "Single project repository" option and click Next.


In the fourth (and last) page of the dialog, select "All Subversion user have Read/Write access" option and click Create.


You'll also need to create a user account.  Right click on Users and select "Create User..."


In the dialog that appears, enter the user name, the password and then confirm the password.


This is just for demo purposes.  In actual practice you might want to consider using the Windows Authentication capability of Visual SVN instead for user authentication.


Go back to the the repository you created, right click on it in the admin tool and select the "Copy URL to Clipboard" option.


Add the PowerBuilder Project to the Subversion Repository

With Subversion we're going to take a different approach to connecting the PowerBuilder workspace to the source control than we have in the past with MSSCCI based interfaces.  Instead of going to workspace properties and selecting the Source Control tab, we're going to right click on the workspace and select the "Add to Source Control..." option.



That brings up a dialog in which you can select either Subversion (SVN) or Git.  Select Subversion (SVN) and then click OK.


In the next dialog, past in the SVN repository URL you copied when you created the repository.  Also provide your user ID and password for the subversion server.


On the next dialog simply click OK.


Now let's examine what PowerBuilder did in the VisualSVN admin tool:


If you're familiar with how source control worked from PowerBuilder using MSSCCI you'll note a couple of significant differences in how it's handled under Subversion.

1.  Instead of extracting the source code for the PowerBuilder objects into the same directory as the PBLs and then checking them in from there, PowerBuilder created a ws_objects folder (I assume ws stands for workspace), created a folder for each PBL underneath that then exported the source from each PBL into it's respective folder.  With MSSCCI based source control it was standard practice to put each PBL into a different directory to ensure there were no collisions if two objects in two different PBLs happened to have the same name.  When Subversion is used for source control, PowerBuilder handles that for us and we can leave the main PBLs all the in same folder.

2.  Under MSSCCI, only the target file and the exported source code was checked into source control.  This was a problem when you a developer needed to get connected to a new (to them) project.  Since the PBLs weren't checked into source control the developer would either need to get a set of PBLs from another developer or create the PBLs from the checked out source.  Under Subversion PowerBuilder checks in the workspace file and all the PBLs as well.  As we will see in a minute, that makes it very simple to get started with a new project.

Note that after you're connected to Subversion, Subversion does show up under the Source Control folder in the workspace properties.  This allows you to see and in some cases edit the connection information.


Download the Repository into a New Workspace

In a bit, we're going to emulate two different developers working with the same project, and so we're going to "check-out" the project we just added to source control into a different workspace.  Close the current workspace, and then select File -> Connect to Workspace.

In the dialog that appears we'll give it the same repository URL we used when we added the source code to the repository.  I've created a second user id that I'll be using for the multi-developer emulation later, and I'll use that user id here.  Finally, make sure that the Checkout Directory is a different directory than the directory for the original workspace.


And viola!  We've got the entire workspace, PBLs and all.

Making Source Code Changes

Here's another area where there is a large departure between how source control is handled via MSSCCI and via Subversion.  Under MSSCCI, you needed to check out an object (obtaining a lock on it) before you could make changes to it and save them back to source control.

When Subversion is used for source control, PowerBuilder will mark an object with a check mark when the developer has made changes to an object and they have not committed yet.  With MSSCCII that meant the file was locked.  With Subversion only means the object has been modified from what is in source control.  Other developers are not prohibited from making changes.to the same object.  Let's see what happens when that occurs.

Let's say we go into one workspace and change the background color of a window to red.  Now lets go into the second workspace and change the title of the same window.  Go ahead and commit the change to the title.



Now let's go back to the first workspace and attempt to commit our change there.  It's not quite as obvious as it could be, but the commit fails.  The reason is that the object has been modified in source control since we started editing it.  The output pane shows "Target file is out of date."  That's the indication that we need to do an update to get the already committed change.


So we select SVN Update from the popup menu on the object.  We should see an indication in the output pane that the update was successful.


It also notes however that there was a merge conflict.  If you look at the system treeview, the object in question has a yellow exclamation in front of it now indicating that it's in a merge conflict status.


When a merge conflict happens, Subversion creates a number of different files n the source control folder.  In this case, where we modified an object called w_main, we find the following:
  • w_main.srw - The object with just the second developer's changes
  • w_main.srw.r{oldrev} - The object as it existed in the second developer's workspace before they started editing it.
  • w_main.srw.r{newrev} - The object that was checked in by the first developer.

{oldrev} and {newrev} aren't literal the they're the subversion checkin revision numbers.

At this point, PowerBuilder still won't let us commit the change to the background color.  What we need to first is review the changes and indicate what should be accepted.  That's one of the reasons I recommend installing TortoiseSVN.  Open up Windows Explorer, navigate to the object in question under the ws_objects folder, right click on it and select TortoiseSVN->Edit Conflicts

That will bring up the following editor.  Indicate which changes you want to include in the final object and then hit "Mark as Resolved".


At that point, the files with the {oldrev} and {newrev} file extensions have been deleted.  Go back into the PowerBuilder IDE and do a Refresh on the object that had the conflict.

The icon changes back to a check mark, indicating that we are now free to commit the merged changes.

One problem with reviewing edits in text mode is that the PowerBuilder IDE in some circumstances will modify the order that functions, events, etc. occur in the source code.  Most merge tools, such as the one provided by default in TortoiseSVN, don't handle source code that has had blocks of code moved well.  For example, this is what that merge tool showed when I deleted and added empty functions in an object.


Note that the merge tool doesn't recognize that the first function was dropped, instead it thinks I renamed the method.  Once it makes that mistake, the rest of the file (assuming the functions had code in them) would result in huge, false, merge differences.

Fortunately there are merge tools out there that do handle source code where blocks of code have been moved.  One such example is SemanticMerge.  When run on that same sample, SemanticMerge fully recognized which functions were dropped and which were added.


What was particularly impressive here is that SemanticMerge doesn't have a parser that understand PowerScript.  Instead, it treated it as a simple text file.  However, it also has an external parser API so that end users (you and I) can define a parser that does handle PowerScript and even further improve how it works when doing merges.

Avoiding Merge Conflicts

Because merge conflicts require manual editing of the source code as text, it's best to avoid them completely if possible.

Unlike MSSCCI, PowerBuilder doesn't indicate on a Refresh under Subversion whether or not your local objects are in sync with the source control system.  Therefore, one of the primary things you can do to avoid merge conflicts is ensure that your workspace is update to date with source control by doing an SVN Update before making changes to an object.  Otherwise you may experience a merge conflict just because you based your edit on an out of date object.

Another option is, after making sure the object is up-to-date, obtaining a lock on it.  Like MSSCCI, there is a lock option on the Subversion menu:


However, it isn't implemented yet.  Instead, you'll get this notice indicating how you can lock the file until it is.


So, it's back to TorroiseSVN.  Go back to the object in the ws_objects folder, right click on it, and select TortoiseSVN->Get lock.

After you've locked the file it will display with a lock folder in Windows Explorer, but the PowerBuilder IDE current doesn't display any change, even after a refresh.  If you see a file that displays the lock symbol and want to know who has it locked, you can use the TortoiseSVN->Repro-browser option to see more information about the file.



One interesting feature of Subversion, different from MSSCCI, is that you have the ability to "break" or "steal" locks.


This becomes quite helpful if a developer checks out an object, forgets about it, and leaves for vacation for 2 weeks.  If you need to work on the object while they're gone you can simply break the lock and lock it yourself.  The developer who left on vacation will then have to merge once they're back and ready to commit their changes.

Now lets see what happens when another user attempts to edit the object.  They can, but when they attempt to commit they get this error in the output pane.


It would be better if the second developer knew in advance that another user had already locked the file.  One way to ensure that is to have the developers learn the habit of locking the file before they attempt to make any edits.

One way that would normally ensure they learn that habit is by applying the Subversion svn:needs-lock property on the PowerBuilder objects under source control.  That property automatically marks the source code files as read only unless the developer has a lock on the file.  Unfortunately, PowerBuilder 2017 (at least R2) overwrites the file anyway and allows the user to commit without the lock.

In the event that gets resolved when R3 supports locking, you could even consider automatically applying the property to your PowerBuilder source code.  Prior to Subversion 1.8, the best way to do that was through a pre-commit hook that applied the property as files were commited.  Subversion introduced the svn:auto-prop property, which makes it even simpler.

Summary

The Subversion interface provided in PowerBuilder 2017 R2 eliminates the need to use bridge products through the MSSCCI interface to allow PowerBuilder to use Subversion for source control.  Because it works natively with Subversion rather that going through a bridge, it is faster and eventually will provide more complete Subversion support.  Subversion though does bring a bit more complexity to the development experience, particularly dealing with merge conflicts.

No comments: