use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.
the class RepositoryManager method updateRepositoryModel.
/**
* Creates/updates the repository model keyed by repositoryName. Saves all
* repository settings in .git/config. This method allows for renaming
* repositories and will update user access permissions accordingly.
*
* All repositories created by this method are bare and automatically have
* .git appended to their names, which is the standard convention for bare
* repositories.
*
* @param repositoryName
* @param repository
* @param isCreate
* @throws GitBlitException
*/
@Override
public void updateRepositoryModel(String repositoryName, RepositoryModel repository, boolean isCreate) throws GitBlitException {
if (isCollectingGarbage(repositoryName)) {
throw new GitBlitException(MessageFormat.format("sorry, Gitblit is busy collecting garbage in {0}", repositoryName));
}
Repository r = null;
String projectPath = StringUtils.getFirstPathElement(repository.name);
if (!StringUtils.isEmpty(projectPath)) {
if (projectPath.equalsIgnoreCase(settings.getString(Keys.web.repositoryRootGroupName, "main"))) {
// strip leading group name
repository.name = repository.name.substring(projectPath.length() + 1);
}
}
boolean isRename = false;
if (isCreate) {
// ensure created repository name ends with .git
if (!repository.name.toLowerCase().endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT_EXT)) {
repository.name += org.eclipse.jgit.lib.Constants.DOT_GIT_EXT;
}
if (hasRepository(repository.name)) {
throw new GitBlitException(MessageFormat.format("Can not create repository ''{0}'' because it already exists.", repository.name));
}
// create repository
logger.info("create repository " + repository.name);
String shared = settings.getString(Keys.git.createRepositoriesShared, "FALSE");
r = JGitUtils.createRepository(repositoriesFolder, repository.name, shared);
} else {
// rename repository
isRename = !repositoryName.equalsIgnoreCase(repository.name);
if (isRename) {
if (!repository.name.toLowerCase().endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT_EXT)) {
repository.name += org.eclipse.jgit.lib.Constants.DOT_GIT_EXT;
}
if (new File(repositoriesFolder, repository.name).exists()) {
throw new GitBlitException(MessageFormat.format("Failed to rename ''{0}'' because ''{1}'' already exists.", repositoryName, repository.name));
}
close(repositoryName);
File folder = new File(repositoriesFolder, repositoryName);
File destFolder = new File(repositoriesFolder, repository.name);
if (destFolder.exists()) {
throw new GitBlitException(MessageFormat.format("Can not rename repository ''{0}'' to ''{1}'' because ''{1}'' already exists.", repositoryName, repository.name));
}
File parentFile = destFolder.getParentFile();
if (!parentFile.exists() && !parentFile.mkdirs()) {
throw new GitBlitException(MessageFormat.format("Failed to create folder ''{0}''", parentFile.getAbsolutePath()));
}
if (!folder.renameTo(destFolder)) {
throw new GitBlitException(MessageFormat.format("Failed to rename repository ''{0}'' to ''{1}''.", repositoryName, repository.name));
}
// rename the roles
if (!userManager.renameRepositoryRole(repositoryName, repository.name)) {
throw new GitBlitException(MessageFormat.format("Failed to rename repository permissions ''{0}'' to ''{1}''.", repositoryName, repository.name));
}
// rename fork origins in their configs
if (!ArrayUtils.isEmpty(repository.forks)) {
for (String fork : repository.forks) {
Repository rf = getRepository(fork);
try {
StoredConfig config = rf.getConfig();
String origin = config.getString("remote", "origin", "url");
origin = origin.replace(repositoryName, repository.name);
config.setString("remote", "origin", "url", origin);
config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.name);
config.save();
} catch (Exception e) {
logger.error("Failed to update repository fork config for " + fork, e);
}
rf.close();
}
}
// update this repository's origin's fork list
if (!StringUtils.isEmpty(repository.originRepository)) {
String originKey = getRepositoryKey(repository.originRepository);
RepositoryModel origin = repositoryListCache.get(originKey);
if (origin != null && !ArrayUtils.isEmpty(origin.forks)) {
origin.forks.remove(repositoryName);
origin.forks.add(repository.name);
}
}
// clear the cache
clearRepositoryMetadataCache(repositoryName);
repository.resetDisplayName();
}
// load repository
logger.info("edit repository " + repository.name);
r = getRepository(repository.name);
}
// update settings
if (r != null) {
updateConfiguration(r, repository);
// Update the description file
File descFile = new File(r.getDirectory(), "description");
if (repository.description != null) {
com.gitblit.utils.FileUtils.writeContent(descFile, repository.description);
} else if (descFile.exists() && !descFile.isDirectory()) {
descFile.delete();
}
// only update symbolic head if it changes
String currentRef = JGitUtils.getHEADRef(r);
if (!StringUtils.isEmpty(repository.HEAD) && !repository.HEAD.equals(currentRef)) {
logger.info(MessageFormat.format("Relinking {0} HEAD from {1} to {2}", repository.name, currentRef, repository.HEAD));
if (JGitUtils.setHEADtoRef(r, repository.HEAD)) {
// clear the cache
clearRepositoryMetadataCache(repository.name);
}
}
// Adjust permissions in case we updated the config files
JGitUtils.adjustSharedPerm(new File(r.getDirectory().getAbsolutePath(), "config"), settings.getString(Keys.git.createRepositoriesShared, "FALSE"));
JGitUtils.adjustSharedPerm(new File(r.getDirectory().getAbsolutePath(), "HEAD"), settings.getString(Keys.git.createRepositoriesShared, "FALSE"));
// close the repository object
r.close();
}
// update repository cache
removeFromCachedRepositoryList(repositoryName);
// model will actually be replaced on next load because config is stale
addToCachedRepositoryList(repository);
if (isCreate && pluginManager != null) {
for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
try {
listener.onCreation(repository);
} catch (Throwable t) {
logger.error(String.format("failed to call plugin onCreation %s", repositoryName), t);
}
}
} else if (isRename && pluginManager != null) {
for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
try {
listener.onRename(repositoryName, repository);
} catch (Throwable t) {
logger.error(String.format("failed to call plugin onRename %s", repositoryName), t);
}
}
}
}
use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.
the class RepositoryManager method deleteRepository.
/**
* Deletes the repository from the file system and removes the repository
* permission from all repository users.
*
* @param repositoryName
* @return true if successful
*/
@Override
public boolean deleteRepository(String repositoryName) {
RepositoryModel repository = getRepositoryModel(repositoryName);
if (!canDelete(repository)) {
logger.warn("Attempt to delete {} rejected!", repositoryName);
return false;
}
try {
close(repositoryName);
// clear the repository cache
clearRepositoryMetadataCache(repositoryName);
RepositoryModel model = removeFromCachedRepositoryList(repositoryName);
if (model != null && !ArrayUtils.isEmpty(model.forks)) {
resetRepositoryListCache();
}
File folder = new File(repositoriesFolder, repositoryName);
if (folder.exists() && folder.isDirectory()) {
FileUtils.delete(folder, FileUtils.RECURSIVE | FileUtils.RETRY);
if (userManager.deleteRepositoryRole(repositoryName)) {
logger.info(MessageFormat.format("Repository \"{0}\" deleted", repositoryName));
if (pluginManager != null) {
for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
try {
listener.onDeletion(repository);
} catch (Throwable t) {
logger.error(String.format("failed to call plugin onDeletion %s", repositoryName), t);
}
}
}
return true;
}
}
} catch (Throwable t) {
logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t);
}
return false;
}
use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.
the class GitblitManager method fork.
/*
* IGITBLIT
*/
/**
* Creates a personal fork of the specified repository. The clone is view
* restricted by default and the owner of the source repository is given
* access to the clone.
*
* @param repository
* @param user
* @return the repository model of the fork, if successful
* @throws GitBlitException
*/
@Override
public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name);
// clone the repository
try {
Repository canonical = getRepository(repository.name);
File folder = new File(repositoryManager.getRepositoriesFolder(), cloneName);
CloneCommand clone = new CloneCommand();
clone.setBare(true);
// fetch branches with exclusions
Collection<Ref> branches = canonical.getRefDatabase().getRefs(Constants.R_HEADS).values();
List<String> branchesToClone = new ArrayList<String>();
for (Ref branch : branches) {
String name = branch.getName();
if (name.startsWith(Constants.R_TICKET)) {
// exclude ticket branches
continue;
}
branchesToClone.add(name);
}
clone.setBranchesToClone(branchesToClone);
clone.setURI(fromUrl);
clone.setDirectory(folder);
Git git = clone.call();
// fetch tags
FetchCommand fetch = git.fetch();
fetch.setRefSpecs(new RefSpec("+refs/tags/*:refs/tags/*"));
fetch.call();
git.getRepository().close();
} catch (Exception e) {
throw new GitBlitException(e);
}
// create a Gitblit repository model for the clone
RepositoryModel cloneModel = repository.cloneAs(cloneName);
// owner has REWIND/RW+ permissions
cloneModel.addOwner(user.username);
// is not lower than the source repository (issue-495/ticket-167)
if (repository.accessRestriction.exceeds(cloneModel.accessRestriction)) {
cloneModel.accessRestriction = repository.accessRestriction;
}
repositoryManager.updateRepositoryModel(cloneName, cloneModel, false);
// add the owner of the source repository to the clone's access list
if (!ArrayUtils.isEmpty(repository.owners)) {
for (String owner : repository.owners) {
UserModel originOwner = userManager.getUserModel(owner);
if (originOwner != null && !originOwner.canClone(cloneModel)) {
// origin owner can't yet clone fork, grant explicit clone access
originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
reviseUser(originOwner.username, originOwner);
}
}
}
// grant origin's user list clone permission to fork
List<String> users = repositoryManager.getRepositoryUsers(repository);
List<UserModel> cloneUsers = new ArrayList<UserModel>();
for (String name : users) {
if (!name.equalsIgnoreCase(user.username)) {
UserModel cloneUser = userManager.getUserModel(name);
if (cloneUser.canClone(repository) && !cloneUser.canClone(cloneModel)) {
// origin user can't yet clone fork, grant explicit clone access
cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE);
}
cloneUsers.add(cloneUser);
}
}
userManager.updateUserModels(cloneUsers);
// grant origin's team list clone permission to fork
List<String> teams = repositoryManager.getRepositoryTeams(repository);
List<TeamModel> cloneTeams = new ArrayList<TeamModel>();
for (String name : teams) {
TeamModel cloneTeam = userManager.getTeamModel(name);
if (cloneTeam.canClone(repository) && !cloneTeam.canClone(cloneModel)) {
// origin team can't yet clone fork, grant explicit clone access
cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE);
}
cloneTeams.add(cloneTeam);
}
userManager.updateTeamModels(cloneTeams);
// add this clone to the cached model
repositoryManager.addToCachedRepositoryList(cloneModel);
if (pluginManager != null) {
for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
try {
listener.onFork(repository, cloneModel);
} catch (Throwable t) {
logger.error(String.format("failed to call plugin onFork %s", repository.name), t);
}
}
}
return cloneModel;
}
Aggregations