예제 #1
0
        public async Task <SyncContext> CalculateSyncContext(RepositoryInfo targetRepository)
        {
            var syncContext = new SyncContext(targetRepository);

            using (var syncer = new Syncer(targetRepository.Credentials, null, log))
            {
                var diffs         = new List <Mapper>();
                var includedPaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

                var descriptionBuilder = new StringBuilder();
                descriptionBuilder.AppendLine("This is an automated synchronization PR.");
                descriptionBuilder.AppendLine();
                descriptionBuilder.AppendLine("The following source template repositories were used:");

                // Note: iterate backwards, later registered sources should override earlier registrations
                for (var i = sources.Count - 1; i >= 0; i--)
                {
                    var sourceRepository            = sources[i];
                    var sourceRepositoryDisplayName = $"{sourceRepository.Owner}/{sourceRepository.Repository}";
                    var itemsToSync = new List <SyncItem>();

                    foreach (var item in await OctokitEx.GetRecursive(sourceRepository.Credentials, sourceRepository.Owner, sourceRepository.Repository))
                    {
                        if (includedPaths.Contains(item))
                        {
                            continue;
                        }

                        includedPaths.Add(item);

                        if (manualSyncItems.Any(x => item.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
                        {
                            switch (syncMode)
                            {
                            case SyncMode.IncludeAllByDefault:
                                // Continue
                                break;

                            case SyncMode.ExcludeAllByDefault:
                                // Ignore this file
                                continue;

                            default:
                                throw new ArgumentOutOfRangeException(nameof(syncMode), $"Sync mode '{syncMode}' is not supported");
                            }
                        }

                        itemsToSync.Add(new SyncItem
                        {
                            Parts = new Parts($"{sourceRepository.Owner}/{sourceRepository.Repository}",
                                              TreeEntryTargetType.Blob, sourceRepository.Branch, item),
                            ToBeAdded = true,
                            Target    = null
                        });
                    }

                    var targetRepositoryToSync = new RepoToSync
                    {
                        Owner        = targetRepository.Owner,
                        Repo         = targetRepository.Repository,
                        TargetBranch = targetRepository.Branch
                    };

                    var sourceMapper = targetRepositoryToSync.GetMapper(itemsToSync);
                    var diff         = await syncer.Diff(sourceMapper);

                    if (diff.ToBeAddedOrUpdatedEntries.Count() > 0 ||
                        diff.ToBeRemovedEntries.Count() > 0)
                    {
                        diffs.Add(diff);

                        descriptionBuilder.AppendLine($"* {sourceRepositoryDisplayName}");
                    }
                }

                var finalDiff = new Mapper();

                foreach (var diff in diffs)
                {
                    foreach (var item in diff.ToBeAddedOrUpdatedEntries)
                    {
                        foreach (var value in item.Value)
                        {
                            log($"Mapping '{item.Key.Url}' => '{value.Url}'");

                            finalDiff.Add(item.Key, value);
                        }
                    }

                    // Note: how to deal with items to be removed
                }

                syncContext.Diff        = finalDiff;
                syncContext.Description = descriptionBuilder.ToString();
            }

            return(syncContext);
        }