src/Authentication.Abstractions/Utilities/FileUtilities.cs (250 lines of code) (raw):
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Properties;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// File utilities using the data store
/// </summary>
public static class FileUtilities
{
static FileUtilities()
{
DataStore = new DiskDataStore();
}
/// <summary>
/// The data store to use in these utilities
/// </summary>
public static IDataStore DataStore { get; set; }
/// <summary>
/// Get the directory for the executing assembly
/// </summary>
/// <returns></returns>
public static string GetAssemblyDirectory()
{
var assemblyPath = Uri.UnescapeDataString(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath);
return Path.GetDirectoryName(assemblyPath);
}
/// <summary>
/// Search for the path of a file starting in the assembly directory
/// </summary>
/// <param name="fileName">The file name</param>
/// <returns>The path of the given file in the assembly directory</returns>
public static string GetContentFilePath(string fileName)
{
return GetContentFilePath(GetAssemblyDirectory(), fileName);
}
/// <summary>
/// Search for the path of the given file starting in the given directory
/// </summary>
/// <param name="startDirectory">The directory to search in</param>
/// <param name="fileName">The file name</param>
/// <returns>The path to the file</returns>
public static string GetContentFilePath(string startDirectory, string fileName)
{
string path = Path.Combine(startDirectory, fileName);
// Try search in the subdirectories in case that the file path does not exist in root path
if (!DataStore.FileExists(path) && !DataStore.DirectoryExists(path))
{
try
{
path = DataStore.GetDirectories(startDirectory, fileName, SearchOption.AllDirectories).FirstOrDefault();
if (string.IsNullOrEmpty(path))
{
path = DataStore.GetFiles(startDirectory, fileName, SearchOption.AllDirectories).First();
}
}
catch
{
throw new FileNotFoundException(Path.Combine(startDirectory, fileName));
}
}
return path;
}
/// <summary>
/// Get the directory path to the given directory in the paltform-appropriate program files path
/// </summary>
/// <param name="directoryName">The name fo the directory</param>
/// <param name="throwIfNotFound">Whether to throw if the directory is not found</param>
/// <returns>The full directory path</returns>
public static string GetWithProgramFilesPath(string directoryName, bool throwIfNotFound)
{
string programFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (DataStore.DirectoryExists(Path.Combine(programFilesPath, directoryName)))
{
return Path.Combine(programFilesPath, directoryName);
}
else
{
if (programFilesPath.IndexOf(Resources.x86InProgramFiles, StringComparison.InvariantCultureIgnoreCase) == -1)
{
programFilesPath += Resources.x86InProgramFiles;
if (throwIfNotFound)
{
ValidateDirectoryExists(Path.Combine(programFilesPath, directoryName));
}
return Path.Combine(programFilesPath, directoryName);
}
else
{
programFilesPath = programFilesPath.Replace(Resources.x86InProgramFiles, String.Empty);
if (throwIfNotFound)
{
ValidateDirectoryExists(Path.Combine(programFilesPath, directoryName));
}
return Path.Combine(programFilesPath, directoryName);
}
}
}
/// <summary>
/// Copies a directory.
/// </summary>
/// <param name="sourceDirName">The source directory name</param>
/// <param name="destDirName">The destination directory name</param>
/// <param name="copySubDirs">Should the copy be recursive</param>
public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
var dirs = DataStore.GetDirectories(sourceDirName);
if (!DataStore.DirectoryExists(sourceDirName))
{
throw new DirectoryNotFoundException(String.Format(Resources.PathDoesNotExist, sourceDirName));
}
DataStore.CreateDirectory(destDirName);
var files = DataStore.GetFiles(sourceDirName);
foreach (var file in files)
{
string tempPath = Path.Combine(destDirName, Path.GetFileName(file));
DataStore.CopyFile(file, tempPath);
}
if (copySubDirs)
{
foreach (var subdir in dirs)
{
string temppath = Path.Combine(destDirName, Path.GetDirectoryName(subdir));
DirectoryCopy(subdir, temppath, copySubDirs);
}
}
}
/// <summary>
/// Ensures that a directory exists beofre attempting to write a file
/// </summary>
/// <param name="pathName">The path to the file that will be created</param>
public static void EnsureDirectoryExists(string pathName)
{
ValidateStringIsNullOrEmpty(pathName, "Settings directory");
string directoryPath = Path.GetDirectoryName(pathName);
if (!DataStore.DirectoryExists(directoryPath))
{
DataStore.CreateDirectory(directoryPath);
}
}
/// <summary>
/// Create a unique temp directory.
/// </summary>
/// <returns>Path to the temp directory.</returns>
public static string CreateTempDirectory()
{
string tempPath;
do
{
tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
}
while (DataStore.DirectoryExists(tempPath) || DataStore.FileExists(tempPath));
DataStore.CreateDirectory(tempPath);
return tempPath;
}
/// <summary>
/// Copy a directory from one path to another.
/// </summary>
/// <param name="sourceDirectory">Source directory.</param>
/// <param name="destinationDirectory">Destination directory.</param>
public static void CopyDirectory(string sourceDirectory, string destinationDirectory)
{
Debug.Assert(!String.IsNullOrEmpty(sourceDirectory), "sourceDictory cannot be null or empty!");
Debug.Assert(Directory.Exists(sourceDirectory), "sourceDirectory must exist!");
Debug.Assert(!String.IsNullOrEmpty(destinationDirectory), "destinationDirectory cannot be null or empty!");
Debug.Assert(!Directory.Exists(destinationDirectory), "destinationDirectory must not exist!");
foreach (string file in DataStore.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories))
{
string relativePath = file.Substring(
sourceDirectory.Length + 1,
file.Length - sourceDirectory.Length - 1);
string destinationPath = Path.Combine(destinationDirectory, relativePath);
string destinationDir = Path.GetDirectoryName(destinationPath);
if (!DataStore.DirectoryExists(destinationDir))
{
DataStore.CreateDirectory(destinationDir);
}
DataStore.CopyFile(file, destinationPath);
}
}
/// <summary>
/// Get the encoding of the given file
/// </summary>
/// <param name="path">The path to the file</param>
/// <returns>The encoding of the file, or the defautl encoding if the file does not exist</returns>
public static Encoding GetFileEncoding(string path)
{
Encoding encoding;
if (DataStore.FileExists(path))
{
using (StreamReader r = new StreamReader(DataStore.ReadFileAsStream(path)))
{
encoding = r.CurrentEncoding;
}
}
else
{
encoding = Encoding.Default;
}
return encoding;
}
/// <summary>
/// Combine the given array of paths
/// </summary>
/// <param name="paths">The paths to combine</param>
/// <returns>The combined paths</returns>
public static string CombinePath(params string[] paths)
{
return Path.Combine(paths);
}
/// <summary>
/// Returns true if path is a valid directory.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static bool IsValidDirectoryPath(string path)
{
if (String.IsNullOrEmpty(path))
{
return false;
}
try
{
FileAttributes attributes = DataStore.GetFileAttributes(path);
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
/// <summary>
/// Remove the given directory if it exists, then create the directory
/// </summary>
/// <param name="dir">The directory to recreate</param>
public static void RecreateDirectory(string dir)
{
if (DataStore.DirectoryExists(dir))
{
DataStore.DeleteDirectory(dir);
}
DataStore.CreateDirectory(dir);
}
/// <summary>
/// Gets the root installation path for the given Azure module.
/// </summary>
/// <param name="module" >The module name</param>
/// <returns>The module full path</returns>
public static string GetPSModulePathForModule(AzureModule module)
{
return GetContentFilePath(GetInstallPath(), GetModuleFolderName(module));
}
/// <summary>
/// Gets the root directory for all modules installation.
/// </summary>
/// <returns>The install path</returns>
public static string GetInstallPath()
{
string currentPath = GetAssemblyDirectory();
while (!currentPath.EndsWith(GetModuleFolderName(AzureModule.AzureProfile)) &&
!currentPath.EndsWith(GetModuleFolderName(AzureModule.AzureResourceManager)) &&
!currentPath.EndsWith(GetModuleFolderName(AzureModule.AzureServiceManagement)))
{
currentPath = Directory.GetParent(currentPath).FullName;
}
// The assemption is that the install directory looks like that:
// ServiceManagement
// AzureServiceManagement
// <Service Commands Folders>
// ResourceManager
// AzureResourceManager
// <Service Commands Folders>
// Profile
// AzureSMProfile
// <Service Commands Folders>
return Directory.GetParent(currentPath).FullName;
}
/// <summary>
/// Get the module name for the given modules
/// </summary>
/// <param name="module">The module type</param>
/// <returns>The mdoule name for th emoduel type</returns>
public static string GetModuleName(AzureModule module)
{
switch (module)
{
case AzureModule.AzureServiceManagement:
return "Azure";
case AzureModule.AzureResourceManager:
return "AzureResourceManager";
case AzureModule.AzureProfile:
return "AzureProfile";
default:
throw new ArgumentOutOfRangeException(module.ToString());
}
}
/// <summary>
/// Get the name of the folder containign the given module type
/// </summary>
/// <param name="module">The module type</param>
/// <returns>The name fo the contianing folder</returns>
public static string GetModuleFolderName(AzureModule module)
{
return module.ToString().Replace("Azure", "");
}
private static void ValidateDirectoryExists(string directory, string exceptionMessage = null)
{
string msg = string.Format(Resources.PathDoesNotExist, directory);
if (!DataStore.DirectoryExists(directory))
{
if (!string.IsNullOrEmpty(exceptionMessage))
{
msg = exceptionMessage;
}
throw new FileNotFoundException(msg);
}
}
private static void ValidateStringIsNullOrEmpty(string data, string messageData, bool useDefaultMessage = true)
{
if (string.IsNullOrEmpty(data))
{
if (useDefaultMessage)
{
throw new ArgumentException(string.Format(Resources.InvalidOrEmptyArgumentMessage, messageData));
}
else
{
throw new ArgumentException(messageData);
}
}
}
}
}