About yossiz74

Dad, PC gamer, and SCM specialist. Sometimes not in this particular order.

Quick tip: Using Python’s expandvars() with quoted variables on Windows

I recently encountered an elusive bug, which eventually I tracked down to the fact that environment variables are not replaced in a certain string even though it is set by calling os.path.expandvars(original string).

Turns out, the problem is that expandvars() doesn’t expand variables who are enclosed within a string literal. I couldn’t find it documented anywhere but facts are, this is the case.

Small example:

>>> import os
>>> os.environ['VAR1'] = 'Value1'
>>> s1 = "this is '%VAR1%'"
>>> os.path.expandvars(s1)
"this is '%VAR1%'"
>>> s2 = "this is %VAR1%"
>>> os.path.expandvars(s2)
'this is Value1'

It may be a good idea in some cases, but for me it was quite an annoyance.

So, how to overcome this?

Continue reading


Running Python Unit Test in a VSTS/TFS build

Here’s a short explanation how to execute python unit tests during VSTS/TFS builds, without the need of plug-ins. The basic idea is to create a JUnit XML from your test results, and then have it published to the TFS build dashboard.

First, on the relevant build agent(s), install the pytest module. You can use the following command, or your favorite CM tool.

python -m pip install pytest

Next, edit your build definition in TFS, and add two build steps: one (Batch Script) for running py.test to generate a junit XML, and one (Publish Test Results) for publishing the xml to the test results page.
The full command line to run the tests is as follows (in this example, the unittest code is in test_MyApp.py):

python -m py.test --junitxml test-results.xml test_MyApp.py

Here is a sample build definition which includes only those two steps:


Build Steps


Batch Script Settings


Finally, queue the build, and you will able to see the test results in the build page:




InstallShield: Where is the ‘Create New Folder’ button when browsing?

InstallShield users may have noticed that, in all the ‘select folder’ type dialogs, there is no ‘Create New Folder’ button. If the user wants to create one, he can only do it from Windows itself, or (in some dialogs) type it as text. This is because all these dialogs call the SelectDir() function when clicking Browse.

This is of course very inconvenient, I saw several uses complain about it, but the situation remains.

I came up with a solution, inspired by this KB Article (how to browse for files in InstallScript). Basically I created my own version of AskDestPath() dialog, and modified the behavior so when clicking Browse it will call a custom function i wrote, based on Windows API SHBrowseForFolder().

You can find the custom function on my GitHub here.

The only issue I have is that I cannot set the initial folder. This is a known drawback of this specific API function, and there is a known C++ workaround – but it cannot apply to InstallShield since it does not support pointers to functions (it crashes if you try).

ClearCase Windows Quick Tip: Find all symbolic links

Our ClearCase repository make heavy use of ClearCase symbolic links. We began an initiative to get rid of them, since they cause lots of problems – from snapshot view size, to tools not supporting them (e.g. WebPack), and Git migration efforts. See also my previous post on this matter.

The first step, of course, is to find all of them. One may think that cleartool find command will provide this functionality, but it’s lackcing. So we came up with this simple command-line:

cleartool ls -l -r <folder> | findstr /C:"symbolic link"

Folder must be a VOB, or a folder inside a VOB. To iterate on all VOBs, you can run:

for /d %i in (<view root>\*) do @cleartool ls -l -r %i | findstr /C:"symbolic link"

Now, we just need to figure out what to do with all of them…

InstallShield scripting: Create a list of distinct items from a given list

Recently I had a situation when I needed the ability to take a list of strings and eliminate duplicates.

Now, in all modern languages, this is a built-in capability or data structure – set() in Python, Distinct() in C#,  etc.

But InstallScript is too basic for that. Since we need dynamic arrays, all we have to work with is the LIST object. So, after some trial and error, I came up with this piece of code, which is quite efficient; the only downside is that the order of items is not kept – but in my case it didn’t matter.

Continue reading

Atlassian DevOps Event Impressions

Today I attended an event, organized by ManageWare, titled “Bridging the Gap Between Dev & Ops”, focusing on Atlassian’s tools suite. JIRA is a very popular tool here in Israel, so the main theme of the event was to showcase how productivity and collaboration can be increased when integrating JIRA with other tools.

There were quite a few presentation (detailed at the end of the post) on various DevOps-oriented subjects, such as CI/CD pipelines, monitoring and reporting. Nothing revolutionary, but it was nice to see how a good integration between various tools (not just Atlassian ones…) can really make things flow faster and help focus on generating value for the business.

I only wish some of the sessions were longer, there was a lot more to see; unfortunately, due to time constraints, most presenters had to rush through their materials.

And finally we had some fresh Pizza and ice-cold beer 🙂

The presentations:

Continue reading