Convert build to buck Build a plugin jar linked that depends on this plugin being cloned/linked into the Gerrit tree so it has access to Gerrit's buck defs. Build an output jar including resources in /+static. The Gerrit-HttpStaticPrefix has to match the actual location in the jar of the resources. Unlike the Gitiles dev server, which actually maps /+static to an arbitrary resource path, we need to copy these to the root of the jar. Encoded URIs would also be passed through untouched to Gitiles, which would cause errors finding repositories or performing diffs. By decoding the URI in a filter and HttpRequestWrapper, we can instead provide the decoded URI to Gitiles. Change-Id: I9974756cb6fdcf6efdf2effd62016431ea2d49c1
diff --git a/BUCK b/BUCK new file mode 100644 index 0000000..41dc7a7 --- /dev/null +++ b/BUCK
@@ -0,0 +1,89 @@ +include_defs('//lib/maven.defs') + +genrule( + name = 'gitiles', + cmd = ' && '.join([ + 'cp $(location :gitiles_base) $OUT', + 'unzip -qd $TMP $(location :gitiles-servlet) "com/google/gitiles/static/*"', + 'cd $TMP/com/google/gitiles', + 'mv static +static', + 'zip -Drq $OUT -g . -i "+static/*"', + ]), + out = 'gitiles.jar', + deps = [ + ':gitiles-servlet', + ':gitiles_base', + ], +) + +gerrit_plugin( + name = 'gitiles_base', + srcs = glob(['src/main/java/**/*.java']), + deps = [ + ':gitiles-servlet', + + # Deps only needed by Gitiles. + ':guice-multibindings', + ':soy', + ':commons-lang3', + ], + # Deps shared with Gerrit but not in the plugin API. + compile_deps = [ + '//lib/jgit:jgit-servlet', + ], + resources = glob(['src/main/resources/**/*']), + manifest_entries = [ + 'Gerrit-PluginName: gitiles', + 'Gerrit-Module: com.googlesource.gerrit.plugins.gitiles.Module', + 'Gerrit-HttpModule: com.googlesource.gerrit.plugins.gitiles.HttpModule', + 'Gerrit-InitStep: com.googlesource.gerrit.plugins.gitiles.InitGitiles', + + # Gitiles uses /repo to access a repo, so the default plugin layout would + # disallow repos named "static" or "Documentation". Paths starting with + + # are reserved by Gitiles and can't match repos. + 'Gerrit-HttpStaticPrefix: +static', + 'Gerrit-HttpDocumentationPrefix: +Documentation', + ], + visibility = [], +) + +maven_jar( + name = 'gitiles-servlet', + id = 'com.google.gitiles:gitiles-servlet:0.1-2', + sha1 = '31c84c6fdcde30174c70e4f1f5a5a8d71c57a19e', + license = 'Apache2.0', + repository = GERRIT, + visibility = [], +) + +maven_jar( + name = 'commons-lang3', + id = 'org.apache.commons:commons-lang3:3.1', + sha1 = '905075e6c80f206bbe6cf1e809d2caa69f420c76', + license = 'Apache2.0', + visibility = [], +) + +maven_jar( + name = 'soy', + id = 'com.google.template:soy:2012-12-21', + sha1 = 'cc28da103845a0f08cfd3fa5abdd45899b0adae1', + license = 'Apache2.0', + visibility = [], +) + +maven_jar( + name = 'guice-multibindings', + id = 'com.google.inject.extensions:guice-multibindings:4.0-beta', + sha1 = '558a3dcfd203db33a5a96a70a18076c866723ee4', + license = 'Apache2.0', + exclude_java_sources = True, + exclude = [ + 'META-INF/DEPENDENCIES', + 'META-INF/LICENSE', + 'META-INF/NOTICE', + 'META-INF/maven/com.google.guava/guava/pom.properties', + 'META-INF/maven/com.google.guava/guava/pom.xml', + ], + visibility = [], +)
diff --git a/pom.xml b/pom.xml deleted file mode 100644 index dd31e43..0000000 --- a/pom.xml +++ /dev/null
@@ -1,172 +0,0 @@ -<!-- -Copyright (C) 2013 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <groupId>com.googlesource.gerrit.plugins.gitiles</groupId> - <artifactId>gitiles</artifactId> - <packaging>jar</packaging> - <version>1.0-SNAPSHOT</version> - <name>gitiles</name> - - <properties> - <Gerrit-ApiType>plugin</Gerrit-ApiType> - <Gerrit-ApiVersion>2.10-SNAPSHOT</Gerrit-ApiVersion> - - <gitilesVersion>0.1-2</gitilesVersion> - </properties> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <version>2.4</version> - <configuration> - <archive> - <manifestEntries> - </manifestEntries> - </archive> - </configuration> - </plugin> - - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>2.3.2</version> - <configuration> - <source>1.6</source> - <target>1.6</target> - <encoding>UTF-8</encoding> - </configuration> - </plugin> - - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-shade-plugin</artifactId> - <version>1.6</version> - <configuration> - <promoteTransitiveDependencies>true</promoteTransitiveDependencies> - <artifactSet> - <excludes> - <!-- Common Gitiles/Gerrit/Soy transitive dependencies. --> - <exclude>aopalliance:aopalliance</exclude> - <exclude>args4j:args4j</exclude> - <exclude>com.google.code.findbugs:jsr305</exclude> - <exclude>com.google.code.gson:gson</exclude> - <exclude>com.google.guava:guava</exclude> - <exclude>com.google.inject.extensions:guice-assistedinject</exclude> - <exclude>com.google.inject:guice</exclude> - <exclude>com.google.inject:guice-multibindings:3.0</exclude> - <exclude>com.googlecode.javaewah</exclude> - <exclude>com.jcraft:jsch</exclude> - <exclude>javax.inject:javax.inject</exclude> - <exclude>org.eclipse.jgit:org.eclipse.jgit.http.server</exclude> - <exclude>org.eclipse.jgit:org.eclipse.jgit</exclude> - <exclude>org.slf4j:slf4j-api</exclude> - </excludes> - </artifactSet> - <transformers> - <transformer - implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> - <manifestEntries> - <Gerrit-Module>com.googlesource.gerrit.plugins.gitiles.Module</Gerrit-Module> - <Gerrit-HttpModule>com.googlesource.gerrit.plugins.gitiles.HttpModule</Gerrit-HttpModule> - <Gerrit-InitStep>com.googlesource.gerrit.plugins.gitiles.InitGitiles</Gerrit-InitStep> - - <!-- Gitiles uses /repo to access a repo, so the default plugin layout would - disallow repos named "static" or "Documentation". Paths starting with + are - reserved by Gitiles and can't match repos. --> - <Gerrit-HttpStaticPrefix>+static</Gerrit-HttpStaticPrefix>> - <Gerrit-HttpDocumentationPrefix>+Documentation</Gerrit-HttpDocumentationPrefix>> - - <Implementation-Vendor>Gerrit Code Review</Implementation-Vendor> - <Implementation-URL>http://code.google.com/p/gerrit/</Implementation-URL> - <Implementation-Title>${Gerrit-ApiType} ${project.artifactId}</Implementation-Title> - <Implementation-Version>${project.version}</Implementation-Version> - <Gerrit-ApiType>${Gerrit-ApiType}</Gerrit-ApiType> - <Gerrit-ApiVersion>${Gerrit-ApiVersion}</Gerrit-ApiVersion> - </manifestEntries> - </transformer> - </transformers> - <filters> - <filter> - <artifact>*:*</artifact> - <excludes> - <exclude>META-INF/*.SF</exclude> - <exclude>META-INF/*.DSA</exclude> - <exclude>META-INF/*.RSA</exclude> - </excludes> - </filter> - </filters> - <relocations> - <relocation> - <pattern>com.google.gitiles.static</pattern> - <shadedPattern>+static</shadedPattern> - </relocation> - </relocations> - - </configuration> - <executions> - <execution> - <phase>package</phase> - <goals> - <goal>shade</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> - - <dependencies> - <dependency> - <groupId>com.google.gerrit</groupId> - <artifactId>gerrit-${Gerrit-ApiType}-api</artifactId> - <version>${Gerrit-ApiVersion}</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>com.google.gitiles</groupId> - <artifactId>gitiles-servlet</artifactId> - <version>${gitilesVersion}</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.11</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>com.google.inject.extensions</groupId> - <artifactId>guice-multibindings</artifactId> - <version>4.0-beta</version> - </dependency> - </dependencies> - - <repositories> - <repository> - <id>gerrit-api-repository</id> - <url>https://gerrit-api.commondatastorage.googleapis.com/snapshot/</url> - </repository> - </repositories> -</project>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitiles/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/gitiles/HttpModule.java index a5d7023..9913999 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/gitiles/HttpModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/gitiles/HttpModule.java
@@ -34,16 +34,56 @@ import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; class HttpModule extends ServletModule { + protected Filter createPathFilter() { + return new Filter() { + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletRequestWrapper wrappedRequest = + new HttpServletRequestWrapper((HttpServletRequest) request) { + @Override + public String getRequestURI() { + try { + // Note: URLDecoder.decode() will decode "+" to a space. + // This doesn't work, so use URI.getPath() instead. + URI uri = new URI(super.getRequestURI()); + return uri.getPath(); + } catch (URISyntaxException e) { + return super.getRequestURI(); + } + } + }; + chain.doFilter(wrappedRequest, response); + } + + @Override + public void destroy() {} + + @Override + public void init(FilterConfig config) throws ServletException {} + }; + } + private static final Logger log = LoggerFactory .getLogger(ServletModule.class); @Override protected void configureServlets() { + // Filter all paths so we can decode escaped entities in the URI + filter("/*").through(createPathFilter()); // Let /+static, /+Documentation, etc. fall through to default servlet, but // handle everything else. serveRegex("^(/)$", "^(/[^+].*)").with(GitilesServlet.class);