Commit 72df17c6 by Edward Thomson

remote: introduce git_remote_ready_cb

Introduce a new callback that fires when the remote is ready to connect.
parent 67240677
......@@ -514,6 +514,18 @@ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, cons
typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload);
/**
* Callback invoked immediately before we attempt to connect to the
* given url. Callers may change the URL before the connection by
* calling `git_remote_set_instance_url` in the callback.
*
* @param remote The remote to be connected
* @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
* @param payload Payload provided by the caller
* @return 0 on success, or an error
*/
typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload);
/**
* The callback settings structure
*
* Set the callbacks to be called by the remote when informing the user
......@@ -598,6 +610,11 @@ struct git_remote_callbacks {
git_transport_cb transport;
/**
* Callback when the remote is ready to connect.
*/
git_remote_ready_cb remote_ready;
/**
* This will be passed to each of the callbacks in this struct
* as the last parameter.
*/
......
......@@ -709,11 +709,19 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int
GIT_ASSERT_ARG(remote);
GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
if (direction == GIT_DIRECTION_FETCH) {
if (callbacks && callbacks->remote_ready) {
int status = callbacks->remote_ready(remote, direction, callbacks->payload);
if (status != 0 && status != GIT_PASSTHROUGH) {
git_error_set_after_callback_function(status, "git_remote_ready_cb");
return status;
}
}
if (direction == GIT_DIRECTION_FETCH)
url = remote->url;
} else if (direction == GIT_DIRECTION_PUSH) {
else if (direction == GIT_DIRECTION_PUSH)
url = remote->pushurl ? remote->pushurl : remote->url;
}
if (!url) {
git_error_set(GIT_ERROR_INVALID,
......@@ -722,6 +730,7 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int
direction == GIT_DIRECTION_FETCH ? "fetch" : "push");
return GIT_EINVALID;
}
return resolve_url(url_out, url, direction, callbacks);
}
......
......@@ -56,6 +56,48 @@ void test_network_remote_remotes__parsing(void)
git_buf_dispose(&url);
}
static int remote_ready_callback(git_remote *remote, int direction, void *payload)
{
if (direction == GIT_DIRECTION_PUSH) {
const char *url = git_remote_pushurl(remote);
cl_assert_equal_p(url, NULL);;
cl_assert_equal_s(payload, "payload");
return git_remote_set_instance_pushurl(remote, "push_url");
}
if (direction == GIT_DIRECTION_FETCH) {
const char *url = git_remote_url(remote);
cl_assert_equal_s(url, "git://github.com/libgit2/libgit2");
cl_assert_equal_s(payload, "payload");
return git_remote_set_instance_url(remote, "fetch_url");
}
return -1;
}
void test_network_remote_remotes__remote_ready(void)
{
git_buf url = GIT_BUF_INIT;
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
callbacks.remote_ready = remote_ready_callback;
callbacks.payload = "payload";
cl_assert_equal_s(git_remote_name(_remote), "test");
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
cl_assert(git_remote_pushurl(_remote) == NULL);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks));
cl_assert_equal_s(url.ptr, "fetch_url");
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks));
cl_assert_equal_s(url.ptr, "push_url");
git_buf_dispose(&url);
}
static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload)
{
cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0);
......
......@@ -12,7 +12,7 @@ extern const git_oid OID_ZERO;
* @param data pointer to a record_callbacks_data instance
*/
#define RECORD_CALLBACKS_INIT(data) \
{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data, NULL }
{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, NULL, data, NULL }
typedef struct {
char *name;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment