blob: 65023b1de494e3659a10a0a0f71d8196d38bdc69 [file] [log] [blame]
Brian O'Connorbe95f682016-05-18 15:40:19 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.checkstyle;
17
Brian O'Connorbe95f682016-05-18 15:40:19 -070018import com.puppycrawl.tools.checkstyle.Checker;
19import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
20import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
21import com.puppycrawl.tools.checkstyle.PropertiesExpander;
22import com.puppycrawl.tools.checkstyle.api.AuditEvent;
23import com.puppycrawl.tools.checkstyle.api.AuditListener;
24import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
25import com.puppycrawl.tools.checkstyle.api.Configuration;
Thomas Vachuska275d2e82016-07-14 17:41:34 -070026import org.onosproject.buckdaemon.BuckTask;
27import org.onosproject.buckdaemon.BuckTaskContext;
Brian O'Connorbe95f682016-05-18 15:40:19 -070028
29import java.io.File;
Brian O'Connorbe95f682016-05-18 15:40:19 -070030import java.util.List;
31import java.util.concurrent.CountDownLatch;
32import java.util.stream.Collectors;
Brian O'Connorbe95f682016-05-18 15:40:19 -070033
Brian O'Connorfc247f42016-05-23 15:25:34 -070034import static com.google.common.base.Strings.isNullOrEmpty;
35
Thomas Vachuska275d2e82016-07-14 17:41:34 -070036/**
37 * Buck task for executing checkstyle on the specified project files.
38 */
39public class CheckstyleRunner implements BuckTask {
Brian O'Connorbe95f682016-05-18 15:40:19 -070040
41 private final Configuration config;
42
Thomas Vachuska275d2e82016-07-14 17:41:34 -070043 public CheckstyleRunner(String configLocation, String suppressionLocation) {
44 try {
45 // create a configuration
46 DefaultConfiguration config = (DefaultConfiguration) ConfigurationLoader
47 .loadConfiguration(configLocation, new PropertiesExpander(System.getProperties()));
Brian O'Connorbe95f682016-05-18 15:40:19 -070048
Thomas Vachuska275d2e82016-07-14 17:41:34 -070049 // add the suppression file to the configuration
50 DefaultConfiguration suppressions = new DefaultConfiguration("SuppressionFilter");
51 suppressions.addAttribute("file", suppressionLocation);
52 config.addChild(suppressions);
Brian O'Connorbe95f682016-05-18 15:40:19 -070053
Thomas Vachuska275d2e82016-07-14 17:41:34 -070054 this.config = config;
55 } catch (CheckstyleException e) {
56 throw new RuntimeException(e);
Brian O'Connorbe95f682016-05-18 15:40:19 -070057 }
Thomas Vachuska275d2e82016-07-14 17:41:34 -070058 }
59
60 @Override
61 public void execute(BuckTaskContext context) {
62 List<String> input = context.input();
63 if (input.size() < 3 || input.get(2).length() == 0) {
64 return;
65 }
66 String project = input.get(0);
67 String baseDir = input.get(1);
Brian O'Connorbe95f682016-05-18 15:40:19 -070068
69 // create a listener for output
Thomas Vachuska275d2e82016-07-14 17:41:34 -070070 StringAuditor listener = new StringAuditor(context);
Brian O'Connorfc247f42016-05-23 15:25:34 -070071 listener.setProjectName(project);
72 listener.setBaseDir(baseDir);
Brian O'Connorbe95f682016-05-18 15:40:19 -070073
74 // create Checker object and run it
75 final Checker checker = new Checker();
76 final ClassLoader moduleClassLoader = Checker.class.getClassLoader();
77 checker.setModuleClassLoader(moduleClassLoader);
78
79 try {
Brian O'Connorbe95f682016-05-18 15:40:19 -070080 checker.configure(config);
81 checker.addListener(listener);
82
83 // run Checker
Thomas Vachuska275d2e82016-07-14 17:41:34 -070084 List<File> fileList = input.subList(2, input.size() - 1).stream()
85 .map(File::new)
86 .collect(Collectors.toList());
Brian O'Connorbe95f682016-05-18 15:40:19 -070087 int errorCounter = checker.process(fileList);
88 if (errorCounter > 0) {
Thomas Vachuska275d2e82016-07-14 17:41:34 -070089 context.output("CHECKSTYLE ERROR");
Brian O'Connorbe95f682016-05-18 15:40:19 -070090 }
Thomas Vachuska275d2e82016-07-14 17:41:34 -070091
92 listener.await();
93 } catch (CheckstyleException | InterruptedException e) {
Ray Milkey8df94b82016-11-16 11:03:32 -080094 e.printStackTrace(); //dump exeception to stderr
Thomas Vachuska275d2e82016-07-14 17:41:34 -070095 throw new RuntimeException(e);
Brian O'Connorbe95f682016-05-18 15:40:19 -070096 } finally {
97 checker.destroy();
98 }
99
Brian O'Connorfc247f42016-05-23 15:25:34 -0700100 }
101
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700102 static class StringAuditor implements AuditListener {
Brian O'Connorbe95f682016-05-18 15:40:19 -0700103
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700104 private final BuckTaskContext context;
105 private CountDownLatch finishedLatch = new CountDownLatch(1);
106 private String baseDir = "";
107 private String project = "";
Brian O'Connorbe95f682016-05-18 15:40:19 -0700108
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700109 StringAuditor(BuckTaskContext context) {
110 this.context = context;
111 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700112
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700113 public void setBaseDir(String base) {
114 this.baseDir = base;
115 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700116
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700117 public void setProjectName(String projectName) {
118 this.project = projectName;
119 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700120
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700121 public void await() throws InterruptedException {
122 finishedLatch.await();
123 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700124
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700125 @Override
126 public void auditStarted(AuditEvent evt) {
127 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700128
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700129 @Override
130 public void auditFinished(AuditEvent evt) {
131 finishedLatch.countDown();
132 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700133
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700134 @Override
135 public void fileStarted(AuditEvent evt) {
136 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700137
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700138 @Override
139 public void fileFinished(AuditEvent evt) {
140 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700141
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700142 @Override
143 public void addError(AuditEvent evt) {
144 switch (evt.getSeverityLevel()) {
145 case ERROR:
146 StringBuilder output = new StringBuilder();
147 String fileName = evt.getFileName();
148 if (!isNullOrEmpty(baseDir)) {
149 int index = fileName.indexOf(baseDir);
150 if (index >= 0) {
151 fileName = fileName.substring(index + baseDir.length() + 1);
152 if (!isNullOrEmpty(project)) {
153 output.append(project).append(':');
154 }
Brian O'Connorfc247f42016-05-23 15:25:34 -0700155 }
156 }
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700157 output.append(fileName).append(':').append(evt.getLine());
158 if (evt.getColumn() > 0) {
159 output.append(':').append(evt.getColumn());
160 }
161 output.append(": ").append(evt.getMessage());
162 context.output(output.toString());
163 break;
164 case IGNORE:
165 case INFO:
166 case WARNING:
167 default:
168 break;
169 }
170 }
171
172 @Override
173 public void addException(AuditEvent evt, Throwable throwable) {
174 addError(evt);
175 context.output(throwable.getMessage());
Brian O'Connorbe95f682016-05-18 15:40:19 -0700176 }
177 }
178
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700179}