Skip to content

Commit 2566faa

Browse files
author
Andrew Kanieski
committed
Fixed wit relation migration. Added node filters. Fixed history migrate.
1 parent b6b74d4 commit 2566faa

File tree

10 files changed

+144
-31
lines changed

10 files changed

+144
-31
lines changed

AzureDevOpsMigrator.WPF/Pages/RunMigrationPage.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private void Orchestrator_StatusChanged(object source, (int Increment, SyncState
5757
{
5858
CurrentCount += eventArgs.Increment;
5959
Bar_Progress.Value = CurrentCount;
60-
System.Diagnostics.Debug.WriteLine($"{CurrentCount}/{CurrentMax}");
60+
Text_Progress.Text = ($"{CurrentCount}/{CurrentMax}");
6161
Logs.Add(eventArgs);
6262
});
6363
}

AzureDevOpsMigrator.WPF/Pages/WitPages/WitAreaPathsPage.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</Grid.ColumnDefinitions>
1717
<Grid.RowDefinitions>
1818
<RowDefinition Height="40"></RowDefinition>
19+
<RowDefinition Height="40"></RowDefinition>
1920
</Grid.RowDefinitions>
2021

2122
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="0" Grid.Column="0">
@@ -25,5 +26,13 @@
2526
</StackPanel>
2627
<CheckBox Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"
2728
IsChecked="{Binding Model.Execution.AreaPathMigratorEnabled, Mode=TwoWay}" />
29+
30+
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="1" Grid.Column="0">
31+
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Area Path Filter (Regex)" />
32+
<Button Margin="20,0,0,0" Foreground="DodgerBlue" Background="Transparent" BorderThickness="0">
33+
</Button>
34+
</StackPanel>
35+
<TextBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"
36+
Text="{Binding Model.AreaPathFilter, Mode=TwoWay}" />
2837
</Grid>
2938
</Page>

AzureDevOpsMigrator.WPF/Pages/WitPages/WitGeneralPage.xaml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
<RowDefinition Height="40"></RowDefinition>
2626
<RowDefinition Height="40"></RowDefinition>
2727
<RowDefinition Height="40"></RowDefinition>
28+
<RowDefinition Height="40"></RowDefinition>
29+
<RowDefinition Height="40"></RowDefinition>
30+
<RowDefinition Height="40"></RowDefinition>
2831
</Grid.RowDefinitions>
2932

3033

@@ -51,9 +54,11 @@
5154
<Button Margin="20,0,0,0" Foreground="DodgerBlue" Background="Transparent" BorderThickness="0">
5255
</Button>
5356
</StackPanel>
54-
<TextBox Grid.Column="1" Grid.Row="2" VerticalAlignment="Center"
55-
Text="{Binding Model.MaxDegreeOfParallelism, Mode=TwoWay}" />
56-
57+
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1">
58+
<Slider VerticalAlignment="Center" Width="200" Minimum="1" Maximum="20"
59+
Value="{Binding Model.MaxDegreeOfParallelism, Mode=TwoWay}" />
60+
<TextBlock Text="{Binding Model.MaxDegreeOfParallelism, Mode=OneWay}" VerticalAlignment="Center" Margin="20,0,0,0"/>
61+
</StackPanel>
5762

5863
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="3" Grid.Column="0">
5964
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Compare Fields" />
@@ -92,13 +97,29 @@
9297
IsChecked="{Binding Model.MigrateAttachments, Mode=TwoWay}" />
9398

9499

100+
95101
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="7" Grid.Column="0">
102+
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Migrate Relations" />
103+
</StackPanel>
104+
<CheckBox Grid.Column="1" Grid.Row="7" VerticalAlignment="Center"
105+
IsChecked="{Binding Model.MigrateItemRelations, Mode=TwoWay}" />
106+
107+
108+
109+
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="8" Grid.Column="0">
110+
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Migrate Artifact Links" />
111+
</StackPanel>
112+
<CheckBox Grid.Column="1" Grid.Row="8" VerticalAlignment="Center"
113+
IsChecked="{Binding Model.MigrateArtifactLinks, Mode=TwoWay}" />
114+
115+
116+
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="9" Grid.Column="0">
96117
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Migration State Field" />
97118
<Button Margin="20,0,0,0" Foreground="DodgerBlue" Background="Transparent" BorderThickness="0">
98119

99120
</Button>
100121
</StackPanel>
101-
<TextBox Grid.Column="1" Grid.Row="7" VerticalAlignment="Center"
122+
<TextBox Grid.Column="1" Grid.Row="9" VerticalAlignment="Center"
102123
Text="{Binding Model.MigrationStateField, Mode=TwoWay}" />
103124
</Grid>
104125
</Grid>

