// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #include "Commandlets/GenerateTextLocalizationResourceCommandlet.h" #include "HAL/FileManager.h" #include "Templates/ScopedPointer.h" #include "TextLocalizationResourceGenerator.h" #include "UniquePtr.h" DEFINE_LOG_CATEGORY_STATIC(LogGenerateTextLocalizationResourceCommandlet, Log, All); UGenerateTextLocalizationResourceCommandlet::UGenerateTextLocalizationResourceCommandlet(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } int32 UGenerateTextLocalizationResourceCommandlet::Main(const FString& Params) { // Parse command line - we're interested in the param vals TArray Tokens; TArray Switches; TMap ParamVals; UCommandlet::ParseCommandLine(*Params, Tokens, Switches, ParamVals); // Set config file. const FString* ParamVal = ParamVals.Find(FString(TEXT("Config"))); FString GatherTextConfigPath; if ( ParamVal ) { GatherTextConfigPath = *ParamVal; } else { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No config specified.")); return -1; } // Set config section. ParamVal = ParamVals.Find(FString(TEXT("Section"))); FString SectionName; if ( ParamVal ) { SectionName = *ParamVal; } else { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No config section specified.")); return -1; } // Get source path. FString SourcePath; if( !( GetPathFromConfig( *SectionName, TEXT("SourcePath"), SourcePath, GatherTextConfigPath ) ) ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No source path specified.")); return -1; } // Get manifest name. FString ManifestName; if( !( GetStringFromConfig( *SectionName, TEXT("ManifestName"), ManifestName, GatherTextConfigPath ) ) ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No manifest name specified.")); return -1; } // Get archive name. FString ArchiveName; if (!GetStringFromConfig(*SectionName, TEXT("ArchiveName"), ArchiveName, GatherTextConfigPath)) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No archive name specified.")); return -1; } // Get cultures to generate. FString NativeCultureName; if( !( GetStringFromConfig( *SectionName, TEXT("NativeCulture"), NativeCultureName, GatherTextConfigPath ) ) ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No native culture specified.")); return -1; } // Get cultures to generate. TArray CulturesToGenerate; GetStringArrayFromConfig( *SectionName, TEXT("CulturesToGenerate"), CulturesToGenerate, GatherTextConfigPath ); if( CulturesToGenerate.Num() == 0 ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No cultures specified for generation.")); return -1; } for(int32 i = 0; i < CulturesToGenerate.Num(); ++i) { if( FInternationalization::Get().GetCulture( CulturesToGenerate[i] ).IsValid() ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Verbose, TEXT("Specified culture is not a valid runtime culture, but may be a valid base language: %s"), *(CulturesToGenerate[i])); } } // Get destination path. FString DestinationPath; if( !( GetPathFromConfig( *SectionName, TEXT("DestinationPath"), DestinationPath, GatherTextConfigPath ) ) ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No destination path specified.")); return -1; } // Get resource name. FString ResourceName; if( !( GetStringFromConfig( *SectionName, TEXT("ResourceName"), ResourceName, GatherTextConfigPath ) ) ) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("No resource name specified.")); return -1; } // Get whether to skip the source check. bool bSkipSourceCheck = false; if (!GetBoolFromConfig(*SectionName, TEXT("bSkipSourceCheck"), bSkipSourceCheck, GatherTextConfigPath)) { bSkipSourceCheck = false; } // Load the manifest and all archives FLocTextHelper LocTextHelper(SourcePath, ManifestName, ArchiveName, NativeCultureName, CulturesToGenerate, MakeShareable(new FLocFileSCCNotifies(SourceControlInfo))); { FText LoadError; if (!LocTextHelper.LoadAll(ELocTextHelperLoadFlags::LoadOrCreate, &LoadError)) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("%s"), *LoadError.ToString()); return false; } } // For each culture: for (const FString& CultureName : CulturesToGenerate) { // Write resource. const FString TextLocalizationResourcePath = DestinationPath / CultureName / ResourceName; const bool bLocResFileSaved = FLocalizedAssetSCCUtil::SaveFileWithSCC(SourceControlInfo, TextLocalizationResourcePath, [&LocTextHelper, &CultureName, &bSkipSourceCheck](const FString& InSaveFileName) -> bool { bool bSaved = false; TUniquePtr TextLocalizationResourceArchive(IFileManager::Get().CreateFileWriter(*InSaveFileName)); if (TextLocalizationResourceArchive) { bSaved = FTextLocalizationResourceGenerator::Generate(LocTextHelper, CultureName, bSkipSourceCheck, *TextLocalizationResourceArchive); if (!bSaved) { IFileManager::Get().Delete(*InSaveFileName); } TextLocalizationResourceArchive->Close(); } return bSaved; }); if (!bLocResFileSaved) { UE_LOG(LogGenerateTextLocalizationResourceCommandlet, Error, TEXT("Could not write file %s"), *TextLocalizationResourcePath); return false; } } return 0; }