//Use with SIL version 5.8.0 and above string rootFolder = silEnv("sil.home"); string [] ignoredFolderPrefixes = ".|_|!|examples"; //<-- add folder names or prefixes in order to have them ignored by search string seperator = "/"; //<-- for windows servers change to "\\" string [] vals; string [] nulls; string [] readOnly; function cleanUpList(string [] array) { array = arrayToSet(array); return arraySort(array, false); } //searches for SIL code that is found in validators function searchScripts(string dir) { for(string file in findFiles(dir, ".*")) { //vals check if(fileContains(file, "return false") && fileContains(file, "customfield")) { vals += file; } int fid = fileOpen(file); int [] nullLines; int [] readOnlyLines; //loop through file line by line for(int x=1; x < 500; x++) { try { string text = trim(fileReadLine(fid)); //make sure line isn't commented out if(!startsWith(text, "//")) { //nulls check if(contains(text, " null") || contains(text, " Null")) { nullLines += x; } //readOnly check boolean lineCatch = false; //exclude JQL query strings if possible if(!contains(text, "selectIssues")) { if(matchText(text, "issueType ?= ?(?!=)") != null) { lineCatch = true; } else if(matchText(text, "type ?= ?(?!=)") != null) { lineCatch = true; } else if(matchText(text, "project ?= ?(?!=)") != null) { lineCatch = true; } } //found you! if(lineCatch) { readOnlyLines += x;; } } } catch string err { if(err != "eof") { runnerLog(err); } } } if(size(nullLines) > 0) { nulls += file + " [line(s): " + replace((string) nullLines, "|", ", ") + "]"; } if(size(readOnlyLines) > 0) { readOnly += file + " [line(s): " + replace((string) readOnlyLines, "|", ", ") + "]"; } fileClose(fid); } } //an attempt to make a recursive directory search function getAllDirs(string root) { string [] dirs = findDirectories(root, ".*");; string [] subDirs = dirs; int loopCount = 0; while(size(subDirs) > 0 && loopCount < 100) { string [] temp; for(string sd in subDirs) { boolean systemFolder = false; string [] dirNames = split(replace(sd, seperator, "@"), "@"); for(string name in dirNames) { for(string pre in ignoredFolderPrefixes) { if(startsWith(name, pre)) { systemFolder = true; } } } if(!systemFolder) { temp += findDirectories(sd, ".*"); } } dirs += temp; subDirs = temp; loopCount ++; } return cleanUpList(dirs); } //-----start checking the files----- searchScripts(rootFolder); //loop through all the files found for(string dir in getAllDirs(rootFolder)) { searchScripts(dir); } //make validator output pretty vals = cleanUpList(vals); if(size(vals) > 0) { string list = "Validators to check [" + trim(size(vals)) + "]:\n
    \n"; for(string v in vals) { list += "
  1. " + replace(v, rootFolder + seperator, "") + "
  2. \n"; } list += "

"; list += "For more information about the change see this page in the documentation.

"; runnerLog(list, true); } //make nulls output pretty nulls = cleanUpList(nulls); if(size(nulls) > 0) { string list = "Nulls used as keywords in script: [" + trim(size(nulls)) + "]:\n
    \n"; for(string n in nulls) { list += "
  1. " + replace(n, rootFolder + seperator, "") + "
  2. \n"; } list += "

"; list += "For more information about the change see this page in the documentation.

"; runnerLog(list, true); } //make readOnly output pretty //readOnly = cleanUpList(readOnly); if(size(readOnly) > 0) { string list = "Read only variables used in script: [" + trim(size(readOnly)) + "]:\n
    \n"; for(string n in readOnly) { list += "
  1. " + replace(n, rootFolder + seperator, "") + "
  2. \n"; } list += "

"; list += "For more information about the change see this page in the documentation."; runnerLog(list, true); }