Make the android app use our c-lib for all git operations

* Apart from gitPull which is currently broken
* And the ssh key generation which fails on Android
This commit is contained in:
Vishesh Handa
2019-05-15 19:12:55 +02:00
parent 8748132e70
commit f5b98ab9c6
9 changed files with 206 additions and 214 deletions

View File

@ -13,6 +13,7 @@ void gj_log(const char *message) {
}
// FIXME: Figure out better error handling!
int handle_error(int err) {
if (err != 0) {
const gj_error *e = gj_error_info(err);
@ -24,6 +25,126 @@ int handle_error(int err) {
return err;
}
JNIEXPORT void JNICALL
Java_io_gitjournal_gitjournal_Git_setupLib(
JNIEnv *env,
jobject this_obj) {
gj_init();
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_init(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
int err = gj_git_init(git_base_path);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_clone(
JNIEnv *env,
jobject this_obj,
jstring jni_clone_url,
jstring jni_git_base_path) {
const char *clone_url = (*env)->GetStringUTFChars(env, jni_clone_url, 0);
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
int err = gj_git_clone(clone_url, git_base_path);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_pull(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path,
jstring jni_author_name,
jstring jni_author_email) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
const char *author_name = (*env)->GetStringUTFChars(env, jni_author_name, 0);
const char *author_email = (*env)->GetStringUTFChars(env, jni_author_email, 0);
int err = gj_git_pull(git_base_path, author_name, author_email);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_push(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
int err = gj_git_push(git_base_path);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_commit(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path,
jstring jni_author_name,
jstring jni_author_email,
jstring jni_message) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
const char *author_name = (*env)->GetStringUTFChars(env, jni_author_name, 0);
const char *author_email = (*env)->GetStringUTFChars(env, jni_author_email, 0);
const char *message = (*env)->GetStringUTFChars(env, jni_message, 0);
int err = gj_git_commit(git_base_path, author_name, author_email, message);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_resetHard(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path,
jstring jni_ref) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
const char *ref = (*env)->GetStringUTFChars(env, jni_ref, 0);
int err = gj_git_reset_hard(git_base_path, ref);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_add(
JNIEnv *env,
@ -33,9 +154,6 @@ Java_io_gitjournal_gitjournal_Git_add(
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
const char *add_pattern = (*env)->GetStringUTFChars(env, jni_add_pattern, 0);
// FIXME: This should be done somewhere else!
gj_init();
int err = gj_git_add(git_base_path, add_pattern);
if (err < 0) {
handle_error(err);
@ -46,3 +164,39 @@ Java_io_gitjournal_gitjournal_Git_add(
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jstring JNICALL
Java_io_gitjournal_gitjournal_Git_rm(
JNIEnv *env,
jobject this_obj,
jstring jni_git_base_path,
jstring jni_pattern) {
const char *git_base_path = (*env)->GetStringUTFChars(env, jni_git_base_path, 0);
const char *pattern = (*env)->GetStringUTFChars(env, jni_pattern, 0);
int err = gj_git_rm(git_base_path, pattern);
if (err < 0) {
handle_error(err);
return (*env)->NewStringUTF(env, "Error");
}
__android_log_print(ANDROID_LOG_ERROR, "GitAdd", "Everything seems fine");
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT void JNICALL
Java_io_gitjournal_gitjournal_Git_setSshKeys(
JNIEnv *env,
jobject this_obj,
jstring jni_public_key_path,
jstring jni_private_key_path,
jstring jni_passphrase) {
const char *public_key_path = (*env)->GetStringUTFChars(env, jni_public_key_path, 0);
const char *private_key_path = (*env)->GetStringUTFChars(env, jni_private_key_path, 0);
const char *passphrase = (*env)->GetStringUTFChars(env, jni_passphrase, 0);
gj_set_ssh_keys_paths((char *) public_key_path, (char *) private_key_path, (char *) passphrase);
}

View File

@ -5,7 +5,21 @@ public class Git {
System.loadLibrary("native-lib");
}
// This needs to be called once!
public native void setupLib();
public native String generateKeys(String privateKeyPath, String publicKeyPath, String comment);
public native String init(String basePath);
public native String clone(String cloneUrl, String basePath);
public native String pull(String basePath, String authorName, String authorEmail);
public native String push(String basePath);
public native String commit(String basePath, String authorName, String authorEmail, String message);
public native String resetHard(String basePath, String ref);
public native String add(String basePath, String pattern);
public native String rm(String basePath, String pattern);
public native void setSshKeys(String publicKeyPath, String privateKeyPath, String passphrase);
}

View File

@ -3,17 +3,6 @@ package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.lib.TextProgressMonitor;
import java.io.PrintWriter;
import java.io.File;
import io.flutter.plugin.common.MethodChannel.Result;
@ -29,35 +18,18 @@ public class GitCloneTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... params) {
String url = params[0];
String cloneDirPath = params[1];
final String privateKeyPath = params[2];
final String publicKeyPath = params[2];
final String privateKeyPath = params[3];
File cloneDir = new File(cloneDirPath);
Log.d("GitClone Directory", cloneDirPath);
try {
CloneCommand cloneCommand = Git.cloneRepository().setURI(url).setDirectory(cloneDir)
.setProgressMonitor(new TextProgressMonitor(new PrintWriter(System.out)));
Git git = new Git();
git.setSshKeys(publicKeyPath, privateKeyPath, "");
cloneCommand.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport transport) {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(new CustomSshSessionFactory(privateKeyPath));
}
});
cloneCommand.call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
String errorStr = git.clone(url, cloneDirPath);
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -3,18 +3,7 @@ package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.PersonIdent;
import java.io.File;
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import io.flutter.plugin.common.MethodChannel.Result;
@ -36,53 +25,10 @@ public class GitCommitTask extends AsyncTask<String, Void, Void> {
File cloneDir = new File(cloneDirPath);
Log.d("GitClone Directory", cloneDirPath);
try {
Git git = Git.open(cloneDir);
PersonIdent identity = new PersonIdent(authorName, authorEmail);
if (commitDateTimeStr != null && !commitDateTimeStr.isEmpty()) {
Log.d(TAG, "CustomDateTime: " + commitDateTimeStr);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = format.parse(commitDateTimeStr);
TimeZone tz = identity.getTimeZone();
// Check for timezone
/*
if (commitDateTimeStr.indexOf('+') == 19) {
// FIXME: This does not deal with timezones with minutes!
int hours = Integer.parseInt(commitDateTimeStr.substring(20, 22));
int minutes = Integer.parseInt(commitDateTimeStr.substring(23));
Log.d(TAG, "TimeZone Hours: " + hours);
Log.d(TAG, "TimeZone Minutes: " + minutes);
tz = new SimpleTimeZone(hours, "foo");
} else {
Log.d(TAG, "No custom timezone provided");
}
*/
identity = new PersonIdent(identity, date, tz);
} else {
Log.d(TAG, "No custom datetime provided");
}
CommitCommand commitCommand = git.commit();
commitCommand.setAuthor(identity);
commitCommand.setMessage(message);
//commitCommand.setAllowEmpty(false);
commitCommand.call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
Git git = new Git();
String errorStr = git.commit(cloneDirPath, authorName, authorEmail, message);
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -3,19 +3,6 @@ package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.lib.TextProgressMonitor;
import java.io.PrintWriter;
import java.io.File;
import io.flutter.plugin.common.MethodChannel.Result;
public class GitInitTask extends AsyncTask<String, Void, Void> {
@ -28,24 +15,12 @@ public class GitInitTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... params) {
String cloneDirPath = params[0];
File cloneDir = new File(cloneDirPath);
Log.d("GitInit Directory", cloneDirPath);
try {
Git.init().setDirectory(cloneDir).call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
Git git = new Git();
String errorStr = git.init(cloneDirPath);
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -3,15 +3,6 @@ package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.SshTransport;
import java.io.File;
import io.flutter.plugin.common.MethodChannel.Result;
@ -26,35 +17,17 @@ public class GitPushTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... params) {
String cloneDirPath = params[0];
final String privateKeyPath = params[1];
final String publicKeyPath = params[1];
final String privateKeyPath = params[2];
File cloneDir = new File(cloneDirPath);
Log.d("GitClone Directory", cloneDirPath);
try {
Git git = Git.open(cloneDir);
PushCommand pushCommand = git.push();
pushCommand.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport transport) {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(new CustomSshSessionFactory(privateKeyPath));
}
});
pushCommand.setPushAll().call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
Git git = new Git();
git.setSshKeys(publicKeyPath, privateKeyPath, "");
String errorStr = git.push(cloneDirPath);
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -1,14 +1,6 @@
package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.TransportException;
import java.io.File;
import io.flutter.plugin.common.MethodChannel.Result;
@ -23,28 +15,10 @@ public class GitResetLastTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... params) {
final String cloneDirPath = params[0];
File cloneDir = new File(cloneDirPath);
Log.d("GitResetLastTask", "Clone Path: " + cloneDirPath);
try {
Git git = Git.open(cloneDir);
ResetCommand command = git.reset();
command.setMode(ResetCommand.ResetType.HARD);
command.setRef("HEAD^");
command.call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
Git git = new Git();
String errorStr = git.resetHard(cloneDirPath, "HEAD^");
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -3,11 +3,6 @@ package io.gitjournal.gitjournal;
import android.os.AsyncTask;
import android.util.Log;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.RmCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.TransportException;
import java.io.File;
import io.flutter.plugin.common.MethodChannel.Result;
@ -27,24 +22,10 @@ public class GitRmTask extends AsyncTask<String, Void, Void> {
File cloneDir = new File(cloneDirPath);
Log.d("GitClone Directory", cloneDirPath);
try {
Git git = Git.open(cloneDir);
RmCommand rmCommand = git.rm();
rmCommand.addFilepattern(filePattern);
rmCommand.call();
} catch (TransportException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (GitAPIException e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
return null;
} catch (Exception e) {
Log.d(TAG, e.toString());
result.error("FAILED", e.getMessage(), null);
Git git = new Git();
String errorStr = git.rm(cloneDirPath, filePattern);
if (!errorStr.isEmpty()) {
result.error("FAILED", errorStr, null);
return null;
}

View File

@ -31,6 +31,9 @@ public class MainActivity extends FlutterActivity implements MethodCallHandler {
channel = new MethodChannel(getFlutterView(), CHANNEL_NAME);
channel.setMethodCallHandler(this);
Git g = new Git();
g.setupLib();
}
@Override
@ -58,7 +61,7 @@ public class MainActivity extends FlutterActivity implements MethodCallHandler {
String cloneLocation = filesDir + "/" + folderName;
new GitCloneTask(result).execute(cloneUrl, cloneLocation, privateKeyPath);
new GitCloneTask(result).execute(cloneUrl, cloneLocation, publicKeyPath, privateKeyPath);
return;
} else if (call.method.equals("gitPull")) {
String folderName = call.argument("folderName");
@ -82,7 +85,7 @@ public class MainActivity extends FlutterActivity implements MethodCallHandler {
String cloneLocation = filesDir + "/" + folderName;
new GitPushTask(result).execute(cloneLocation, privateKeyPath);
new GitPushTask(result).execute(cloneLocation, publicKeyPath, privateKeyPath);
return;
} else if (call.method.equals("gitAdd")) {
String folderName = call.argument("folderName");