Skip to content

Commit

Permalink
Keeping build output and ability to show it in the web UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
jlahoda authored Jan 28, 2020
1 parent 61238c4 commit 3aaa0c0
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.netbeans.jackpot.prs.webapp;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.prefs.Preferences;

/**
Expand All @@ -43,4 +44,7 @@ public Preferences getPreferences() {
return Preferences.userRoot();
}

public Path getRunDir() {
return Paths.get(getPreferences().node("app").get("run_dir", ""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.servlet.ServletContainer;

Expand Down Expand Up @@ -81,4 +82,6 @@ public static void main(String... origArgs) throws IOException {
System.out.println("Running on port: " + gws.getSelectorThread().getPortLowLevel());
}
}

public static final Logger LOG = Logger.getLogger(WebApp.class.getName());
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
Expand Down Expand Up @@ -82,7 +80,7 @@ public static String main(@Context HttpServletRequest request) {
} else {
checked = "";
}
page.append("<li><input type='checkbox' onclick='enableDisable(\"" + userLogin + "/" + e.getValue().getName() + "\")'" + checked + "/>"+ e.getValue().getName() + "</li>");
page.append("<li><input type='checkbox' onclick='enableDisable(\"" + userLogin + "/" + e.getValue().getName() + "\")'" + checked + "/><a href=\"/github/repopullrequests?repositoryName=" + userLogin + "/" + e.getValue().getName() + "\">" + e.getValue().getName() + "</a></li>");
}
page.append("</ul>");
Set<String> admins = Set.of(Config.getDefault().getPreferences().node("app").get("admins", "").split(","));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.prefs.Preferences;
import java.util.zip.GZIPOutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
Expand Down Expand Up @@ -71,7 +73,55 @@ public static void webhook(String data) throws IOException {
//XXX: how to handle the access tokens?
builder.environment().put("OAUTH_TOKEN", Config.getDefault().getPreferences().node("users").node(userAndRepo[0]).get("access_token", ""));
builder.environment().put("OAUTH_APP_TOKEN", Config.getDefault().getPreferences().node("app").get("access_token", ""));
//TODO: logs!
builder.inheritIO().start();
java.nio.file.Path targetDir = Config.getDefault().getRunDir().resolve("github").resolve((String) repository.get("full_name"));
java.nio.file.Path thisRunDir = targetDir.resolve(String.valueOf((Integer) pullRequest.get("number")));
Files.createDirectories(thisRunDir);
Files.deleteIfExists(thisRunDir.resolve("finished"));
Files.newOutputStream(thisRunDir.resolve("preparing")).close();
java.nio.file.Path stdout = thisRunDir.resolve("stdout");
builder.redirectOutput(stdout.toFile());
java.nio.file.Path stderr = thisRunDir.resolve("stderr");
builder.redirectError(stderr.toFile());
Process process = builder.start();
Files.newOutputStream(thisRunDir.resolve("running")).close();
Files.delete(thisRunDir.resolve("preparing"));
new Thread(() -> {
while (true) {
try {
process.waitFor();
break;
} catch (InterruptedException ex) {
//ignore...
}
}
try {
Files.newOutputStream(thisRunDir.resolve("finished")).close();
} catch (IOException ex) {
WebApp.LOG.log(Level.SEVERE, null, ex);
}
try {
Files.delete(thisRunDir.resolve("running"));
} catch (IOException ex) {
WebApp.LOG.log(Level.SEVERE, null, ex);
}
pack(stdout);
pack(stderr);
}).start();
}

private static void pack(java.nio.file.Path log) {
java.nio.file.Path logGZ = log.getParent().resolve(log.getFileName() + ".gz");
try (InputStream in = Files.newInputStream(log);
OutputStream out = new GZIPOutputStream(Files.newOutputStream(logGZ))) {
int r;

while ((r = in.read()) != (-1)) {
out.write(r);
}

Files.delete(log);
} catch (IOException ex) {
WebApp.LOG.log(Level.SEVERE, null, ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.jackpot.prs.webapp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.util.logging.Level;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

/**
*
* @author lahvac
*/
@Path("/github/repopullrequests")
public class WebAppRepoPullRequests {
@GET
@Produces(MediaType.TEXT_HTML)
public static String repoPullRequests(@Context HttpServletRequest request, @QueryParam("repositoryName") String repositoryName) throws IOException {
String userName = (String) request.getSession().getAttribute("user_name");
if (userName != null) {
if (repositoryName.startsWith(userName + "/")) {
return "<html>" +
"<body>" +
" Repository: " + repositoryName + " not owned by: " + userName +
"</body>";
}
StringBuilder page = new StringBuilder();
page.append("<html>");
page.append("<body>");
page.append("Pull Requests of: " + repositoryName);
page.append("<ul>");
java.nio.file.Path targetDir = Config.getDefault().getRunDir().resolve("github").resolve(repositoryName);
try (DirectoryStream<java.nio.file.Path> ds = Files.newDirectoryStream(targetDir)) {
for (java.nio.file.Path p : ds) {
String pr = p.getFileName().toString();
page.append("<li>");
page.append(pr);
page.append("&nbsp;");
if (Files.exists(p.resolve("preparing"))) {
page.append("preparing");
}
if (Files.exists(p.resolve("running"))) {
page.append("running");
}
if (Files.exists(p.resolve("finished"))) {
page.append("finished");
}
if (Files.exists(p.resolve("stdout")) || Files.exists(p.resolve("stdout.gz"))) {
page.append("<a href=\"/github/repopullrequests/stdout?repositoryName=" + repositoryName + "&pr=" + pr + "\">stdout</a>");
}
if (Files.exists(p.resolve("stderr")) || Files.exists(p.resolve("stderr.gz"))) {
page.append("<a href=\"/github/repopullrequests/stderr?repositoryName=" + repositoryName + "&pr=" + pr + "\">stderr</a>");
}
page.append("</li>");
}
} catch (IOException ex) {
WebApp.LOG.log(Level.FINE, null, ex);
}
page.append("</ul>");
page.append("</body>");
return page.toString();
} else {
String clientId = Config.getDefault().getPreferences().node("app").get("client_id", null);
return "<html>" +
"<body>" +
" <a href=\"https://github.com/login/oauth/authorize?client_id=" + clientId + "&scope=write:repo_hook%20repo:status&state=9843759384\">Login with GitHub.</a>" +
"</body>";
}
}

@GET
@Path("/stdout")
public static Response stdout(@Context HttpServletRequest request, @QueryParam("repositoryName") String repositoryName, @QueryParam("pr") String pr) throws IOException {
return log(request, repositoryName, pr, "stdout");
}

@GET
@Path("/stderr")
public static Response stderr(@Context HttpServletRequest request, @QueryParam("repositoryName") String repositoryName, @QueryParam("pr") String pr) throws IOException {
return log(request, repositoryName, pr, "stderr");
}

private static Response log(HttpServletRequest request, String repositoryName, String pr, String log) throws IOException {
String userName = (String) request.getSession().getAttribute("user_name");
if (userName != null) {
if (repositoryName.startsWith(userName + "/")) {
return Response.ok("<html>" +
"<body>" +
" Repository: " + repositoryName + " not owned by: " + userName +
"</body>",
MediaType.TEXT_HTML)
.build();
}
class StreamingOutputImpl implements StreamingOutput {
@Override
public void write(OutputStream out) throws IOException, WebApplicationException {
java.nio.file.Path logFile = Config.getDefault().getRunDir().resolve("github").resolve(repositoryName).resolve(pr).resolve(log);
try (InputStream in = Files.newInputStream(logFile)) {
in.transferTo(out);
} catch (IOException ex) {
java.nio.file.Path logFileGZ = Config.getDefault().getRunDir().resolve("github").resolve(repositoryName).resolve(pr).resolve(log + ".gz");
try (InputStream in = new GZIPInputStream(Files.newInputStream(logFileGZ))) {
in.transferTo(out);
}
}
}
}
return Response.ok(new StreamingOutputImpl(), MediaType.TEXT_PLAIN)
.build();
} else {
String clientId = Config.getDefault().getPreferences().node("app").get("client_id", null);
return Response.ok("<html>" +
"<body>" +
" <a href=\"https://github.com/login/oauth/authorize?client_id=" + clientId + "&scope=write:repo_hook%20repo:status&state=9843759384\">Login with GitHub.</a>" +
"</body>",
MediaType.TEXT_HTML)
.build();

}
}
}

0 comments on commit 3aaa0c0

Please sign in to comment.