Skip to content

Commit

Permalink
Merge pull request #284 from AArnott/IncludeSchemaInInstall
Browse files Browse the repository at this point in the history
Include schema in install
  • Loading branch information
AArnott authored Dec 22, 2018
2 parents 3fe3dfd + 14b5792 commit 9af6b90
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ public async Task GetBuildVersion_OverrideBuildNumberOffset()
this.WriteVersionFile(versionOptions);
this.testProject.AddProperty("OverrideBuildNumberOffset", "10");
var buildResult = await this.BuildAsync();
Assert.Equal("14.1.11.31122", buildResult.AssemblyFileVersion);
Assert.StartsWith("14.1.11.", buildResult.AssemblyFileVersion);
}

[Fact]
Expand Down
17 changes: 15 additions & 2 deletions src/NerdBank.GitVersioning/VersionFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,20 @@ public static bool IsVersionDefined(string projectDirectory)
/// </param>
/// <param name="version">The version information to write to the file.</param>
/// <returns>The path to the file written.</returns>
public static string SetVersion(string projectDirectory, VersionOptions version)
public static string SetVersion(string projectDirectory, VersionOptions version) => SetVersion(projectDirectory, version, includeSchemaProperty: false);

/// <summary>
/// Writes the version.json file to a directory within a repo with the specified version information.
/// </summary>
/// <param name="projectDirectory">
/// The path to the directory in which to write the version.json file.
/// The file's impact will be all descendent projects and directories from this specified directory,
/// except where any of those directories have their own version.json file.
/// </param>
/// <param name="version">The version information to write to the file.</param>
/// <param name="includeSchemaProperty">A value indicating whether to serialize the $schema property for easier editing in most JSON editors.</param>
/// <returns>The path to the file written.</returns>
public static string SetVersion(string projectDirectory, VersionOptions version, bool includeSchemaProperty)
{
Requires.NotNullOrEmpty(projectDirectory, nameof(projectDirectory));
Requires.NotNull(version, nameof(version));
Expand All @@ -260,7 +273,7 @@ public static string SetVersion(string projectDirectory, VersionOptions version)
}

string versionJsonPath = Path.Combine(projectDirectory, JsonFileName);
var jsonContent = JsonConvert.SerializeObject(version, VersionOptions.GetJsonSettings(version.Inherit));
var jsonContent = JsonConvert.SerializeObject(version, VersionOptions.GetJsonSettings(version.Inherit, includeSchemaProperty));
File.WriteAllText(versionJsonPath, jsonContent);
return versionJsonPath;
}
Expand Down
29 changes: 21 additions & 8 deletions src/NerdBank.GitVersioning/VersionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public class VersionOptions : IEquatable<VersionOptions>
/// </summary>
private const int DefaultSemVer1NumericIdentifierPadding = 4;

/////// <summary>
/////// The $schema field that should be serialized when writing
/////// </summary>
////[JsonProperty(PropertyName = "$schema")]
////private string Schema => "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json";
/// <summary>
/// The $schema field that should be serialized when writing
/// </summary>
[JsonProperty(PropertyName = "$schema")]
public string Schema => "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json";

