static int DoSyncWork(SyncOptions clo) { string localGitDir = clo.LocalFolder != null && Path.IsPathRooted(clo.LocalFolder) ? clo.LocalFolder : Path.Combine(Environment.CurrentDirectory, clo.LocalFolder ?? repoPath); EnsureGitDir(localGitDir); string gitRepoPath = clo.Repo; string username = clo.Login; string password = clo.Password; string gitlabauthtoken = clo.AuthToken; string branchName = clo.Branch; string trackerPath = clo.Tracker; string gitServer = clo.Server; DXVcsWrapper vcsWrapper = new DXVcsWrapper(vcsServer, username, password); TrackBranch branch = FindBranch(branchName, trackerPath, vcsWrapper); if (branch == null) return 1; string historyPath = GetVcsSyncHistory(vcsWrapper, branch.HistoryPath); if (historyPath == null) return 1; SyncHistory history = SyncHistory.Deserialize(historyPath); if (history == null) return 1; SyncHistoryWrapper syncHistory = new SyncHistoryWrapper(history, vcsWrapper, branch.HistoryPath, historyPath); var head = syncHistory.GetHistoryHead(); if (head == null) return 1; GitLabWrapper gitLabWrapper = new GitLabWrapper(gitServer, gitlabauthtoken); RegisteredUsers registeredUsers = new RegisteredUsers(gitLabWrapper, vcsWrapper); User defaultUser = registeredUsers.GetUser(username); if (!defaultUser.IsRegistered) { Log.Error($"default user {username} is not registered in the active directory."); return 1; } var checkMergeChangesResult = CheckChangesForMerging(gitLabWrapper, gitRepoPath, branchName, head, vcsWrapper, branch, syncHistory, defaultUser); if (checkMergeChangesResult == CheckMergeChangesResult.NoChanges) return 0; if (checkMergeChangesResult == CheckMergeChangesResult.Error) return 1; GitWrapper gitWrapper = CreateGitWrapper(gitRepoPath, localGitDir, branch.Name, username, password); if (gitWrapper == null) return 1; ProcessHistoryResult processHistoryResult = ProcessHistory(vcsWrapper, gitWrapper, registeredUsers, defaultUser, gitRepoPath, localGitDir, branch, clo.CommitsCount, syncHistory, true); if (processHistoryResult == ProcessHistoryResult.NotEnough) return 0; if (processHistoryResult == ProcessHistoryResult.Failed) return 1; int result = ProcessMergeRequests(vcsWrapper, gitWrapper, gitLabWrapper, registeredUsers, defaultUser, gitRepoPath, localGitDir, clo.Branch, clo.Tracker, syncHistory, username); if (result != 0) return result; return 0; }
static DateTime CalcLastCommitDate(SyncHistoryWrapper syncHistory) { var head = syncHistory.GetHistoryHead(); return new DateTime(head.VcsCommitTimeStamp); }
static int DoPatchWork(PatchOptions clo) { string localGitDir = clo.LocalFolder != null && Path.IsPathRooted(clo.LocalFolder) ? clo.LocalFolder : Path.Combine(Environment.CurrentDirectory, clo.LocalFolder ?? repoPath); string targetRepoPath = GetSimpleGitHttpPath(clo.Repo); if (string.IsNullOrEmpty(targetRepoPath)) { Log.Error($"Can`t parse repo path {clo.Repo}"); return 1; } string sourceRepoPath = GetSimpleGitHttpPath(clo.SourceRepo); if (string.IsNullOrEmpty(sourceRepoPath)) { Log.Error($"Can`t parse source repo path {clo.SourceRepo}"); return 1; } string username = clo.Login; string password = clo.Password; string gitlabauthtoken = clo.AuthToken; string targetBranchName = clo.Branch; string trackerPath = clo.Tracker; string gitServer = clo.Server; string sourceBranchName = clo.SourceBranch; string patchdir = clo.PatchDir ?? localGitDir; DXVcsWrapper vcsWrapper = new DXVcsWrapper(vcsServer, username, password); TrackBranch trackBranch = FindBranch(targetBranchName, trackerPath, vcsWrapper); if (trackBranch == null) { return 1; } string historyPath = GetVcsSyncHistory(vcsWrapper, trackBranch.HistoryPath); if (historyPath == null) return 1; SyncHistory history = SyncHistory.Deserialize(historyPath); if (history == null) return 1; SyncHistoryWrapper syncHistory = new SyncHistoryWrapper(history, vcsWrapper, trackBranch.HistoryPath, historyPath); var head = syncHistory.GetHistoryHead(); if (head == null) return 1; GitLabWrapper gitLabWrapper = new GitLabWrapper(gitServer, gitlabauthtoken); Project targetProject = gitLabWrapper.FindProject(targetRepoPath); if (targetProject == null) { Log.Error($"Can`t find target project {targetRepoPath}."); return 1; } Log.Message($"Target project url: {targetProject.HttpUrl}"); Branch targetBranch = gitLabWrapper.GetBranch(targetProject, targetBranchName); if (targetBranch == null) { Log.Error($"Can`t find targetBranch branch {targetBranchName}"); return 1; } Log.Message($"Target branch name: {targetBranch.Name}"); var sourceProject = gitLabWrapper.FindProjectFromAll(sourceRepoPath); if (sourceProject == null) { Log.Error($"Can`t find source project {sourceRepoPath}"); return 1; } Log.Message($"Source project url: {sourceProject.HttpUrl}"); var sourceBranch = gitLabWrapper.GetBranch(sourceProject, sourceBranchName); if (sourceBranch == null) { Log.Error($"Source branch {sourceBranchName} was not found."); return 1; } Log.Message($"Target branch name: {sourceBranch.Name}"); MergeRequest mergeRequest = gitLabWrapper.GetMergeRequests(targetProject, x => x.SourceBranch == sourceBranchName && x.TargetBranch == targetBranchName && x.SourceProjectId == sourceProject.Id).FirstOrDefault(); if (mergeRequest == null) { Log.Error($"Can`t find merge request."); return 1; } Log.Message($"Merge request id: {mergeRequest.Id}."); Log.Message($"Merge request title: {mergeRequest.Title}."); var comments = gitLabWrapper.GetComments(mergeRequest); var mergeRequestSyncOptions = comments?.Where(x => IsXml(x.Note)).Where(x => { var mr = MergeRequestOptions.ConvertFromString(x.Note); return mr?.ActionType == MergeRequestActionType.sync; }).Select(x => (MergeRequestSyncAction)MergeRequestOptions.ConvertFromString(x.Note).Action).LastOrDefault(); if (mergeRequest.Assignee?.Name != username || (!mergeRequestSyncOptions?.PerformTesting ?? false)) { Log.Error($"Merge request is not assigned to service user {username} or doesn`t require testing."); return 1; } GitWrapper gitWrapper = CreateGitWrapper(sourceRepoPath, localGitDir, sourceBranchName, username, password); if (gitWrapper == null) { Log.Error("Can`t create git wrapper."); return 1; } var changes = gitLabWrapper .GetMergeRequestChanges(mergeRequest) .Where(x => trackBranch.TrackItems.FirstOrDefault(track => CheckItemForChangeSet(x, track)) != null) .Select(x => new PatchItem() { SyncAction = CalcSyncAction(x), OldPath = x.OldPath, NewPath = x.NewPath, OldVcsPath = CalcVcsPath(trackBranch, x.OldPath), NewVcsPath = CalcVcsPath(trackBranch, x.NewPath), }).ToList(); var patch = new PatchInfo() { TimeStamp = DateTime.Now.Ticks, Items = changes }; var patchPath = Path.Combine(patchdir, patchZip); using (Package zip = Package.Open(patchPath, FileMode.Create)) { SavePatchInfo(patchdir, patch); AddPart(zip, patchdir, "patch.info"); foreach (var path in CalcFilesForPatch(patch)) { AddPart(zip, localGitDir, path); } } Log.Message($"Patch.info generated at {patchPath}"); return 0; }