/// <summary> /// Gets the <see cref="BumpVersionDescriptor"/> corresponding to the /// <paramref name="item"/>. /// </summary> /// <param name="item"></param> /// <param name="log"></param> /// <returns></returns> internal static BumpVersionDescriptor ToDescriptor(this ITaskItem item , TaskLoggingHelper log = null) { // TODO: TBD: To Descriptor? used in what way? var descriptor = new BumpVersionDescriptor(item); // TODO: TBD: may combine these into a common area... void SetPropertyFromMetadata <T>(string metadataName, Func <string, T> convert , Action <BumpVersionDescriptor, T> setter) { if (item.HasMetadataName(metadataName)) { setter(descriptor, convert(item.GetMetadata(metadataName))); } } SetPropertyFromMetadata(UseUtc, bool.Parse, (d, x) => d.UseUtc = x); SetPropertyFromMetadata(CreateNew, bool.Parse, (d, x) => d.CreateNew = x); SetPropertyFromMetadata(MayReset, bool.Parse, (d, x) => d.MayReset = x); SetPropertyFromMetadata(IncludeWildcard, bool.Parse, (d, x) => d.IncludeWildcard = x); SetPropertyFromMetadata(DefaultVersion, s => s, (d, s) => d.DefaultVersion = s); // TODO: TBD: look into it, see if there is a way that Property Groups could be used instead, i.e. that do not appear as "project items" ... // TODO: TBD: they must include attributes, etc... VersionKind ParseVersionKind(string s) { var kind = s.ToNullableVersionKind(); if (kind != null) { return(kind.Value); } IEnumerable <string> GetVersionKindListing() => from k in Enum.GetValues(typeof(VersionKind)).OfType <VersionKind>() select $"'{k}'"; throw new InvalidOperationException( $"Expecting '{typeof(ITaskItem).FullName + '.' + nameof(ITaskItem.ItemSpec)}' to be among: {{ {Join(", ", GetVersionKindListing())} }}" ); } descriptor.Kind = ParseVersionKind(item.ItemSpec); #if TASK_LOGGING_HELPER_DIAGNOSTICS log?.LogWarning($"Parsed version kind '{descriptor.Kind}'."); #endif return(descriptor); }
/// <summary> /// Returns a <see cref="IVersionProvider"/> corresponding to the /// <paramref name="item"/>, <paramref name="providerRequest"/>, and /// <paramref name="timestamp"/>. /// </summary> /// <param name="item"></param> /// <param name="providerRequest"></param> /// <param name="timestamp"></param> /// <returns></returns> /// <see cref="!:http://semver.org/#spec-item-9"/> internal static IVersionProvider ToVersionProvider(this ITaskItem item , string providerRequest, DateTime timestamp) { var preq = providerRequest; IVersionProvider Lookup() => item.HasMetadataName(preq) ? item.GetMetadata(preq).LookupVersionProvider() : NoOp; var provider = Lookup(); int ParseInteger(string s) => int.Parse(s); bool ParseBoolean(string s) => bool.Parse(s); // ReSharper disable once ImplicitlyCapturedClosure void SetPropertyFromMetadata <T>(string metadataName, Func <string, T> convert , Action <IVersionProvider, T> setProviderAttribute) { if (!item.HasMetadataName(metadataName)) { return; } setProviderAttribute(provider, convert(item.GetMetadata(metadataName))); } SetPropertyFromMetadata($"{preq}{nameof(IVersionProvider.MayReset)}" , ParseBoolean, (versionProvider, x) => versionProvider.MayReset = x); // May specify whether to UseUtc across the entire request, or for specific Version Elements. SetPropertyFromMetadata($"{preq}{nameof(IVersionProvider.UseUtc)}" , ParseBoolean, (versionProvider, x) => versionProvider.SetTimestamp(timestamp, x)); /* Most of the Providers are "vanilla" with base options. However, in a * couple of instances there are specialized options that we can expect. */ // ReSharper disable once InvertIf if (provider is PreReleaseIncrementVersionProvider preReleaseProvider) { string FilterLabel(string s) { s = s.Trim(); /* TODO: TBD: may want this to be a subset involving just the alpha characters, and maybe * the hypen as well, but not the digits on account that is the Value of this Provider. */ const string acceptablePattern = @"^[0-9A-Za-z\-]+$"; if (IsNullOrEmpty(s)) { // This is acceptable. } else if (!IsMatch(s, acceptablePattern)) { /* This according to Semantic Versioning 2.0.0: http://semver.org/#spec-item-9. * Not matching now, however, is not acceptable. */ throw new InvalidOperationException( $"Label '{s}' contains invalid Semantic Version characters '{acceptablePattern}'." ); } return(s); } SetPropertyFromMetadata($"{preq}{nameof(preReleaseProvider.Label)}" , FilterLabel, (_, x) => preReleaseProvider.Label = x); SetPropertyFromMetadata($"{preq}{nameof(preReleaseProvider.ValueWidth)}" , ParseInteger, (_, x) => preReleaseProvider.ValueWidth = x); SetPropertyFromMetadata($"{preq}{nameof(preReleaseProvider.ShouldDiscard)}" , ParseBoolean, (_, x) => preReleaseProvider.ShouldDiscard = x); } return(provider); }