ZEPPELIN-143: .history() implemented

This commit is contained in:
Alexander Bezzubov 2015-12-01 16:27:14 +09:00
parent 4ef879a24e
commit 274830f128
4 changed files with 60 additions and 38 deletions

View file

@ -19,7 +19,6 @@ package org.apache.zeppelin.notebook.repo;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
@ -30,22 +29,21 @@ import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
/**
* NotebookRepo that hosts all the notebook FS in a single Git repo
*
* This impl intended to be simple and straightforward:
* - does not handle branches
* - only basic git, no Github push\pull yet
* - only basic local git file repo, no remote Github push\pull yet
*
*
* TODO(bzz): describe config
* GIT_REMOTE_URL remote
* auth credentials
* TODO(bzz): add default .gitignore
*/
public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVersioned {
private static final Logger LOG = LoggerFactory.getLogger(GitNotebookRepo.class);
@ -53,21 +51,6 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
private String localPath;
private Git git;
// I. First useful case:
// start \w repo + tutorial notebook
// all modifications results in a commit
// II. Next case:
// start \wo .git
// create one
// add existing notebooks
// ..and then case I. ...
// III. Next case:
// start \w repo
// show history
// user can switch to REV in read-only
public GitNotebookRepo(ZeppelinConfiguration conf) throws IOException {
super(conf);
localPath = getRootDir().getName().getPath();
@ -91,9 +74,9 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
try {
List<DiffEntry> gitDiff = git.diff().call();
if (!gitDiff.isEmpty()) {
LOG.info("Changes found for pattern {}: {}", pattern, gitDiff);
LOG.debug("Changes found for pattern '{}': {}", pattern, gitDiff);
DirCache added = git.add().addFilepattern(pattern).call();
LOG.info("{} changes area about to be commited", added.getEntryCount());
LOG.debug("{} changes are about to be commited", added.getEntryCount());
git.commit().setMessage("Updated " + pattern).call();
} else {
LOG.info("No changes found {}", pattern);
@ -105,14 +88,24 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
@Override
public Note get(String noteId, String rev) throws IOException {
//TODO(alex): something instead of 'git checkout rev', that will not change-the-world
//TODO(bzz): something like 'git checkout rev', that will not change-the-world though
return super.get(noteId);
}
@Override
public List<String> history(String noteId) {
//TODO(alex): git logs -- "noteId"
return Collections.emptyList();
public List<Rev> history(String noteId) {
List<Rev> history = Lists.newArrayList();
LOG.debug("Listing history for {}:", noteId);
try {
Iterable<RevCommit> logs = git.log().addPath(noteId).call();
for (RevCommit log: logs) {
history.add(new Rev(log.getName(), log.getCommitTime()));
LOG.debug(" - ({},{})", log.getName(), log.getCommitTime());
}
} catch (GitAPIException e) {
LOG.error("Failed to get logs for {}", noteId, e);
}
return history;
}
//DI replacements for Tests

View file

@ -9,22 +9,35 @@ import org.apache.zeppelin.notebook.Note;
* Notebook repository w/ versions
*/
public interface NotebookRepoVersioned extends NotebookRepo {
/**
* Get particular revision of the Notebooks
*
*
* @param noteId Id of the Notebook
* @param rev revision of the Notebook
* @return a Notebook
* @throws IOException
* @throws IOException
*/
public abstract Note get(String noteId, String rev) throws IOException;
/**
* List of revisions of the given Notebook
*
*
* @param noteId id of the Notebook
* @return list of revisions
*/
public abstract List<String> history(String noteId);
public abstract List<Rev> history(String noteId);
/**
* Represents the 'Revision' a point in life of the notebook
*/
static class Rev {
public Rev(String name, int time) {
this.name = name;
this.time = time;
}
String name;
int time;
}
}

View file

@ -28,6 +28,7 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
import org.apache.zeppelin.notebook.repo.NotebookRepoVersioned.Rev;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
@ -38,12 +39,13 @@ import org.junit.Test;
import com.google.common.base.Joiner;
public class GitNotebookRepoTest {
private File zeppelinDir;
//private Notebook notebook;
private GitNotebookRepo notebookRepo;
private static final String TEST_NOTE_ID = "2A94M5J1Z";
private File zeppelinDir;
private String notebooksDir;
private ZeppelinConfiguration conf;
private GitNotebookRepo notebookRepo;
@Before
public void setUp() throws Exception {
@ -56,9 +58,8 @@ public class GitNotebookRepoTest {
File notebookDir = new File(notebooksDir);
notebookDir.mkdirs();
String testNoteId = "2A94M5J1Z";
String testNoteDir = Joiner.on(File.separator).join(notebooksDir, testNoteId);
FileUtils.copyDirectory(new File(Joiner.on(File.separator).join("src", "test", "resources", testNoteId)),
String testNoteDir = Joiner.on(File.separator).join(notebooksDir, TEST_NOTE_ID);
FileUtils.copyDirectory(new File(Joiner.on(File.separator).join("src", "test", "resources", TEST_NOTE_ID)),
new File(testNoteDir)
);
@ -110,4 +111,17 @@ public class GitNotebookRepoTest {
assertThat(diff).isEmpty();
}
@Test
public void showNotebookHistory() throws GitAPIException, IOException {
//given
notebookRepo = new GitNotebookRepo(conf);
assertThat(notebookRepo.list()).isNotEmpty();
//when
List<Rev> testNotebookHistory = notebookRepo.history(TEST_NOTE_ID);
//then
assertThat(testNotebookHistory).isNotEmpty();
}
}

View file

@ -27,6 +27,8 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n
# Root logger option
log4j.rootLogger=INFO, stdout
log4j.logger.org.apache.zeppelin.notebook.repo=DEBUG
#mute some noisy guys
log4j.logger.org.apache.hadoop.mapred=WARN