Commits

Nathan Durnan committed 057a8fc Merge

Merge with Release 0.1.1

Comments (0)

Files changed (2)

 TimeStampMod.png,1305052883.0
-TimestampMod.py,1312919198.14
+TimestampMod.py,1323983870.97
 TimeStampMod.xmind,1306451621.66
 README.rst,1312921197.45
 .hgignore,1305849292.78
-.hgtags,1312921264.66
-.hgtimestamp,1312921264.67
+.hgtags,1306451758.73
+.hgtimestamp,1323983905.95
 #==============================================================================
 # TimestampMod.py - Automatically save and restore the modification times of files
-# !!!BETA RELEASE!!!
+# Version 0.1.1  --> !!BETA RELEASE!!!
 # Copyright 2011 Nathan Durnan <nedmech@gmail.com>
 #
 # Based on timestamp extension by Friedrich Kastner-Masilko <face@snoopie.at>
 #	recorded and restored during commit, update, revert, etc. operations.
 #
 # Development information:
-#	Mercurial Version:	1.8.3 - 1.9.1 (from TortoiseHg package)
+#	Mercurial Version:	1.8.3 - 2.0.1 (from TortoiseHg package)
 #	Python Version:		2.6.6 (from TortoiseHg package)
-#	TortoiseHg Version: 2.0.4 - 2.1.2
+#	TortoiseHg Version: 2.0.4 - 2.2.1
 #==============================================================================
 # begin Extension Help Text:
 '''Automatically store and retrieve modification times of files.'''
 #==============================================================================
 # Import Modules
 #------------------------------------------------------------------------------
+import sys	#requied for debugging/exception info.
 import os	#required for filesystem access methods.
 import time	#required for time functions.
 from mercurial import localrepo	#required for creating a pseudo-pre-commit hook.
 from mercurial import commands	#required for accessing Mercurial commands.
+from mercurial import scmutil	#required for "match" object in commit wrapper.
 #_ end of imported modules_____________________________________________________
 
 #==============================================================================
 #------------------------------------------------------------------------------
 File_TimestampRecords = '.hgtimestamp'
 TimeStamp_dict = dict()
-List_CommitMatch = []
 #_ end of global objects ______________________________________________________
 
 
 	'''Initialize UI-Level Callback'''
 	ui.debug('* Loading TimestampMod uisetup\n')
 	ui.setconfig("hooks", "post-status.TimestampMod", Hook_Post_Status)
+	ui.setconfig("hooks", "pre-commit.TimestampMod", Hook_Pre_Commit)
+	ui.setconfig("hooks", "pre-merge.TimestampMod", Hook_Pre_Merge)
 #_ end of uisetup _____________________________________________________________
 
 
 #	(v2.0.4).  Ideally, this will be revised to a cleaner method in the future.
 #==============================================================================
 def Wrap_Commit(repo, text="", user=None, date=None, match=None, force=False, editor=False, extra={}):
-	repo.ui.debug('Wrap_Commit accessed!\n')
+	repo.ui.note('Wrap_Commit accessed!\n')
 	#Check for a merge-commit. 
 	#  Don't run timestamp code on merge.
 	if (len(repo.parents()) > 1):
 	else:
 		# Make sure the match object is created.
 		if not match:
-			match = match.always('')
+			repo.ui.debug('Empty match: Must create!\n')
+			match = scmutil.matchall(repo) #match all files if nothing specified.
 		else:
 			pass
 		# End of check for non-existent match object.
-		List_CommitMatch = match.files() + [File_TimestampRecords]
-		timestamp_mod(repo.ui, repo, **dict({'save': True, 'restore': None}))
+		myList_Match = list()
+		myList_Match = match.files() + [File_TimestampRecords]
+		timestamp_mod(repo.ui, repo, **dict({'save': True, 'restore': None, 'match': myList_Match}))
 		# Make sure record file is part of repository and commit. 
-		if not File_TimestampRecords in repo.dirstate:
+		if not (File_TimestampRecords in repo.dirstate):
 			repo.ui.debug('Wrap_Commit: ', File_TimestampRecords, ' not in repo.dirstate  Adding...\n')
 			commands.add(repo.ui, repo, File_TimestampRecords)
 		#end of check for record file in repository.
 		#Update match fileset for use under TortoiseHg.
 		#  TortoiseHg doesn't seem to catch the updated file
 		#  unless it is manually added to the match fileset.
