Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #567 from github/grokys/maintainer-workflow
Browse files Browse the repository at this point in the history
Maintainer workflow
  • Loading branch information
haacked authored Oct 24, 2016
2 parents 6f99a4c + 5ad4d53 commit 865bc2b
Show file tree
Hide file tree
Showing 53 changed files with 2,707 additions and 92 deletions.
10 changes: 10 additions & 0 deletions src/GitHub.App/Api/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ public IObservable<Unit> DeleteApplicationAuthorization(int id, [AllowNull]strin
return gitHubClient.Authorization.Delete(id, twoFactorAuthorizationCode);
}

public IObservable<PullRequest> GetPullRequest(string owner, string name, int number)
{
return gitHubClient.PullRequest.Get(owner, name, number);
}

public IObservable<PullRequestFile> GetPullRequestFiles(string owner, string name, int number)
{
return gitHubClient.PullRequest.Files(owner, name, number);
}

public IObservable<PullRequest> GetPullRequestsForRepository(string owner, string name)
{
return gitHubClient.PullRequest.GetAllForRepository(owner, name,
Expand Down
4 changes: 4 additions & 0 deletions src/GitHub.App/GitHub.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,15 @@
<Compile Include="Factories\UIFactory.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Infrastructure\LoggingConfiguration.cs" />
<Compile Include="Models\PullRequestFileModel.cs" />
<Compile Include="Models\PullRequestModel.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="SampleData\AccountDesigner.cs" />
<Compile Include="SampleData\LocalRepositoryModelDesigner.cs" />
<Compile Include="SampleData\PullRequestCreationViewModelDesigner.cs" />
<Compile Include="SampleData\PullRequestDetailViewModelDesigner.cs" />
<Compile Include="SampleData\LoggedOutViewModelDesigner.cs" />
Expand Down Expand Up @@ -204,6 +206,8 @@
<Compile Include="ViewModels\LogoutRequiredViewModel.cs" />
<Compile Include="ViewModels\PullRequestCreationViewModel.cs" />
<Compile Include="ViewModels\PullRequestDetailViewModel.cs" />
<Compile Include="ViewModels\PullRequestDirectoryNode.cs" />
<Compile Include="ViewModels\PullRequestFileNode.cs" />
<Compile Include="ViewModels\PullRequestListViewModel.cs" />
<Compile Include="ViewModels\RepositoryCreationViewModel.cs" />
<Compile Include="ViewModels\RepositoryCloneViewModel.cs" />
Expand Down
7 changes: 7 additions & 0 deletions src/GitHub.App/Models/Account.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ public Account(Octokit.Account account)
HasMaximumPrivateRepositories = OwnedPrivateRepos >= PrivateReposInPlan;
}

public Account(Octokit.Account account, IObservable<BitmapSource> bitmapSource)
: this(account)
{
bitmapSource.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => Avatar = x);
}

public bool IsOnFreePlan { get; private set; }

public bool HasMaximumPrivateRepositories { get; private set; }
Expand Down
16 changes: 16 additions & 0 deletions src/GitHub.App/Models/PullRequestFileModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace GitHub.Models
{
public class PullRequestFileModel : IPullRequestFileModel
{
public PullRequestFileModel(string fileName, PullRequestFileStatus status)
{
FileName = fileName;
Status = status;
}

public string FileName { get; set; }
public PullRequestFileStatus Status { get; set; }
}
}
47 changes: 38 additions & 9 deletions src/GitHub.App/Models/PullRequestModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@
using GitHub.VisualStudio.Helpers;
using NullGuard;
using System.Diagnostics;
using GitHub.SampleData;
using System.Collections.Generic;

namespace GitHub.Models
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
[NullGuard(ValidationFlags.None)]
public sealed class PullRequestModel : NotificationAwareObject, IPullRequestModel,
IEquatable<PullRequestModel>,
IComparable<PullRequestModel>
{
public PullRequestModel(int number, string title,
IAccount author, [AllowNull]IAccount assignee,
public PullRequestModel(int number, string title, IAccount author,
DateTimeOffset createdAt, DateTimeOffset? updatedAt = null)
{
Number = number;
Title = title;
Author = author;
Assignee = assignee;
CreatedAt = createdAt;
UpdatedAt = updatedAt ?? CreatedAt;
}
Expand All @@ -30,10 +29,10 @@ public void CopyFrom(IPullRequestModel other)
if (!Equals(other))
throw new ArgumentException("Instance to copy from doesn't match this instance. this:(" + this + ") other:(" + other + ")", nameof(other));
Title = other.Title;
State = other.State;
UpdatedAt = other.UpdatedAt;
CommentCount = other.CommentCount;
HasNewComments = other.HasNewComments;
IsOpen = other.IsOpen;
Assignee = other.Assignee;
}

Expand Down Expand Up @@ -107,30 +106,60 @@ public string Title
set { title = value; this.RaisePropertyChange(); }
}

bool isOpen;
public bool IsOpen
PullRequestStateEnum status;
public PullRequestStateEnum State
{
get { return isOpen; }
set { isOpen = value; this.RaisePropertyChange(); }
get { return status; }
set
{
status = value;
this.RaisePropertyChange();

// TODO: These notifications will be removed once maintainer workflow has been merged to master.
this.RaisePropertyChange(nameof(IsOpen));
this.RaisePropertyChange(nameof(Merged));
}
}

// TODO: Remove these property once maintainer workflow has been merged to master.
public bool IsOpen => State == PullRequestStateEnum.Open;
public bool Merged => State == PullRequestStateEnum.Merged;

int commentCount;
public int CommentCount
{
get { return commentCount; }
set { commentCount = value; this.RaisePropertyChange(); }
}

int commitCount;
public int CommitCount
{
get { return commitCount; }
set { commitCount = value; this.RaisePropertyChange(); }
}

bool hasNewComments;
public bool HasNewComments
{
get { return hasNewComments; }
set { hasNewComments = value; this.RaisePropertyChange(); }
}

string body;
public string Body
{
get { return body; }
set { body = value; this.RaisePropertyChange(); }
}

public GitReferenceModel Base { get; set; }
[AllowNull]
public GitReferenceModel Head { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
public IAccount Author { get; set; }
public IReadOnlyCollection<IPullRequestFileModel> ChangedFiles { get; set; } = new IPullRequestFileModel[0];

IAccount assignee;
[AllowNull]
Expand Down
40 changes: 40 additions & 0 deletions src/GitHub.App/SampleData/LocalRepositoryModelDesigner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using GitHub.Models;
using GitHub.Primitives;
using GitHub.UI;
using NullGuard;

namespace GitHub.App.SampleData
{
[NullGuard(ValidationFlags.None)]
public class LocalRepositoryModelDesigner : ILocalRepositoryModel
{
public UriString CloneUrl { get; set; }
public IBranch CurrentBranch { get; set; }
public Octicon Icon { get; set; }
public string LocalPath { get; set; }
public string Name { get; set; }
public string Owner { get; set; }

#pragma warning disable CS0067
public event PropertyChangedEventHandler PropertyChanged;
#pragma warning restore CS0067

public Task<UriString> GenerateUrl(string path = null, int startLine = -1, int endLine = -1)
{
throw new NotImplementedException();
}

public void Refresh()
{
throw new NotImplementedException();
}

public void SetIcon(bool isPrivate, bool isFork)
{
throw new NotImplementedException();
}
}
}
65 changes: 65 additions & 0 deletions src/GitHub.App/SampleData/PullRequestDetailViewModelDesigner.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive;
using GitHub.Models;
using GitHub.ViewModels;
using ReactiveUI;

namespace GitHub.SampleData
{
Expand All @@ -8,7 +12,68 @@ public class PullRequestDetailViewModelDesigner : BaseViewModel, IPullRequestDet
{
public PullRequestDetailViewModelDesigner()
{
Model = new PullRequestModel(419,
"Error handling/bubbling from viewmodels to views to viewhosts",
new AccountDesigner { Login = "shana", IsUser = true },
DateTime.Now.Subtract(TimeSpan.FromDays(3)))
{
State = PullRequestStateEnum.Open,
CommitCount = 9,
};

SourceBranchDisplayName = "shana/error-handling";
TargetBranchDisplayName = "master";
Body = @"Adds a way to surface errors from the view model to the view so that view hosts can get to them.
ViewModels are responsible for handling the UI on the view they control, but they shouldn't be handling UI for things outside of the view. In this case, we're showing errors in VS outside the view, and that should be handled by the section that is hosting the view.
This requires that errors be propagated from the viewmodel to the view and from there to the host via the IView interface, since hosts don't usually know what they're hosting.
![An image](https://cloud.githubusercontent.com/assets/1174461/18882991/5dd35648-8496-11e6-8735-82c3a182e8b4.png)";

var gitHubDir = new PullRequestDirectoryNode("GitHub");
var modelsDir = new PullRequestDirectoryNode("Models");
var repositoriesDir = new PullRequestDirectoryNode("Repositories");
var itrackingBranch = new PullRequestFileNode(@"GitHub\Models\ITrackingBranch.cs", PullRequestFileStatus.Modified);
var oldBranchModel = new PullRequestFileNode(@"GitHub\Models\OldBranchModel.cs", PullRequestFileStatus.Removed);
var concurrentRepositoryConnection = new PullRequestFileNode(@"GitHub\Repositories\ConcurrentRepositoryConnection.cs", PullRequestFileStatus.Added);

repositoriesDir.Files.Add(concurrentRepositoryConnection);
modelsDir.Directories.Add(repositoriesDir);
modelsDir.Files.Add(itrackingBranch);
modelsDir.Files.Add(oldBranchModel);
gitHubDir.Directories.Add(modelsDir);

ChangedFilesTree = new ReactiveList<IPullRequestChangeNode>();
ChangedFilesTree.Add(gitHubDir);

ChangedFilesList = new ReactiveList<IPullRequestFileNode>();
ChangedFilesList.Add(concurrentRepositoryConnection);
ChangedFilesList.Add(itrackingBranch);
ChangedFilesList.Add(oldBranchModel);

CheckoutMode = CheckoutMode.Fetch;
}

public IPullRequestModel Model { get; }
public string SourceBranchDisplayName { get; }
public string TargetBranchDisplayName { get; }
public string Body { get; }
public ChangedFilesViewType ChangedFilesViewType { get; set; }
public OpenChangedFileAction OpenChangedFileAction { get; set; }
public IReactiveList<IPullRequestChangeNode> ChangedFilesTree { get; }
public IReactiveList<IPullRequestFileNode> ChangedFilesList { get; }
public CheckoutMode CheckoutMode { get; set; }
public string CheckoutError { get; set; }
public int CommitsBehind { get; set; }
public string CheckoutDisabledMessage { get; set; }

public ReactiveCommand<Unit> Checkout { get; }
public ReactiveCommand<object> OpenOnGitHub { get; }
public ReactiveCommand<object> ActivateItem { get; }
public ReactiveCommand<object> ToggleChangedFilesView { get; }
public ReactiveCommand<object> ToggleOpenChangedFileAction { get; }
public ReactiveCommand<object> OpenFile { get; }
public ReactiveCommand<object> DiffFile { get; }
}
}
24 changes: 17 additions & 7 deletions src/GitHub.App/SampleData/PullRequestListViewModelDesigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,26 @@ public PullRequestListViewModelDesigner()
var prs = new TrackingCollection<IPullRequestModel>(Observable.Empty<IPullRequestModel>());
prs.Add(new PullRequestModel(399, "Let's try doing this differently",
new AccountDesigner { Login = "shana", IsUser = true },
new AccountDesigner { Login = "shana", IsUser = true },
DateTimeOffset.Now - TimeSpan.FromDays(1)));
DateTimeOffset.Now - TimeSpan.FromDays(1))
{
Assignee = new AccountDesigner { Login = "shana", IsUser = true },
});
prs.Add(new PullRequestModel(389, "Build system upgrade",
new AccountDesigner { Login = "haacked", IsUser = true },
new AccountDesigner { Login = "shana", IsUser = true },
DateTimeOffset.Now - TimeSpan.FromMinutes(2)) { CommentCount = 4, HasNewComments = false });
DateTimeOffset.Now - TimeSpan.FromMinutes(2))
{
CommentCount = 4,
HasNewComments = false,
Assignee = new AccountDesigner { Login = "haacked", IsUser = true },
});
prs.Add(new PullRequestModel(409, "Fix publish button style and a really, really long name for this thing... OMG look how long this name is yusssss",
new AccountDesigner { Login = "shana", IsUser = true },
new AccountDesigner { Login = "Haacked", IsUser = true },
DateTimeOffset.Now - TimeSpan.FromHours(5)) { CommentCount = 27, HasNewComments = true });
new AccountDesigner { Login = "shana", IsUser = true },
DateTimeOffset.Now - TimeSpan.FromHours(5))
{
CommentCount = 27,
HasNewComments = true,
Assignee = new AccountDesigner { Login = "Haacked", IsUser = true },
});
PullRequests = prs;

