static void SetRepository(IRepositoryCloneTabViewModel vm, IRepositoryModel repository) { vm.Repository.Returns(repository); vm.PropertyChanged += Raise.Event <PropertyChangedEventHandler>( vm, new PropertyChangedEventArgs(nameof(vm.Repository))); }
public IObservable <Unit> SwitchRemotes(IRepositoryModel destinationRepository, bool updateOrigin, bool addUpstream, bool trackMasterUpstream) { return(Observable.Defer(() => Observable.Return(new object()) .ObserveOn(RxApp.MainThreadScheduler) .Select(_ => vsGitServices.GetActiveRepo())) .SelectMany(async activeRepo => { using (activeRepo) { Uri currentOrigin = null; if (addUpstream) { var remote = await gitClient.GetHttpRemote(activeRepo, "origin"); currentOrigin = new Uri(remote.Url); } await SwitchRemotes(activeRepo, updateOrigin ? destinationRepository.CloneUrl.ToUri() : null, currentOrigin, trackMasterUpstream); } if (updateOrigin) { vsGitExt.RefreshActiveRepositories(); var updatedRepository = vsGitExt.ActiveRepositories.FirstOrDefault(); log.Assert(updatedRepository?.CloneUrl == destinationRepository.CloneUrl, "CloneUrl is {UpdatedRepository} not {DestinationRepository}", updatedRepository?.CloneUrl ?? "[NULL]", destinationRepository.CloneUrl); } return Unit.Default; })); }
public async Task LoadsRepositories() { var repos = new IRepositoryModel[] { Substitute.For <IRepositoryModel>(), Substitute.For <IRepositoryModel>(), Substitute.For <IRepositoryModel>() }; var col = TrackingCollection.Create(repos.ToObservable()); var repositoryHost = Substitute.For <IRepositoryHost>(); repositoryHost.ModelService.GetRepositories(Arg.Any <ITrackingCollection <IRepositoryModel> >()).Returns(_ => col); var cloneService = Substitute.For <IRepositoryCloneService>(); var vm = GetVM( repositoryHost, cloneService, Substitute.For <IOperatingSystem>(), Substitute.For <INotificationService>(), Substitute.For <IUsageTracker>()); await col.OriginalCompleted; Assert.Equal(3, vm.Repositories.Count); }
public Task <string> ShowReCloneDialog(IRepositoryModel repository) { Guard.ArgumentNotNull(repository, nameof(repository)); var controller = uiProvider.Configure(UIControllerFlow.ReClone); var basePath = default(string); controller.TransitionSignal.Subscribe(x => { var vm = x.View.ViewModel as IBaseCloneViewModel; if (vm != null) { vm.SelectedRepository = repository; } vm.Done.Subscribe(_ => { basePath = vm?.BaseRepositoryPath; }); }); uiProvider.RunInDialog(controller); return(Task.FromResult(basePath)); }
public IObservable <Repository> ForkRepository(IApiClient apiClient, IRepositoryModel sourceRepository, NewRepositoryFork repositoryFork, bool updateOrigin, bool addUpstream, bool trackMasterUpstream) { log.Verbose("ForkRepository Source:{SourceOwner}/{SourceName} To:{DestinationOwner}", sourceRepository.Owner, sourceRepository.Name, repositoryFork.Organization ?? "[Current User]"); log.Verbose("ForkRepository updateOrigin:{UpdateOrigin} addUpstream:{AddUpstream} trackMasterUpstream:{TrackMasterUpstream}", updateOrigin, addUpstream, trackMasterUpstream); usageTracker.IncrementCounter(model => model.NumberOfReposForked).Forget(); return(Observable.Defer(() => apiClient.ForkRepository(sourceRepository.Owner, sourceRepository.Name, repositoryFork) .ObserveOn(RxApp.MainThreadScheduler) .Select(remoteRepo => new { RemoteRepo = remoteRepo, ActiveRepo = updateOrigin ? vsGitServices.GetActiveRepo() : null })) .SelectMany(async repo => { if (repo.ActiveRepo != null) { using (repo.ActiveRepo) { var originUri = repo.RemoteRepo != null ? new Uri(repo.RemoteRepo.CloneUrl) : null; var upstreamUri = addUpstream ? sourceRepository.CloneUrl.ToUri() : null; await SwitchRemotes(repo.ActiveRepo, originUri, upstreamUri, trackMasterUpstream); } } return repo.RemoteRepo; })); }
public bool Equals([AllowNull] IRepositoryModel other) { if (ReferenceEquals(this, other)) { return(true); } return(other != null && Id == other.Id); }
public void CopyFrom(IRepositoryModel other) { if (!Equals(other)) { throw new ArgumentException("Instance to copy from doesn't match this instance. this:(" + this + ") other:(" + other + ")", nameof(other)); } Icon = other.Icon; }
public BranchModel(Octokit.Branch branch, IRepositoryModel repo) { Extensions.Guard.ArgumentNotNull(branch, nameof(branch)); Extensions.Guard.ArgumentNotNull(repo, nameof(repo)); Name = DisplayName = branch.Name; Repository = repo; Id = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", Repository.Owner, Name); }
public BranchModel(string name, IRepositoryModel repo) { Extensions.Guard.ArgumentNotEmptyString(name, nameof(name)); Extensions.Guard.ArgumentNotNull(repo, nameof(repo)); Name = DisplayName = name; Repository = repo; Id = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", Repository.Owner, Name); }
public async Task <string> ShowReCloneDialog(IRepositoryModel repository) { Guard.ArgumentNotNull(repository, nameof(repository)); var viewModel = factory.CreateViewModel <IRepositoryRecloneViewModel>(); viewModel.SelectedRepository = repository; return((string)await showDialog.ShowWithFirstConnection(viewModel)); }
public IssueCommentThreadViewModel( IRepositoryModel repository, int number, IAccount currentUser) : base(currentUser) { Repository = repository; Number = number; }
public IObservable <IBranch> GetBranches(IRepositoryModel repo) { var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|branch", user.Login, repo.Name)); return(Observable.Defer(() => keyobs .SelectMany(key => apiClient.GetBranches(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName))) .Select(x => new BranchModel(x, repo))); }
public BranchModel(LibGit2Sharp.Branch branch, IRepositoryModel repo) { Extensions.Guard.ArgumentNotNull(branch, nameof(branch)); Extensions.Guard.ArgumentNotNull(repo, nameof(repo)); Name = DisplayName = branch.FriendlyName; Repository = branch.IsRemote ? new LocalRepositoryModel(branch.Remote.Url) : repo; IsTracking = branch.IsTracking; Id = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", Repository.Owner, Name); }
public static Task <IConnection> GetConnection(this IConnectionManager cm, IRepositoryModel repository) { if (repository?.CloneUrl != null) { var hostAddress = HostAddress.Create(repository.CloneUrl); return(cm.GetConnection(hostAddress)); } return(null); }
bool FilterRepository(IRepositoryModel repo, int position, IList <IRepositoryModel> list) { if (string.IsNullOrWhiteSpace(FilterText)) { return(true); } // Not matching on NameWithOwner here since that's already been filtered on by the selected account return(repo.Name.IndexOf(FilterText ?? "", StringComparison.OrdinalIgnoreCase) != -1); }
public BranchModel(LibGit2Sharp.Branch branch, IRepositoryModel repo) { Extensions.Guard.ArgumentNotNull(branch, nameof(branch)); Extensions.Guard.ArgumentNotNull(repo, nameof(repo)); Name = DisplayName = branch.FriendlyName; #pragma warning disable 0618 // TODO: Replace `Branch.Remote` with `Repository.Network.Remotes[branch.RemoteName]`. Repository = branch.IsRemote ? new LocalRepositoryModel(branch.Remote.Url) : repo; #pragma warning restore 0618 IsTracking = branch.IsTracking; Id = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", Repository.Owner, Name); }
/// <inheritdoc/> public async Task InitializeAsync(ILocalRepositoryModel repository, IConnection connection) { try { LocalRepository = repository; SelectedState = States.FirstOrDefault(); AuthorFilter = new UserFilterViewModel(LoadAuthors); IsLoading = true; var parent = await repositoryService.FindParent( HostAddress.Create(repository.CloneUrl), repository.Owner, repository.Name); if (parent == null) { RemoteRepository = repository; } else { // TODO: Handle forks with different names. RemoteRepository = new RepositoryModel( repository.Name, UriString.ToUriString(repository.CloneUrl.ToRepositoryUrl(parent.Value.owner))); Forks = new IRepositoryModel[] { RemoteRepository, repository, }; } this.WhenAnyValue(x => x.SelectedState, x => x.RemoteRepository) .Skip(1) .Subscribe(_ => Refresh().Forget()); Observable.Merge( this.WhenAnyValue(x => x.SearchQuery).Skip(1).SelectUnit(), AuthorFilter.WhenAnyValue(x => x.Selected).Skip(1).SelectUnit()) .Subscribe(_ => FilterChanged()); await Refresh(); } catch (Exception ex) { Error = ex; IsLoading = false; log.Error(ex, "Error initializing IssueListViewModelBase"); } }
public IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body ) { Extensions.Guard.ArgumentNotNull(host, nameof(host)); Extensions.Guard.ArgumentNotNull(sourceRepository, nameof(sourceRepository)); Extensions.Guard.ArgumentNotNull(targetRepository, nameof(targetRepository)); Extensions.Guard.ArgumentNotNull(sourceBranch, nameof(sourceBranch)); Extensions.Guard.ArgumentNotNull(targetBranch, nameof(targetBranch)); Extensions.Guard.ArgumentNotNull(title, nameof(title)); Extensions.Guard.ArgumentNotNull(body, nameof(body)); return PushAndCreatePR(host, sourceRepository, targetRepository, sourceBranch, targetBranch, title, body).ToObservable(); }
async Task <CloneDialogResult> ShowCloneDialog( IGitHubServiceProvider gitHubServiceProvider, IProgress <ServiceProgressData> progress, IRepositoryModel repository = null) { var dialogService = gitHubServiceProvider.GetService <IDialogService>(); var cloneService = gitHubServiceProvider.GetService <IRepositoryCloneService>(); var usageTracker = gitHubServiceProvider.GetService <IUsageTracker>(); CloneDialogResult result = null; if (repository == null) { result = await dialogService.ShowCloneDialog(null); } else { var basePath = await dialogService.ShowReCloneDialog(repository); if (basePath != null) { result = new CloneDialogResult(basePath, repository); } } if (result != null) { try { await cloneService.CloneRepository( result.Repository.CloneUrl, result.Repository.Name, result.Path, progress); usageTracker.IncrementCounter(x => x.NumberOfStartPageClones).Forget(); } catch { var teServices = gitHubServiceProvider.TryGetService <ITeamExplorerServices>(); teServices.ShowError($"Failed to clone the repository '{result.Repository.Name}'"); result = null; } } return(result); }
public IObservable <string> GetFileContents(IRepositoryModel repo, string commitSha, string path, string fileSha) { return(Observable.Defer(() => Task.Run(async() => { // Store cached file contents a the temp directory so they can be deleted by disk cleanup etc. var tempDir = Path.Combine(Path.GetTempPath(), TempFilesDirectory, CachedFilesDirectory, fileSha.Substring(0, 2)); var tempFile = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(path) + '@' + fileSha + Path.GetExtension(path)); if (!File.Exists(tempFile)) { var contents = await ApiClient.GetFileContents(repo.Owner, repo.Name, commitSha, path); Directory.CreateDirectory(tempDir); File.WriteAllBytes(tempFile, Convert.FromBase64String(contents.EncodedContent)); } return Observable.Return(tempFile); }))); }
public async Task LoadsRepositories() { var repos = new IRepositoryModel[] { Substitute.For<IRepositoryModel>(), Substitute.For<IRepositoryModel>(), Substitute.For<IRepositoryModel>() }; var repositoryHost = Substitute.For<IRepositoryHost>(); repositoryHost.ModelService.GetRepositories().Returns(Observable.Return(repos)); var cloneService = Substitute.For<IRepositoryCloneService>(); var vm = new RepositoryCloneViewModel( repositoryHost, cloneService, Substitute.For<IOperatingSystem>(), Substitute.For<IVSServices>()); await vm.LoadRepositoriesCommand.ExecuteAsync(); Assert.Equal(3, vm.FilteredRepositories.Count); }
public async Task LoadsRepositories() { var repos = new IRepositoryModel[] { Substitute.For <IRepositoryModel>(), Substitute.For <IRepositoryModel>(), Substitute.For <IRepositoryModel>() }; var repositoryHost = Substitute.For <IRepositoryHost>(); repositoryHost.ModelService.GetRepositories().Returns(Observable.Return(repos)); var cloneService = Substitute.For <IRepositoryCloneService>(); var vm = new RepositoryCloneViewModel( repositoryHost, cloneService, Substitute.For <IOperatingSystem>(), Substitute.For <IVSServices>()); await vm.LoadRepositoriesCommand.ExecuteAsync(); Assert.Equal(3, vm.FilteredRepositories.Count); }
/// <summary> /// Gets a collection of Pull Requests. If you want to refresh existing data, pass a collection in /// </summary> /// <param name="repo"></param> /// <param name="collection"></param> /// <returns></returns> public ITrackingCollection <IPullRequestModel> GetPullRequests(IRepositoryModel repo, ITrackingCollection <IPullRequestModel> collection) { // Since the api to list pull requests returns all the data for each pr, cache each pr in its own entry // and also cache an index that contains all the keys for each pr. This way we can fetch prs in bulk // but also individually without duplicating information. We store things in a custom observable collection // that checks whether an item is being updated (coming from the live stream after being retrieved from cache) // and replaces it instead of appending, so items get refreshed in-place as they come in. var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, repo.Owner, repo.Name)); var source = Observable.Defer(() => keyobs .SelectMany(key => hostCache.GetAndFetchLatestFromIndex(key, () => ApiClient.GetPullRequestsForRepository(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName) .Select(PullRequestCacheItem.Create), item => { if (collection.Disposed) { return; } // this could blow up due to the collection being disposed somewhere else try { collection.RemoveItem(Create(item)); } catch (ObjectDisposedException) { } }, TimeSpan.Zero, TimeSpan.FromDays(7)) ) .Select(Create) ); collection.Listen(source); return(collection); }
/// <summary> /// Initializes a new instance of the <see cref="CloneDialogResult"/> class. /// </summary> /// <param name="basePath">The selected base path for the clone.</param> /// <param name="repository">The selected repository.</param> public CloneDialogResult(string basePath, IRepositoryModel repository) { BasePath = basePath; Repository = repository; }
async Task <CodeContainer> RunAcquisition(IProgress <ServiceProgressData> downloadProgress, CancellationToken cancellationToken, IRepositoryModel repository) { CloneDialogResult request = null; try { var uiProvider = await Task.Run(() => Package.GetGlobalService(typeof(IGitHubServiceProvider)) as IGitHubServiceProvider); await ShowTeamExplorerPage(uiProvider); request = await ShowCloneDialog(uiProvider, downloadProgress, repository); } catch (Exception e) { log.Error(e, "Error showing Start Page clone dialog"); } if (request == null) { return(null); } var uri = request.Repository.CloneUrl.ToRepositoryUrl(); return(new CodeContainer( localProperties: new CodeContainerLocalProperties(request.Path, CodeContainerType.Folder, new CodeContainerSourceControlProperties(request.Repository.Name, request.Path, new Guid(Guids.GitSccProviderId))), remote: new RemoteCodeContainer(request.Repository.Name, new Guid(Guids.CodeContainerProviderId), uri, new Uri(uri.ToString().TrimSuffix(".git")), DateTimeOffset.UtcNow), isFavorite: false, lastAccessed: DateTimeOffset.UtcNow)); }
public IObservable<IBranch> GetBranches(IRepositoryModel repo) { var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|branch", user.Login, repo.Name)); return Observable.Defer(() => keyobs .SelectMany(key => apiClient.GetBranches(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName))) .Select(x => new BranchModel(x, repo)); }
public static IObservable <IPullRequestModel> GetPullRequest(this IModelService service, IRepositoryModel repo, int number) { return(service.GetPullRequest(repo.Owner, repo.Name, number)); }
public IObservable <IPullRequestModel> CreatePullRequest(ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body) { var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, targetRepository.Owner, targetRepository.Name)); return(Observable.Defer(() => keyobs .SelectMany(key => hostCache.PutAndUpdateIndex(key, () => apiClient.CreatePullRequest( new NewPullRequest(title, string.Format(CultureInfo.InvariantCulture, "{0}:{1}", sourceRepository.Owner, sourceBranch.Name), targetBranch.Name) { Body = body }, targetRepository.Owner, targetRepository.Name) .Select(PullRequestCacheItem.Create) , TimeSpan.FromMinutes(30)) ) .Select(Create) )); }
public EmployeesController(IRepositoryModel irm, ILogger <EmployeesController> ilg) { _irepositoryModel = irm; _Logging = ilg; }
public ProductCategoriesController(IRepositoryModel irm) { _irepositoryModel = irm; }
public IObservable <IPullRequestModel> CreatePullRequest(IModelService modelService, ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body ) { Extensions.Guard.ArgumentNotNull(modelService, nameof(modelService)); Extensions.Guard.ArgumentNotNull(sourceRepository, nameof(sourceRepository)); Extensions.Guard.ArgumentNotNull(targetRepository, nameof(targetRepository)); Extensions.Guard.ArgumentNotNull(sourceBranch, nameof(sourceBranch)); Extensions.Guard.ArgumentNotNull(targetBranch, nameof(targetBranch)); Extensions.Guard.ArgumentNotNull(title, nameof(title)); Extensions.Guard.ArgumentNotNull(body, nameof(body)); return(PushAndCreatePR(modelService, sourceRepository, targetRepository, sourceBranch, targetBranch, title, body).ToObservable()); }
public CRUDController(IRepositoryModel irm) { _irepositoryModel = irm; }
bool FilterRepository(IRepositoryModel repo) { if (string.IsNullOrWhiteSpace(FilterText)) return true; // Not matching on NameWithOwner here since that's already been filtered on by the selected account return repo.Name.IndexOf(FilterText ?? "", StringComparison.OrdinalIgnoreCase) != -1; }
public IObservable<IPullRequestModel> CreatePullRequest(ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body) { var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, targetRepository.Owner, targetRepository.Name)); return Observable.Defer(() => keyobs .SelectMany(key => hostCache.PutAndUpdateIndex(key, () => apiClient.CreatePullRequest( new NewPullRequest(title, string.Format(CultureInfo.InvariantCulture, "{0}:{1}", sourceRepository.Owner, sourceBranch.Name), targetBranch.Name) { Body = body }, targetRepository.Owner, targetRepository.Name) .Select(PullRequestCacheItem.Create) , TimeSpan.FromMinutes(30)) ) .Select(Create) ); }
public IObservable<string> GetFileContents(IRepositoryModel repo, string commitSha, string path, string fileSha) { return Observable.Defer(() => Task.Run(async () => { // Store cached file contents a the temp directory so they can be deleted by disk cleanup etc. var tempDir = Path.Combine(Path.GetTempPath(), TempFilesDirectory, CachedFilesDirectory, fileSha.Substring(0, 2)); var tempFile = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(path) + '@' + fileSha + Path.GetExtension(path)); if (!File.Exists(tempFile)) { var contents = await apiClient.GetFileContents(repo.Owner, repo.Name, commitSha, path); Directory.CreateDirectory(tempDir); File.WriteAllBytes(tempFile, Convert.FromBase64String(contents.EncodedContent)); } return Observable.Return(tempFile); })); }
async Task <IPullRequestModel> PushAndCreatePR(IModelService modelService, ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body) { // PullRequestModel doesn't keep a reference to repo using (var repo = await Task.Run(() => gitService.GetRepository(sourceRepository.LocalPath))) { var remote = await gitClient.GetHttpRemote(repo, "origin"); await gitClient.Push(repo, sourceBranch.Name, remote.Name); if (!repo.Branches[sourceBranch.Name].IsTracking) { await gitClient.SetTrackingBranch(repo, sourceBranch.Name, remote.Name); } // delay things a bit to avoid a race between pushing a new branch and creating a PR on it if (!Splat.ModeDetector.Current.InUnitTestRunner().GetValueOrDefault()) { await Task.Delay(TimeSpan.FromSeconds(5)); } var ret = await modelService.CreatePullRequest(sourceRepository, targetRepository, sourceBranch, targetBranch, title, body); await usageTracker.IncrementCounter(x => x.NumberOfUpstreamPullRequests); return(ret); } }
async Task<IPullRequestModel> PushAndCreatePR(IRepositoryHost host, ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository, IBranch sourceBranch, IBranch targetBranch, string title, string body) { var repo = await Task.Run(() => gitService.GetRepository(sourceRepository.LocalPath)); var remote = await gitClient.GetHttpRemote(repo, "origin"); await gitClient.Push(repo, sourceBranch.Name, remote.Name); if (!repo.Branches[sourceBranch.Name].IsTracking) await gitClient.SetTrackingBranch(repo, sourceBranch.Name, remote.Name); // delay things a bit to avoid a race between pushing a new branch and creating a PR on it if (!Splat.ModeDetector.Current.InUnitTestRunner().GetValueOrDefault()) await Task.Delay(TimeSpan.FromSeconds(5)); var ret = await host.ModelService.CreatePullRequest(sourceRepository, targetRepository, sourceBranch, targetBranch, title, body); await usageTracker.IncrementUpstreamPullRequestCount(); return ret; }