1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.skara.bots.bridgekeeper; 24 25 import org.openjdk.skara.bot.*; 26 import org.openjdk.skara.forge.*; 27 28 import java.nio.file.Path; 29 import java.util.*; 30 import java.util.function.Consumer; 31 import java.util.logging.Logger; 32 33 class BridgekeeperWorkItem implements WorkItem { 34 private final Logger log = Logger.getLogger("org.openjdk.skara.bots");; 35 private final HostedRepository repository; 36 private final PullRequest pr; 37 private final Consumer<RuntimeException> errorHandler; 38 39 BridgekeeperWorkItem(HostedRepository repository, PullRequest pr, Consumer<RuntimeException> errorHandler) { 40 this.pr = pr; 41 this.repository = repository; 42 this.errorHandler = errorHandler; 43 } 44 45 private final String welcomeMarker = "<!-- BridgeKeeperBot welcome message -->"; 46 47 private void checkWelcomeMessage() { 48 log.info("Checking welcome message of " + pr); 49 50 var comments = pr.comments(); 51 var welcomePosted = comments.stream() 52 .anyMatch(comment -> comment.body().contains(welcomeMarker)); 53 54 if (!welcomePosted) { 55 var message = "Welcome to the OpenJDK organization on GitHub!\n\n" + 56 "This repository is currently a read-only git mirror of the official Mercurial " + 57 "repository (located at https://hg.openjdk.java.net/). As such, we are not " + 58 "currently accepting pull requests here. If you would like to contribute to " + 59 "the OpenJDK project, please see http://openjdk.java.net/contribute/ on how " + 60 "to proceed.\n\n" + 61 "This pull request will be automatically closed."; 62 63 log.fine("Posting welcome message"); 64 pr.addComment(welcomeMarker + "\n\n" + message); 65 } 66 pr.setState(PullRequest.State.CLOSED); 67 } 68 69 70 @Override 71 public boolean concurrentWith(WorkItem other) { 72 if (!(other instanceof BridgekeeperWorkItem)) { 73 return true; 74 } 75 BridgekeeperWorkItem otherItem = (BridgekeeperWorkItem)other; 76 if (!pr.id().equals(otherItem.pr.id())) { 77 return true; 78 } 79 if (!repository.name().equals(otherItem.repository.name())) { 80 return true; 81 } 82 return false; 83 } 84 85 @Override 86 public void run(Path scratchPath) { 87 checkWelcomeMessage(); 88 } 89 90 @Override 91 public void handleRuntimeException(RuntimeException e) { 92 errorHandler.accept(e); 93 } 94 } 95 96 public class BridgekeeperBot implements Bot { 97 private final HostedRepository remoteRepo; 98 private final PullRequestUpdateCache updateCache; 99 100 BridgekeeperBot(HostedRepository repo) { 101 this.remoteRepo = repo; 102 this.updateCache = new PullRequestUpdateCache(); 103 } 104 105 @Override 106 public List<WorkItem> getPeriodicItems() { 107 List<WorkItem> ret = new LinkedList<>(); 108 109 for (var pr : remoteRepo.pullRequests()) { 110 if (updateCache.needsUpdate(pr)) { 111 var item = new BridgekeeperWorkItem(remoteRepo, pr, e -> updateCache.invalidate(pr)); 112 ret.add(item); 113 } 114 } 115 116 return ret; 117 } 118 }