Skip to content

Instantly share code, notes, and snippets.

Last active March 25, 2022 20:17
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Houdini python script for versioning otls/hda
Increments the version of a hda/otl
If no version information is in the filename / definition, it will be added
myAwesomeThing.hda --> myAwesomeThing__1.0.hda (definition is myAwesomeThing::1.0)
namespaces are respected
blah::myAwesomeThing::1.0 --> blah::myAwesomeThing::1.1
== Installation ==
Save this file somewhere in your pythonpath.
invoke it with
import version_hda
want the right click menu?
save the next section (all the xml-ey part, wihtout the quotes) into an OPMenu.xml file somewhere in your HOUDINI_PATH.
more info on that here:
<?xml version="1.0" encoding="UTF-8"?>
<scriptItem id="cg_versionUpHDA">
<label>Version up HDA</label>
node = kwargs["node"]
if node.type().definition() is None:
return False
# this should be after checking the node definition is not None
installPath = hou.expandString('$HFS')
if installPath in node.type().definition().libraryFilePath():
return False
#if not node.matchesCurrentDefinition():
# return False
if node.isInsideLockedHDA() and not node.isEditableInsideLockedHDA():
return False
if hou.hda.safeguardHDAs():
return False
if not node.type().areContentsViewable():
return False
return True
node = kwargs["node"]
import version_hda
def versionUpHda(node):
print node
if node is None:
return None
if node.type().definition() is None:
return None
typeDef = node.type().definition()
if typeDef.libraryFilePath() == 'Embedded':
print 'HDA is embedded. Cannot version up'
return None
reSrch ='(.*)::(\d+)?\.?(\d+).*$', node.type().name())
if reSrch:
base =
maj = int(
min = int(
newMaj = '%s::%d.%d' % (base, maj + 1, 0)
newMin = '%s::%d.%d' % (base, maj, min + 1)
ret = hou.ui.displayMessage("Version major or minor?", buttons=(newMaj, newMin, 'Cancel'))
if ret == 2:
# cancel
if ret == 0:
maj += 1
min = 0
elif ret == 1:
min += 1
maj = 1
min = 0
base = node.type().name()
newVersion = '%s::%d.%d' % (base, maj, min)
newVersionFile = '%s__%d.%d.hda' % (base.replace(':', '_'), maj, min)
newVersionLabel = '%d.%d' % (maj, min)
hdaDir, hdaFile = os.path.split(typeDef.libraryFilePath())
newHdaPath = os.path.join(hdaDir, newVersionFile).replace('\\', '/')
if os.path.isfile(newHdaPath):
if hou.ui.displayMessage("New version exists. Overwrite?\n" + newHdaPath, buttons=('Overwrite', 'Cancel')) == 1:
elif os.path.isdir(newHdaPath):
# H16+ 'expanded' HDAs are directories
if hou.ui.displayMessage("New version exists. Overwrite?\n" + newHdaPath, buttons=('Overwrite', 'Cancel')) == 1:
print 'Saving new version to:', newHdaPath
if node.matchesCurrentDefinition():
typeDef.copyToHDAFile(newHdaPath, new_name=newVersion)
node.changeNodeType(newVersion, keep_network_contents=False)
typeDef.copyToHDAFile(newHdaPath, new_name=newVersion)
node = node.changeNodeType(newVersion, keep_name=True,
return newVersion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment