Skip to content

Commit

Permalink
Merge pull request #70 from BlythMeister/FlattenPropertyGroup
Browse files Browse the repository at this point in the history
Property Group Label Enhancements
  • Loading branch information
Richard Green authored Aug 25, 2017
2 parents 3a44e5d + 96b4641 commit 7cc590a
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
// [assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0-feature-Ma-local")]
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
// [assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0-feature-Ma-local")]
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,38 @@
<Property name="avalue">idvalue</Property>
</Properties>
</PropertyGroup>
<PropertyGroup identity="0">
<Label>Label1</Label>
<Label>Label2</Label>
<Properties>
<Property name="Value">ABC123</Property>
</Properties>
</PropertyGroup>
<PropertyGroup identity="1">
<Label>Label1</Label>
<Properties>
<Property name="Value">321CBA</Property>
</Properties>
</PropertyGroup>
<PropertyGroup identity="0">
<Label>Label3</Label>
<Property name="Value">999</Property>
</PropertyGroup>
<PropertyGroup identity="0">
<Labels>
<Label>LabelGrouped1</Label>
<Label>LabelGrouped2</Label>
</Labels>
<Properties>
<Property name="Value">888</Property>
</Properties>
</PropertyGroup>
<PropertyGroup label="FlatGroup" identity="0">
<Property name="Value">FlatGroup-0</Property>
</PropertyGroup>
<PropertyGroup label="FlatGroup" identity="1">
<Property name="Value">FlatGroup-1</Property>
</PropertyGroup>
</PropertyGroups>
<DbLogins>
<DbLogin>
Expand Down
46 changes: 43 additions & 3 deletions src/15below.Deployment.Update.Tests/TagDictionaryTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using NUnit.Framework;

namespace FifteenBelow.Deployment.Update.Tests
{
Expand Down Expand Up @@ -232,6 +232,13 @@ public void LoadLabelledGroups()
Assert.IsTrue(sut.ContainsKey("GDS"));
}

[Test]
public void LoadFlatLabelledGroups()
{
var sut = new TagDictionary("ident", XmlData);
Assert.IsTrue(sut.ContainsKey("FlatGroup"));
}

[Test]
public void LoadLabelledGroupsValuesAndNormalIdentityValuesAvailable()
{
Expand Down Expand Up @@ -275,7 +282,7 @@ public void OctopusVariablesConvertedToFriendlyTagNames(string key, string value
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.Environment, "" }, { TagSource.XmlData, XmlData } });
Assert.AreEqual(value, sut[friendlyKey]);
}

[Test]
public void UseAnInvalidProperty_Throws()
{
Expand Down Expand Up @@ -433,5 +440,38 @@ public void EnsureThatXmlIncludesWork_AndArriveRenderered()
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.XmlData, XmlData } });
Assert.AreEqual(xml.Value.RenderTemplate(sut), "{% include \"webservice-structure.xml\" %}".RenderTemplate(sut));
}

[Test]
public void DualLabeledGroupWorks()
{
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.XmlData, XmlData } });
Assert.AreEqual("ABC123", "{{ Label1.0.Value }}".RenderTemplate(sut));
Assert.AreEqual("ABC123", "{{ Label2.0.Value }}".RenderTemplate(sut));
Assert.AreEqual("321CBA", "{{ Label1.1.Value }}".RenderTemplate(sut));
Assert.Throws<ArgumentException>(() => "{{ Label2.1.Value }}".RenderTemplate(sut));
}

[Test]
public void FlatLabelGroupsHaveValues()
{
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.XmlData, XmlData } });
Assert.AreEqual("FlatGroup-0", "{{ FlatGroup.0.Value }}".RenderTemplate(sut));
Assert.AreEqual("FlatGroup-1", "{{ FlatGroup.1.Value }}".RenderTemplate(sut));
}

[Test]
public void LabelNodeWithoutProperties()
{
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.XmlData, XmlData } });
Assert.AreEqual("999", "{{ Label3.0.Value }}".RenderTemplate(sut));
}

[Test]
public void DualLabeledGroupWithContainerNodeWorks()
{
var sut = new TagDictionary("ident", new Dictionary<TagSource, string> { { TagSource.XmlData, XmlData } });
Assert.AreEqual("888", "{{ LabelGrouped1.0.Value }}".RenderTemplate(sut));
Assert.AreEqual("888", "{{ LabelGrouped2.0.Value }}".RenderTemplate(sut));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FixedStructure.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
91 changes: 91 additions & 0 deletions src/15below.Deployment.Update/FixedStructure.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:i="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:group name="Property">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="Property">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:element name="Structure">
<xs:complexType>
<xs:all>
<xs:element name="ClientCode" type="xs:string" />
<xs:element name="Environment" type="xs:string" />
<xs:element name="Properties">
<xs:complexType>
<xs:group ref="Property"/>
</xs:complexType>
</xs:element>
<xs:element name="PropertyGroups">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element maxOccurs="unbounded" minOccurs="0" name="PropertyGroup">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name="Labels" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Label" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" minOccurs="0" name="Label" type="xs:string" />
</xs:choice>
<xs:choice>
<xs:element name="Properties">
<xs:complexType>
<xs:group ref="Property"/>
</xs:complexType>
</xs:element>
<xs:group ref="Property"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="identity" type="xs:string" use="required" />
<xs:attribute name="label" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DbLogins">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="DbLogin">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="Key" type="xs:string" />
<xs:element name="Name" type="xs:string" />
<xs:element name="DefaultDb" type="xs:string" />
<xs:element name="Password" type="xs:string" />
</xs:sequence>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:choice>
<xs:sequence>
<xs:element name="DefaultDb" type="xs:string" />
<xs:element name="Password" type="xs:string" />
</xs:sequence>
<xs:element name="ConnectionString" type="xs:string" />
</xs:choice>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
6 changes: 3 additions & 3 deletions src/15below.Deployment.Update/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
// [assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0-feature-Ma-local")]
38 changes: 32 additions & 6 deletions src/15below.Deployment.Update/TagDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;

namespace FifteenBelow.Deployment.Update
Expand Down Expand Up @@ -94,13 +97,24 @@ private void PropertiesFromXml(string identifier, string xmlData)
return;
}

