Example #1
0
bool FPluginHelpers::CopyPluginTemplateFolder(const TCHAR* DestinationDirectory, const TCHAR* Source, const FString& PluginName)
{
	check(DestinationDirectory);
	check(Source);

	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();

	FString DestDir(DestinationDirectory);
	FPaths::NormalizeDirectoryName(DestDir);

	FString SourceDir(Source);
	FPaths::NormalizeDirectoryName(SourceDir);

	// Does Source dir exist?
	if (!PlatformFile.DirectoryExists(*SourceDir))
	{
		return false;
	}

	// Destination directory exists already or can be created ?
	if (!PlatformFile.DirectoryExists(*DestDir) &&
		!PlatformFile.CreateDirectory(*DestDir))
	{
		return false;
	}

	// Copy all files and directories, renaming specific sections to the plugin name
	struct FCopyPluginFilesAndDirs : public IPlatformFile::FDirectoryVisitor
	{
		IPlatformFile& PlatformFile;
		const TCHAR* SourceRoot;
		const TCHAR* DestRoot;
		const FString& PluginName;
		TArray<FString> NameReplacementFileTypes;
		TArray<FString> IgnoredFileTypes;

		FCopyPluginFilesAndDirs(IPlatformFile& InPlatformFile, const TCHAR* InSourceRoot, const TCHAR* InDestRoot, const FString& InPluginName)
			: PlatformFile(InPlatformFile)
			, SourceRoot(InSourceRoot)
			, DestRoot(InDestRoot)
			, PluginName(InPluginName)
		{
			// Which file types we want to replace instances of PLUGIN_NAME with the new Plugin Name
			NameReplacementFileTypes.Add(TEXT("cs"));
			NameReplacementFileTypes.Add(TEXT("cpp"));
			NameReplacementFileTypes.Add(TEXT("h"));
			NameReplacementFileTypes.Add(TEXT("vcxproj"));

			// Which file types do we want to ignore
			IgnoredFileTypes.Add(TEXT("opensdf"));
			IgnoredFileTypes.Add(TEXT("sdf"));
			IgnoredFileTypes.Add(TEXT("user"));
			IgnoredFileTypes.Add(TEXT("suo"));
		}

		virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory)
		{
			FString NewName(FilenameOrDirectory);
			// change the root and rename paths/files
			NewName.RemoveFromStart(SourceRoot);
			NewName = NewName.Replace(TEXT("PLUGIN_NAME"), *PluginName, ESearchCase::CaseSensitive);
			NewName = FPaths::Combine(DestRoot, *NewName);

			if (bIsDirectory)
			{
				// create new directory structure
				if (!PlatformFile.CreateDirectoryTree(*NewName) && !PlatformFile.DirectoryExists(*NewName))
				{
					return false;
				}
			}
			else
			{
				FString NewExt = FPaths::GetExtension(FilenameOrDirectory);

				if (!IgnoredFileTypes.Contains(NewExt))
				{
					// Delete destination file if it exists
					if (PlatformFile.FileExists(*NewName))
					{
						PlatformFile.DeleteFile(*NewName);
					}

					// If file of specified extension - open the file as text and replace PLUGIN_NAME in there before saving
					if (NameReplacementFileTypes.Contains(NewExt))
					{
						FString OutFileContents;
						if (!FFileHelper::LoadFileToString(OutFileContents, FilenameOrDirectory))
						{
							return false;
						}

						OutFileContents = OutFileContents.Replace(TEXT("PLUGIN_NAME"), *PluginName, ESearchCase::CaseSensitive);

						if (!FFileHelper::SaveStringToFile(OutFileContents, *NewName))
						{
							return false;
						}
					}
					else
					{
						// Copy file from source
						if (!PlatformFile.CopyFile(*NewName, FilenameOrDirectory))
						{
							// Not all files could be copied
							return false;
						}
					}
				}
			}
			return true; // continue searching
		}
	};

	// copy plugin files and directories visitor
	FCopyPluginFilesAndDirs CopyFilesAndDirs(PlatformFile, *SourceDir, *DestDir, PluginName);

	// create all files subdirectories and files in subdirectories!
	return PlatformFile.IterateDirectoryRecursively(*SourceDir, CopyFilesAndDirs);
}
bool IPlatformFile::CopyDirectoryTree(const TCHAR* DestinationDirectory, const TCHAR* Source, bool bOverwriteAllExisting)
{
	check(DestinationDirectory);
	check(Source);

	FString DestDir(DestinationDirectory);
	FPaths::NormalizeDirectoryName(DestDir);

	FString SourceDir(Source);
	FPaths::NormalizeDirectoryName(SourceDir);

	// Does Source dir exist?
	if (!DirectoryExists(*SourceDir))
	{
		return false;
	}

	// Destination directory exists already or can be created ?
	if (!DirectoryExists(*DestDir) &&
		!CreateDirectory(*DestDir))
	{
		return false;
	}

	// Copy all files and directories
	struct FCopyFilesAndDirs : public FDirectoryVisitor
	{
		IPlatformFile & PlatformFile;
		const TCHAR* SourceRoot;
		const TCHAR* DestRoot;
		bool bOverwrite;

		FCopyFilesAndDirs(IPlatformFile& InPlatformFile, const TCHAR* InSourceRoot, const TCHAR* InDestRoot, bool bInOverwrite)
			: PlatformFile(InPlatformFile)
			, SourceRoot(InSourceRoot)
			, DestRoot(InDestRoot)
			, bOverwrite(bInOverwrite)
		{
		}

		virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory)
		{
			FString NewName(FilenameOrDirectory);
			// change the root
			NewName = NewName.Replace(SourceRoot, DestRoot);

			if (bIsDirectory)
			{
				// create new directory structure
				if (!PlatformFile.CreateDirectoryTree(*NewName) && !PlatformFile.DirectoryExists(*NewName))
				{
					return false;
				}
			}
			else
			{
				// Delete destination file if it exists and we are overwriting
				if (PlatformFile.FileExists(*NewName) && bOverwrite)
				{
					PlatformFile.DeleteFile(*NewName);
				}

				// Copy file from source
				if (!PlatformFile.CopyFile(*NewName, FilenameOrDirectory))
				{
					// Not all files could be copied
					return false;
				}
			}
			return true; // continue searching
		}
	};

	// copy files and directories visitor
	FCopyFilesAndDirs CopyFilesAndDirs(*this, *SourceDir, *DestDir, bOverwriteAllExisting);

	// create all files subdirectories and files in subdirectories!
	return IterateDirectoryRecursively(*SourceDir, CopyFilesAndDirs);
}