States = new List<PullRequestState> {
Expand Down
34 changes: 32 additions & 2 deletions src/GitHub.App/Services/GitClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reactive;
Expand Down Expand Up @@ -61,13 +62,33 @@ public Task Fetch(IRepository repository, string remoteName, params string[] ref
});
}

public Task Checkout(IRepository repository, string branchName)
{
Guard.ArgumentNotEmptyString(branchName, nameof(branchName));

return Task.Factory.StartNew(() =>
{
repository.Checkout(branchName);
});
}

public Task SetConfig(IRepository repository, string key, string value)
{
Guard.ArgumentNotEmptyString(key, nameof(key));
Guard.ArgumentNotEmptyString(value, nameof(value));

return Task.Factory.StartNew(() =>
{
repository.Config.Set(key, value);
});
}

public Task SetRemote(IRepository repository, string remoteName, Uri url)
{
Guard.ArgumentNotEmptyString(remoteName, nameof(remoteName));

return Task.Factory.StartNew(() =>
{
repository.Config.Set("remote." + remoteName + ".url", url.ToString());
repository.Config.Set("remote." + remoteName + ".fetch", "+refs/heads/*:refs/remotes/" + remoteName + "/*");
});
Expand All @@ -92,11 +113,20 @@ public Task SetTrackingBranch(IRepository repository, string branchName, string
});
}

public Task<Remote> GetHttpRemote(IRepository repo, string remote)
public Task UnsetConfig(IRepository repository, string key)
{
Guard.ArgumentNotEmptyString(key, nameof(key));

return Task.Factory.StartNew(() =>
{
repository.Config.Unset(key);
});
}

public Task<Remote> GetHttpRemote(IRepository repo, string remote)
{
return Task.Factory.StartNew(() =>
{
var uri = GitService.GitServiceHelper.GetRemoteUri(repo, remote);
var remoteName = uri.IsHypertextTransferProtocol ? remote : remote + "-http";
var ret = repo.Network.Remotes[remoteName];
Expand Down
Loading

0 comments on commit 865bc2b

Please sign in to comment.