Merge "Allow use server.go for testing against local site"
This commit is contained in:
@@ -338,7 +338,7 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi
|
|||||||
new AbstractModule() {
|
new AbstractModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(GerritOptions.class).toInstance(new GerritOptions(false, false, false));
|
bind(GerritOptions.class).toInstance(new GerritOptions(false, false, ""));
|
||||||
bind(GerritRuntime.class).toInstance(GerritRuntime.DAEMON);
|
bind(GerritRuntime.class).toInstance(GerritRuntime.DAEMON);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1,160 +0,0 @@
|
|||||||
// Copyright (C) 2016 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.httpd.raw;
|
|
||||||
|
|
||||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.escape.Escaper;
|
|
||||||
import com.google.common.flogger.FluentLogger;
|
|
||||||
import com.google.common.html.HtmlEscapers;
|
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.gerrit.launcher.GerritLauncher;
|
|
||||||
import com.google.gerrit.server.util.time.TimeUtil;
|
|
||||||
import com.google.gerrit.util.http.CacheHeaders;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.eclipse.jgit.util.RawParseUtils;
|
|
||||||
|
|
||||||
public class BazelBuild {
|
|
||||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
|
||||||
|
|
||||||
private final Path sourceRoot;
|
|
||||||
|
|
||||||
public BazelBuild(Path sourceRoot) {
|
|
||||||
this.sourceRoot = sourceRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
// builds the given label.
|
|
||||||
public void build(Label label) throws IOException, BuildFailureException {
|
|
||||||
ProcessBuilder proc = newBuildProcess(label);
|
|
||||||
proc.directory(sourceRoot.toFile()).redirectErrorStream(true);
|
|
||||||
logger.atInfo().log("building %s", label.fullName());
|
|
||||||
long start = TimeUtil.nowMs();
|
|
||||||
Process rebuild = proc.start();
|
|
||||||
byte[] out;
|
|
||||||
try (InputStream in = rebuild.getInputStream()) {
|
|
||||||
out = ByteStreams.toByteArray(in);
|
|
||||||
} finally {
|
|
||||||
rebuild.getOutputStream().close();
|
|
||||||
}
|
|
||||||
|
|
||||||
int status;
|
|
||||||
try {
|
|
||||||
status = rebuild.waitFor();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
String msg = "interrupted waiting for: " + Joiner.on(' ').join(proc.command());
|
|
||||||
logger.atSevere().withCause(e).log(msg);
|
|
||||||
throw new InterruptedIOException(msg);
|
|
||||||
}
|
|
||||||
if (status != 0) {
|
|
||||||
logger.atWarning().log("build failed: %s", new String(out, UTF_8));
|
|
||||||
throw new BuildFailureException(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
long time = TimeUtil.nowMs() - start;
|
|
||||||
logger.atInfo().log("UPDATED %s in %.3fs", label.fullName(), time / 1000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Represents a label in bazel.
|
|
||||||
static class Label {
|
|
||||||
protected final String pkg;
|
|
||||||
protected final String name;
|
|
||||||
|
|
||||||
public String fullName() {
|
|
||||||
return "//" + pkg + ":" + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return fullName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label in Bazel style.
|
|
||||||
Label(String pkg, String name) {
|
|
||||||
this.name = name;
|
|
||||||
this.pkg = pkg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class BuildFailureException extends Exception {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
final byte[] why;
|
|
||||||
|
|
||||||
BuildFailureException(byte[] why) {
|
|
||||||
this.why = why;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void display(String rule, HttpServletResponse res) throws IOException {
|
|
||||||
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
|
||||||
res.setContentType("text/html");
|
|
||||||
res.setCharacterEncoding(UTF_8.name());
|
|
||||||
CacheHeaders.setNotCacheable(res);
|
|
||||||
|
|
||||||
Escaper html = HtmlEscapers.htmlEscaper();
|
|
||||||
try (PrintWriter w = res.getWriter()) {
|
|
||||||
w.write("<html><title>BUILD FAILED</title><body>");
|
|
||||||
w.format("<h1>%s FAILED</h1>", html.escape(rule));
|
|
||||||
w.write("<pre>");
|
|
||||||
w.write(html.escape(RawParseUtils.decode(why)));
|
|
||||||
w.write("</pre>");
|
|
||||||
w.write("</body></html>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessBuilder newBuildProcess(Label label) throws IOException {
|
|
||||||
Properties properties = GerritLauncher.loadBuildProperties(sourceRoot.resolve(".bazel_path"));
|
|
||||||
String bazel = firstNonNull(properties.getProperty("bazel"), "bazel");
|
|
||||||
List<String> cmd = new ArrayList<>();
|
|
||||||
cmd.add(bazel);
|
|
||||||
cmd.add("build");
|
|
||||||
if (GerritLauncher.isJdk9OrLater()) {
|
|
||||||
String v = GerritLauncher.getJdkVersionPostJdk8();
|
|
||||||
cmd.add("--host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java" + v);
|
|
||||||
cmd.add("--java_toolchain=@bazel_tools//tools/jdk:toolchain_java" + v);
|
|
||||||
}
|
|
||||||
cmd.add(label.fullName());
|
|
||||||
ProcessBuilder proc = new ProcessBuilder(cmd);
|
|
||||||
if (properties.containsKey("PATH")) {
|
|
||||||
proc.environment().put("PATH", properties.getProperty("PATH"));
|
|
||||||
}
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns the root relative path to the artifact for the given label */
|
|
||||||
public Path targetPath(Label l) {
|
|
||||||
return sourceRoot.resolve("bazel-bin").resolve(l.pkg).resolve(l.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Label for the polygerrit component zip. */
|
|
||||||
public Label polygerritComponents() {
|
|
||||||
return new Label("polygerrit-ui", "polygerrit_components.bower_components.zip");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Label for the fonts zip file. */
|
|
||||||
public Label fontZipLabel() {
|
|
||||||
return new Label("polygerrit-ui", "fonts.zip");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,49 +0,0 @@
|
|||||||
// Copyright (C) 2015 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.httpd.raw;
|
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.gerrit.launcher.GerritLauncher;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/* Bower component servlet only used in development mode */
|
|
||||||
class BowerComponentsDevServlet extends ResourceServlet {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Path bowerComponents;
|
|
||||||
private final Path zip;
|
|
||||||
|
|
||||||
BowerComponentsDevServlet(Cache<Path, Resource> cache, BazelBuild builder) throws IOException {
|
|
||||||
super(cache, true);
|
|
||||||
|
|
||||||
Objects.requireNonNull(builder);
|
|
||||||
BazelBuild.Label label = builder.polygerritComponents();
|
|
||||||
try {
|
|
||||||
builder.build(label);
|
|
||||||
} catch (BazelBuild.BuildFailureException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
zip = builder.targetPath(label);
|
|
||||||
bowerComponents = GerritLauncher.newZipFileSystem(zip).getPath("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Path getResourcePath(String pathInfo) throws IOException {
|
|
||||||
return bowerComponents.resolve(pathInfo);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (C) 2016 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.httpd.raw;
|
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.gerrit.launcher.GerritLauncher;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/* Font servlet only used in development mode */
|
|
||||||
class FontsDevServlet extends ResourceServlet {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Path fonts;
|
|
||||||
|
|
||||||
FontsDevServlet(Cache<Path, Resource> cache, BazelBuild builder) throws IOException {
|
|
||||||
super(cache, true);
|
|
||||||
Objects.requireNonNull(builder);
|
|
||||||
|
|
||||||
BazelBuild.Label zipLabel = builder.fontZipLabel();
|
|
||||||
try {
|
|
||||||
builder.build(zipLabel);
|
|
||||||
} catch (BazelBuild.BuildFailureException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Path zip = builder.targetPath(zipLabel);
|
|
||||||
Objects.requireNonNull(zip);
|
|
||||||
|
|
||||||
fonts = GerritLauncher.newZipFileSystem(zip).getPath("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Path getResourcePath(String pathInfo) throws IOException {
|
|
||||||
return fonts.resolve(pathInfo);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
package com.google.gerrit.httpd.raw;
|
package com.google.gerrit.httpd.raw;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static java.nio.file.Files.exists;
|
import static java.nio.file.Files.exists;
|
||||||
import static java.nio.file.Files.isReadable;
|
import static java.nio.file.Files.isReadable;
|
||||||
|
|
||||||
@@ -222,7 +221,8 @@ public class StaticModule extends ServletModule {
|
|||||||
@CanonicalWebUrl @Nullable String canonicalUrl,
|
@CanonicalWebUrl @Nullable String canonicalUrl,
|
||||||
@GerritServerConfig Config cfg,
|
@GerritServerConfig Config cfg,
|
||||||
GerritApi gerritApi) {
|
GerritApi gerritApi) {
|
||||||
String cdnPath = cfg.getString("gerrit", null, "cdnPath");
|
String cdnPath =
|
||||||
|
options.useDevCdn() ? options.devCdn() : cfg.getString("gerrit", null, "cdnPath");
|
||||||
String faviconPath = cfg.getString("gerrit", null, "faviconPath");
|
String faviconPath = cfg.getString("gerrit", null, "faviconPath");
|
||||||
return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi);
|
return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi);
|
||||||
}
|
}
|
||||||
@@ -233,29 +233,8 @@ public class StaticModule extends ServletModule {
|
|||||||
return new PolyGerritUiServlet(cache, polyGerritBasePath());
|
return new PolyGerritUiServlet(cache, polyGerritBasePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
BowerComponentsDevServlet getBowerComponentsServlet(@Named(CACHE) Cache<Path, Resource> cache)
|
|
||||||
throws IOException {
|
|
||||||
return getPaths().isDev() ? new BowerComponentsDevServlet(cache, getPaths().builder) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
FontsDevServlet getFontsServlet(@Named(CACHE) Cache<Path, Resource> cache) throws IOException {
|
|
||||||
return getPaths().isDev() ? new FontsDevServlet(cache, getPaths().builder) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path polyGerritBasePath() {
|
private Path polyGerritBasePath() {
|
||||||
Paths p = getPaths();
|
Paths p = getPaths();
|
||||||
if (options.forcePolyGerritDev()) {
|
|
||||||
checkArgument(
|
|
||||||
p.sourceRoot != null, "no source root directory found for PolyGerrit developer mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.isDev()) {
|
|
||||||
return p.sourceRoot.resolve("polygerrit-ui").resolve("app");
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.warFs != null
|
return p.warFs != null
|
||||||
? p.warFs.getPath("/polygerrit_ui")
|
? p.warFs.getPath("/polygerrit_ui")
|
||||||
@@ -265,7 +244,6 @@ public class StaticModule extends ServletModule {
|
|||||||
|
|
||||||
private static class Paths {
|
private static class Paths {
|
||||||
private final FileSystem warFs;
|
private final FileSystem warFs;
|
||||||
private final BazelBuild builder;
|
|
||||||
private final Path sourceRoot;
|
private final Path sourceRoot;
|
||||||
private final Path unpackedWar;
|
private final Path unpackedWar;
|
||||||
private final boolean development;
|
private final boolean development;
|
||||||
@@ -285,21 +263,19 @@ public class StaticModule extends ServletModule {
|
|||||||
launcherLoadedFrom.getParentFile().getParentFile().getParentFile().toURI());
|
launcherLoadedFrom.getParentFile().getParentFile().getParentFile().toURI());
|
||||||
sourceRoot = null;
|
sourceRoot = null;
|
||||||
development = false;
|
development = false;
|
||||||
builder = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
warFs = getDistributionArchive(launcherLoadedFrom);
|
warFs = getDistributionArchive(launcherLoadedFrom);
|
||||||
if (warFs == null) {
|
if (warFs == null) {
|
||||||
unpackedWar = makeWarTempDir();
|
unpackedWar = makeWarTempDir();
|
||||||
development = true;
|
development = true;
|
||||||
} else if (options.forcePolyGerritDev()) {
|
} else if (options.useDevCdn()) {
|
||||||
unpackedWar = null;
|
unpackedWar = null;
|
||||||
development = true;
|
development = true;
|
||||||
} else {
|
} else {
|
||||||
unpackedWar = null;
|
unpackedWar = null;
|
||||||
development = false;
|
development = false;
|
||||||
sourceRoot = null;
|
sourceRoot = null;
|
||||||
builder = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -307,7 +283,6 @@ public class StaticModule extends ServletModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sourceRoot = getSourceRootOrNull();
|
sourceRoot = getSourceRootOrNull();
|
||||||
builder = new BazelBuild(sourceRoot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Path getSourceRootOrNull() {
|
private static Path getSourceRootOrNull() {
|
||||||
@@ -376,21 +351,15 @@ public class StaticModule extends ServletModule {
|
|||||||
private final Paths paths;
|
private final Paths paths;
|
||||||
private final HttpServlet polyGerritIndex;
|
private final HttpServlet polyGerritIndex;
|
||||||
private final PolyGerritUiServlet polygerritUI;
|
private final PolyGerritUiServlet polygerritUI;
|
||||||
private final BowerComponentsDevServlet bowerComponentServlet;
|
|
||||||
private final FontsDevServlet fontServlet;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PolyGerritFilter(
|
PolyGerritFilter(
|
||||||
Paths paths,
|
Paths paths,
|
||||||
@Named(POLYGERRIT_INDEX_SERVLET) HttpServlet polyGerritIndex,
|
@Named(POLYGERRIT_INDEX_SERVLET) HttpServlet polyGerritIndex,
|
||||||
PolyGerritUiServlet polygerritUI,
|
PolyGerritUiServlet polygerritUI) {
|
||||||
@Nullable BowerComponentsDevServlet bowerComponentServlet,
|
|
||||||
@Nullable FontsDevServlet fontServlet) {
|
|
||||||
this.paths = paths;
|
this.paths = paths;
|
||||||
this.polyGerritIndex = polyGerritIndex;
|
this.polyGerritIndex = polyGerritIndex;
|
||||||
this.polygerritUI = polygerritUI;
|
this.polygerritUI = polygerritUI;
|
||||||
this.bowerComponentServlet = bowerComponentServlet;
|
|
||||||
this.fontServlet = fontServlet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -408,22 +377,6 @@ public class StaticModule extends ServletModule {
|
|||||||
GuiceFilterRequestWrapper reqWrapper = new GuiceFilterRequestWrapper(req);
|
GuiceFilterRequestWrapper reqWrapper = new GuiceFilterRequestWrapper(req);
|
||||||
String path = pathInfo(req);
|
String path = pathInfo(req);
|
||||||
|
|
||||||
// Special case assets during development that are built by Bazel and not
|
|
||||||
// served out of the source tree.
|
|
||||||
//
|
|
||||||
// In the war case, these are either inlined, or live under
|
|
||||||
// /polygerrit_ui in the war file, so we can just treat them as normal
|
|
||||||
// assets.
|
|
||||||
if (paths.isDev()) {
|
|
||||||
if (path.startsWith("/bower_components/")) {
|
|
||||||
bowerComponentServlet.service(reqWrapper, res);
|
|
||||||
return;
|
|
||||||
} else if (path.startsWith("/fonts/")) {
|
|
||||||
fontServlet.service(reqWrapper, res);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPolyGerritIndex(path)) {
|
if (isPolyGerritIndex(path)) {
|
||||||
polyGerritIndex.service(reqWrapper, res);
|
polyGerritIndex.service(reqWrapper, res);
|
||||||
return;
|
return;
|
||||||
|
@@ -168,8 +168,18 @@ public class Daemon extends SiteProgram {
|
|||||||
@Option(name = "--headless", usage = "Don't start the UI frontend")
|
@Option(name = "--headless", usage = "Don't start the UI frontend")
|
||||||
private boolean headless;
|
private boolean headless;
|
||||||
|
|
||||||
@Option(name = "--polygerrit-dev", usage = "Force PolyGerrit UI for development")
|
private String devCdn = "";
|
||||||
private boolean polyGerritDev;
|
|
||||||
|
@Option(name = "--dev-cdn", usage = "Use specified cdn for serving static content.")
|
||||||
|
private void setDevCdn(String cdn) {
|
||||||
|
if (cdn == null) {
|
||||||
|
cdn = "";
|
||||||
|
}
|
||||||
|
if (cdn.endsWith("/")) {
|
||||||
|
cdn = cdn.substring(0, cdn.length() - 1);
|
||||||
|
}
|
||||||
|
devCdn = cdn;
|
||||||
|
}
|
||||||
|
|
||||||
@Option(
|
@Option(
|
||||||
name = "--init",
|
name = "--init",
|
||||||
@@ -463,8 +473,7 @@ public class Daemon extends SiteProgram {
|
|||||||
new AbstractModule() {
|
new AbstractModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(GerritOptions.class)
|
bind(GerritOptions.class).toInstance(new GerritOptions(headless, replica, devCdn));
|
||||||
.toInstance(new GerritOptions(headless, replica, polyGerritDev));
|
|
||||||
if (inMemoryTest) {
|
if (inMemoryTest) {
|
||||||
bind(String.class)
|
bind(String.class)
|
||||||
.annotatedWith(SecureStoreClassName.class)
|
.annotatedWith(SecureStoreClassName.class)
|
||||||
|
@@ -17,12 +17,12 @@ package com.google.gerrit.server.config;
|
|||||||
public class GerritOptions {
|
public class GerritOptions {
|
||||||
private final boolean headless;
|
private final boolean headless;
|
||||||
private final boolean slave;
|
private final boolean slave;
|
||||||
private final boolean forcePolyGerritDev;
|
private final String devCdn;
|
||||||
|
|
||||||
public GerritOptions(boolean headless, boolean slave, boolean forcePolyGerritDev) {
|
public GerritOptions(boolean headless, boolean slave, String devCdn) {
|
||||||
this.headless = headless;
|
this.headless = headless;
|
||||||
this.slave = slave;
|
this.slave = slave;
|
||||||
this.forcePolyGerritDev = forcePolyGerritDev;
|
this.devCdn = devCdn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean headless() {
|
public boolean headless() {
|
||||||
@@ -33,7 +33,11 @@ public class GerritOptions {
|
|||||||
return !slave;
|
return !slave;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forcePolyGerritDev() {
|
public String devCdn() {
|
||||||
return !headless && forcePolyGerritDev;
|
return devCdn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean useDevCdn() {
|
||||||
|
return !headless && devCdn.length() > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -181,7 +181,7 @@ public class InMemoryModule extends FactoryModule {
|
|||||||
// support Path-based Configs, only FileBasedConfig.
|
// support Path-based Configs, only FileBasedConfig.
|
||||||
bind(Path.class).annotatedWith(SitePath.class).toInstance(Paths.get("."));
|
bind(Path.class).annotatedWith(SitePath.class).toInstance(Paths.get("."));
|
||||||
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
|
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
|
||||||
bind(GerritOptions.class).toInstance(new GerritOptions(false, false, false));
|
bind(GerritOptions.class).toInstance(new GerritOptions(false, false, ""));
|
||||||
|
|
||||||
bind(GitRepositoryManager.class).to(InMemoryRepositoryManager.class);
|
bind(GitRepositoryManager.class).to(InMemoryRepositoryManager.class);
|
||||||
bind(InMemoryRepositoryManager.class).in(SINGLETON);
|
bind(InMemoryRepositoryManager.class).in(SINGLETON);
|
||||||
|
@@ -39,12 +39,11 @@ npm install
|
|||||||
It may complain about a missing `typescript@2.3.4` peer dependency, which is
|
It may complain about a missing `typescript@2.3.4` peer dependency, which is
|
||||||
harmless.
|
harmless.
|
||||||
|
|
||||||
## Running locally against production data
|
## Serving files locally
|
||||||
|
|
||||||
#### Go server
|
#### Go server
|
||||||
|
|
||||||
To test the local Polymer frontend against gerrit-review.googlesource.com
|
To test the local Polymer frontend against production data or a local test site execute:
|
||||||
simply execute:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./polygerrit-ui/run-server.sh
|
./polygerrit-ui/run-server.sh
|
||||||
@@ -53,10 +52,7 @@ simply execute:
|
|||||||
npm run start
|
npm run start
|
||||||
```
|
```
|
||||||
|
|
||||||
Then visit http://localhost:8081
|
These commands start the [simple hand-written Go webserver](https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/server.go).
|
||||||
|
|
||||||
This method is based on a
|
|
||||||
[simple hand-written Go webserver](https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/server.go).
|
|
||||||
Mostly it just switches between serving files locally and proxying the real
|
Mostly it just switches between serving files locally and proxying the real
|
||||||
server based on the file name. It also does some basic response rewriting, e.g.
|
server based on the file name. It also does some basic response rewriting, e.g.
|
||||||
it patches the `config/server/info` response with plugin information provided on
|
it patches the `config/server/info` response with plugin information provided on
|
||||||
@@ -66,6 +62,12 @@ the command line:
|
|||||||
./polygerrit-ui/run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
|
./polygerrit-ui/run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running locally against production data
|
||||||
|
|
||||||
|
### Local website
|
||||||
|
|
||||||
|
Start [Go server](#go-server) and then visit http://localhost:8081
|
||||||
|
|
||||||
The biggest draw back of this method is that you cannot log in, so cannot test
|
The biggest draw back of this method is that you cannot log in, so cannot test
|
||||||
scenarios that require it.
|
scenarios that require it.
|
||||||
|
|
||||||
@@ -89,9 +91,11 @@ Set up a local test site once:
|
|||||||
3. Optionally [populate](https://gerrit.googlesource.com/gerrit/+/master/contrib/populate-fixture-data.py) your test site with some test data.
|
3. Optionally [populate](https://gerrit.googlesource.com/gerrit/+/master/contrib/populate-fixture-data.py) your test site with some test data.
|
||||||
|
|
||||||
For running a locally built Gerrit war against your test instance use
|
For running a locally built Gerrit war against your test instance use
|
||||||
[this command](https://gerrit-review.googlesource.com/Documentation/dev-readme.html#run_daemon),
|
[this command](https://gerrit-review.googlesource.com/Documentation/dev-readme.html#run_daemon).
|
||||||
and add the `--polygerrit-dev` option, if you want to serve the Polymer frontend
|
|
||||||
directly from the sources in `polygerrit_ui/app/` instead of from the war:
|
If you want to serve the Polymer frontend directly from the sources in `polygerrit_ui/app/` instead of from the war:
|
||||||
|
1. Start [Go server](#go-server)
|
||||||
|
2. Add the `--dev-cdn` option:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$(bazel info output_base)/external/local_jdk/bin/java \
|
$(bazel info output_base)/external/local_jdk/bin/java \
|
||||||
@@ -99,9 +103,11 @@ $(bazel info output_base)/external/local_jdk/bin/java \
|
|||||||
-jar bazel-bin/gerrit.war daemon \
|
-jar bazel-bin/gerrit.war daemon \
|
||||||
-d $GERRIT_SITE \
|
-d $GERRIT_SITE \
|
||||||
--console-log \
|
--console-log \
|
||||||
--polygerrit-dev
|
--dev-cdn http://localhost:8081
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*NOTE* You can use any other cdn here, for example: https://cdn.googlesource.com/polygerrit_ui/678.0
|
||||||
|
|
||||||
## Running Tests
|
## Running Tests
|
||||||
|
|
||||||
This step requires the `web-component-tester` npm module.
|
This step requires the `web-component-tester` npm module.
|
||||||
|
@@ -64,11 +64,12 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Handle("/", http.FileServer(http.Dir("app")))
|
http.Handle("/", addDevHeadersMiddleware(http.FileServer(http.Dir("app"))))
|
||||||
http.Handle("/bower_components/",
|
http.Handle("/bower_components/",
|
||||||
http.FileServer(httpfs.New(zipfs.New(componentsArchive, "bower_components"))))
|
addDevHeadersMiddleware(
|
||||||
|
http.FileServer(httpfs.New(zipfs.New(componentsArchive, "bower_components")))))
|
||||||
http.Handle("/fonts/",
|
http.Handle("/fonts/",
|
||||||
http.FileServer(httpfs.New(zipfs.New(fontsArchive, "fonts"))))
|
addDevHeadersMiddleware(http.FileServer(httpfs.New(zipfs.New(fontsArchive, "fonts")))))
|
||||||
|
|
||||||
http.HandleFunc("/index.html", handleIndex)
|
http.HandleFunc("/index.html", handleIndex)
|
||||||
http.HandleFunc("/changes/", handleProxy)
|
http.HandleFunc("/changes/", handleProxy)
|
||||||
@@ -92,6 +93,14 @@ func main() {
|
|||||||
log.Fatal(http.ListenAndServe(*port, &server{}))
|
log.Fatal(http.ListenAndServe(*port, &server{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addDevHeadersMiddleware(h http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
|
||||||
|
writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
writer.Header().Set("Cache-Control", "public, max-age=10, must-revalidate")
|
||||||
|
h.ServeHTTP(writer, req)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func openDataArchive(path string) (*zip.ReadCloser, error) {
|
func openDataArchive(path string) (*zip.ReadCloser, error) {
|
||||||
absBinPath, err := resourceBasePath()
|
absBinPath, err := resourceBasePath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user