Skip to content

Instantly share code, notes, and snippets.

@djfr
Created March 21, 2016 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djfr/555093c3faf917733b88 to your computer and use it in GitHub Desktop.
Save djfr/555093c3faf917733b88 to your computer and use it in GitHub Desktop.
namespace DevOpsFlex.Analyzers
{
using System.Diagnostics.Contracts;
using System.IO;
using System.Text.RegularExpressions;
/// <summary>
/// Wraps logic around Name, Version and generic regular expression lazy initializations to support
/// the package consolidation analyzer.
/// </summary>
public class Package
{
private static readonly string PackageVersionRegex = PackagesFolderName.Replace("\\", "\\\\") + "[^0-9]*([0-9]+(?:\\.[0-9]+)+)(?:\\\\)?";
private static readonly string PackageNameRegex = PackagesFolderName.Replace("\\", "\\\\") + "([a-zA-Z]+(?:\\.[a-zA-Z]+)*)[^\\\\]*(?:\\\\)?";
private static readonly string PackageFolderRegex = "(.*" + PackagesFolderName.Replace("\\", "\\\\") + "[^\\\\]*)\\\\?";
private string _version;
private string _name;
/// <summary>
/// This is a convention constant that olds a string that all folders that we consider a "packages" folder contain.
/// </summary>
internal const string PackagesFolderName = "\\packages\\"; // convention
/// <summary>
/// Initializes a new instance of <see cref="Package"/>.
/// Has built in Contract validations that will all throw before any other code is able to throw.
/// </summary>
/// <param name="path">The path to the package folder that this package is based on.</param>
public Package(string path)
{
Contract.Requires(!string.IsNullOrEmpty(path));
Contract.Requires(Directory.Exists(path));
Contract.Requires(path.Contains(PackagesFolderName));
Contract.Requires(Regex.IsMatch(path, PackageFolderRegex, RegexOptions.Singleline), $"When casting string (path) to Package you need to ensure your path is being matched by the Folder Regex [{PackageFolderRegex}]");
Folder = Regex.Match(path, PackageFolderRegex, RegexOptions.Singleline).Groups[1].Value;
}
/// <summary>
/// Gets the package folder without the last "\".
/// </summary>
public string Folder { get; }
/// <summary>
/// Gets the package name component of the package folder as a string.
/// </summary>
public string Name => _name ?? (_name = Regex.Match(Folder, PackageNameRegex, RegexOptions.Singleline).Groups[1].Value);
/// <summary>
/// Gets the package version component of the package folder as a string.
/// </summary>
public string Version => _version ?? (_version = Regex.Match(Folder, PackageVersionRegex, RegexOptions.Singleline).Groups[1].Value);
/// <summary>
/// Determines whether the specified objects are equal.
/// </summary>
/// <param name="y">The second <see cref="Package"/> object to compare.</param>
/// <returns>true if the specified objects are equal; otherwise, false.</returns>
public override bool Equals(object y)
{
Contract.Requires(y != null);
Contract.Requires(y.GetType() == typeof(Package));
return Folder == (y as Package)?.Folder;
}
/// <summary>
/// Returns a hash code for the specified object.
/// </summary>
/// <returns>A hash code for the specified object.</returns>
public override int GetHashCode()
{
return Folder.GetHashCode();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment