Skip to content

Commit

Permalink
Improve script usage commands to successfully determine usage of scri…
Browse files Browse the repository at this point in the history
…pts in other scripts
  • Loading branch information
phalestrivir committed Sep 20, 2024
1 parent e44a68a commit a2e5893
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 22 deletions.
72 changes: 62 additions & 10 deletions src/ops/ScriptOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const {
getFilePath,
getWorkingDirectory,
saveToFile,
decodeBase64,
} = frodo.utils;
const {
readScript,
Expand All @@ -52,6 +53,10 @@ const {

const langMap = { JAVASCRIPT: 'JavaScript', GROOVY: 'Groovy' };

type SeparatedScripts = {
realm: Record<string, { script: Record<string, ScriptSkeleton> }>;
};

/**
* Get a one-line description of the script object
* @param {ScriptSkeleton} scriptObj script object to describe
Expand Down Expand Up @@ -128,6 +133,7 @@ export async function listScripts(
return true;
}
let fullExport: FullExportInterface = null;
let scriptExport: SeparatedScripts = null;
const headers = long
? ['Name', 'UUID', 'Language', 'Context', 'Description']
: ['Name'];
Expand All @@ -138,10 +144,7 @@ export async function listScripts(
printError(error);
return false;
}
//Delete scripts from full export so they aren't mistakenly used for determining usage
for (const realmExport of Object.values(fullExport.realm)) {
delete realmExport.script;
}
scriptExport = separateScriptsFromFullExport(fullExport);
headers.push('Used');
}
const table = createTable(headers);
Expand All @@ -156,7 +159,9 @@ export async function listScripts(
]
: [wordwrap(script.name, 25, ' ')];
if (usage) {
const locations = getIdLocations(fullExport, script._id, false);
const locations = getIdLocations(fullExport, script._id, false).concat(
getScriptLocations(scriptExport, script.name)
);
values.push(
locations.length > 0
? `${'yes'['brightGreen']} (${locations.length === 1 ? `at` : `${locations.length} uses, including:`} ${locations[0]})`
Expand Down Expand Up @@ -205,11 +210,10 @@ export async function describeScript(
if (usage) {
try {
const fullExport = await getFullExportConfig(file);
//Delete scripts from full export so they aren't mistakenly used for determining usage
for (const realmExport of Object.values(fullExport.realm)) {
delete realmExport.script;
}
script.locations = getIdLocations(fullExport, script._id, false);
const scriptExport = separateScriptsFromFullExport(fullExport);
script.locations = getIdLocations(fullExport, script._id, false).concat(
getScriptLocations(scriptExport, script.name)
);
} catch (error) {
stopProgressIndicator(
spinnerId,
Expand Down Expand Up @@ -795,3 +799,51 @@ export async function deleteAllScripts(): Promise<boolean> {
}
return false;
}

/**
* Helper that takes a full export and separates the scripts from it into their own export
* @param {FullExportInterface} fullExport The full export
* @returns {SeparatedScripts} The scripts separated from the fullExport
*/
function separateScriptsFromFullExport(
fullExport: FullExportInterface
): SeparatedScripts {
const scripts = { realm: {} };
for (const [realm, realmExport] of Object.entries(fullExport.realm)) {
if (!scripts.realm[realm]) {
scripts.realm[realm] = {};
}
scripts.realm[realm].script = realmExport.script;
delete realmExport.script;
}
return scripts;
}

/**
* Helper that finds all locations where a script is being used as a library in another script
* @param {SeparatedScripts} configuration The scripts to search
* @param {string} scriptName The name of the script being searched for
*/
function getScriptLocations(
configuration: SeparatedScripts,
scriptName: string
): string[] {
const locations = [];
const regex = new RegExp(`require\\(['|"]${scriptName}['|"]\\)`);
for (const [realm, realmExport] of Object.entries(configuration.realm)) {
for (const scriptData of Object.values(realmExport.script)) {
let scriptString = scriptData.script as string;
if (Array.isArray(scriptData.script)) {
scriptString = scriptData.script.join('\n');
} else if (isBase64Encoded(scriptData.script)) {
scriptString = decodeBase64(scriptData.script);
}
if (regex.test(scriptString)) {
locations.push(
`realm.${realm}.script.${scriptData._id}(name: '${scriptData.name}').script`
);
}
}
}
return locations;
}
Loading

0 comments on commit a2e5893

Please sign in to comment.