Automating blueprint indexing

I want to automate the process that UE goes through when it indexes blueprints with a commandlet. My thought is, the automation would allow me to index and check in the blueprints on a regular basis so that other users can have more accurate search results without having to do a long tedious index on their own.

I pretty much extracted the functionality from FCacheAllBlueprintsTickableObject::Tick(). But I’m not really sure what changes the function makes to packages. It seems to just load up a package and saves it back, where does the change to the package come from?

I trusted that the logic in the function did actually do the indexing and ran my function for 100 blueprints and observed there were changes made them to them (via perforce). But when I ran the editor and did a search, the number of unindexed blueprints had actually increased instead :open_mouth:

This is a trimmed down version of my code. What am I doing wrong?

	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
	AssetRegistryModule.Get().SearchAllAssets(true);
	TArray<FAssetData> BlueprintList;
	AssetRegistryModule.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetFName(), BlueprintList);
	AssetRegistryModule.Get().GetAssetsByClass(UAnimBlueprint::StaticClass()->GetFName(), BlueprintList);

	for (FAssetData& AssetData : BlueprintList)
	{
		// Index the blueprints that aren't loaded
		if (!AssetData.IsAssetLoaded())
		{
			bool bIsWorldAsset = AssetData.GetClass() == UWorld::StaticClass();

			// Construct a full package filename with path so we can query the read only status and save to disk
			FString FinalPackageFilename = FPackageName::LongPackageNameToFilename(AssetData.PackageName.ToString());
			if (FinalPackageFilename.Len() > 0 && FPaths::GetExtension(FinalPackageFilename).Len() == 0)
			{
				FinalPackageFilename += bIsWorldAsset ? FPackageName::GetMapPackageExtension() : FPackageName::GetAssetPackageExtension();
			}

			UObject* Asset = AssetData.GetAsset();
			if (!Asset)
			{
				continue;
			}

			// Check out the package
			UPackage* Package = AssetData.GetPackage();
			ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
			const FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(FinalPackageFilename, EStateCacheUsage::ForceUpdate);
			ECommandResult::Type result = SourceControlProvider.Execute(ISourceControlOperation::Create<FCheckOut>(), FinalPackageFilename);

			UWorld* WorldAsset = Cast<UWorld>(Asset);
			EObjectFlags ObjectFlags = (WorldAsset == nullptr) ? RF_Standalone : RF_NoFlags;
			if (!GEditor->SavePackage(Package, WorldAsset, ObjectFlags, *FinalPackageFilename))
			{
				UE_LOG(LogIndexBlueprintsCommandlet, Error, TEXT("[%s] Failed to index. Could not save file: %s"), *AssetData.AssetName.ToString(), *FinalPackageFilename);
			}

			if (indexedBlueprintCount == 100) goto FINISHED;
		}
	}