-		if File_TimestampRecords in match.files():
+		if (File_TimestampRecords in match.files()):
 			# Don't need to do anything if record file already in commit.
 			repo.ui.debug('Wrap_Commit: ', File_TimestampRecords, ' already in match\n')
 			pass
 #------------------------------------------------------------------------------
 # Summary: These functions are intended to be triggered by the hooks defined
 #	either by Mercurial or in the configuration files.
-# NOTES: The pre-commit hook is the only one that does not function properly
-#	under the TortoiseHg (v2.0.4) GUI.  All the hooks work from command-line.
+# NOTES: The pre-** hooks are the only ones that does not function properly
+#	under the TortoiseHg GUI.  All the hooks work from command-line.
 #==============================================================================
 def Hook_Pre_Commit(repo, **kwargs):
+	repo.ui.note("Pre-Commit Hook accessed!\n")
+	repo.ui.debug(kwargs, "\n")
 	timestamp_mod(repo.ui, repo, **dict({'save': True, 'restore': None}))
 	kwargs['pats'].append(File_TimestampRecords)
 
 def Hook_Post_Status(repo, **kwargs):
 	timestamp_mod(repo.ui, repo, **dict({'save': None, 'restore': None}))
 
+def Hook_Pre_Merge(repo, **kwargs):
+	repo.ui.note("Pre-Merge Hook accessed!\n")
+	repo.ui.debug(kwargs, "\n")
+
 def Hook_Update(repo, **kwargs):
+	repo.ui.note("Update Hook accessed!\n")
 	timestamp_mod(repo.ui, repo, **dict({'save': None, 'restore': True}))
 #_ end of Hook Functions ______________________________________________________
 
 # Summary: save or restore file modification times.
 #
 #==============================================================================
-def timestamp_mod(ui, repo, **opts):
+def timestamp_mod(ui, repo, **kwargs):
 	'''Save or restore file modification times.'''
 	ui.note("Executing timestamp_mod function\n")
-	
 	# Retrieve Repository file list contents.
 	myChangedList = list()
 	myDroppedList = list()
-	myChangedList, myDroppedList = _get_RepoFileList(repo)
-	
+	myMatchList = list()
+	if ('match' in kwargs):
+		ui.note("-----\nmatch: ", str(kwargs['match']), "\n")
+		myMatchList = kwargs['match']
+	else:
+		ui.note("-----\nmatch argument not specified\n")
+	# end of check for match argument'''
+	myChangedList, myDroppedList = _get_RepoFileList(repo, myMatchList, TimeStamp_dict)
 	# Retrieve existing timestamps from the record file.
-	myRet = _read_TimestampRecords(repo)
+	myRet = _read_TimestampRecords(repo, File_TimestampRecords, TimeStamp_dict)
 	
 	# Check for command optional argument
-	if opts['save']:
-		_save_Timestamps(repo, myChangedList)
+	if kwargs['save']:
+		_save_Timestamps(repo, File_TimestampRecords, myChangedList, TimeStamp_dict)
 	elif myRet:	# Only evaluate Restore or Display if file was read.
-		if opts['restore']:
-			_restore_Timestamps(repo)
+		if kwargs['restore']:
+			_restore_Timestamps(repo, TimeStamp_dict)
 		else:
-			_display_Timestamps(repo)
+			_display_Timestamps(repo, TimeStamp_dict)
 		# end of check options (Restore/Display)
 	else:
 		repo.ui.warn('Timestamp_Mod can not continue without ', File_TimestampRecords, ' file! \n')
 #_ end of timestamp_mod _______________________________________________________
 
 
-
 #==============================================================================
 # Command Table Definition
 #------------------------------------------------------------------------------
 #------------------------------------------------------------------------------
 # Summary: Return a UTC timestamp value for the specified file's modified time.
 #==============================================================================
-def _get_fileModTime(repo, myFileName):
+def _get_fileModTime(repo, IN_FileName):
 	'''Retrieve the Modification Timestamp for the specified file.'''
 	repo.ui.debug('get_mtime: ')
-	myFilePath = repo.wjoin(myFileName)
+	myFilePath = repo.wjoin(IN_FileName)
 	try:
 		myModTime = float(os.stat(myFilePath).st_mtime)
