Welcome! Thanks for joining our crusade. I know the code isn't great so let me try and clarify some of its structure.
You will find 4 main files in this repository:
ac2git.py
- the main script that contains the pop, diff and deep-hist algorithms.accurev.py
- my python wrapper and extensions for accurev commands.git.py
- my git wrapper because I couldn't figure out how to use an existing one.
Let's start with the accurev CLI wrapper. This file has 3 classes which I use primarily as namespaces, and they are:
obj
- Which prefixes all of the python objects which represent results of the unprefixed commands.raw
- The namespace which exists solely to map python functions and their arguments to accurev commands and command line arguments. The return value of all of these functions is the raw text that was returned by the accurev command.ext
- This namespace contains extensions to the accurev commandline, likedeep_hist()
, which help make getting information out of accurev later simpler.
There are also functions in the global namespace which return objects from the obj
namespace.
For example let us look at the accurev pop
command. To invoke it you can do the following:
import accurev
result = accurev.pop(verSpec="MyStream", location=".", timeSpec="now", isRecursive=True, elementList="*")
if result:
print("Successfully populated latest from MyStream")
else:
print("Error! Failed to populate MyStream!")
The result is an accurev.obj.Pop
object which contains two lists: result.messages
and result.elements
. Each element of the result.messages
list is an accurev.obj.Pop.Message
and each element of the result.elements
list is an accurev.obj.Pop.Element
. You can read their attributes directly and they are loaded from the XML output of an accurev command.
Effectively the pop()
function from earlier is a convenience function that you could have decomposed into its constituents like so:
xmlResult = accurev.raw.pop(verSpec="MyStream", location=".", timeSpec="now", isRecursive=True, elementList="*", isXmlOutput=True)
result = accurev.obj.Pop.fromxmlstring(xmlResult)
if result:
print("Successfully populated latest from MyStream")
else:
print("Error! Failed to populate MyStream!")
In the end the only purpose of the fully specified accurev.obj
namespace, as I call it, is to explicitly state what possible members we might be getting from the accurev XML output.
Note: Accurev doesn't always produce the full output for each object listed and some components of the object may be uninitialized and left as None
. This is dependent on the accurev command that you've run and whether or not it failed to execute.
This script followes a similar format as the accurev.py
script but is a lot simpler and its size is still managable. Both are henious boiler-plate that could have been avoided but were handy in detecting errors in the early code.
This script is the main script that actually performs the conversion. It contains the implementations for all of the algorithms mentioned in the README.md
.
This script contains 2 primary classes,Config
and AccuRev2Git
; an AccuRev2GitMain()
function and a few helper functions.
AccuRev2Git
is a monstrosity that grew over time and I haven't split up yet. If you're looking at the internals of my script I would recommend having a look at the following functions:
AccuRev2GitMain()
- This is the entry point to the script and should be your first point of call. It sets up the command line options, loads the configuration into anac2git.Config
file, creates an instance ofAccuRev2Git
and starts the conversion.AccuRev2Git.Start()
- This is the function that starts the conversion. It ensures a couple of things like that you have logged into accurev and then calls intoAccuRev2Git.ProcessStreams()
.AccuRev2Git.RetrieveStreams()
- Is a very simple function that iterates over the streams specified in the configuration, calls RetrieveStream() for each one and pushes them to any specified remotes.AccuRev2Git.RetrieveStream()
- This is the workhorse that does most of the work in its two related functions RetrieveStreamInfo() and RetrieveStreamData().AccuRev2Git.FindNextChangeTransaction()
- This function finds the next transaction that could have changed/affected the stream that we are processing. It either uses the 'pop', 'diff' or the 'deep-hist' method to do this depending on the user configured option for the method.AccuRev2Git.RetrieveStreamInfo()
- For each transaction returned byFindNextChangeTransaction()
This function executes 3 accurev commands, stores their XML output in 3 files:hist.xml
,streams.xml
anddiff.xml
; and then commits them to therefs/ac2git/<depot_name>/streams/stream_<stream_number>_info
with the transaction number in an easy to parse commit message.AccuRev2Git.RetrieveStreamData()
- For each transaction that was committed to therefs/ac2git/<depot_name>/streams/stream_<stream_number>_info
ref but was not yet committed torefs/ac2git/<depot_name>/streams/stream_<stream_number>_data
it does anaccurev pop
command and commits the contents of the stream at this transaction to therefs/ac2git<depot_name>/streams/stream_<stream_number>_data
.