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;
}
static readonly Regex SimpleHttpGitRegex = new Regex(@"http://[\w\._-]+/[\w\._-]+/[\w\._-]+.git", RegexOptions.Compiled);