Last active
December 17, 2020 10:09
-
-
Save shiftkey/4de1f005164648138578 to your computer and use it in GitHub Desktop.
five minutes spent mashing together Rx and LibGit2Sharp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reactive.Linq; | |
using LibGit2Sharp; | |
namespace ReactiveGit | |
{ | |
public class ObservableRepository : IDisposable | |
{ | |
readonly Repository _repository; | |
public ObservableRepository(string directory) | |
{ | |
_repository = new Repository(directory); | |
} | |
public IObservable<MergeResult> Pull(IObserver<Tuple<string, int>> observer) | |
{ | |
var signature = _repository.Config.BuildSignature(DateTimeOffset.Now); | |
var options = new PullOptions | |
{ | |
MergeOptions = new MergeOptions | |
{ | |
OnCheckoutProgress = (s, completedSteps, totalSteps) => | |
{ | |
// surface the progress from libgit2 | |
var progress = (100 * completedSteps) / totalSteps; | |
observer.OnNext(Tuple.Create(s, progress)); | |
} | |
} | |
}; | |
// this is a blocking call, hence all the ceremony before | |
return Observable.Start(() => _repository.Network.Pull(signature, options)) | |
.Finally(() => | |
{ | |
// ensure the observable signals even when the branch is up to date | |
observer.OnNext(Tuple.Create("pull completed", 100)); | |
observer.OnCompleted(); | |
}); | |
} | |
public void Dispose() | |
{ | |
_repository.Dispose(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reactive; | |
using System.Reactive.Concurrency; | |
using System.Reactive.Linq; | |
using System.Threading.Tasks; | |
using LibGit2Sharp; | |
using Xunit; | |
namespace ReactiveGit.Tests | |
{ | |
public class ObservableRepositoryTests | |
{ | |
[Fact] | |
public async Task CanPullSomeRepository() | |
{ | |
var repository = new ObservableRepository( | |
@"C:\Users\brendanforster\Documents\GìtHūb\atom-dark-syntax"); | |
var progress = Observer.Create<Tuple<string, int>>( | |
next => { Console.WriteLine("progress: " + next.Item2); }, | |
() => { Console.WriteLine("it is done"); }) | |
.NotifyOn(DefaultScheduler.Instance); | |
var result = await repository.Pull(progress); | |
Assert.NotEqual(MergeStatus.Conflicts, result.Status); | |
} | |
} | |
} |
I think you need some spaces and single quotes along with the accented characters in your GitHub path ;)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The real power in this approach, is when the value you pass into
progress
is a Subject, which means you can start using Rx operators on the progress output.