mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-04 20:29:08 -04:00
feat(remote): add ability to pass callbacks as arguments
This commit is contained in:
parent
b15b56f0ae
commit
299d1a17e7
8 changed files with 374 additions and 68 deletions
|
@ -19,5 +19,6 @@ export 'src/patch.dart';
|
||||||
export 'src/stash.dart';
|
export 'src/stash.dart';
|
||||||
export 'src/remote.dart';
|
export 'src/remote.dart';
|
||||||
export 'src/refspec.dart';
|
export 'src/refspec.dart';
|
||||||
|
export 'src/callbacks.dart';
|
||||||
export 'src/error.dart';
|
export 'src/error.dart';
|
||||||
export 'src/git_types.dart';
|
export 'src/git_types.dart';
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
import '../callbacks.dart';
|
||||||
import '../error.dart';
|
import '../error.dart';
|
||||||
import '../oid.dart';
|
import '../oid.dart';
|
||||||
import 'libgit2_bindings.dart';
|
|
||||||
import '../util.dart';
|
import '../util.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
import 'remote_callbacks.dart';
|
||||||
|
|
||||||
/// Get a list of the configured remotes for a repo.
|
/// Get a list of the configured remotes for a repo.
|
||||||
///
|
///
|
||||||
|
@ -297,13 +299,19 @@ void connect(
|
||||||
Pointer<git_remote> remote,
|
Pointer<git_remote> remote,
|
||||||
int direction,
|
int direction,
|
||||||
String? proxyOption,
|
String? proxyOption,
|
||||||
|
Callbacks callbacks,
|
||||||
) {
|
) {
|
||||||
final callbacks = calloc<git_remote_callbacks>();
|
final callbacksOptions = calloc<git_remote_callbacks>();
|
||||||
final callbacksError = libgit2.git_remote_init_callbacks(
|
final callbacksError = libgit2.git_remote_init_callbacks(
|
||||||
callbacks,
|
callbacksOptions,
|
||||||
GIT_REMOTE_CALLBACKS_VERSION,
|
GIT_REMOTE_CALLBACKS_VERSION,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
RemoteCallbacks.plug(
|
||||||
|
callbacksOptions: callbacksOptions.ref,
|
||||||
|
callbacks: callbacks,
|
||||||
|
);
|
||||||
|
|
||||||
if (callbacksError < 0) {
|
if (callbacksError < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
@ -313,13 +321,14 @@ void connect(
|
||||||
final error = libgit2.git_remote_connect(
|
final error = libgit2.git_remote_connect(
|
||||||
remote,
|
remote,
|
||||||
direction,
|
direction,
|
||||||
callbacks,
|
callbacksOptions,
|
||||||
proxyOptions,
|
proxyOptions,
|
||||||
nullptr,
|
nullptr,
|
||||||
);
|
);
|
||||||
|
|
||||||
calloc.free(callbacks);
|
calloc.free(callbacksOptions);
|
||||||
calloc.free(proxyOptions);
|
calloc.free(proxyOptions);
|
||||||
|
RemoteCallbacks.reset();
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
@ -383,6 +392,7 @@ void fetch(
|
||||||
String? reflogMessage,
|
String? reflogMessage,
|
||||||
int prune,
|
int prune,
|
||||||
String? proxyOption,
|
String? proxyOption,
|
||||||
|
Callbacks callbacks,
|
||||||
) {
|
) {
|
||||||
var refspecsC = calloc<git_strarray>();
|
var refspecsC = calloc<git_strarray>();
|
||||||
final refspecsPointers =
|
final refspecsPointers =
|
||||||
|
@ -395,6 +405,7 @@ void fetch(
|
||||||
|
|
||||||
refspecsC.ref.count = refspecs.length;
|
refspecsC.ref.count = refspecs.length;
|
||||||
refspecsC.ref.strings = strArray;
|
refspecsC.ref.strings = strArray;
|
||||||
|
final reflogMessageC = reflogMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
||||||
|
|
||||||
final proxyOptions = _proxyOptionsInit(proxyOption);
|
final proxyOptions = _proxyOptionsInit(proxyOption);
|
||||||
|
|
||||||
|
@ -408,11 +419,13 @@ void fetch(
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoteCallbacks.plug(
|
||||||
|
callbacksOptions: opts.ref.callbacks,
|
||||||
|
callbacks: callbacks,
|
||||||
|
);
|
||||||
opts.ref.prune = prune;
|
opts.ref.prune = prune;
|
||||||
opts.ref.proxy_opts = proxyOptions.ref;
|
opts.ref.proxy_opts = proxyOptions.ref;
|
||||||
|
|
||||||
final reflogMessageC = reflogMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
|
||||||
|
|
||||||
final error = libgit2.git_remote_fetch(
|
final error = libgit2.git_remote_fetch(
|
||||||
remote,
|
remote,
|
||||||
refspecsC,
|
refspecsC,
|
||||||
|
@ -428,6 +441,7 @@ void fetch(
|
||||||
calloc.free(proxyOptions);
|
calloc.free(proxyOptions);
|
||||||
calloc.free(reflogMessageC);
|
calloc.free(reflogMessageC);
|
||||||
calloc.free(opts);
|
calloc.free(opts);
|
||||||
|
RemoteCallbacks.reset();
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
@ -441,6 +455,7 @@ void push(
|
||||||
Pointer<git_remote> remote,
|
Pointer<git_remote> remote,
|
||||||
List<String> refspecs,
|
List<String> refspecs,
|
||||||
String? proxyOption,
|
String? proxyOption,
|
||||||
|
Callbacks callbacks,
|
||||||
) {
|
) {
|
||||||
var refspecsC = calloc<git_strarray>();
|
var refspecsC = calloc<git_strarray>();
|
||||||
final refspecsPointers =
|
final refspecsPointers =
|
||||||
|
@ -464,6 +479,10 @@ void push(
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoteCallbacks.plug(
|
||||||
|
callbacksOptions: opts.ref.callbacks,
|
||||||
|
callbacks: callbacks,
|
||||||
|
);
|
||||||
opts.ref.proxy_opts = proxyOptions.ref;
|
opts.ref.proxy_opts = proxyOptions.ref;
|
||||||
|
|
||||||
final error = libgit2.git_remote_push(remote, refspecsC, opts);
|
final error = libgit2.git_remote_push(remote, refspecsC, opts);
|
||||||
|
@ -475,6 +494,7 @@ void push(
|
||||||
calloc.free(refspecsC);
|
calloc.free(refspecsC);
|
||||||
calloc.free(proxyOptions);
|
calloc.free(proxyOptions);
|
||||||
calloc.free(opts);
|
calloc.free(opts);
|
||||||
|
RemoteCallbacks.reset();
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
@ -499,10 +519,13 @@ void disconnect(Pointer<git_remote> remote) {
|
||||||
/// Prune tracking refs that are no longer present on remote.
|
/// Prune tracking refs that are no longer present on remote.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void prune(Pointer<git_remote> remote) {
|
void prune(
|
||||||
final callbacks = calloc<git_remote_callbacks>();
|
Pointer<git_remote> remote,
|
||||||
|
Callbacks callbacks,
|
||||||
|
) {
|
||||||
|
final callbacksOptions = calloc<git_remote_callbacks>();
|
||||||
final callbacksError = libgit2.git_remote_init_callbacks(
|
final callbacksError = libgit2.git_remote_init_callbacks(
|
||||||
callbacks,
|
callbacksOptions,
|
||||||
GIT_REMOTE_CALLBACKS_VERSION,
|
GIT_REMOTE_CALLBACKS_VERSION,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -510,9 +533,15 @@ void prune(Pointer<git_remote> remote) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
final error = libgit2.git_remote_prune(remote, callbacks);
|
RemoteCallbacks.plug(
|
||||||
|
callbacksOptions: callbacksOptions.ref,
|
||||||
|
callbacks: callbacks,
|
||||||
|
);
|
||||||
|
|
||||||
calloc.free(callbacks);
|
final error = libgit2.git_remote_prune(remote, callbacksOptions);
|
||||||
|
|
||||||
|
calloc.free(callbacksOptions);
|
||||||
|
RemoteCallbacks.reset();
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
|
157
lib/src/bindings/remote_callbacks.dart
Normal file
157
lib/src/bindings/remote_callbacks.dart
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import '../callbacks.dart';
|
||||||
|
import '../repository.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
import '../oid.dart';
|
||||||
|
import '../remote.dart';
|
||||||
|
|
||||||
|
class RemoteCallbacks {
|
||||||
|
/// Callback function that reports transfer progress.
|
||||||
|
static void Function(TransferProgress)? transferProgress;
|
||||||
|
|
||||||
|
/// A callback that will be regularly called with the current count of progress
|
||||||
|
/// done by the indexer during the download of new data.
|
||||||
|
static int transferProgressCb(
|
||||||
|
Pointer<git_indexer_progress> stats,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
transferProgress!(TransferProgress(stats));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Callback function that reports textual progress from the remote.
|
||||||
|
static void Function(String)? sidebandProgress;
|
||||||
|
|
||||||
|
/// Callback for messages received by the transport.
|
||||||
|
static int sidebandProgressCb(
|
||||||
|
Pointer<Int8> progressOutput,
|
||||||
|
int length,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
sidebandProgress!(progressOutput.cast<Utf8>().toDartString(length: length));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Callback function that report reference updates.
|
||||||
|
static void Function(String, Oid, Oid)? updateTips;
|
||||||
|
|
||||||
|
/// A callback that will be called for every reference.
|
||||||
|
static int updateTipsCb(
|
||||||
|
Pointer<Int8> refname,
|
||||||
|
Pointer<git_oid> oldOid,
|
||||||
|
Pointer<git_oid> newOid,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
updateTips!(refname.cast<Utf8>().toDartString(), Oid(oldOid), Oid(newOid));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Callback function used to inform of the update status from the remote.
|
||||||
|
static void Function(String, String)? pushUpdateReference;
|
||||||
|
|
||||||
|
/// Callback called for each updated reference on push. If [message] is
|
||||||
|
/// not empty, the update was rejected by the remote server
|
||||||
|
/// and [message] contains the reason given.
|
||||||
|
static int pushUpdateReferenceCb(
|
||||||
|
Pointer<Int8> refname,
|
||||||
|
Pointer<Int8> message,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
final messageResult =
|
||||||
|
message == nullptr ? '' : message.cast<Utf8>().toDartString();
|
||||||
|
pushUpdateReference!(refname.cast<Utf8>().toDartString(), messageResult);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function matching the `Remote Function(Repository repo, String name, String url)` signature
|
||||||
|
/// to override the remote creation and customization process during a clone operation.
|
||||||
|
static Remote Function(Repository, String, String)? remoteFunction;
|
||||||
|
|
||||||
|
/// A callback used to create the git remote, prior to its being used to perform
|
||||||
|
/// the clone operation.
|
||||||
|
static int remoteCb(
|
||||||
|
Pointer<Pointer<git_remote>> remote,
|
||||||
|
Pointer<git_repository> repo,
|
||||||
|
Pointer<Int8> name,
|
||||||
|
Pointer<Int8> url,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
remote[0] = remoteFunction!(
|
||||||
|
Repository(repo),
|
||||||
|
name.cast<Utf8>().toDartString(),
|
||||||
|
url.cast<Utf8>().toDartString(),
|
||||||
|
).pointer;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A function matching the `Repository Function(String path, bool bare)` signature to override
|
||||||
|
/// the repository creation and customization process during a clone operation.
|
||||||
|
static Repository Function(String, bool)? repositoryFunction;
|
||||||
|
|
||||||
|
/// A callback used to create the new repository into which to clone.
|
||||||
|
static int repositoryCb(
|
||||||
|
Pointer<Pointer<git_repository>> repo,
|
||||||
|
Pointer<Int8> path,
|
||||||
|
int bare,
|
||||||
|
Pointer<Void> payload,
|
||||||
|
) {
|
||||||
|
repo[0] = repositoryFunction!(
|
||||||
|
path.cast<Utf8>().toDartString(),
|
||||||
|
bare == 1 ? true : false,
|
||||||
|
).pointer;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Plugs provided callbacks into libgit2 callbacks.
|
||||||
|
static void plug({
|
||||||
|
required git_remote_callbacks callbacksOptions,
|
||||||
|
required Callbacks callbacks,
|
||||||
|
}) {
|
||||||
|
const except = -1;
|
||||||
|
|
||||||
|
if (callbacks.transferProgress != null) {
|
||||||
|
transferProgress = callbacks.transferProgress;
|
||||||
|
callbacksOptions.transfer_progress = Pointer.fromFunction(
|
||||||
|
transferProgressCb,
|
||||||
|
except,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbacks.sidebandProgress != null) {
|
||||||
|
sidebandProgress = callbacks.sidebandProgress;
|
||||||
|
callbacksOptions.sideband_progress = Pointer.fromFunction(
|
||||||
|
sidebandProgressCb,
|
||||||
|
except,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbacks.updateTips != null) {
|
||||||
|
updateTips = callbacks.updateTips;
|
||||||
|
callbacksOptions.update_tips = Pointer.fromFunction(
|
||||||
|
updateTipsCb,
|
||||||
|
except,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbacks.pushUpdateReference != null) {
|
||||||
|
pushUpdateReference = callbacks.pushUpdateReference;
|
||||||
|
callbacksOptions.push_update_reference = Pointer.fromFunction(
|
||||||
|
pushUpdateReferenceCb,
|
||||||
|
except,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets callback functions to their original null values.
|
||||||
|
static void reset() {
|
||||||
|
transferProgress = null;
|
||||||
|
sidebandProgress = null;
|
||||||
|
updateTips = null;
|
||||||
|
pushUpdateReference = null;
|
||||||
|
remoteFunction = null;
|
||||||
|
repositoryFunction = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
import '../callbacks.dart';
|
||||||
import '../error.dart';
|
import '../error.dart';
|
||||||
import '../remote.dart';
|
import '../remote.dart';
|
||||||
import '../repository.dart';
|
import '../repository.dart';
|
||||||
import 'libgit2_bindings.dart';
|
import 'libgit2_bindings.dart';
|
||||||
import '../util.dart';
|
import '../util.dart';
|
||||||
|
import 'remote_callbacks.dart';
|
||||||
|
|
||||||
/// Attempt to open an already-existing repository at [path].
|
/// Attempt to open an already-existing repository at [path].
|
||||||
///
|
///
|
||||||
|
@ -140,6 +142,7 @@ Pointer<git_repository> clone(
|
||||||
Remote Function(Repository, String, String)? remote,
|
Remote Function(Repository, String, String)? remote,
|
||||||
Repository Function(String, bool)? repository,
|
Repository Function(String, bool)? repository,
|
||||||
String? checkoutBranch,
|
String? checkoutBranch,
|
||||||
|
Callbacks callbacks,
|
||||||
) {
|
) {
|
||||||
final out = calloc<Pointer<git_repository>>();
|
final out = calloc<Pointer<git_repository>>();
|
||||||
final urlC = url.toNativeUtf8().cast<Int8>();
|
final urlC = url.toNativeUtf8().cast<Int8>();
|
||||||
|
@ -163,18 +166,23 @@ Pointer<git_repository> clone(
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoteCallbacks.plug(
|
||||||
|
callbacksOptions: fetchOptions.ref.callbacks,
|
||||||
|
callbacks: callbacks,
|
||||||
|
);
|
||||||
|
|
||||||
const except = -1;
|
const except = -1;
|
||||||
|
|
||||||
git_remote_create_cb remoteCb = nullptr;
|
git_remote_create_cb remoteCb = nullptr;
|
||||||
if (remote != null) {
|
if (remote != null) {
|
||||||
_remoteFunction = remote;
|
RemoteCallbacks.remoteFunction = remote;
|
||||||
remoteCb = Pointer.fromFunction(_remoteCb, except);
|
remoteCb = Pointer.fromFunction(RemoteCallbacks.remoteCb, except);
|
||||||
}
|
}
|
||||||
|
|
||||||
git_repository_create_cb repositoryCb = nullptr;
|
git_repository_create_cb repositoryCb = nullptr;
|
||||||
if (repository != null) {
|
if (repository != null) {
|
||||||
_repositoryFunction = repository;
|
RemoteCallbacks.repositoryFunction = repository;
|
||||||
repositoryCb = Pointer.fromFunction(_repositoryCb, except);
|
repositoryCb = Pointer.fromFunction(RemoteCallbacks.repositoryCb, except);
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneOptions.ref.bare = bare ? 1 : 0;
|
cloneOptions.ref.bare = bare ? 1 : 0;
|
||||||
|
@ -190,8 +198,7 @@ Pointer<git_repository> clone(
|
||||||
calloc.free(checkoutBranchC);
|
calloc.free(checkoutBranchC);
|
||||||
calloc.free(cloneOptions);
|
calloc.free(cloneOptions);
|
||||||
calloc.free(fetchOptions);
|
calloc.free(fetchOptions);
|
||||||
_remoteFunction = null;
|
RemoteCallbacks.reset();
|
||||||
_repositoryFunction = null;
|
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
@ -200,47 +207,6 @@ Pointer<git_repository> clone(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A function matching the `Remote Function(Repository repo, String name, String url)` signature
|
|
||||||
/// to override the remote creation and customization process during a clone operation.
|
|
||||||
Remote Function(Repository, String, String)? _remoteFunction;
|
|
||||||
|
|
||||||
/// A callback used to create the git remote, prior to its being used to perform
|
|
||||||
/// the clone operation.
|
|
||||||
int _remoteCb(
|
|
||||||
Pointer<Pointer<git_remote>> remote,
|
|
||||||
Pointer<git_repository> repo,
|
|
||||||
Pointer<Int8> name,
|
|
||||||
Pointer<Int8> url,
|
|
||||||
Pointer<Void> payload,
|
|
||||||
) {
|
|
||||||
remote[0] = _remoteFunction!(
|
|
||||||
Repository(repo),
|
|
||||||
name.cast<Utf8>().toDartString(),
|
|
||||||
url.cast<Utf8>().toDartString(),
|
|
||||||
).pointer;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A function matching the `Repository Function(String path, bool bare)` signature to override
|
|
||||||
/// the repository creation and customization process during a clone operation.
|
|
||||||
Repository Function(String, bool)? _repositoryFunction;
|
|
||||||
|
|
||||||
/// A callback used to create the new repository into which to clone.
|
|
||||||
int _repositoryCb(
|
|
||||||
Pointer<Pointer<git_repository>> repo,
|
|
||||||
Pointer<Int8> path,
|
|
||||||
int bare,
|
|
||||||
Pointer<Void> payload,
|
|
||||||
) {
|
|
||||||
repo[0] = _repositoryFunction!(
|
|
||||||
path.cast<Utf8>().toDartString(),
|
|
||||||
bare == 1 ? true : false,
|
|
||||||
).pointer;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the path to the `.git` folder for normal repositories or the
|
/// Returns the path to the `.git` folder for normal repositories or the
|
||||||
/// repository itself for bare repositories.
|
/// repository itself for bare repositories.
|
||||||
String path(Pointer<git_repository> repo) {
|
String path(Pointer<git_repository> repo) {
|
||||||
|
|
25
lib/src/callbacks.dart
Normal file
25
lib/src/callbacks.dart
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import 'oid.dart';
|
||||||
|
import 'remote.dart';
|
||||||
|
|
||||||
|
class Callbacks {
|
||||||
|
const Callbacks({
|
||||||
|
this.transferProgress,
|
||||||
|
this.sidebandProgress,
|
||||||
|
this.updateTips,
|
||||||
|
this.pushUpdateReference,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Callback function that reports transfer progress.
|
||||||
|
final void Function(TransferProgress)? transferProgress;
|
||||||
|
|
||||||
|
/// Callback function that reports textual progress from the remote.
|
||||||
|
final void Function(String)? sidebandProgress;
|
||||||
|
|
||||||
|
/// Callback function matching the `void Function(String refname, Oid old, Oid new)`
|
||||||
|
/// that report reference updates.
|
||||||
|
final void Function(String, Oid, Oid)? updateTips;
|
||||||
|
|
||||||
|
/// Callback function matching the `void Function(String refname, String message)`
|
||||||
|
/// used to inform of the update status from the remote.
|
||||||
|
final void Function(String, String)? pushUpdateReference;
|
||||||
|
}
|
|
@ -154,8 +154,16 @@ class Remote {
|
||||||
/// specified url. By default connection isn't done through proxy.
|
/// specified url. By default connection isn't done through proxy.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<Map<String, dynamic>> ls([String? proxy]) {
|
List<Map<String, dynamic>> ls({
|
||||||
bindings.connect(_remotePointer, GitDirection.fetch.value, proxy);
|
String? proxy,
|
||||||
|
Callbacks callbacks = const Callbacks(),
|
||||||
|
}) {
|
||||||
|
bindings.connect(
|
||||||
|
_remotePointer,
|
||||||
|
GitDirection.fetch.value,
|
||||||
|
proxy,
|
||||||
|
callbacks,
|
||||||
|
);
|
||||||
final result = bindings.lsRemotes(_remotePointer);
|
final result = bindings.lsRemotes(_remotePointer);
|
||||||
bindings.disconnect(_remotePointer);
|
bindings.disconnect(_remotePointer);
|
||||||
return result;
|
return result;
|
||||||
|
@ -174,22 +182,40 @@ class Remote {
|
||||||
String? reflogMessage,
|
String? reflogMessage,
|
||||||
GitFetchPrune prune = GitFetchPrune.unspecified,
|
GitFetchPrune prune = GitFetchPrune.unspecified,
|
||||||
String? proxy,
|
String? proxy,
|
||||||
|
Callbacks callbacks = const Callbacks(),
|
||||||
}) {
|
}) {
|
||||||
bindings.fetch(_remotePointer, refspecs, reflogMessage, prune.value, proxy);
|
bindings.fetch(
|
||||||
|
_remotePointer,
|
||||||
|
refspecs,
|
||||||
|
reflogMessage,
|
||||||
|
prune.value,
|
||||||
|
proxy,
|
||||||
|
callbacks,
|
||||||
|
);
|
||||||
return TransferProgress(bindings.stats(_remotePointer));
|
return TransferProgress(bindings.stats(_remotePointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs a push.
|
/// Performs a push.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void push(List<String> refspecs, [String? proxy]) {
|
void push({
|
||||||
bindings.push(_remotePointer, refspecs, proxy);
|
required List<String> refspecs,
|
||||||
|
String? proxy,
|
||||||
|
Callbacks callbacks = const Callbacks(),
|
||||||
|
}) {
|
||||||
|
bindings.push(
|
||||||
|
_remotePointer,
|
||||||
|
refspecs,
|
||||||
|
proxy,
|
||||||
|
callbacks,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prunes tracking refs that are no longer present on remote.
|
/// Prunes tracking refs that are no longer present on remote.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void prune() => bindings.prune(_remotePointer);
|
void prune([Callbacks callbacks = const Callbacks()]) =>
|
||||||
|
bindings.prune(_remotePointer, callbacks);
|
||||||
|
|
||||||
/// Releases memory allocated for remote object.
|
/// Releases memory allocated for remote object.
|
||||||
void free() => bindings.free(_remotePointer);
|
void free() => bindings.free(_remotePointer);
|
||||||
|
|
|
@ -107,6 +107,7 @@ class Repository {
|
||||||
Remote Function(Repository, String, String)? remote,
|
Remote Function(Repository, String, String)? remote,
|
||||||
Repository Function(String, bool)? repository,
|
Repository Function(String, bool)? repository,
|
||||||
String? checkoutBranch,
|
String? checkoutBranch,
|
||||||
|
Callbacks callbacks = const Callbacks(),
|
||||||
}) {
|
}) {
|
||||||
libgit2.git_libgit2_init();
|
libgit2.git_libgit2_init();
|
||||||
|
|
||||||
|
@ -117,6 +118,7 @@ class Repository {
|
||||||
remote,
|
remote,
|
||||||
repository,
|
repository,
|
||||||
checkoutBranch,
|
checkoutBranch,
|
||||||
|
callbacks,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,7 @@ void main() {
|
||||||
remote.free();
|
remote.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully fetches data', () async {
|
test('successfully fetches data', () {
|
||||||
repo.remotes.setUrl(
|
repo.remotes.setUrl(
|
||||||
'libgit2',
|
'libgit2',
|
||||||
'https://github.com/libgit2/TestGitRepository',
|
'https://github.com/libgit2/TestGitRepository',
|
||||||
|
@ -222,7 +222,99 @@ void main() {
|
||||||
remote.free();
|
remote.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully pushes', () async {
|
test('successfully fetches data with provided transfer progress callback',
|
||||||
|
() {
|
||||||
|
repo.remotes.setUrl(
|
||||||
|
'libgit2',
|
||||||
|
'https://github.com/libgit2/TestGitRepository',
|
||||||
|
);
|
||||||
|
final remote = repo.remotes['libgit2'];
|
||||||
|
|
||||||
|
TransferProgress? callbackStats;
|
||||||
|
void tp(TransferProgress stats) => callbackStats = stats;
|
||||||
|
final callbacks = Callbacks(transferProgress: tp);
|
||||||
|
|
||||||
|
final stats = remote.fetch(callbacks: callbacks);
|
||||||
|
|
||||||
|
expect(stats.totalObjects == callbackStats?.totalObjects, true);
|
||||||
|
expect(stats.indexedObjects == callbackStats?.indexedObjects, true);
|
||||||
|
expect(stats.receivedObjects == callbackStats?.receivedObjects, true);
|
||||||
|
expect(stats.localObjects == callbackStats?.localObjects, true);
|
||||||
|
expect(stats.totalDeltas == callbackStats?.totalDeltas, true);
|
||||||
|
expect(stats.indexedDeltas == callbackStats?.indexedDeltas, true);
|
||||||
|
expect(stats.receivedBytes == callbackStats?.receivedBytes, true);
|
||||||
|
|
||||||
|
remote.free();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successfully fetches data with provided sideband progress callback',
|
||||||
|
() {
|
||||||
|
const sidebandMessage = """
|
||||||
|
Enumerating objects: 69, done.
|
||||||
|
Counting objects: 100% (1/1)\rCounting objects: 100% (1/1), done.
|
||||||
|
Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
||||||
|
""";
|
||||||
|
repo.remotes.setUrl(
|
||||||
|
'libgit2',
|
||||||
|
'https://github.com/libgit2/TestGitRepository',
|
||||||
|
);
|
||||||
|
final remote = repo.remotes['libgit2'];
|
||||||
|
|
||||||
|
var sidebandOutput = StringBuffer();
|
||||||
|
void sideband(String message) {
|
||||||
|
sidebandOutput.write(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
final callbacks = Callbacks(sidebandProgress: sideband);
|
||||||
|
|
||||||
|
remote.fetch(callbacks: callbacks);
|
||||||
|
expect(sidebandOutput.toString(), sidebandMessage);
|
||||||
|
|
||||||
|
remote.free();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successfully fetches data with provided update tips callback', () {
|
||||||
|
repo.remotes.setUrl(
|
||||||
|
'libgit2',
|
||||||
|
'https://github.com/libgit2/TestGitRepository',
|
||||||
|
);
|
||||||
|
final remote = repo.remotes['libgit2'];
|
||||||
|
const tipsExpected = [
|
||||||
|
{
|
||||||
|
'refname': 'refs/tags/annotated_tag',
|
||||||
|
'oldSha': '0000000000000000000000000000000000000000',
|
||||||
|
'newSha': 'd96c4e80345534eccee5ac7b07fc7603b56124cb',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'refname': 'refs/tags/blob',
|
||||||
|
'oldSha': '0000000000000000000000000000000000000000',
|
||||||
|
'newSha': '55a1a760df4b86a02094a904dfa511deb5655905'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'refname': 'refs/tags/commit_tree',
|
||||||
|
'oldSha': '0000000000000000000000000000000000000000',
|
||||||
|
'newSha': '8f50ba15d49353813cc6e20298002c0d17b0a9ee',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
var updateTipsOutput = <Map<String, String>>[];
|
||||||
|
void updateTips(String refname, Oid oldOid, Oid newOid) {
|
||||||
|
updateTipsOutput.add({
|
||||||
|
'refname': refname,
|
||||||
|
'oldSha': oldOid.sha,
|
||||||
|
'newSha': newOid.sha,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
final callbacks = Callbacks(updateTips: updateTips);
|
||||||
|
|
||||||
|
remote.fetch(callbacks: callbacks);
|
||||||
|
expect(updateTipsOutput, tipsExpected);
|
||||||
|
|
||||||
|
remote.free();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successfully pushes with update reference callback', () async {
|
||||||
final originDir =
|
final originDir =
|
||||||
Directory('${Directory.systemTemp.path}/origin_testrepo');
|
Directory('${Directory.systemTemp.path}/origin_testrepo');
|
||||||
|
|
||||||
|
@ -238,11 +330,19 @@ void main() {
|
||||||
repo.remotes.create(name: 'local', url: originDir.path);
|
repo.remotes.create(name: 'local', url: originDir.path);
|
||||||
final remote = repo.remotes['local'];
|
final remote = repo.remotes['local'];
|
||||||
|
|
||||||
remote.push(['refs/heads/master']);
|
var updateRefOutput = <String, String>{};
|
||||||
|
void updateRef(String refname, String message) {
|
||||||
|
updateRefOutput[refname] = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
final callbacks = Callbacks(pushUpdateReference: updateRef);
|
||||||
|
|
||||||
|
remote.push(refspecs: ['refs/heads/master'], callbacks: callbacks);
|
||||||
expect(
|
expect(
|
||||||
(originRepo[originRepo.head.target.sha] as Commit).id.sha,
|
(originRepo[originRepo.head.target.sha] as Commit).id.sha,
|
||||||
'821ed6e80627b8769d170a293862f9fc60825226',
|
'821ed6e80627b8769d170a293862f9fc60825226',
|
||||||
);
|
);
|
||||||
|
expect(updateRefOutput, {'refs/heads/master': ''});
|
||||||
|
|
||||||
remote.free();
|
remote.free();
|
||||||
originRepo.free();
|
originRepo.free();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue