diff --git a/appsettings.json b/appsettings.json
index 8dfba0693..9d301c515 100644
--- a/appsettings.json
+++ b/appsettings.json
@@ -58,9 +58,7 @@
"CommonTools": {
"FieldMappingTool": {
"Enabled": false,
- "FieldMaps": [],
- "FieldMapDefaults": {
- }
+ "FieldMaps": []
},
"TfsChangeSetMappingTool": {
"Enabled": false,
@@ -148,6 +146,12 @@
}
},
"CommonToolSamples": {
+ "TfsGitRepositoryTool": {
+ "Enabled": true,
+ "Mappings": {
+ "RepoInSource": "RepoInTarget"
+ }
+ },
"FieldMappingTool": {
"Enabled": true,
"FieldMaps": [
@@ -159,13 +163,42 @@
"formatExpression": "{0} \n {1}"
},
{
- "FieldMapType": "FieldLiteralMap",
+ "FieldMapType": "FieldValueMap",
+ "ApplyTo": [ "SomeWorkItemType" ],
+ "sourceField": "System.State",
+ "targetField": "System.State",
+ "defaultValue": "New",
+ "valueMapping": {
+ "Active": "InProgress",
+ "Resolved": "InProgress",
+ "Closed": "Done"
+ }
+ },
+ {
+ "FieldMapType": "FieldToFieldMap",
+ "ApplyTo": [ "SomeWorkItemType" ],
+ "sourceField": "Microsoft.VSTS.Common.BacklogPriority",
+ "targetField": "Microsoft.VSTS.Common.StackRank",
+ "defaultValue": 42
+ }
+ ],
+ "FieldMapSamples": {
+ "FieldClearMap": {
+ "ApplyTo": [ "SomeWorkItemType" ],
+ "targetField": "Custom.FieldC"
+ },
+ "FieldMergeMap": {
+ "ApplyTo": [ "SomeWorkItemType" ],
+ "sourceFields": [ "Custom.FieldA", "Custom.FieldB" ],
+ "targetField": "Custom.FieldC",
+ "formatExpression": "{0} \n {1}"
+ },
+ "FieldLiteralMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"targetField": "Custom.SomeField",
"value": "New field value"
},
- {
- "FieldMapType": "MultiValueConditionalMap",
+ "MultiValueConditionalMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceFieldsAndValues": {
"Field1": "Value1",
@@ -176,13 +209,11 @@
"Field2": "Value2"
}
},
- {
- "FieldMapType": "FieldSkipMap",
+ "targetFieldsAndValues": {
"ApplyTo": [ "SomeWorkItemType" ],
"targetField": "Custom.ReflectedWorkItemId"
},
- {
- "FieldMapType": "FieldValueMap",
+ "FieldValueMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceField": "System.State",
"targetField": "System.State",
@@ -191,29 +222,25 @@
"StateA": "StateB"
}
},
- {
- "FieldMapType": "FieldToFieldMap",
+ "FieldToFieldMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceField": "Microsoft.VSTS.Common.BacklogPriority",
"targetField": "Microsoft.VSTS.Common.StackRank",
"defaultValue": 42
},
- {
- "FieldMapType": "FieldToFieldMultiMap",
+ "FieldToFieldMultiMap": {
"ApplyTo": [ "SomeWorkItemType", "SomeOtherWorkItemType" ],
"SourceToTargetMappings": {
"SourceField1": "TargetField1",
"SourceField2": "TargetField2"
}
},
- {
- "FieldMapType": "FieldToTagMap",
+ "FieldToTagMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceField": "System.State",
"formatExpression": "ScrumState:{0}"
},
- {
- "FieldMapType": "FieldToTagFieldMap",
+ "FieldToTagFieldMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceFields": [
"System.Description",
@@ -222,29 +249,25 @@
"targetField": "System.Description",
"formatExpression": "{0}
Acceptance Criteria
{1}"
},
- {
- "FieldMapType": "RegexFieldMap",
+ "RegexFieldMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceField": "COMPANY.PRODUCT.Release",
"targetField": "COMPANY.DEVISION.MinorReleaseVersion",
"pattern": "PRODUCT \\d{4}.(\\d{1})",
"replacement": "$1"
},
- {
- "FieldMapType": "FieldValueToTagMap",
+ "FieldValueToTagMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"sourceField": "Microsoft.VSTS.CMMI.Blocked",
"pattern": "Yes",
"formatExpression": "{0}"
},
- {
- "FieldMapType": "TreeToTagMap",
+ "TreeToTagMap": {
"ApplyTo": [ "SomeWorkItemType" ],
"toSkip": 3,
"timeTravel": 1
}
- ]
-
+ }
},
"TfsChangeSetMappingTool": {
"Enabled": true,
@@ -330,12 +353,6 @@
},
"TfsEmbededImagesTool": {
"Enabled": true
- },
- "GitRepositoryTool": {
- "Enabled": true,
- "Mappings": {
- "Repo1": "Repo2"
- }
}
},
"ProcessorDefaults": {
diff --git a/docs/Reference/Generated/MigrationTools.Clients.AzureDevops.ObjectModel.xml b/docs/Reference/Generated/MigrationTools.Clients.AzureDevops.ObjectModel.xml
index ff49060cd..84cdced43 100644
--- a/docs/Reference/Generated/MigrationTools.Clients.AzureDevops.ObjectModel.xml
+++ b/docs/Reference/Generated/MigrationTools.Clients.AzureDevops.ObjectModel.xml
@@ -455,6 +455,12 @@
from https://gist.github.com/pietergheysens/792ed505f09557e77ddfc1b83531e4fb
+
+
+ List of work item mappings.
+
+ {}
+
The TfsNodeStructureToolEnricher is used to create missing nodes in the target project. To configure it add a `TfsNodeStructureToolOptions` section to `CommonEnrichersConfig` in the config file. Otherwise defaults will be applied.
diff --git a/docs/Reference/Generated/MigrationTools.xml b/docs/Reference/Generated/MigrationTools.xml
index 5f4728aed..ae68ade4f 100644
--- a/docs/Reference/Generated/MigrationTools.xml
+++ b/docs/Reference/Generated/MigrationTools.xml
@@ -201,17 +201,6 @@
If set to `true` then the tool will run. Set to `false` and the processor will not run.
-
-
- Used to process the String fields of a work item. This is useful for cleaning up data. It will limit fields to a max length and apply regex replacements based on what is configured. Each regex replacement is applied in order and can be enabled or disabled.
-
-
-
-
- List of work item mappings.
-
- {}
-
Used to process the String fields of a work item. This is useful for cleaning up data. It will limit fields to a max length and apply regex replacements based on what is configured. Each regex replacement is applied in order and can be enabled or disabled.
@@ -274,27 +263,27 @@
- => @"91912a6b"
+ => @"7eaf4f78"
- => @"91912a6b094734882a9067fd23d5d7bbda82b191"
+ => @"7eaf4f78b693a09be4ba34347308121603371a18"
- => @"2024-08-28T10:20:42+01:00"
+ => @"2024-08-28T10:49:54+01:00"
- => @"216"
+ => @"217"
- => @"v15.2.1-216-g91912a6b"
+ => @"v15.2.1-217-g7eaf4f78"
@@ -329,7 +318,7 @@
- => @"217"
+ => @"218"
diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryTool.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryTool.cs
index 2223758a7..a717c129b 100644
--- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryTool.cs
+++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryTool.cs
@@ -81,7 +81,6 @@ public int Enrich(TfsProcessor processor, WorkItemData sourceWorkItem, WorkItem
Log.LogInformation("GitRepositoryEnricher: Enriching {Id} To fix Git Repo Links", targetWorkItem.Id);
var changeSetMappings = Services.GetService();
- var gitRepoMaps = Services.GetService();
List newEL = new List();
List removeEL = new List();
int count = 0;
@@ -110,7 +109,7 @@ public int Enrich(TfsProcessor processor, WorkItemData sourceWorkItem, WorkItem
{
var anyProjectSourceRepoInfo = TfsGitRepositoryInfo.Create(el, allSourceRepos, changeSetMappings, sourceWorkItem?.ProjectName);
// if repo is found in a different project and the repo Name is listed in repo mappings, use it
- if (anyProjectSourceRepoInfo.GitRepo != null && gitRepoMaps.Mappings.ContainsKey(anyProjectSourceRepoInfo.GitRepo.Name))
+ if (anyProjectSourceRepoInfo.GitRepo != null && Options.Mappings.ContainsKey(anyProjectSourceRepoInfo.GitRepo.Name))
{
sourceRepoInfo = anyProjectSourceRepoInfo;
}
@@ -122,7 +121,7 @@ public int Enrich(TfsProcessor processor, WorkItemData sourceWorkItem, WorkItem
if (sourceRepoInfo.GitRepo != null)
{
- string targetRepoName = GetTargetRepoName(gitRepoMaps.Mappings, sourceRepoInfo);
+ string targetRepoName = GetTargetRepoName(Options.Mappings, sourceRepoInfo);
string sourceProjectName = sourceRepoInfo?.GitRepo?.ProjectReference?.Name ?? _processor.Target.Options.Project;
string targetProjectName = _processor.Target.Options.Project;
@@ -130,7 +129,7 @@ public int Enrich(TfsProcessor processor, WorkItemData sourceWorkItem, WorkItem
// if repo was not found in the target project, try to find it in the whole target project collection
if (targetRepoInfo.GitRepo == null)
{
- if (gitRepoMaps.Mappings.Values.Contains(targetRepoName))
+ if (Options.Mappings.Values.Contains(targetRepoName))
{
var anyTargetRepoInCollectionInfo = TfsGitRepositoryInfo.Create(targetRepoName, sourceRepoInfo, allTargetRepos);
if (anyTargetRepoInCollectionInfo.GitRepo != null)
@@ -233,7 +232,7 @@ where gitWits.Contains(lq.ArtifactLinkType.Name)
return count;
}
- private string GetTargetRepoName(ReadOnlyDictionary gitRepoMappings, TfsGitRepositoryInfo repoInfo)
+ private string GetTargetRepoName(Dictionary gitRepoMappings, TfsGitRepositoryInfo repoInfo)
{
if (gitRepoMappings.ContainsKey(repoInfo.GitRepo.Name))
{
diff --git a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryToolOptions.cs b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryToolOptions.cs
index efaf4b74f..ca248b643 100644
--- a/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryToolOptions.cs
+++ b/src/MigrationTools.Clients.AzureDevops.ObjectModel/Tools/TfsGitRepositoryToolOptions.cs
@@ -8,6 +8,10 @@ namespace MigrationTools.Tools
{
public class TfsGitRepositoryToolOptions : ToolOptions
{
-
+ ///
+ /// List of work item mappings.
+ ///
+ /// {}
+ public Dictionary Mappings { get; set; }
}
}
\ No newline at end of file
diff --git a/src/MigrationTools.ConsoleDataGenerator/ClassDataLoader.cs b/src/MigrationTools.ConsoleDataGenerator/ClassDataLoader.cs
index 8adf7ff48..e21b1e3ae 100644
--- a/src/MigrationTools.ConsoleDataGenerator/ClassDataLoader.cs
+++ b/src/MigrationTools.ConsoleDataGenerator/ClassDataLoader.cs
@@ -96,7 +96,7 @@ private ClassData CreateClassDataFromOptions(List allTy
data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "defaults", SampleFor = data.OptionsClassFullName, Code = json.Trim() });
} else
{
- data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "defaults", SampleFor = data.OptionsClassFullName, Code = "Default Unavailable" });
+ data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "defaults", SampleFor = data.OptionsClassFullName, Code = "There are no defaults! Check the sample for options!" });
}
}
if (!string.IsNullOrEmpty(instanceOfOption.ConfigurationMetadata.PathToSample))
@@ -111,7 +111,7 @@ private ClassData CreateClassDataFromOptions(List allTy
}
else
{
- data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "sample", SampleFor = data.OptionsClassFullName, Code = "Sample Unavailable" });
+ data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "sample", SampleFor = data.OptionsClassFullName, Code = "There is no sample, but you can check the classic below for a general feel." });
}
}
data.ConfigurationSamples.Add(new ConfigurationSample() { Name = "classic", SampleFor = data.OptionsClassFullName, Code = saveData.SeraliseDataToJson(instanceOfOption).Trim() });
diff --git a/src/MigrationTools.ConsoleDataGenerator/Program.cs b/src/MigrationTools.ConsoleDataGenerator/Program.cs
index dc5cfea8d..5c68e0a6a 100644
--- a/src/MigrationTools.ConsoleDataGenerator/Program.cs
+++ b/src/MigrationTools.ConsoleDataGenerator/Program.cs
@@ -54,11 +54,11 @@ static void Main(string[] args)
List classDataList = new List();
classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "Processors"));
- //classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "Tools"));
- //classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "FieldMaps"));
- //classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "ProcessorEnrichers"));
- //classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "Endpoints"));
- //classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "EndpointEnrichers"));
+ classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "Tools"));
+ classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "FieldMaps"));
+ classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "ProcessorEnrichers"));
+ classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "Endpoints"));
+ classDataList.AddRange(cdLoader.GetClassDataFromOptions(allMigrationTypes, "EndpointEnrichers"));
diff --git a/src/MigrationTools/ServiceCollectionExtensions.cs b/src/MigrationTools/ServiceCollectionExtensions.cs
index 6d03db4ff..742d23e87 100644
--- a/src/MigrationTools/ServiceCollectionExtensions.cs
+++ b/src/MigrationTools/ServiceCollectionExtensions.cs
@@ -45,12 +45,12 @@ public static void AddMigrationToolServices(this IServiceCollection context, ICo
case MigrationConfigSchema.v1:
context.AddSingleton().AddSingleton>(Microsoft.Extensions.Options.Options.Create(configuration.GetSectionCommonEnrichers_v15()));
context.AddSingleton().AddSingleton>(Microsoft.Extensions.Options.Options.Create(configuration.GetSectionCommonEnrichers_v15()));
- context.AddSingleton().AddSingleton>(Microsoft.Extensions.Options.Options.Create(configuration.GetSectionCommonEnrichers_v15()));
+ //context.AddSingleton().AddSingleton>(Microsoft.Extensions.Options.Options.Create(configuration.GetSectionCommonEnrichers_v15()));
break;
case MigrationConfigSchema.v160:
context.AddSingleton().AddMigrationToolsOptions(configuration);
context.AddSingleton().AddMigrationToolsOptions(configuration);
- context.AddSingleton().AddMigrationToolsOptions(configuration);
+ // context.AddSingleton().AddMigrationToolsOptions(configuration);
break;
}
context.AddSingleton()
diff --git a/src/MigrationTools/Tools/FieldMappingTool/Infrastructure/FieldMapOptions.cs b/src/MigrationTools/Tools/FieldMappingTool/Infrastructure/FieldMapOptions.cs
index 0029621d9..eb43bb5ba 100644
--- a/src/MigrationTools/Tools/FieldMappingTool/Infrastructure/FieldMapOptions.cs
+++ b/src/MigrationTools/Tools/FieldMappingTool/Infrastructure/FieldMapOptions.cs
@@ -15,11 +15,12 @@ public abstract class FieldMapOptions : IFieldMapOptions
[JsonIgnore]
public ConfigurationMetadata ConfigurationMetadata => new ConfigurationMetadata
{
- PathToInstance = $"MigrationTools:CommonTools:FieldMappingTool:FieldMaps:{OptionFor}",
+ IsCollection = true,
+ PathToInstance = $"MigrationTools:CommonTools:FieldMappingTool:FieldMaps",
ObjectName = $"FieldMapType",
OptionFor = OptionFor,
- PathToDefault = $"MigrationTools::CommonToolDefaults:FieldMappingTool:FieldMaps:{OptionFor}",
- PathToSample = $"MigrationTools::CommonToolSamples:FieldMappingTool:FieldMaps:{OptionFor}"
+ PathToDefault = $"MigrationTools:CommonTools:FieldMappingTool:FieldMapDefaults:{OptionFor}",
+ PathToSample = $"MigrationTools:CommonToolSamples:FieldMappingTool:FieldMapSamples:{OptionFor}"
};
protected FieldMapOptions()
diff --git a/src/MigrationTools/Tools/GitRepoMappingTool.cs b/src/MigrationTools/Tools/GitRepoMappingTool.cs
deleted file mode 100644
index f98f3e76e..000000000
--- a/src/MigrationTools/Tools/GitRepoMappingTool.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Text;
-using System.Text.RegularExpressions;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using MigrationTools.DataContracts;
-using MigrationTools.Enrichers;
-using MigrationTools.Processors;
-using MigrationTools.Tools.Infrastructure;
-using static Microsoft.VisualStudio.Services.Graph.GraphResourceIds.Users;
-
-namespace MigrationTools.Tools
-{
- ///
- /// Used to process the String fields of a work item. This is useful for cleaning up data. It will limit fields to a max length and apply regex replacements based on what is configured. Each regex replacement is applied in order and can be enabled or disabled.
- ///
- public class GitRepoMappingTool : Tool
- {
- public ReadOnlyDictionary Mappings { get; private set; }
-
- public GitRepoMappingTool(IOptions options, IServiceProvider services, ILogger logger, ITelemetryLogger telemetryLogger)
- : base(options, services, logger, telemetryLogger)
- {
-
- Mappings = new ReadOnlyDictionary(Options.Mappings);
- }
-
- }
-
-}
-
diff --git a/src/MigrationTools/Tools/GitRepoMappingToolOptions.cs b/src/MigrationTools/Tools/GitRepoMappingToolOptions.cs
deleted file mode 100644
index 5bd749d48..000000000
--- a/src/MigrationTools/Tools/GitRepoMappingToolOptions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MigrationTools.Enrichers;
-using MigrationTools.Options;
-using MigrationTools.Tools.Infrastructure;
-
-namespace MigrationTools.Tools
-{
- public class GitRepoMappingToolOptions : ToolOptions
- {
-
- ///
- /// List of work item mappings.
- ///
- /// {}
- public Dictionary Mappings { get; set; }
- }
-
-}
\ No newline at end of file
diff --git a/src/MigrationTools/Tools/Infrastructure/ToolOptions.cs b/src/MigrationTools/Tools/Infrastructure/ToolOptions.cs
index 6727be5bc..f856cd34d 100644
--- a/src/MigrationTools/Tools/Infrastructure/ToolOptions.cs
+++ b/src/MigrationTools/Tools/Infrastructure/ToolOptions.cs
@@ -9,7 +9,7 @@ namespace MigrationTools.Tools.Infrastructure
public abstract class ToolOptions : IToolOptions
{
[JsonIgnore]
- public string OptionFor => $"{GetType().Name.Replace("Options", "")}";
+ private string OptionFor => $"{GetType().Name.Replace("Options", "")}";
[JsonIgnore]
public ConfigurationMetadata ConfigurationMetadata => new ConfigurationMetadata