Mini Kabibi Habibi
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2023 Adobe Inc.
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Inc. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Inc. and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Inc..
**************************************************************************/
console.time('customhook');
const fs = require('fs-extra');
const path = require('path');
const args = process.argv.slice(2);
const AdobeCommonUXPMac = path.resolve('/', 'Library', 'Application Support', 'Adobe/UXP/extensions');
const AdobeCommonUXPWin = path.resolve('C:/', 'Program Files', 'Common Files', 'Adobe/UXP/extensions');
const isMac = process.platform === 'darwin';
const minimumHsBuildMajor = 3;
const minimumHsBuildMinor = 3;
const maximumHsBuildMajor = 8;
// Below directories are not to be deleted as they have manifest min version changes.
let hsUniqueBuildsIntervals = [
'com.adobe.ccx.start-3.4.2',
'com.adobe.ccx.start-3.6.0',
'com.adobe.ccx.start-3.8.1',
'com.adobe.ccx.start-4.3.1',
'com.adobe.ccx.start-4.4.0',
'com.adobe.ccx.start-5.12.2',
'com.adobe.ccx.start-6.1.0',
'com.adobe.ccx.start-6.7.0',
'com.adobe.ccx.start-6.8.0',
'com.adobe.ccx.start-7.0.0',
'com.adobe.ccx.start-7.1.0',
'com.adobe.ccx.start-7.2.1',
'com.adobe.ccx.start-7.9.1',
];
let hsUniqueBuildsIntervalsFound = new Map();
const directoryPath = isMac ? AdobeCommonUXPMac : AdobeCommonUXPWin;
const regex = /^com\.adobe\.ccx\.start-\d+\.\d+\.\d+$/;
let directoriesToDelete = [];
let directoriesOnMachine = [];
let buildsToKeep = [];
// Function to get the major and minor versions from a directory name
function getVersionParts(directory) {
const [, major, minor, patch] = directory?.match(/com.adobe.ccx.start-(\d+)\.(\d+).(\d+)/);
return { major: parseInt(major), minor: parseInt(minor), patch: parseInt(patch) };
}
// Function to iterate to the new interval based on the current build
function iterateToTheNextHsInterval(buildMajor, buildMinor, hsBuildsIntervalsIndex) {
while (hsBuildsIntervalsIndex < hsUniqueBuildsIntervals.length) {
const { major: intervalMajor, minor: intervalMinor } = getVersionParts(
hsUniqueBuildsIntervals[hsBuildsIntervalsIndex],
);
const notOverflown = hsBuildsIntervalsIndex < hsUniqueBuildsIntervals.length;
const buildMajorIsDistinct = intervalMajor !== undefined && buildMajor !== intervalMajor;
const buildMinorIsBigger = intervalMinor !== undefined && buildMinor > intervalMinor;
if (notOverflown && (buildMajorIsDistinct || buildMinorIsBigger)) {
hsBuildsIntervalsIndex++;
} else {
break;
}
}
return hsBuildsIntervalsIndex;
}
// Iterate between all of the builds and find the ones to keep
findTheBuildsToKeep = () => {
let userBuildsArrayIndex = 0;
let lastValidBuild;
const { major, minor } = getVersionParts(directoriesOnMachine?.[0]);
let hsBuildsIntervalsIndex = iterateToTheNextHsInterval(major, minor, 0);
while (userBuildsArrayIndex < directoriesOnMachine.length) {
const currentBuild = directoriesOnMachine[userBuildsArrayIndex];
const currentInterval = hsUniqueBuildsIntervals[hsBuildsIntervalsIndex];
const { major: currentBuildMajor, minor: currentBuildMinor } = getVersionParts(currentBuild);
const { major: currentIntervalEndMajor, minor: currentIntervalEndMinor } = getVersionParts(currentInterval);
if (hsUniqueBuildsIntervals.includes(currentBuild)) {
buildsToKeep.push(currentBuild);
hsUniqueBuildsIntervalsFound.set(currentBuild, true);
if (lastValidBuild && !hsUniqueBuildsIntervalsFound.get(currentInterval)) {
buildsToKeep.push(lastValidBuild);
hsUniqueBuildsIntervalsFound.set(currentInterval, true);
}
lastValidBuild = null;
hsBuildsIntervalsIndex = iterateToTheNextHsInterval(
currentBuildMajor,
currentBuildMinor,
hsBuildsIntervalsIndex,
);
} else if (currentBuildMajor === currentIntervalEndMajor && currentBuildMinor <= currentIntervalEndMinor) {
lastValidBuild = currentBuild;
} else {
if (lastValidBuild) {
buildsToKeep.push(lastValidBuild);
hsUniqueBuildsIntervalsFound.set(currentInterval, true);
}
lastValidBuild = currentBuild;
hsBuildsIntervalsIndex = iterateToTheNextHsInterval(
currentBuildMajor,
currentBuildMinor,
hsBuildsIntervalsIndex,
);
}
userBuildsArrayIndex++;
}
if (lastValidBuild) {
buildsToKeep.push(lastValidBuild);
}
};
// Thor deletes the cwd after calling this script. Therefore it crashes on mac
// as we do not have a valid working directory.
process.chdir(__dirname);
if (args.includes('removehs')) {
try {
// Read the list of directories
fs.readdir(directoryPath, (err, directories) => {
if (err) throw err;
directories.forEach(directory => {
// Populate a list of directories present on user machine.
// Condition to check if HS extension is directory and is in expected format
if (fs.statSync(directoryPath + '/' + directory).isDirectory() && regex.test(directory)) {
const { major, minor } = getVersionParts(directory);
// Keep all the versions less that 3.3 safe, we add it to directoriesToKeep list.
if (
major < minimumHsBuildMajor ||
(major === minimumHsBuildMajor && minor <= minimumHsBuildMinor) ||
major >= maximumHsBuildMajor
) {
buildsToKeep.push(directory);
} else {
directoriesOnMachine.push(directory);
}
}
});
if (directoriesOnMachine.length === 0) {
console.log('No valid directories found on user machine');
return;
}
directoriesOnMachine.sort((a, b) => {
const { major: aMajor, minor: aMinor, patch: aPatch } = getVersionParts(a);
const { major: bMajor, minor: bMinor, patch: bPatch } = getVersionParts(b);
if (aMajor !== bMajor) {
return aMajor - bMajor;
} else if (aMinor !== bMinor) {
return aMinor - bMinor;
} else {
return aPatch - bPatch;
}
});
findTheBuildsToKeep();
console.log('directories on user machine', directoriesOnMachine);
console.log('builds to keep', buildsToKeep);
// Get a list of directories which are present on user machine but not present on directories to keep list.
directoriesToDelete = directoriesOnMachine.filter(item => !buildsToKeep.includes(item));
console.log('directories to delete', directoriesToDelete);
// Delete directories that are not the highest minor version for their respective major version and also directories not present in directories to keep list.
directoriesToDelete.forEach(directory => {
fs.remove(directoryPath + '/' + directory, err => {
if (err) {
console.log(`Error deleting ${directory} - ${err}`);
return;
}
console.log(`Deleted: ${directory}`);
});
});
});
console.timeEnd('customhook');
} catch (error) {
console.log(`Failed to execute customhook script ${error}`);
}
}