Table of Contents
Files form the raw ingredients of a software sytem – source files, build files, configuration files, resource files, scripts and so on. These files are typically organised into directories.
As the system develops, this directory structure must develop with it: maybe an extra level of hierarchy needs adding to accommodate a new revision of an operating system; maybe third party libraries need gathering into a single place; maybe we are porting to a platform which imposes some restriction on file names; or maybe the name originally chosen for a directory has simply become misleading.
This article describes the development of a simple Python script to facilitate relocating a source tree. It is as much – if not more – about getting started with Python as it is about solving the particular problem used as an example.
Let's suppose that we have a directory structure we wish to modify. This existing structure has been reviewed and the decision has been taken to re-map source directories as follows:
From A | To B |
---|---|
png |
graphics/thirdparty/png |
jpeg |
graphics/thirdparty/jpeg |
bitmap |
graphics/common/bitmap |
UserIF |
ui |
UserIF/Wgts |
ui/widgets |
os |
platform/os |
os/hpux |
platform/os/hpux10 |
By re-mapped, I mean that the directory and its contents should be recursively moved to the new location. So, for example:
UserIF/Wgts/buttons/switchbutton.cpp
is relocated to:
ui/widgets/buttons/switchbutton.cpp
Although it's straightforward create a new top-level directory and copy existing directories to their new locations, the problem we then face is that our source files will no longer build because the files they include have moved. In fact, some of the build files themselves need adjusting, since they too reference moving targets.
In outline, our script will implement a two-pass algorithm:
The actual processing for a file in the second pass depends on the type of the file. We can simply copy a bitmap, for example, to its new home, but when relocating a C/C++ source file we'll need to be more careful. This is why I've chosen a two-pass solution: when updating internal file references, I prefer look-up to recalculation.