blob: 25f3d5346885524cd5e9091ded4ce9585d95634b [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) {
94 throw new RuntimeException(e);
Brian O'Connorbe95f682016-05-18 15:40:19 -070095 } finally {
96 checker.destroy();
97 }
98
Brian O'Connorfc247f42016-05-23 15:25:34 -070099 }
100
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700101 static class StringAuditor implements AuditListener {
Brian O'Connorbe95f682016-05-18 15:40:19 -0700102
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700103 private final BuckTaskContext context;
104 private CountDownLatch finishedLatch = new CountDownLatch(1);
105 private String baseDir = "";
106 private String project = "";
Brian O'Connorbe95f682016-05-18 15:40:19 -0700107
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700108 StringAuditor(BuckTaskContext context) {
109 this.context = context;
110 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700111
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700112 public void setBaseDir(String base) {
113 this.baseDir = base;
114 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700115
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700116 public void setProjectName(String projectName) {
117 this.project = projectName;
118 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700119
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700120 public void await() throws InterruptedException {
121 finishedLatch.await();
122 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700123
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700124 @Override
125 public void auditStarted(AuditEvent evt) {
126 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700127
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700128 @Override
129 public void auditFinished(AuditEvent evt) {
130 finishedLatch.countDown();
131 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700132
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700133 @Override
134 public void fileStarted(AuditEvent evt) {
135 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700136
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700137 @Override
138 public void fileFinished(AuditEvent evt) {
139 }
Brian O'Connorbe95f682016-05-18 15:40:19 -0700140
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700141 @Override
142 public void addError(AuditEvent evt) {
143 switch (evt.getSeverityLevel()) {
144 case ERROR:
145 StringBuilder output = new StringBuilder();
146 String fileName = evt.getFileName();
147 if (!isNullOrEmpty(baseDir)) {
148 int index = fileName.indexOf(baseDir);
149 if (index >= 0) {
150 fileName = fileName.substring(index + baseDir.length() + 1);
151 if (!isNullOrEmpty(project)) {
152 output.append(project).append(':');
153 }
Brian O'Connorfc247f42016-05-23 15:25:34 -0700154 }
155 }
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700156 output.append(fileName).append(':').append(evt.getLine());
157 if (evt.getColumn() > 0) {
158 output.append(':').append(evt.getColumn());
159 }
160 output.append(": ").append(evt.getMessage());
161 context.output(output.toString());
162 break;
163 case IGNORE:
164 case INFO:
165 case WARNING:
166 default:
167 break;
168 }
169 }
170
171 @Override
172 public void addException(AuditEvent evt, Throwable throwable) {
173 addError(evt);
174 context.output(throwable.getMessage());
Brian O'Connorbe95f682016-05-18 15:40:19 -0700175 }
176 }
177
Thomas Vachuska275d2e82016-07-14 17:41:34 -0700178}