Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//
// File: tidy.js
//
// JScript file which walks a directory tree removing all read/write files
// from the tree. It will skip over files that are in the current SD
// changelist as well as copying questionable read/write files to the temp
// directory in case they were really needed.
//
// A "questionable" file is any read/write file that is not in an object
// directory (obj, objd) and is not clearly a generated file (such as a lib,
// pdb, etc).
//
// This script assumes the current directory is the root of whatever project
// you want tidied. This limitation can be removed once support for getting
// the local path rather than the depot path of opened files is into SD.
//
// Written by Lyle Corbin, 8/18/99
//
var g_FSObj = new ActiveXObject("Scripting.FileSystemObject"); var g_Shell = new ActiveXObject("WScript.Shell");
var g_fDebug = false; var g_fVerbose = false; var g_fForce = false; var g_folderTemp; var g_cKilledFiles = 0; var g_cMovedFiles = 0; var g_cKilledDirs = 0;
if (WScript.Arguments.length > 0) { var args = WScript.Arguments; var i;
for (i = 0; i < args.length; i++) { switch (args(i).toLowerCase()) { case '/?': case '-?': Usage(); WScript.Quit(0); break;
case '/d': case '-d': g_fDebug = true; break;
case '/v': case '-v': g_fVerbose = true; break;
case '/f': case '-f': g_fForce = true; break; } } }
var tempdir = g_FSObj.GetSpecialFolder(2).Path; // Temp directory
var tempfile = tempdir + '\\' + g_FSObj.GetTempName();
// This limitation of running from the root of an SD client view can be removed
// once support for giving the local paths to opened files is available in SD.
if (!g_FSObj.FileExists('sd.ini')) { WScript.Echo('\nThis script must be run from the root directory of a SD project.\n\t(e.g. d:\\newnt\\base)'); Usage(); WScript.Quit(1); }
if (g_fDebug) { WScript.Echo('\nDebug Mode: no actions will actually be performed!'); }
// First, call Source Depot and get a list of the "opened" files in this
// project.
var iRet = g_Shell.Run('cmd /c sd -s opened > ' + tempfile, 2, true);
if (iRet != 0) { WScript.Echo('Error: SD returned failure code ' + iRet); WScript.Quit(1); }
var file = g_FSObj.OpenTextFile(tempfile, 1, false); // Open for reading only
// Build a list of all the files that we should skip
var aOutFiles = new Array();
while (!file.AtEndOfStream) { line = file.ReadLine(); fields = line.split(' ');
if (fields.length == 0) continue;
switch (fields[0].toLowerCase()) { case 'info:': filename = SDPathToLocalPath(fields[1]);
filename = g_FSObj.GetAbsolutePathName(filename);
// Do a sanity check on our parsing of the SD output file and verify
// that all the files it gave us actually exist (except for files
// marked for deletion).
if (fields[3] != 'delete' && !g_FSObj.FileExists(filename)) { WScript.Echo('Error parsing SD output: file ' + filename + ' marked as open doesnt exist!'); WScript.Quit(1); }
aOutFiles[filename.toLowerCase()] = true;
break;
default: break; } }
file.Close();
if (g_fDebug) { WScript.Echo('Files opened in this project: '); for (i in aOutFiles) { WScript.Echo('\t' + i); } }
g_FSObj.DeleteFile(tempfile);
if (!g_fForce) { // Make sure we have a place to archive old files
var tidyFolder;
tempdir += '\\tidy';
if (!g_FSObj.FolderExists(tempdir)) { tidyFolder = g_FSObj.CreateFolder(tempdir); } else { tidyFolder = g_FSObj.GetFolder(tempdir); }
tempdir += '\\' + g_FSObj.GetFolder('.').Name;
if (!g_FSObj.FolderExists(tempdir)) { g_folderTemp = g_FSObj.CreateFolder(tempdir); } else { g_folderTemp = g_FSObj.GetFolder(tempdir); } }
DeleteReadWriteFiles('.');
if (g_fDebug) { WScript.Echo('\nDebug Mode: no actions were actually performed!'); }
WScript.Echo('\n' + g_cKilledFiles + ' files were deleted.');
if (g_cMovedFiles > 0) { WScript.Echo(g_cMovedFiles + ' files were moved to ' + g_folderTemp.Path); WScript.Echo(' for safekeeping. If a file you need is gone, look there.'); }
WScript.Echo(g_cKilledDirs + ' object directories were deleted.');
WScript.Echo('');
WScript.Quit(0);
// ************************************************************************
function Usage() { WScript.Echo("\nUsage: tidy [/?dvf]\n"); WScript.Echo("\t/? - Show this usage."); WScript.Echo("\t/d - Debug mode (don't delete anything)."); WScript.Echo("\t/v - Verbose mode"); WScript.Echo("\t/f - Don't save files not in an obj dir in %temp%\\tidy\\<projname>"); WScript.Echo(""); }
function SDPathToLocalPath(path) { var re = new RegExp("//depot/main/", "i") var re2 = new RegExp("//depot/main/Root", "i")
var index = path.lastIndexOf('#');
if (index != -1) { path = path.slice(0, index); }
path = path.replace(re2, '.\\');
return path.replace(re, '..\\'); }
function DeleteReadWriteFiles(path) { var sf; var curdir; var aSubFolders = new Array(); var i; var fInObjDir = false;
try { curdir = g_FSObj.GetFolder(path); } catch(ex) { WScript.Echo('Error opening directory ' + path + ': ' + ex.description); return; }
// Are we an object directory? If so, just delete the whole thing.
if ( curdir.Name.toLowerCase() == 'obj' || curdir.Name.toLowerCase() == 'objd' || curdir.Name.toLowerCase() == 'objp') // Any other names?
{ g_cKilledDirs++;
if (g_fVerbose) { WScript.Echo('Delete directory ' + curdir.Path); }
if (!g_fDebug) { try { curdir.Delete();
return; } catch(ex) { // Probably means there are read-only files in this directory.
// Go through subdirs and delete read/write files explicitely
// instead.
//
if (g_fVerbose) { WScript.Echo('Could not delete ' + curdir.Path + ': ' + ex.description); }
fInObjDir = true; } } else { return; } }
// First, collect the list of subfolder names
sf = new Enumerator(curdir.SubFolders); for (; !sf.atEnd(); sf.moveNext()) { aSubFolders[aSubFolders.length] = sf.item().Path; }
// Now, walk the files in this directory and clear out read/write files.
// We save these files in the temp directory (unless force is on)
sf = new Enumerator(curdir.Files); for (; !sf.atEnd(); sf.moveNext()) { // Is this a checked out file we want to skip?
// NOTE - THIS CHECK MUST BE TOTALLY RELIABLE, OR DATA COULD BE LOST!
if (aOutFiles[sf.item().Path.toLowerCase()]) { WScript.Echo('Skipping opened file ' + sf.item().Path + '...'); continue; }
if ((sf.item().Attributes & 0x1F) == 0) // A "normal" file
{ var ext = g_FSObj.GetExtensionName(sf.item().Name).toLowerCase();
if ( g_fForce || fInObjDir || ext == 'lib' // Don't archive files obviously not
|| ext == 'pdb' // user-created.
|| ext == 'bin' || ext == 'res' || ext == 'map' || ext == 'obj' || ext == 'pch') { g_cKilledFiles++;
if (g_fVerbose) { WScript.Echo('Delete file ' + sf.item().Path); }
if (!g_fDebug) { try { sf.item().Delete(); } catch(ex) { WScript.Echo('Could not delete ' + sf.item().Path + ': ' + ex.description); } } } else { g_cMovedFiles++;
var dest = g_folderTemp.Path + '\\' + sf.item().Name;
if (g_fVerbose) { WScript.Echo('Move file ' + sf.item().Path + ' to ' + dest); }
if (!g_fDebug) { try { if (g_FSObj.FileExists(dest)) { g_FSObj.DeleteFile(dest); }
sf.item().Move(dest); } catch(ex) { WScript.Echo('Could not move ' + sf.item().Path + ': ' + ex.description); } } } } }
// Now, recurse into subdirectories
for (i = 0; i < aSubFolders.length; i++) { // Is the subdirectory the root of another SD project (determined by
// the existence of an sd.ini file)? If so, skip it.
// We only check this for directories that are immediate children
// of the starting directory.
if (path != '.' || !g_FSObj.FileExists(aSubFolders[i] + '\\sd.ini')) { DeleteReadWriteFiles(aSubFolders[i]); } else if (g_fVerbose || g_fDebug) { WScript.Echo('Directory ' + aSubFolders[i] + ' is the root of another project! Skipping...'); } } }
|