Skip to content

Commit

Permalink
Merge branch 'release-0.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
williamphan committed Jan 5, 2015
2 parents 9fcdd59 + 97c7eda commit 8b0df33
Show file tree
Hide file tree
Showing 16 changed files with 676 additions and 100 deletions.
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Ignore user specific IDEA components
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/codeStyleSettings.xml

# Don't add temporary files
*~

# Maven output
/target
/target

# Buck stuff
bucklets
.buckversion
7 changes: 7 additions & 0 deletions .idea/dictionaries/simon.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Changelog
All notable changes to this project will be documented in this file.

## 0.3 - 2015-01-05
### Added
- Automatic adding of reviewer with merge rights.
- Load balancing reviewers based how many changes one is reviewing.
- Loading animation while waiting for review advice.
- Review advice now loads on demand.

### Fixed
- Incompatible cache files are recalculated.

## 0.2.1 - 2014-12-10
### Fixed
- Review advice output rounding bug. Should now round correctly and output right ammount of sessions.

## 0.2 - 2014-12-09
### Added
- Automatic adding of reviewer based on git blame.

## 0.1 - 2014-11-22
### Added
- Basic review time suggestion functionality.
3 changes: 2 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2014 Gustav Jansson Ekstrand (gustav.jp@live.se), Simon Wessel (simon.w.karlsson@gmail.com), William Phan (william.da.phan@gmail.com)
Copyright (c) 2014-2015 Gustav Jansson Ekstrand (gustav.jp@live.se), Simon Wessel (simon.w.karlsson@gmail.com),
William Phan (william.da.phan@gmail.com), Sony Mobile Communications

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
gerrit-reviewassistant
======================
# ReviewAssistant for Gerrit Code Review

ReviewAssistant plugin for Gerrit Code Review
**Note that ReviewAssistant is developed against Gerrit v2.10-rc0. At this time, no other versions are supported.**

ReviewAssistant is a plugin for Gerrit Code Review. ReviewAssistant gives advice to reviewers on how the review should be
performed to be as effective as possible. The review time suggestions are based on the following rules:

* No review should be shorter than 5 minutes.
* Five lines per minute is considered to be the optimum review speed.
* Reviewers should not spend more than 60 minutes reviewing. If the review is expected to take longer, it is recommended
to split the review into several sessions.

ReviewAssistant is also capable of adding reviewers automatically, based on:

* Git blame
* Submit history - Users with merge rights.
* Open changes - Users with more open changes are less likely to be chosen as reviewer.

## Credits

The rules are based on Jenkins ReviewBuddy by switchgears.