AzureDevOpsMigrator.WPF/Pages/WitPages/WitIterationsPage.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
</Grid.ColumnDefinitions>
1818
<Grid.RowDefinitions>
1919
<RowDefinition Height="40"></RowDefinition>
20+
<RowDefinition Height="40"></RowDefinition>
2021
</Grid.RowDefinitions>
2122

2223
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="0" Grid.Column="0">
@@ -26,5 +27,13 @@
2627
</StackPanel>
2728
<CheckBox Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"
2829
IsChecked="{Binding Model.Execution.IterationsMigratorEnabled, Mode=TwoWay}" />
30+
31+
<StackPanel Orientation="Horizontal" Margin="5" Grid.Row="1" Grid.Column="0">
32+
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Iteration Filter (Regex)" />
33+
<Button Margin="20,0,0,0" Foreground="DodgerBlue" Background="Transparent" BorderThickness="0">
34+
</Button>
35+
</StackPanel>
36+
<TextBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"
37+
Text="{Binding Model.IterationFilter, Mode=TwoWay}" />
2938
</Grid>
3039
</Page>

AzureDevOpsMigrator/Models/Migration.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ public class MigrationConfig
2424
public string MigrationStateField { get; set; } = "MigrationState";
2525
public bool MigrateHistory { get; set; } = true;
2626
public bool MigrateAttachments { get; set; } = true;
27+
public string AreaPathFilter { get; set; } = "";
28+
public string IterationFilter { get; set; } = "";
2729

2830
public ObservableCollection<GitRepo> GitRepoMappings { get; set; } = new ObservableCollection<GitRepo>();
31+
public bool MigrateItemRelations { get; set; }
32+
public bool MigrateArtifactLinks { get; set; }
2933
}
3034
public class GitRepo
3135
{

AzureDevOpsMigrator/Services/Migrators/AreaPathMigrator.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,18 @@ public AreaPathMigrator(MigrationConfig config, ILogger<IAreaPathMigrator> log,
1515
{ }
1616
protected override TreeStructureGroup _nodesType => TreeStructureGroup.Areas;
1717
protected override TreeNodeStructureType _nodeType => TreeNodeStructureType.Area;
18+
19+
protected override bool IsFilterMatch(string path)
20+
{
21+
if (_areaFilter != _config.AreaPathFilter)
22+
{
23+
_areaFilter = _config.AreaPathFilter;
24+
_areaFilterMatcher = new System.Text.RegularExpressions.Regex(_config.AreaPathFilter);
25+
}
26+
return string.IsNullOrEmpty(_config.AreaPathFilter) ? true : _areaFilterMatcher.IsMatch(path);
27+
}
28+
29+
private string _areaFilter = "";
30+
private System.Text.RegularExpressions.Regex _areaFilterMatcher;
1831
}
1932
}

AzureDevOpsMigrator/Services/Migrators/ClassificationNodeMigrator.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,15 @@ public async Task ExecuteAsync(System.Threading.CancellationToken token)
3838

