using System;
using System.IO;
using JetBrains.Annotations;
using UnityEngine;
namespace NugetForUnity.Helper
{
///
/// Helper class for file system operations.
///
internal static class FileSystemHelper
{
///
/// Recursively moves all files and sub-directories from one directory to another.
/// If a file or directory already exists inside the target directory, it will be overwritten.
///
/// The path to the folder to move from.
/// The path to the folder to move to.
internal static void DirectoryMove([NotNull] string sourceDirectoryPath, [NotNull] string destDirectoryPath)
{
if (!Directory.Exists(destDirectoryPath))
{
// target doesn't exist so we can simply move the folder
NugetLogger.LogVerbose("Moving {0} to {1}", sourceDirectoryPath, destDirectoryPath);
Directory.Move(sourceDirectoryPath, destDirectoryPath);
return;
}
// move the files
var files = Directory.EnumerateFiles(sourceDirectoryPath);
foreach (var file in files)
{
var newFilePath = Path.Combine(destDirectoryPath, Path.GetFileName(file));
try
{
NugetLogger.LogVerbose("Moving {0} to {1}", file, newFilePath);
DeleteFile(newFilePath);
File.Move(file, newFilePath);
}
catch (Exception e)
{
Debug.LogWarningFormat("'{0}' couldn't be moved to '{1}'. \n{2}", file, newFilePath, e);
}
}
// move the directories
var directories = Directory.EnumerateDirectories(sourceDirectoryPath);
foreach (var directory in directories)
{
var newDirectoryPath = Path.Combine(destDirectoryPath, Path.GetFileName(directory));
try
{
NugetLogger.LogVerbose("Moving {0} to {1}", directory, newDirectoryPath);
if (Directory.Exists(newDirectoryPath))
{
DeleteDirectory(newDirectoryPath, false);
}
Directory.Move(directory, newDirectoryPath);
}
catch (Exception e)
{
Debug.LogWarningFormat("'{0}' couldn't be moved to '{1}'. \n{2}", directory, newDirectoryPath, e);
}
}
}
///
/// Recursively deletes the folder at the given path.
/// NOTE: Directory.Delete() doesn't delete Read-Only files, whereas this does.
///
/// The path of the folder to delete.
/// Whether to log the deletion.
internal static void DeleteDirectory([NotNull] string directoryPath, bool log)
{
if (!Directory.Exists(directoryPath))
{
return;
}
if (log)
{
NugetLogger.LogVerbose("Deleting directory: {0}", directoryPath);
}
var directoryInfo = new DirectoryInfo(directoryPath);
// delete any sub-folders first
foreach (var childInfo in directoryInfo.EnumerateDirectories())
{
DeleteDirectory(childInfo.FullName, false);
}
// remove the read-only flag on all files
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
file.Attributes = FileAttributes.Normal;
}
// remove the read-only flag on the directory
directoryInfo.Attributes = FileAttributes.Normal;
// delete the directory
directoryInfo.Delete(true);
}
///
/// Deletes a file at the given file-path.
///
/// The file-path to the file to delete.
internal static void DeleteFile([NotNull] string filePath)
{
if (!File.Exists(filePath))
{
return;
}
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);
}
///
/// Moves a file from one location to another. If the destination file already exists, it is overwritten.
///
/// The path of the file that should be moved.
/// The target path where the file should be moved to.
/// Whether we should check if there is a file located at .
internal static void MoveFile([NotNull] string sourceFilePath, [NotNull] string destFilePath, bool checkSourceExists)
{
if (checkSourceExists && !File.Exists(sourceFilePath))
{
throw new FileNotFoundException($"Source file does not exist or could not be found: {sourceFilePath}");
}
NugetLogger.LogVerbose("Moving {0} to {1}", sourceFilePath, destFilePath);
DeleteFile(destFilePath);
File.Move(sourceFilePath, destFilePath);
}
///
/// Deletes all files in the given directory and in any sub-directory, with the given filter.
///
/// The path to the directory to delete all files of the given extension from.
/// The filter of the files to delete, in the form "*.ext".
internal static void DeleteAllFiles([NotNull] string directoryPath, [NotNull] string filter)
{
var files = Directory.EnumerateFiles(directoryPath, filter, SearchOption.AllDirectories);
foreach (var file in files)
{
DeleteFile(file);
}
}
///
/// Replace all %20 encodings with a normal space.
///
/// The path to the directory.
internal static void FixSpaces([NotNull] string directoryPath)
{
if (directoryPath.Contains("%20"))
{
NugetLogger.LogVerbose("Removing %20 from {0}", directoryPath);
Directory.Move(directoryPath, directoryPath.Replace("%20", " "));
directoryPath = directoryPath.Replace("%20", " ");
}
var subdirectories = Directory.EnumerateDirectories(directoryPath);
foreach (var subDir in subdirectories)
{
FixSpaces(subDir);
}
var files = Directory.EnumerateFiles(directoryPath);
foreach (var file in files)
{
if (file.Contains("%20"))
{
NugetLogger.LogVerbose("Removing %20 from {0}", file);
File.Move(file, file.Replace("%20", " "));
}
}
}
}
}