|
|
@@ -1,7 +1,14 @@
|
|
|
package info.knacki.pass.git;
|
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
+import java.io.InputStreamReader;
|
|
|
import java.io.OutputStream;
|
|
|
+import java.util.ArrayDeque;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
import info.knacki.pass.git.entities.GitCommit;
|
|
|
@@ -9,6 +16,7 @@ import info.knacki.pass.git.entities.GitObject;
|
|
|
import info.knacki.pass.git.entities.GitRef;
|
|
|
import info.knacki.pass.io.AppendableInputStream;
|
|
|
import info.knacki.pass.io.CharsetHelper;
|
|
|
+import info.knacki.pass.io.OnErrorListener;
|
|
|
import info.knacki.pass.io.OnResponseListener;
|
|
|
import info.knacki.pass.io.OnStreamResponseListener;
|
|
|
import info.knacki.pass.io.ssh.SSHConnection;
|
|
|
@@ -23,24 +31,85 @@ public class SSHGitProtocol implements GitInterface {
|
|
|
fConfig = config;
|
|
|
}
|
|
|
|
|
|
- private void GetRefs(SSHConnection con, OutputStream stdin, InputStream stdout) {
|
|
|
+ private Collection<GitRef> GetRefs(SSHConnection con, OutputStream stdin, InputStream stdout) {
|
|
|
+ ArrayDeque<GitRef> references = new ArrayDeque<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ while (true) {
|
|
|
+ byte[] hash = new byte[44];
|
|
|
+ if (stdout.read(hash, 0, 4) < 4) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (CharsetHelper.ByteArrayToString(hash, 0, 4).equals("0000") && stdout.available() == 0) {
|
|
|
+ break; // End Hash
|
|
|
+ }
|
|
|
+ // Read the remaining of the hash
|
|
|
+ if (stdout.read(hash, 4, 40) < 40) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ByteArrayOutputStream buffer = null;
|
|
|
+ boolean ignoreToEol = false;
|
|
|
+ // read the ref name
|
|
|
+ while (true) {
|
|
|
+ byte ch = (byte) stdout.read();
|
|
|
+ if (ch == 0)
|
|
|
+ ignoreToEol = true; // ignore server caps
|
|
|
+ if (ch == '\n')
|
|
|
+ break;
|
|
|
+ if (buffer == null)
|
|
|
+ buffer = new ByteArrayOutputStream();
|
|
|
+ else if (!ignoreToEol)
|
|
|
+ buffer.write(ch);
|
|
|
+ }
|
|
|
+ String branchRef;
|
|
|
+ if (buffer != null && (branchRef = CharsetHelper.ByteArrayToString(buffer.toByteArray())).startsWith("refs/heads/")){
|
|
|
+ GitRef ref = new GitRef(CharsetHelper.ByteArrayToString(hash), branchRef);
|
|
|
+ references.add(ref);
|
|
|
+ log.info("Found ref: " + ref);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (IOException e) {
|
|
|
+ log.log(Level.SEVERE, "Cannot read from ssh command: " +e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return references;
|
|
|
}
|
|
|
|
|
|
- private void WriteStdErrToLogger(byte[] stderr) {
|
|
|
- String err = CharsetHelper.ByteArrayToString(stderr);
|
|
|
- if (!err.isEmpty())
|
|
|
- log.severe(err);
|
|
|
+ public void ListenForErrors(InputStream stderr, OnErrorListener OnError) {
|
|
|
+ (new Thread() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ BufferedReader reader = new BufferedReader(new InputStreamReader(stderr));
|
|
|
+ String line;
|
|
|
+
|
|
|
+ try {
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
+ OnError.OnError(line, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (IOException e) {
|
|
|
+ log.log(Level.SEVERE, "Cannot read from stderr", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void GetRefs(OnResponseListener<GitRef[]> callback) {
|
|
|
- AppendableInputStream stdin_in = new AppendableInputStream();
|
|
|
- OutputStream stdin = stdin_in.GetWriter();
|
|
|
+ AppendableInputStream stdin = new AppendableInputStream();
|
|
|
|
|
|
SSHFactory
|
|
|
- .createInstance(fConfig, "git-upload-pack isundil/config") // FIXME tmp
|
|
|
- .SetOnConnectionReadyListener((connection, stdout, stderr) -> GetRefs(connection, stdin, stdout))
|
|
|
- .connect(stdin_in);
|
|
|
+ .createInstance(fConfig, "git-upload-pack isundil/pass") // FIXME tmp
|
|
|
+ .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
+ ListenForErrors(stderr, (msg, exc) -> log.severe(msg));
|
|
|
+ Collection<GitRef> references = GetRefs(connection, stdin.GetWriter(), stdout);
|
|
|
+ stdin.closeUnsafe();
|
|
|
+ GitRef[] refs = new GitRef[references.size()];
|
|
|
+ callback.OnResponse(references.toArray(refs));
|
|
|
+ connection.disconnect();
|
|
|
+ })
|
|
|
+ .connect();
|
|
|
}
|
|
|
|
|
|
@Override
|