/// <summary> /// Robustly determines the SVN status of a path using the output of the SVN status command. /// Handles both files and directories, in the case of a directory the status of the directory only, and not all the file-system entries within it. /// Handles warnings by turning them into into the associated <see cref="ItemStatus"/> value. /// Resolves the ambiguous <see cref="ItemStatus.NotFound"/> item status by walking up the path hierarchy until an items status is found. /// </summary> public static SvnStringPathStatus StatusRobust(this SvnCommand svnCommand, AbsolutePath path) { var nonDirectoryIndicatedPath = PathUtilities.EnsurePathIsNotDirectoryIndicated(path.Value).AsAbsolutePath(); var status = svnCommand.StatusRobust_Internal(nonDirectoryIndicatedPath); if (status.ItemStatus != ItemStatus.NotFound) { return(status); } // Determine whether the item is in 1) an ignored directory or 2) an unversioned directory by walking up the path hierarchy until var parentItemStatus = ItemStatus.None; var parentPath = path; do { parentPath = PathUtilities.GetParentDirectoryPath(parentPath); var parentStatus = svnCommand.StatusRobust_Internal(parentPath); parentItemStatus = parentStatus.ItemStatus; }while (parentItemStatus == ItemStatus.NotFound); var output = new SvnStringPathStatus { Path = path.Value, ItemStatus = parentItemStatus }; return(output); }
public static bool HasUncommittedChanges(this SvnCommand svnCommand, DirectoryPath directoryPath, out IEnumerable <SvnStringPathStatus> uncommittedChanges) { uncommittedChanges = svnCommand.GetUncommittedChanges(directoryPath); var output = uncommittedChanges.Count() > 1; return(output); }
public static int Update(this SvnCommand svnCommand, string path) { var absolutePath = path.AsAbsolutePath(); var output = svnCommand.Update(absolutePath); return(output); }
/// <summary> /// Many SVN properties have values that are lists of new-line separated strings. /// This method tests if a list property has a given value as an element. /// </summary> public static bool HasListPropertyValue(this SvnCommand svnCommand, AbsolutePath path, string propertyName, string value) { var propertyValues = svnCommand.GetPropertyValues(path, propertyName); var output = propertyValues.Contains(value); return(output); }
/// <summary> /// Determine if a path is under source control. /// Note: non-existent paths are NOT under source control. /// </summary> public static bool IsUnderSourceControl(this SvnCommand svnCommand, string path) { var absolutePath = path.AsAbsolutePath(); var output = svnCommand.IsUnderSourceControl(absolutePath); return(output); }
public static SvnStringPathStatus[] Statuses(this SvnCommand svnCommand, IArgumentsBuilder argumentsBuilder) { svnCommand.Logger.LogDebug($"Getting all SVN status results..."); var statuses = SvnCommandServicesProvider.GetStatuses(svnCommand.SvnExecutableFilePath, argumentsBuilder); svnCommand.Logger.LogInformation($"Got all SVN status results ({statuses.Count()} results)."); return(statuses); }
/// <summary> /// Gets the value of an SVN property. /// If the property does not exist, the <see cref="SvnCommand.NonValue"/> is returned. /// </summary> public static string GetPropertyValueIfExists(this SvnCommand svnCommand, AbsolutePath path, string propertyName) { if (!svnCommand.HasSvnIgnoreProperty(path)) { return(SvnCommand.NonValue); } var output = svnCommand.GetPropertyValue(path, propertyName); return(output); }
/// <summary> /// Many SVN properties have values that are sets of new-line separated strings. /// This method adds a value to that set. /// This method will not add the same value twice, as it checks if the value is already present in the set of values. /// </summary> public static void AddPropertyValue(this SvnCommand svnCommand, AbsolutePath path, string propertyName, string value) { var values = new List <string>(svnCommand.GetPropertyValues(path, propertyName)); // Only add the value once. if (!values.Contains(value)) { values.Add(value); svnCommand.SetPropertyValues(path, propertyName, values.ToArray()); } }
/// <summary> /// Get the SVN status results for a file or directory. /// If the specified path is a file, a single result will be returned. /// If the specified path is a directory, possibly many results will be returned. /// If the path does not exist, zero results will be returned. /// </summary> public static SvnStringPathStatus[] Statuses(this SvnCommand svnCommand, AbsolutePath path) { svnCommand.Logger.LogDebug($"Getting all SVN status results for path {path}..."); var arguments = SvnCommandServicesProvider.GetStatusVerbose(path); var statuses = SvnCommandServicesProvider.GetStatuses(svnCommand.SvnExecutableFilePath, arguments); svnCommand.Logger.LogInformation($"Got all SVN status results for path {path} ({statuses.Count()} results)."); return(statuses); }
/// <summary> /// Gets SVN status values for all directory contents recursively, disregarding any SVN ignore properties and the global SVN ignore values. /// </summary> public static SvnStringPathStatus[] StatusesInfinityNoIgnore(this SvnCommand svnCommand, DirectoryPath directoryPath) { svnCommand.Logger.LogDebug($"Getting all SVN status results for directory path {directoryPath}..."); var arguments = SvnCommandServicesProvider.GetStatusVerboseDepthInfinityNoIgnore(directoryPath); var statuses = SvnCommandServicesProvider.GetStatuses(svnCommand.SvnExecutableFilePath, arguments); svnCommand.Logger.LogInformation($"Got all SVN status results for directroy path {directoryPath} ({statuses.Count()} results)."); return(statuses); }
/// <summary> /// Many SVN properties have values that are sets of new-line separated strings. /// This method gets the values in the property value set. /// </summary> public static string[] GetPropertyValues(this SvnCommand svnCommand, AbsolutePath path, string propertyName) { var value = svnCommand.GetPropertyValueIfExists(path, propertyName); if (SvnCommand.IsValue(value)) { var output = value.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); return(output); } else { return(Array.Empty <string>()); } }
/// <summary> /// Any directory contents with an <see cref="ItemStatus"/> other than <see cref="ItemStatus.NoModifications"/> is an uncommited change. /// </summary> public static IEnumerable <SvnStringPathStatus> GetAllUncommittedChanges(this SvnCommand svnCommand, DirectoryPath directoryPath) { var statuses = svnCommand.StatusesDefault(directoryPath); foreach (var status in statuses) { // Anything with an SVN status other than no-modifications is an uncommitted change. var anythingOtherThanNoModifications = status.ItemStatus != ItemStatus.NoModifications; if (anythingOtherThanNoModifications) { yield return(status); } } }
private static SvnStringPathStatus StatusRobust_Internal(this SvnCommand svnCommand, AbsolutePath absolutePath) { var arguments = SvnCommandServicesProvider.GetStatusVerboseForInstanceOnly(absolutePath) .AddXml(); // Get XML. var outputCollector = SvnCommandServicesProvider.Run(svnCommand.SvnExecutableFilePath, arguments, false); if (outputCollector.AnyError) { var errorText = outputCollector.GetErrorText().Trim(); var notWorkingCopyText = $"svn: warning: W155007: '{absolutePath}' is not a working copy"; if (errorText == notWorkingCopyText) { var output = new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.NotWorkingCopy }; return(output); } var notFoundText = $"svn: warning: W155010: The node '{absolutePath}' was not found."; if (errorText == notFoundText) { var output = new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.NotFound }; return(output); } throw new Exception($"Unknown SVN error:\n{errorText}"); } var xmlText = outputCollector.GetOutputText(); using (var stream = StreamHelper.FromString(xmlText)) { var xmlStatusType = XmlStreamSerializer.Deserialize <StatusType>(stream, SvnXml.DefaultNamespace); var statuses = SvnCommandServicesProvider.GetStatuses(xmlStatusType); var status = statuses.Count() < 1 ? new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.None } : statuses.Single() // Should be only 1. ; return(status); } }
/// <summary> /// Many SVN properties have values that are sets of new-line separated strings. /// This method removes a value from that set. /// Idempotent, can be called mulitple times. /// If, after removing the specified value, no values remain, the property will be deleted. /// </summary> public static void RemovePropertyValue(this SvnCommand svnCommand, AbsolutePath path, string propertyName, string value) { var values = new List <string>(svnCommand.GetSvnIgnoreValues(path)); values.Remove(value); if (values.IsEmpty()) { svnCommand.DeleteProperty(path, propertyName); } else { svnCommand.SetSvnIgnoreValues(path, values.ToArray()); } }
public static CheckoutResult Checkout(this SvnCommand svnCommand, string repositoryUrl, string localDirectoryPath) { svnCommand.Logger.LogDebug($"SVN checkout of '{repositoryUrl}' to '{localDirectoryPath}'..."); // Need to ensure the local directory path is NOT directory indicated (does NOT end with a directory separator). var correctedLocalDirectoryPath = PathUtilities.EnsureFilePathNotDirectoryIndicated(localDirectoryPath); var arguments = SvnCommandServicesProvider.GetCheckoutArguments(repositoryUrl, correctedLocalDirectoryPath); var commandOutput = SvnCommandServicesProvider.Run(svnCommand.SvnExecutableFilePath, arguments); var lines = commandOutput.GetOutputLines().ToList(); var lastLine = lines.Last(); var lastLineTokens = lastLine.Split(' '); var revisionNumberToken = lastLineTokens.Last().TrimEnd('.'); var revisionNumber = Int32.Parse(revisionNumberToken); var entryUpdateLines = lines.ExceptLast(); var statuses = new List <EntryUpdateStatus>(); foreach (var line in entryUpdateLines) { var lineTokens = line.Split(new[] { " " }, 2, StringSplitOptions.RemoveEmptyEntries); var statusToken = lineTokens[0]; var relativePath = lineTokens[1]; var updateStatus = statusToken.ToUpdateStatus(); var status = new EntryUpdateStatus { UpdateStatus = updateStatus, RelativePath = relativePath, }; statuses.Add(status); } var result = new CheckoutResult { RevisionNumber = revisionNumber, Statuses = statuses.ToArray(), }; svnCommand.Logger.LogInformation($"SVN checkout of '{repositoryUrl}' to '{localDirectoryPath}' complete."); return(result); }
/// <summary>s /// Get only the SVN status of a specific directory, and not its children. /// If the directory path does not exist, returns a result with status <see cref="ItemStatus.None"/>. /// </summary> public static SvnStringPathStatus Status(this SvnCommand svnCommand, DirectoryPath directoryPath) { svnCommand.Logger.LogDebug($"Getting SVN status of directory path {directoryPath}..."); var arguments = SvnCommandServicesProvider.GetStatusVerboseForInstanceOnly(directoryPath); var statuses = SvnCommandServicesProvider.GetStatuses(svnCommand.SvnExecutableFilePath, arguments); var status = statuses.Count() < 1 ? new SvnStringPathStatus { Path = directoryPath.Value, ItemStatus = ItemStatus.None } : statuses.Single() // Should be only 1. ; svnCommand.Logger.LogDebug($"Got SVN status of directory path {directoryPath}."); return(status); }
/// <summary> /// Get only the SVN status of a specific file or directory (and for directories, only the SVN status of the directory itself, and not its children). /// If the path does not exist, returns a result with status <see cref="ItemStatus.None"/>. /// </summary> public static SvnPathStatus Status(this SvnCommand svnCommand, AbsolutePath path) { // Allow for possibility that the path is a directory path. Find the entry matching the input path. var statuses = svnCommand.Statuses(path); if (statuses.Count() < 1) { var output = new SvnPathStatus { Path = new GeneralAbsolutePath(path.Value), ItemStatus = ItemStatus.None }; return(output); } var status = statuses.Where(x => x.Path == path.Value).Select(x => new SvnPathStatus { Path = new GeneralAbsolutePath(x.Path), ItemStatus = x.ItemStatus }).Single(); // There should be at least one result. return(status); }
/// <summary> /// Determine if a path is under source control. /// Note: non-existent paths are NOT under source control. /// </summary> public static bool IsUnderSourceControl(this SvnCommand svnCommand, AbsolutePath path) { var status = svnCommand.StatusRobust(path); switch (status.ItemStatus) { case ItemStatus.NotFound: throw new Exception("Ambigous status found. (Should never happen with use of robust status method.)"); case ItemStatus.None: // Non-existent path. case ItemStatus.Ignored: case ItemStatus.NotWorkingCopy: case ItemStatus.Unversioned: return(false); default: return(true); } }
/// <summary> /// The SVN ignore property value is a set of new-line separated strings. /// This method allows removing one of those strings while keeping the rest. /// </summary> public static void RemoveSvnIgnoreValue(this SvnCommand svnCommand, AbsolutePath path, string value) { svnCommand.RemovePropertyValue(path, SvnCommand.SvnIgnorePropertyName, value); }
/// <summary> /// The SVN ignore property value is a set of new-line separated strings. /// Gets the set of values of the SVN ignore property. /// </summary> public static string[] GetSvnIgnoreValues(this SvnCommand svnCommand, AbsolutePath path) { var output = svnCommand.GetPropertyValues(path, SvnCommand.SvnIgnorePropertyName); return(output); }
/// <summary> /// The SVN ignore property value is a set of new-line separated strings. /// This method tests if the set of SVN ignore values containes the specified value. /// </summary> public static bool HasSvnIgnoreValue(this SvnCommand svnCommand, AbsolutePath path, string value) { var output = svnCommand.HasListPropertyValue(path, SvnCommand.SvnIgnorePropertyName, value); return(output); }
/// <summary> /// Deletes the SVN ignore property. /// Idempotent. /// </summary> public static void DeleteSvnIgnore(this SvnCommand svnCommand, AbsolutePath path) { svnCommand.DeleteProperty(path, SvnCommand.SvnIgnorePropertyName); }
public static void SetSvnIgnoreValues(this SvnCommand svnCommand, AbsolutePath path, params string[] values) { svnCommand.SetPropertyValues(path, SvnCommand.SvnIgnorePropertyName, values); }
/// <summary> /// Sets the whole value of the SVN ignore property. /// </summary> public static void SetSvnIgnoreValue(this SvnCommand svnCommand, AbsolutePath path, string value) { SvnCommandServicesProvider.SetPropertyValue(svnCommand.SvnExecutableFilePath, path, SvnCommand.SvnIgnorePropertyName, value, svnCommand.Logger); }
/// <summary> /// Gets the whole value of the SVN ignore property, or <see cref="SvnCommand.NonValue"/> if not. /// </summary> public static string GetSvnIgnoreValue(this SvnCommand svnCommand, AbsolutePath path) { var value = svnCommand.GetPropertyValueIfExists(path, SvnCommand.SvnIgnorePropertyName); return(value); }
public static bool HasSvnIgnoreProperty(this SvnCommand svnCommand, AbsolutePath path) { var output = svnCommand.HasProperty(path, SvnCommand.SvnIgnorePropertyName); return(output); }
public static ProcessOutputCollector Run(this SvnCommand svnCommand, IArgumentsBuilder arguments, bool throwIfAnyError = true) { var output = SvnCommandServicesProvider.Run(svnCommand.SvnExecutableFilePath, arguments, throwIfAnyError); return(output); }
public static void Add(this SvnCommand svnCommand, AbsolutePath path) { SvnCommandServicesProvider.Add(svnCommand.SvnExecutableFilePath, path, svnCommand.Logger); }
/// <summary> /// GitHub does not allow empty directories to be checked in (nor directories that only contain empty directories, i.e. recursively-empty directories). /// Thus many times there are recursively empty unversioned diretories that will be flagged as an uncommitted change, but should not be considered as uncommitted simply because they can't be committed! /// </summary> public static IEnumerable <SvnStringPathStatus> GetUncommittedChangesWithGitHubExceptions(this SvnCommand svnCommand, DirectoryPath directoryPath) { var allUncommittedStatuses = svnCommand.GetAllUncommittedChanges(directoryPath); foreach (var uncommittedStatus in allUncommittedStatuses) { // Unless it's an unversioned, recursively empty directory! var isUnversioned = uncommittedStatus.ItemStatus == ItemStatus.Unversioned; if (isUnversioned) { // Is the path a directory? var isDirectory = PathUtilities.IsDirectory(uncommittedStatus.Path); if (isDirectory) { // Is the directory recursively empty? var isDirectoryRecursivelyEmpty = PathUtilities.IsDirectoryRecursivelyEmpty(uncommittedStatus.Path); if (isDirectoryRecursivelyEmpty) { continue; // Nothing to see here. } } } yield return(uncommittedStatus); } }
/// <summary> /// The default method to get uncommitted changes in a directory. /// Note: uses the <see cref="GetUncommittedChangesWithGitHubExceptions(SvnCommand, DirectoryPath)"/> method. /// </summary> /// <returns></returns> public static IEnumerable <SvnStringPathStatus> GetUncommittedChanges(this SvnCommand svnCommand, DirectoryPath directoryPath) { var uncommittedChangesWithGitHubExceptions = svnCommand.GetUncommittedChangesWithGitHubExceptions(directoryPath); return(uncommittedChangesWithGitHubExceptions); }