* [ReviewBuddy presentation on slideshare](http://www.slideshare.net/AskeOlsson/jenkins-review-buddy)
* [switchgears on github](https://github.com/switchgears/gerrit-review-buddy)

Other notable sources of inspiration include

* [reviewers-by-blame plugin for Gerrit](https://gerrit.googlesource.com/plugins/reviewers-by-blame/)
* [reviewers plugin for Gerrit](https://gerrit.googlesource.com/plugins/reviewers/)
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>com.github.nexception.reviewassistant</groupId>
<artifactId>reviewassistant</artifactId>
<packaging>jar</packaging>
<version>0.1.2</version>
<version>0.3</version>
<name>reviewassistant</name>

<properties>
Expand All @@ -23,7 +23,7 @@
<configuration>
<archive>
<manifestEntries>
<Gerrit-PluginName>ReviewAssistant</Gerrit-PluginName>
<Gerrit-PluginName>reviewassistant</Gerrit-PluginName>
<Gerrit-Module>com.github.nexception.reviewassistant.Module</Gerrit-Module>
<Gerrit-HttpModule>com.github.nexception.reviewassistant.HttpModule</Gerrit-HttpModule>

Expand Down Expand Up @@ -61,4 +61,4 @@
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>
66 changes: 0 additions & 66 deletions src/main/java/com/github/nexception/reviewassistant/Algorithm.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,36 +1,166 @@
package com.github.nexception.reviewassistant;

import com.google.gerrit.common.ChangeListener;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
* The change event listener listens to new commits and passes them on to the algorithm.
*/
class ChangeEventListener implements ChangeListener {

private static final Logger log = LoggerFactory.getLogger(ChangeEventListener.class);
// private final GerritReviewAssistan.Factory gerritReviewAssistantFactory;
private Storage storage;
private final ReviewAssistant.Factory reviewAssistantFactory;
private WorkQueue workQueue;
private GitRepositoryManager repoManager;
private SchemaFactory<ReviewDb> schemaFactory;
private final ThreadLocalRequestContext tl;
private ReviewDb db;
private final PluginUser pluginUser;
private final IdentifiedUser.GenericFactory identifiedUserFactory;

@Inject
// ChangeEventListener(final GerritReviewAssistant.Factory gerritReviewAssistantFactory, Storage storage) {
ChangeEventListener(Storage storage) {
// this.gerritReviewAssistantFactory = gerritReviewAssistantFactory;
this.storage = storage;
ChangeEventListener(final ReviewAssistant.Factory reviewAssistantFactory,
final WorkQueue workQueue, final GitRepositoryManager repoManager,
final SchemaFactory<ReviewDb> schemaFactory,
final ThreadLocalRequestContext tl, final PluginUser pluginUser,
final IdentifiedUser.GenericFactory identifiedUserFactory) {
this.workQueue = workQueue;
this.reviewAssistantFactory = reviewAssistantFactory;
this.repoManager = repoManager;
this.schemaFactory = schemaFactory;
this.tl = tl;
this.pluginUser = pluginUser;
this.identifiedUserFactory = identifiedUserFactory;
}


@Override
public void onChangeEvent(ChangeEvent event) {
if(!(event instanceof PatchSetCreatedEvent))
public void onChangeEvent(ChangeEvent changeEvent) {
if (!(changeEvent instanceof PatchSetCreatedEvent)) {
return;
}
PatchSetCreatedEvent event = (PatchSetCreatedEvent) changeEvent;
log.info("Received new commit: " + event.patchSet.revision);

Project.NameKey projectName = new Project.NameKey(event.change.project);
Repository repo;
try {
repo = repoManager.openRepository(projectName);
} catch (RepositoryNotFoundException e) {
log.error(e.getMessage(), e);
return;
} catch (IOException e) {
log.error(e.getMessage(), e);
return;
PatchSetCreatedEvent e = (PatchSetCreatedEvent) event;
log.info("Received new commit: " + e.patchSet.revision);
storage.storeCalculation(Algorithm.calculate(e));
}

final ReviewDb reviewDb;
final RevWalk walk = new RevWalk(repo);

try {
reviewDb = schemaFactory.open();
try {
Change.Id changeId = new Change.Id(Integer.parseInt(event.change.number));
PatchSet.Id psId = new PatchSet.Id(changeId, Integer.parseInt(event.patchSet.number));
PatchSet ps = reviewDb.patchSets().get(psId);
if (ps == null) {
log.warn("Could not find patch set " + psId.get());
return;
}
// psId.getParentKey = changeID
final Change change = reviewDb.changes().get(psId.getParentKey());
if (change == null) {
log.warn("Could not find change " + psId.getParentKey());
return;
}

RevCommit commit = walk.parseCommit(ObjectId.fromString(event.patchSet.revision));

//TODO: Make the create method take only project name, change and patchset.
//TODO: (The rest should be moved into ReviewAssistant)
final Runnable task = reviewAssistantFactory.create(commit, change, ps, repo, projectName);
workQueue.getDefaultQueue().submit(new Runnable() {
@Override
public void run() {
RequestContext old = tl.setContext(new RequestContext() {

@Override
public CurrentUser getCurrentUser() {
if(!ReviewAssistant.realUser) {
return pluginUser;
} else {
return identifiedUserFactory.create(change.getOwner());
}
}

@Override
public Provider<ReviewDb> getReviewDbProvider() {
return new Provider<ReviewDb>() {
@Override
public ReviewDb get() {
if (db == null) {
try {
db = schemaFactory.open();
} catch (OrmException e) {
throw new ProvisionException("Cannot open ReviewDb", e);
}
}
return db;
}
};
}
});
try {
task.run();
} finally {
tl.setContext(old);
if (db != null) {
db.close();
db = null;
}
}
}
});
} catch (IncorrectObjectTypeException e) {
log.error(e.getMessage(), e);
} catch (MissingObjectException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
reviewDb.close();
}
} catch (OrmException e) {
log.error(e.getMessage(), e);
} finally {
walk.release();
repo.close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Module extends FactoryModule {
protected void configure() {
DynamicSet.bind(binder(), ChangeListener.class).to(ChangeEventListener.class);
bind(Storage.class).to(SimpleStorage.class);
// factory(GerritReviewAssistant.Factory.class);
factory(ReviewAssistant.Factory.class);

install(new RestApiModule() {
@Override
Expand Down
Loading

0 comments on commit 8b0df33

Please sign in to comment.