コード例 #1
0
 private static void RemoveIdentifiableInformation(VstsDefinitionHttpClient client, params JObject[] definitions)
 {
     foreach (var definition in definitions)
     {
         foreach (JProperty property in client.FindIdentifiableDefinitionProperties(definition))
         {
             property.Remove();
         }
     }
 }
コード例 #2
0
 /// <summary>
 /// Copy all needed information according to <paramref name="client"/> from
 /// <paramref name="source"/> to <paramref name="destination"/>.
 /// </summary>
 private static void CopyIdentifiableInformation(
     VstsDefinitionHttpClient client,
     JObject source,
     JObject destination)
 {
     foreach (JProperty property in client.FindIdentifiableDefinitionProperties(source))
     {
         // Find the parent object of the property in destination and assign value by name.
         destination.SelectToken(property.Parent.Path)[property.Name] = property.Value;
     }
 }
コード例 #3
0
        /// <summary>
        /// Validates that definition1 is a content equivalent subset of definition2
        /// </summary>
        private static bool IsDefinitionContentSubsetEquivalent(
            VstsDefinitionHttpClient client,
            JObject definition1,
            JObject definition2)
        {
            JObject clonedDefinition1 = (JObject)definition1.DeepClone();
            JObject clonedDefinition2 = (JObject)definition2.DeepClone();

            RemoveIdentifiableInformation(client, clonedDefinition1, clonedDefinition2);

            // Compare only the child tokens present in the first definition to the corresponding contents of the second definition
            // The second definition may contain additional tokens which we don't care about.
            foreach (var childToken in clonedDefinition1.Children())
            {
                if (!JToken.DeepEquals(childToken.First, clonedDefinition2[childToken.Path]))
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Load a local definition, combine the uniqueIdentifier with the definition name,
        /// check VSTS for a matching definition name, if present, update that definition with the
        /// local definition, otherwise create a new definition.
        /// </summary>
        /// <param name="client">Definition client that interacts with VSTS API and understands
        /// definition JSON content.</param>
        /// <param name="definition">VSTS definition JSON object</param>
        /// <returns>Created or updated definition id</returns>
        private async Task <string> CreateOrUpdateDefinitionAsync(
            VstsDefinitionHttpClient client,
            JObject definition)
        {
            var key = _collectionIdentifier + "_" + definition["name"];

            definition["name"] = key;
            IReadOnlyList <JObject> vstsDefinitions = await client.RetrieveDefinitionsListByNameAndPathAsync(definition).ConfigureAwait(false);

            if (vstsDefinitions.Count == 0)
            {
                /* Create */

                /* Remove definition instance identifiable information */
                RemoveIdentifiableInformation(client, definition);

                JObject vstsDefinition = await client.CreateDefinitionAsync(definition).ConfigureAwait(false);

                return(vstsDefinition["id"].ToString());
            }
            if (vstsDefinitions.Count == 1)
            {
                JObject vstsDefinition = await client.RetrieveDefinitionByIdAsync(vstsDefinitions[0]).ConfigureAwait(false);

                /* Update */
                if (!IsDefinitionContentSubsetEquivalent(client, definition, vstsDefinition))
                {
                    CopyIdentifiableInformation(client, vstsDefinition, definition);
                    vstsDefinition = await client.UpdateDefinitionAsync(definition).ConfigureAwait(false);
                }
                return(vstsDefinition["id"].ToString());
            }
            throw new InvalidOperationException(
                      $"Obtained multiple {vstsDefinitions.Count} definitions with the same " +
                      $"'name' ({vstsDefinitions[0]["name"]}) and " +
                      $"'path' ({vstsDefinitions[0]["path"]}) properties.  " +
                      "This should not be possible.");
        }