3939
var flattenedSourcePaths = new List<(string Path, WorkItemClassificationNode Node)>();
4040
FlattenNodes(sourcePaths, ref flattenedSourcePaths);
41-
flattenedSourcePaths = flattenedSourcePaths.OrderBy(s => s.Path).Select(p => (string.Join('\\', p.Path.Split(@"\").Skip(3)), p.Node)).ToList();
41+
flattenedSourcePaths = flattenedSourcePaths.OrderBy(s => s.Path)
42+
.Where(x => IsFilterMatch(x.Path))
43+
.Select(p => (string.Join('\\', p.Path.Split(@"\").Skip(3)), p.Node))
44+
.ToList();
4245

4346
var flattenedTargetPaths = new List<(string Path, WorkItemClassificationNode Node)>();
4447
FlattenNodes(targetPaths, ref flattenedTargetPaths);
45-
flattenedTargetPaths = flattenedTargetPaths.OrderBy(s => s.Path).Select(p => (string.Join('\\', p.Path.Split(@"\").Skip(3)), p.Node)).ToList();
48+
flattenedTargetPaths = flattenedTargetPaths.OrderBy(s => s.Path).Select(p => (string.Join('\\', p.Path.Split(@"\").Skip(3)), p.Node))
49+
.ToList();
4650

4751
_log.LogInformation($"{flattenedSourcePaths.Count} source nodes flattened");
4852
_log.LogInformation($"{flattenedTargetPaths.Count} target nodes flattened");
@@ -54,11 +58,11 @@ public async Task ExecuteAsync(System.Threading.CancellationToken token)
5458
{
5559
token.ThrowIfCancellationRequested();
5660

57-
5861
// look up modified path in target
5962
var existing = flattenedTargetPaths
60-
.Select(x => new { Path = x.Path, Node = x.Node})
63+
.Select(x => new { Path = x.Path, Node = x.Node })
6164
.FirstOrDefault(p => p.Path.Equals(sourceNode.Path, System.StringComparison.OrdinalIgnoreCase));
65+
6266
if (existing == null)
6367
{
6468
// Create a new area path in target
@@ -71,7 +75,7 @@ public async Task ExecuteAsync(System.Threading.CancellationToken token)
7175
Attributes = sourceNode.Node.Attributes,
7276
HasChildren = sourceNode.Node.HasChildren
7377
}));
74-
}
78+
}
7579
else
7680
{
7781
bool changes = false;
@@ -124,6 +128,11 @@ public async Task ExecuteAsync(System.Threading.CancellationToken token)
124128

125129
}
126130

131+
protected virtual bool IsFilterMatch(string path)
132+
{
133+
throw new NotImplementedException("Filter match is not implemented");
134+
}
135+
127136
private void FlattenNodes(IEnumerable<WorkItemClassificationNode> nodes, ref List<(string Path, WorkItemClassificationNode Node)> paths)
128137
{
129138
foreach (var node in nodes)
@@ -146,7 +155,7 @@ private void FlattenNodes(IEnumerable<WorkItemClassificationNode> nodes, ref Lis
146155
FlattenNodes(
147156
await _sourceEndpoint.GetClassificationNodes(_config.SourceEndpointConfig.ProjectName, _nodesType, token),
148157
ref paths);
149-
return paths.Count;
158+
return paths.Where(node => IsFilterMatch(node.Path)).Count();
150159
}
151160
}
152161
}

AzureDevOpsMigrator/Services/Migrators/IterationMigrator.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,18 @@ public IterationMigrator(MigrationConfig config, ILogger<IIterationMigrator> log
1616
{ }
1717
protected override TreeStructureGroup _nodesType => TreeStructureGroup.Iterations;
1818
protected override TreeNodeStructureType _nodeType => TreeNodeStructureType.Iteration;
19+
20+
protected override bool IsFilterMatch(string path)
21+
{
22+
if (_iterationFilter != _config.IterationFilter)
23+
{
24+
_iterationFilter = _config.IterationFilter;
25+
_iterationFilterMatcher = new System.Text.RegularExpressions.Regex(_config.IterationFilter);
26+
}
27+
return string.IsNullOrEmpty(_config.IterationFilter) ? true : _iterationFilterMatcher.IsMatch(path);
28+
}
29+
30+
private string _iterationFilter = "";
31+
private System.Text.RegularExpressions.Regex _iterationFilterMatcher;
1932
}
2033
}

AzureDevOpsMigrator/Services/Migrators/OrchestratorService.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ await Task.WhenAll(
8282
{
8383
try
8484
{
85-
return plan.IterationsCount = await _iterationMigrator.GetPlannedCount(token);
85+
return plan.IterationsCount = _config.Execution.IterationsMigratorEnabled ? await _iterationMigrator.GetPlannedCount(token) : 0;
8686
}
8787
catch (Exception ex)
8888
{
@@ -94,7 +94,7 @@ await Task.WhenAll(
9494
{
9595
try
9696
{
97-
return plan.AreaPathsCount = await _areaPathMigrator.GetPlannedCount(token);
97+
return plan.AreaPathsCount = _config.Execution.AreaPathMigratorEnabled ? await _areaPathMigrator.GetPlannedCount(token) : 0;
9898
}
9999
catch (Exception ex)
100100
{
@@ -106,7 +106,7 @@ await Task.WhenAll(
106106
{
107107
try
108108
{
109-
return plan.WorkItemsCount = await _workItemMigrator.GetPlannedCount(token);
109+
return plan.WorkItemsCount = _config.Execution.WorkItemsMigratorEnabled ? await _workItemMigrator.GetPlannedCount(token) : 0;
110110
}
111111
catch (Exception ex)
112112
{
@@ -188,7 +188,14 @@ public async Task ExecuteAsync(MigrationPlan plan, CancellationToken token)
188188
}
189189

190190

191-
await _workItemMigrator.ExecuteAsync(token);
191+
if (_config.Execution.WorkItemsMigratorEnabled)
192+
{
193+
await _workItemMigrator.ExecuteAsync(token);
194+
}
195+
else
196+
{
197+
_log.LogInformation("Skipping work item migrations..");
198+
}
192199
}
193200
catch (OperationCanceledException opCanceledEx)
194201
{

0 commit comments

Comments
 (0)