-		repo.ui.note(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(myModTime)), " \t", myFileName, "\n")
+		repo.ui.note(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(myModTime)), " \t", IN_FileName, "\n")
 		return myModTime
 	except:
-		repo.ui.warn('*** File stat failed for ', myFileName, '!\n')
+		repo.ui.warn('*** Get File Stat failed for ', IN_FileName, '!\n')
+		repo.ui.warn('*** Exception: ', str(sys.exc_info()), '  ***\n')
 		return -1
 	# end of file stat access.
 #_ end of _get_fileModTime ____________________________________________________
 #------------------------------------------------------------------------------
 # Summary: Set the UTC timestamp value for the specified file's modified time.
 #==============================================================================
-def _set_fileModTime(repo, myFileName, myModTime):
+def _set_fileModTime(repo, IN_FileName, IN_ModTime):
 	'''Assign the Modification Timestamp for the specified file.'''
 	repo.ui.debug('set_mtime: ')
-	myFilePath = repo.wjoin(myFileName)
+	myFilePath = repo.wjoin(IN_FileName)
 	try:
 		myFileStat = os.stat(myFilePath)
-		os.utime(myFilePath, (myFileStat.st_atime, type(myFileStat.st_mtime)(myModTime)))
-		repo.ui.note(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(myModTime)), " \t", myFileName, "\n")
+		os.utime(myFilePath, (myFileStat.st_atime, type(myFileStat.st_mtime)(IN_ModTime)))
+		repo.ui.note(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(IN_ModTime)), " \t", IN_FileName, "\n")
 	except:
-		repo.ui.warn('*** File stat failed for ', myFileName, '! ***\n')
+		repo.ui.warn('*** Set File Stat failed for ', IN_FileName, '! ***\n')
+		repo.ui.warn('*** Exception: ', str(sys.exc_info()), '  ***\n')
 	# end of file stat access.
 #_ end of _set_fileModTime ____________________________________________________
 
 # NOTE: This function will CLEAR the contents of the global dictionary collection
 #	and rebuild it from scratch.
 #==============================================================================
-def _get_RepoFileList(repo):
+def _get_RepoFileList(repo, IN_ListMatch, OUT_TimeStamp_dict):
 	'''Build lists of files from the repository status contents.'''
 	repo.ui.debug('______\nGenerating file list from repo...\n------\n')
 	# Establish category lists from repository status.
 	modified, added, removed, deleted, unknown, ignored, clean = repo.status(ignored=True, clean=True, unknown=True)
-	myChanged = List_CommitMatch + modified + added
+	myChanged = IN_ListMatch + modified + added
 	myDropped = removed + deleted
 	myFiles = myChanged + clean
 	# Rebuild global dictionary collection
-	TimeStamp_dict.clear() # Be sure to start with a clean collection.
+	OUT_TimeStamp_dict.clear() # Be sure to start with a clean collection.
 	for myFile in myFiles:
 		myFileName = str(myFile).strip()
-		TimeStamp_dict[myFileName] = -1	# initialize dictionary entry
+		OUT_TimeStamp_dict[myFileName] = -1	# initialize dictionary entry
 		repo.ui.debug('Tracking:  ', myFileName, '\n')
 	# end of loop through repo files.
 	myReturnList = myChanged, myDropped
 #	timestamps to their corresponding entries in the global file dictionary
 #	collection object.
 #==============================================================================
-def _read_TimestampRecords(repo):
+def _read_TimestampRecords(repo, IN_TimestampFileName, INOUT_TimeStamp_dict):
 	'''Read data from Timestamp Record File.'''
 	myTimeStampRecordsFile = ''
 	try:
-		myTimeStampRecordsFile = file(repo.wjoin(File_TimestampRecords), 'r')
+		myTimeStampRecordsFile = open(repo.wjoin(IN_TimestampFileName), 'r')
 		repo.ui.debug('______\nRetrieveing timestamps from record file:\n------\n')
 		for myLine in myTimeStampRecordsFile.readlines():
 			# Read the data from the line. (CSV format: [FileName],[ModificationTime])
 			try:
 				myFileName, myModTime = myLine.strip().split(',')
-				if myFileName in TimeStamp_dict:
-					TimeStamp_dict[myFileName] = float(myModTime)
+				if myFileName in INOUT_TimeStamp_dict:
+					INOUT_TimeStamp_dict[myFileName] = float(myModTime)
 					repo.ui.debug('UTC: ', myModTime, '\t: ', myFileName, '\n')
 				# end of check file exists in dictionary.
 			except:
 		myTimeStampRecordsFile.close()
 		return True 	# Set return flag as successful.
 	except:
