Skip to content

Instantly share code, notes, and snippets.

@shiftkey
Last active December 17, 2020 10:09
Show Gist options
  • Save shiftkey/4de1f005164648138578 to your computer and use it in GitHub Desktop.
Save shiftkey/4de1f005164648138578 to your computer and use it in GitHub Desktop.
five minutes spent mashing together Rx and LibGit2Sharp
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();
}
}
}
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);
}
}
}
@anaisbetts
Copy link

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.

@jstangroome
Copy link

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