Download commands: Add JGit archive
Since JGit 3.1 archive command was implemented. Add it to download drop down as new line. The following libraries are introduced in this change: * jgit-archive (Apache 2) * commons-compress (Apache 2) * tukaani-xz (Public domain) Change-Id: I5f61aac8c434414c73585a9320e84f4430dd111d
This commit is contained in:
parent
b6af30e13c
commit
fbf6b7dabd
|
@ -40,9 +40,13 @@ import com.google.gwt.user.client.ui.VerticalPanel;
|
|||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
class DownloadBox extends VerticalPanel {
|
||||
private final static String ARCHIVE[] = {"tar", "tbz2", "tgz", "txz"};
|
||||
private final ChangeInfo change;
|
||||
private final String revision;
|
||||
private final PatchSet.Id psId;
|
||||
|
@ -109,6 +113,7 @@ class DownloadBox extends VerticalPanel {
|
|||
}
|
||||
}
|
||||
insertPatch();
|
||||
insertArchive();
|
||||
insertCommand(null, scheme);
|
||||
}
|
||||
|
||||
|
@ -141,6 +146,34 @@ class DownloadBox extends VerticalPanel {
|
|||
insertCommand("Patch-File", p);
|
||||
}
|
||||
|
||||
private void insertArchive() {
|
||||
List<Anchor> formats = new ArrayList<>(ARCHIVE.length);
|
||||
for (String f : ARCHIVE) {
|
||||
Anchor archive = new Anchor(f);
|
||||
archive.setHref(new RestApi("/changes/")
|
||||
.id(psId.getParentKey().get())
|
||||
.view("revisions")
|
||||
.id(revision)
|
||||
.view("archive")
|
||||
.addParameter("format", f)
|
||||
.url());
|
||||
formats.add(archive);
|
||||
}
|
||||
|
||||
HorizontalPanel p = new HorizontalPanel();
|
||||
Iterator<Anchor> it = formats.iterator();
|
||||
while (it.hasNext()) {
|
||||
Anchor a = it.next();
|
||||
p.add(a);
|
||||
if (it.hasNext()) {
|
||||
InlineLabel spacer = new InlineLabel("|");
|
||||
spacer.setStyleName(Gerrit.RESOURCES.css().downloadBoxSpacer());
|
||||
p.add(spacer);
|
||||
}
|
||||
}
|
||||
insertCommand("Archive", p);
|
||||
}
|
||||
|
||||
private void insertCommand(String commandName, Widget w) {
|
||||
int row = commandTable.getRowCount();
|
||||
commandTable.insertRow(row);
|
||||
|
|
|
@ -57,6 +57,7 @@ java_library2(
|
|||
'//lib/guice:guice-assistedinject',
|
||||
'//lib/guice:guice-servlet',
|
||||
'//lib/jgit:jgit',
|
||||
'//lib/jgit:jgit-archive',
|
||||
'//lib/joda:joda-time',
|
||||
'//lib/log:api',
|
||||
'//lib/prolog:prolog-cafe',
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.change;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.eclipse.jgit.api.ArchiveCommand;
|
||||
import org.eclipse.jgit.archive.TarFormat;
|
||||
import org.eclipse.jgit.archive.Tbz2Format;
|
||||
import org.eclipse.jgit.archive.TgzFormat;
|
||||
import org.eclipse.jgit.archive.TxzFormat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
enum ArchiveFormat {
|
||||
TGZ("application/x-gzip", new TgzFormat()),
|
||||
TAR("application/x-tar", new TarFormat()),
|
||||
TBZ2("application/x-bzip2", new Tbz2Format()),
|
||||
TXZ("application/x-xz", new TxzFormat());
|
||||
// Zip is not supported because it may be interpreted by a Java plugin as a
|
||||
// valid JAR file, whose code would have access to cookies on the domain.
|
||||
|
||||
static final Logger log = LoggerFactory.getLogger(ArchiveFormat.class);
|
||||
|
||||
private final ArchiveCommand.Format<?> format;
|
||||
private final String mimeType;
|
||||
|
||||
private ArchiveFormat(String mimeType, ArchiveCommand.Format<?> format) {
|
||||
this.format = format;
|
||||
this.mimeType = mimeType;
|
||||
ArchiveCommand.registerFormat(name(), format);
|
||||
}
|
||||
|
||||
String getShortName() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
String getDefaultSuffix() {
|
||||
return getSuffixes().iterator().next();
|
||||
}
|
||||
|
||||
Iterable<String> getSuffixes() {
|
||||
return format.suffixes();
|
||||
}
|
||||
|
||||
static Map<String, ArchiveFormat> init() {
|
||||
String[] formats = new String[values().length];
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
formats[i] = values()[i].name();
|
||||
}
|
||||
|
||||
Map<String, ArchiveFormat> exts = Maps.newLinkedHashMap();
|
||||
for (String name : formats) {
|
||||
try {
|
||||
ArchiveFormat format = valueOf(name.toUpperCase());
|
||||
for (String ext : format.getSuffixes()) {
|
||||
exts.put(ext, format);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid archive.format {}", name);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(exts);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright (C) 2014 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.change;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.BinaryResult;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.jgit.api.ArchiveCommand;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
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.kohsuke.args4j.Option;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
class GetArchive implements RestReadView<RevisionResource> {
|
||||
private static final Map<String, ArchiveFormat> formats = ArchiveFormat.init();
|
||||
private final GitRepositoryManager repoManager;
|
||||
|
||||
@Option(name = "--format")
|
||||
private String format;
|
||||
|
||||
@Inject
|
||||
GetArchive(GitRepositoryManager repoManager) {
|
||||
this.repoManager = repoManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResult apply(RevisionResource rsrc)
|
||||
throws BadRequestException, IOException {
|
||||
if (Strings.isNullOrEmpty(format)) {
|
||||
throw new BadRequestException("format is not specified");
|
||||
}
|
||||
final ArchiveFormat f = formats.get("." + format);
|
||||
if (f == null) {
|
||||
throw new BadRequestException("unknown archive format");
|
||||
}
|
||||
boolean close = true;
|
||||
final Repository repo = repoManager
|
||||
.openRepository(rsrc.getControl().getProject().getNameKey());
|
||||
try {
|
||||
final RevWalk rw = new RevWalk(repo);
|
||||
try {
|
||||
final RevCommit commit =
|
||||
rw.parseCommit(ObjectId.fromString(rsrc.getPatchSet()
|
||||
.getRevision().get()));
|
||||
BinaryResult bin = new BinaryResult() {
|
||||
@Override
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
try {
|
||||
new ArchiveCommand(repo)
|
||||
.setFormat(f.name())
|
||||
.setTree(commit.getTree())
|
||||
.setOutputStream(out).call();
|
||||
} catch (GitAPIException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
rw.release();
|
||||
repo.close();
|
||||
}
|
||||
};
|
||||
|
||||
bin.disableGzip()
|
||||
.setContentType(f.getMimeType())
|
||||
.setAttachmentName(name(f, rw, commit));
|
||||
|
||||
close = false;
|
||||
return bin;
|
||||
} finally {
|
||||
if (close) {
|
||||
rw.release();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (close) {
|
||||
repo.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String name(ArchiveFormat format, RevWalk rw, RevCommit commit)
|
||||
throws IOException {
|
||||
return String.format("%s%s",
|
||||
rw.getObjectReader().abbreviate(commit,7).name(),
|
||||
format.getDefaultSuffix());
|
||||
}
|
||||
}
|
|
@ -82,6 +82,7 @@ public class Module extends RestApiModule {
|
|||
get(REVISION_KIND, "submit_type").to(TestSubmitType.Get.class);
|
||||
post(REVISION_KIND, "test.submit_rule").to(TestSubmitRule.class);
|
||||
post(REVISION_KIND, "test.submit_type").to(TestSubmitType.class);
|
||||
get(REVISION_KIND, "archive").to(GetArchive.class);
|
||||
|
||||
child(REVISION_KIND, "drafts").to(Drafts.class);
|
||||
put(REVISION_KIND, "drafts").to(CreateDraft.class);
|
||||
|
|
10
lib/BUCK
10
lib/BUCK
|
@ -20,6 +20,7 @@ define_license(name = 'postgresql')
|
|||
define_license(name = 'prologcafe')
|
||||
define_license(name = 'protobuf')
|
||||
define_license(name = 'slf4j')
|
||||
define_license(name = 'xz')
|
||||
define_license(name = 'DO_NOT_DISTRIBUTE')
|
||||
|
||||
maven_jar(
|
||||
|
@ -248,3 +249,12 @@ maven_jar(
|
|||
visibility = ['//lib:easymock'],
|
||||
attach_source = False,
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = 'tukaani-xz',
|
||||
id = 'org.tukaani:xz:1.4',
|
||||
sha1 = '18a9a2ce6abf32ea1b5fd31dae5210ad93f4e5e3',
|
||||
license = 'xz',
|
||||
attach_source = False,
|
||||
visibility = ['//lib/jgit:jgit-archive'],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
All the files in this package have been written by Lasse Collin
|
||||
and/or Igor Pavlov. All these files have been put into the
|
||||
public domain. You can do whatever you want with these files.
|
||||
This software is provided "as is", without any warranty.
|
|
@ -21,6 +21,15 @@ maven_jar(
|
|||
],
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = 'compress',
|
||||
id = 'org.apache.commons:commons-compress:1.7',
|
||||
sha1 = 'ab365c96ee9bc88adcc6fa40d185c8e15a31410d',
|
||||
license = 'Apache2.0',
|
||||
exclude = ['META-INF/LICENSE.txt', 'META-INF/NOTICE.txt'],
|
||||
visibility = ['//lib/jgit:jgit-archive'],
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = 'dbcp',
|
||||
id = 'commons-dbcp:commons-dbcp:1.4',
|
||||
|
|
|
@ -33,6 +33,23 @@ maven_jar(
|
|||
],
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = 'jgit-archive',
|
||||
id = 'org.eclipse.jgit:org.eclipse.jgit.archive:' + VERS,
|
||||
sha1 = 'c645b284344ec9791404f6fd0e04f6dbedb58b7d',
|
||||
license = 'jgit',
|
||||
repository = REPO,
|
||||
deps = [':jgit',
|
||||
'//lib/commons:compress',
|
||||
'//lib:tukaani-xz',
|
||||
],
|
||||
unsign = True,
|
||||
exclude = [
|
||||
'about.html',
|
||||
'plugin.properties',
|
||||
],
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = 'junit',
|
||||
id = 'org.eclipse.jgit:org.eclipse.jgit.junit:' + VERS,
|
||||
|
|
Loading…
Reference in New Issue