Show differences in two directory trees in TextWrangler

Hello

This is handy at times! :slight_smile:


-- The Idea and implementation and any faults is totally mine. © McUsr 2010 and put in the Public Domain.
-- The usually guarrantees about nothing what so ever applies, use it at your own risk.
-- Read the documentation.
-- You are not allowed to post this code elsewhere, but may of course refer to the post at macscripter.net.
-- http://macscripter.net/edit.php?id=153570
(*
TERMS OF USE. 
This applies only to posting code, as long as you don't post it on other websites, or displays it (the code) on your own, you are welcome to do
whatever you want to do with it without any further permission. 
Except for the following: Selling the code as is, or removing copyright statmentents and the embedded link in the code (without the http:// part) from the code. 
I don't require you to keep this whole novel, but you must keep the link which refers to where it was originally posted. And my copyright.
You must also state what you eventually have done with the original source. This obviously doesn't matter if you distribute AppleScript as read only. I do not require you to embed any properties helding copyright notice for the code when you distribute as read only.

Credit for having contributed to your product would in all cases be nice!

If you use this code as part of script of yours you are of course welcome to post that code with my code in it here at macscripter.net. If you then wish to post your code elsewhere after having uploaded it to MacScripter.net please email me and ask for permission.

The ideal situation is however that you then refer to your code by a link to MacScripter.net
The sole reason for this, is that it is so much better for all of us to have a centralized codebase which are updated, than having to roam the net to find any usable snippets. Which some of us probabaly originated in the first hand.

I'm picky about this. If I find you to have published parts of my code on any other site without previous permission, I'll do what I can to have the site remove the code, ban you, and sue you under the jurisdiction of AGDER LAGMANNSRETT of Norway. Those are the terms you silently agree too by using this code. 

The above paragraphs are also valid if you violate any of my terms.

If you use this or have advantage of this code in a professional setting, where professional setting means that you use this code to earn money by keeping yourself more productive. Or if you as an employee share the resulting script with other coworkers, enhancing the productivity of your company, then a modest donation to MacScripter.net would be appreciated.

*)
-- © McUsr 2012 and put in Public Domain see: macscripter.net/viewtopic.php?id=33758 for reference and terms of use.
property scriptTitle : "TW Folder Diff"
on run
	set infoIcon to a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertNoteIcon.icns")
	set idOfFrontApp to getfrontAppId()
	
	tell application "Finder"
		activate
		set theSel to (get selection)
		
		set selCount to count theSel
		
		if selCount is 2 then
			set {fileA, fileB} to {item 1 of theSel, item 2 of theSel}
		else
			if selCount is greater than 3 then my errMsg()
			
			if (count its windows) is 1 or selCount is 0 then my errMsg()

			set fileA to item 1 of theSel
			if class of fileA is not folder then my errMsg()
			set fw1 to id of its Finder window 1
			tell its Finder window 2 to activate
			
			set theSel to (get selection) -- of Finder window 1
			
			set selCount to count theSel
			if selCount ≠ 1 then my errMsg()
			set fileB to item 1 of theSel
			if class of fileB is not folder then my errMsg()
			tell Finder window id fw1 to activate
			if contents of fileB is equal to contents of fileA then my errMsg()
		end if
		set theAfile to fileA as alias as text
		set theBfile to fileB as alias as text
	end tell
	-- we got two folders
	set shortNm to name of fileA
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
	set shortNm to text item 1 of shortNm
	set AppleScript's text item delimiters to ""
	set shortNm to shortNm as text
	
	
	set theDir to do shell script "/usr/bin/mktemp -d -t " & quoted form of shortNm
	
	set tempFn1 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt(theAfile))
	set tempFn2 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt(theBfile))
	
	try
		do shell script "cd " & quoted form of POSIX path of (fileA as alias) & " ; ls -lRc |grep -v total |grep -v \"^$\" >" & tempFn1
	end try
	
	try
		do shell script "cd " & quoted form of POSIX path of (fileB as alias) & " ; ls -lRc |grep -v total |grep -v \"^$\" >" & tempFn2
	end try
	
	set raised to false
	try
		set res to (do shell script "diff  " & tempFn1 & " " & tempFn2 & " >/dev/null")
	on error e number n
		set raised to true
	end try
	
	if not raised then
		alertDialog({aTextMessage:("The folders: " & return & (text 1 thru -2 of (POSIX path of theAfile)) & return & "and" & return & (text 1 thru -2 of (POSIX path of theBfile)) & return & "are alike!"), aTextTitle:my scriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
		abortNicely({bundleIdFrontApp:idOfFrontApp})
	else
		try
			set myres to (do shell script "/usr/bin/twdiff --ignore-spaces " & tempFn1 & " " & tempFn2)
		end try
		
		try
			tell application "TextWrangler"
				activate
			end tell
			
		on error e number n
			alertDialog({aTextMessage:e & " " & n, aTextTitle:my scriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
			abortNicely({bundleIdFrontApp:idOfFrontApp})
		end try
	end if
end run


on errMsg()
	beep
	tell application "SystemUIServer"
		activate
		display dialog "You need to select two and only two two different folders in the frontmost Finder Window or one folder in each of the two frontmost Finder windows in order to run this script.
" with title my scriptTitle buttons {"Ok"} default button 1 with icon file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:Unsupported.icns")
		abortNicely({bundleIdFrontApp:idOfFrontApp})
	end tell
end errMsg

on getfrontAppId() -- Returns bundleid of active app
	local frontappId
	set frontappId to ""
	tell application "System Events"
		set frontappId to bundle identifier of first application process whose frontmost is true
	end tell
	return frontappId
end getfrontAppId

on abortNicely(r) -- Returns Nothing
	
	tell application "System Events" to tell application process id (bundleIdFrontApp of r)
		key down control
		key code 118
		key up control
	end tell
	error number -128
end abortNicely

on alertDialog(r) -- Returns Nothing
	-- R : {aTextMessage:theMessage,aTextTitle:thetitle,timeInSecs:lenToTimeout,btnAsList:theButton,iconAsFileRef:theIcon,bundleIdOfFrontApp:frontappId}
	local res, failed, e, n
	set failed to false
	tell application "SystemUIServer"
		activate
		try
			if (iconAsFileRef of r) is null then
				set res to button returned of (display dialog (aTextMessage of r) with title (aTextTitle of r) giving up after (timeInSecs of r) buttons (btnAsList of r) default button 1)
			else
				set res to button returned of (display dialog (aTextMessage of r) with title (aTextTitle of r) giving up after (timeInSecs of r) buttons (btnAsList of r) default button 1 with icon (iconAsFileRef of r))
			end if
			if res = "" then set failed to true
		on error e number n
			set failed to true
			
		end try
	end tell
	if failed is true then
		abortNicely({bundleIdFrontApp:(bundleIdOfFrontApp of r)}) -- Returns Nothing
	end if
	return
end alertDialog

on createPathDenotingFileNameWitoutExt(hfSfileNameAsText)
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
	-- set hfsFilenameAsText to {""} & text items 2 thru -1 of hfsFilenameAsText
	-- Uses the line above instead of line under if  you want to convert to unix alike filename.
	set hfSfileNameAsText to text items of hfSfileNameAsText
	set AppleScript's text item delimiters to "_"
	set hfSfileNameAsText to hfSfileNameAsText as text
	set AppleScript's text item delimiters to "."
	set hfSfileNameAsText to text item 1 of hfSfileNameAsText as text
	set AppleScript's text item delimiters to tids
	return hfSfileNameAsText
end createPathDenotingFileNameWitoutExt



Edit
The output is now sorted by modification date

The script above is solidfied, and enhanced with errormessages!