/// <summary>
/// Gets or sets the default version to use.
Expand Down Expand Up @@ -156,10 +156,19 @@ public static VersionOptions FromVersion(Version version, string unstableTag = n

/// <summary>
/// Gets the <see cref="JsonSerializerSettings"/> to use based on certain requirements.
/// The $schema property is not serialized when using this overload.
/// </summary>
/// <param name="includeDefaults"></param>
/// <param name="includeDefaults">A value indicating whether default values should be serialized.</param>
/// <returns>The serializer settings to use.</returns>
public static JsonSerializerSettings GetJsonSettings(bool includeDefaults = false)
public static JsonSerializerSettings GetJsonSettings(bool includeDefaults) => GetJsonSettings(includeDefaults, includeSchemaProperty: false);

/// <summary>
/// Gets the <see cref="JsonSerializerSettings"/> to use based on certain requirements.
/// </summary>
/// <param name="includeDefaults">A value indicating whether default values should be serialized.</param>
/// <param name="includeSchemaProperty">A value indicating whether the $schema property should be serialized.</param>
/// <returns>The serializer settings to use.</returns>
public static JsonSerializerSettings GetJsonSettings(bool includeDefaults = false, bool includeSchemaProperty = false)
{
return new JsonSerializerSettings
{
Expand All @@ -169,7 +178,11 @@ public static JsonSerializerSettings GetJsonSettings(bool includeDefaults = fals
new AssemblyVersionOptionsConverter(includeDefaults),
new StringEnumConverter() { CamelCaseText = true },
},
ContractResolver = includeDefaults ? VersionOptionsContractResolver.IncludeDefaultsContractResolver : VersionOptionsContractResolver.ExcludeDefaultsContractResolver,
ContractResolver = new VersionOptionsContractResolver
{
IncludeDefaults = includeDefaults,
IncludeSchemaProperty = includeSchemaProperty,
},
Formatting = Formatting.Indented,
};
}
Expand Down
62 changes: 54 additions & 8 deletions src/NerdBank.GitVersioning/VersionOptionsContractResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,65 @@

internal class VersionOptionsContractResolver : CamelCasePropertyNamesContractResolver
{
internal static readonly IContractResolver IncludeDefaultsContractResolver = new VersionOptionsContractResolver();
internal static readonly IContractResolver ExcludeDefaultsContractResolver = new ExcludeDefaults();
private static readonly object TypeContractCacheLock = new object();

protected VersionOptionsContractResolver()
private static readonly Dictionary<Tuple<bool, bool, Type>, JsonContract> contractCache = new Dictionary<Tuple<bool, bool, Type>, JsonContract>();

public VersionOptionsContractResolver()
{
}

private class ExcludeDefaults : VersionOptionsContractResolver
internal bool IncludeSchemaProperty { get; set; }

internal bool IncludeDefaults { get; set; } = true;

/// <summary>
/// Obtains a contract for a given type.
/// </summary>
/// <param name="type">The type to obtain a contract for.</param>
/// <returns>The contract.</returns>
/// <remarks>
/// This override changes the caching policy from the base class, which caches based on this.GetType().
/// The inherited policy is problematic because we have instance properties that change the contract.
/// So instead, we cache with a complex key to capture the settings as well.
/// </remarks>
public override JsonContract ResolveContract(Type type)
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
var contractKey = Tuple.Create(this.IncludeSchemaProperty, this.IncludeDefaults, type);

JsonContract contract;
lock (TypeContractCacheLock)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (contractCache.TryGetValue(contractKey, out contract))
{
return contract;
}
}

contract = base.CreateContract(type);

lock (TypeContractCacheLock)
{
if (!contractCache.ContainsKey(contractKey))
{
contractCache.Add(contractKey, contract);
}
}

return contract;
}

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);

if (property.DeclaringType == typeof(VersionOptions) && member.Name == nameof(VersionOptions.Schema))
{
property.ShouldSerialize = instance => this.IncludeSchemaProperty;
}

if (!this.IncludeDefaults)
{
if (property.DeclaringType == typeof(VersionOptions) && member.Name == nameof(VersionOptions.AssemblyVersion))
{
property.ShouldSerialize = instance => !((VersionOptions)instance).AssemblyVersionOrDefault.IsDefault;
Expand Down Expand Up @@ -68,9 +114,9 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
{
property.ShouldSerialize = instance => ((VersionOptions.CloudBuildNumberCommitIdOptions)instance).WhereOrDefault != VersionOptions.CloudBuildNumberCommitIdOptions.DefaultInstance.Where.Value;
}

return property;
}

return property;
}
}
}
2 changes: 1 addition & 1 deletion src/nbgv/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ private static ExitCodes OnInstallCommand(string versionJsonRoot, string version
}
else
{
string versionJsonPath = VersionFile.SetVersion(versionJsonRoot, options);
string versionJsonPath = VersionFile.SetVersion(versionJsonRoot, options, includeSchemaProperty: true);
LibGit2Sharp.Commands.Stage(repository, versionJsonPath);
}

Expand Down

0 comments on commit 9af6b90

Please sign in to comment.