ValidateStructureFile(doc);
BasePropertiesFromXml(doc);
IdentityPropertyGroupsFromXml(identifier, doc);
GeneralPropertiesFromXml(doc);
LabelPropertiesFromXml(doc);
DbLoginPropertiesFromXml(doc);
}

private static void ValidateStructureFile(XDocument doc)
{
var schemas = new XmlSchemaSet();
var assembly = Assembly.GetExecutingAssembly();

schemas.Add(null, XmlReader.Create(assembly.GetManifestResourceStream("FifteenBelow.Deployment.Update.FixedStructure.xsd")));

doc.Validate(schemas, (sender, args) => { throw args.Exception; });
}

private void BasePropertiesFromXml(XDocument doc)
{
var environmentNode = doc.XPathSelectElement("/Structure/Environment");
Expand All @@ -121,7 +135,7 @@ private void IdentityPropertyGroupsFromXml(string identifier, XDocument doc)
{
var key = prop.Attribute("name").Value;
var value = prop.Value.Trim();
this[key] = value;
this[key] = value;
}
}

Expand All @@ -138,11 +152,23 @@ private void GeneralPropertiesFromXml(XDocument doc)

private void LabelPropertiesFromXml(XDocument doc)
{
var labelledGroups = doc.XPathSelectElements("/Structure/PropertyGroups/PropertyGroup").Where(pg => pg.Elements().Select(e => e.Name).Contains("Label"));
foreach (var labelledGroup in labelledGroups)
foreach (var propertyGroup in doc.XPathSelectElements("/Structure/PropertyGroups/PropertyGroup"))
{
var labels = labelledGroup.Elements("Label").Select(e => e.Value);
var identity = labelledGroup.Attribute("identity").Value;
var labels = new List<string>();
if (propertyGroup.Attribute("label") != null)
{
labels.Add(propertyGroup.Attribute("label").Value);
}
else if (propertyGroup.XPathSelectElements(".//Label").Any())
{
labels.AddRange(propertyGroup.XPathSelectElements(".//Label").Select(x => x.Value));
}
else
{
throw new InvalidDataException("PropertyGroup found with no label attribute or nodes");
}

var identity = propertyGroup.Attribute("identity").Value;
foreach (var label in labels)
{
SubTagDictionary labelDic;
Expand Down Expand Up @@ -171,7 +197,7 @@ private void LabelPropertiesFromXml(XDocument doc)
labelDic.Add(identity, instanceDic);
}

foreach (var prop in labelledGroup.XPathSelectElements("Properties/Property"))
foreach (var prop in propertyGroup.XPathSelectElements(".//Property"))
{
var key = prop.Attribute("name").Value;
var value = prop.Value.Trim();
Expand Down
9 changes: 3 additions & 6 deletions src/15below.Deployment.Update/UpdateFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,12 @@ public static string Update(XDocument subsXml, XmlNamespaceManager nsm, string b

if (fileElement == null) return File.ReadAllText(baseFile);

string replacementTemplate;
string baseData = null;

var replacementTemplateElement = fileElement.XPathSelectElement("s:ReplacementTemplate", nsm);
if (replacementTemplateElement != null)
{
replacementTemplate = replacementTemplateElement.Value.RenderTemplate(tagValues);
var replacementTemplate = replacementTemplateElement.Value.RenderTemplate(tagValues);
baseData = File.ReadAllText(replacementTemplate).RenderTemplate(tagValues);
}

Expand All @@ -113,9 +112,7 @@ private static void ValidateSubstitutionDoc(XDocument subsXml)
var schemas = new XmlSchemaSet();
var assembly = Assembly.GetExecutingAssembly();

schemas.Add(null,
XmlReader.Create(
assembly.GetManifestResourceStream("FifteenBelow.Deployment.Update.Substitutions.xsd")));
schemas.Add(null, XmlReader.Create(assembly.GetManifestResourceStream("FifteenBelow.Deployment.Update.Substitutions.xsd")));

subsXml.Validate(schemas, (sender, args) => { throw args.Exception; });
}
Expand Down Expand Up @@ -146,7 +143,7 @@ private static string UpdateXml(IDictionary<string, object> tagValues,

if (activeNode == null)
{
throw new ApplicationException(String.Format("XPath select of {0} returned null", sub.XPath));
throw new ApplicationException(string.Format("XPath select of {0} returned null", sub.XPath));
}

if (sub.HasReplacementContent) ReplaceChildNodes(tagValues, activeNode, sub);
Expand Down
2 changes: 1 addition & 1 deletion src/Deploy/ensconce.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package>
<metadata>
<id>Ensconce</id>
<version>1.0.2.0</version>
<version>1.0.3.0</version>
<title>Ensconce</title>
<authors>15below Ltd</authors>
<owners>15below Ltd</owners>
Expand Down
6 changes: 3 additions & 3 deletions src/Ensconce.Database.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
// [assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0-feature-Ma-local")]
6 changes: 3 additions & 3 deletions src/Ensconce/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
// [assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0-feature-Ma-local")]

0 comments on commit 7cc590a

Please sign in to comment.