-		repo.ui.warn('*** Error accessing ', File_TimestampRecords, ' file! ***\n')
+		repo.ui.warn('*** Error accessing ', IN_TimestampFileName, ' file! ***\n')
+		repo.ui.warn('*** Exception: ', str(sys.exc_info()), '  ***\n')
 		return False	# Make sure return flag is not set.
 	# end of accessing record file.
 #_ end of _read_TimestampRecords ______________________________________________
 #	for timestamps will be retrieved for files that have changed or are missing
 #	timestamp records in the first place.
 #==============================================================================
-def _save_Timestamps(repo, myChangedList):
+def _save_Timestamps(repo, IN_TimestampFileName, IN_ChangedList, INOUT_TimeStamp_dict):
 	'''Save File Modification Timestamps to record file.'''
 	repo.ui.note('______\nSaving timestamps...\n------\n')
-	myTimeStampRecordsFile = file(repo.wjoin(File_TimestampRecords), 'w')
+	myTimeStampRecordsFile = open(repo.wjoin(IN_TimestampFileName), 'w')
 	# Remove the record file from the list to loop through.
 	#	It will be updated separately at the end.
-	if File_TimestampRecords in TimeStamp_dict:
-		del TimeStamp_dict[File_TimestampRecords]
+	if IN_TimestampFileName in INOUT_TimeStamp_dict:
+		del INOUT_TimeStamp_dict[IN_TimestampFileName]
 	# end of check for record file.
-	for s_fileName, f_fileModTime in TimeStamp_dict.items():
-		if (s_fileName in myChangedList) or (f_fileModTime<=0):
-			f_fileModTime = TimeStamp_dict[s_fileName] = _get_fileModTime(repo, s_fileName)
+	for s_fileName, f_fileModTime in INOUT_TimeStamp_dict.items():
+		if (s_fileName in IN_ChangedList) or (f_fileModTime<=0):
+			f_fileModTime = INOUT_TimeStamp_dict[s_fileName] = _get_fileModTime(repo, s_fileName)
 		# end of update timestamps for changed items or missing timestamps.
 		myTimeStampRecordsFile.write("%s,%s\n" % (s_fileName, f_fileModTime))
 	# end of loop through dictionary items.
 	# Update the record file timestamp last with the current time.
-	f_fileModTime = TimeStamp_dict[File_TimestampRecords] = time.time()
-	myTimeStampRecordsFile.write("%s,%s\n" % (File_TimestampRecords, f_fileModTime))
+	f_fileModTime = INOUT_TimeStamp_dict[IN_TimestampFileName] = time.time()
+	myTimeStampRecordsFile.write("%s,%s\n" % (IN_TimestampFileName, f_fileModTime))
 	# Make sure to close the file!
 	myTimeStampRecordsFile.close()
 #_ end of _save_Timestamps ____________________________________________________
 # NOTE: This presumes that the dictionary has been initialized and the original
 #	timestamp data has already been read into the dictionary.
 #==============================================================================
-def _restore_Timestamps(repo):
+def _restore_Timestamps(repo, IN_TimeStamp_dict):
 	'''Restore File Modification Timestamps from record file.'''
 	repo.ui.note('______\nRestoring timestamps...\n------\n')
-	for s_fileName, f_fileModTime in TimeStamp_dict.items():
+	for s_fileName, f_fileModTime in IN_TimeStamp_dict.items():
 		# Check for valid timestamp.
 		if (f_fileModTime>0):
 			# Valid timestamp detected!
 # NOTE: This presumes that the dictionary has been initialized and the original
 #	timestamp data has already been read into the dictionary.
 #==============================================================================
-def _display_Timestamps(repo):
+def _display_Timestamps(repo, myTimeStamp_dict):
 	'''Display File Timestamps currently recorded.'''
 	repo.ui.note('______\nDisplaying timestamps...\n------\n')
-	for s_fileName, f_fileModTime in TimeStamp_dict.items():
+	for s_fileName, f_fileModTime in myTimeStamp_dict.items():
 		# Check for valid timestamp
 		if (f_fileModTime>0):
 			# Valid timestamp detected!